{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TupleSections #-}
module Theory.Drasil.DifferentialModel (
DifferentialModel(..), ODESolverFormat(..), InitialValueProblem(..),
($^^), ($**), ($++),
makeAODESolverFormat, makeAIVP, makeASystemDE, makeASingleDE,
formEquations
) where
import Control.Lens (makeLenses, (^.), view)
import Data.List (find)
import Drasil.Database (HasUID(uid))
import Language.Drasil
(ConceptChunk, dccWDS, Express(..), ConceptDomain(..), Definition(..), Idea(..), NamedIdea(..)
, ModelExpr, NP, Sentence, Expr, UnitalChunk, ModelExprC(nthderiv, equiv)
, ExprC(..), columnVec, ConstrConcept, LiteralC(exactDbl, int), RequiresChecking (requiredChecks)
, Space, HasSpace (..), dqdWr)
type Unknown = Integer
data Term = T{
Term -> Expr
_coeff :: Expr,
Term -> Unknown
_unk :: Unknown
}
makeLenses ''Term
type LHS = [Term]
($^^) :: ConstrConcept -> Integer -> Unknown
$^^ :: ConstrConcept -> Unknown -> Unknown
($^^) ConstrConcept
_ Unknown
unk' = Unknown
unk'
($**) :: Expr -> Unknown -> Term
$** :: Expr -> Unknown -> Term
($**) = Expr -> Unknown -> Term
T
($++) :: [Term] -> Term -> LHS
$++ :: [Term] -> Term -> [Term]
($++) [Term]
xs Term
x = [Term]
xs [Term] -> [Term] -> [Term]
forall a. [a] -> [a] -> [a]
++ [Term
x]
data DifferentialModel = SystemOfLinearODEs {
DifferentialModel -> UnitalChunk
_indepVar :: UnitalChunk,
DifferentialModel -> ConstrConcept
_depVar :: ConstrConcept,
DifferentialModel -> [[Expr]]
_coefficients :: [[Expr]],
DifferentialModel -> [Unknown]
_unknowns :: [Unknown],
DifferentialModel -> [Expr]
_dmConstants :: [Expr],
DifferentialModel -> ConceptChunk
_dmconc :: ConceptChunk
}
makeLenses ''DifferentialModel
data InitialValueProblem = IVP{
InitialValueProblem -> Expr
initTime :: Expr,
InitialValueProblem -> Expr
finalTime :: Expr,
InitialValueProblem -> [Expr]
initValues :: [Expr]
}
data ODESolverFormat = X'{
ODESolverFormat -> [[Expr]]
coeffVects :: [[Expr]],
ODESolverFormat -> [Unknown]
unknownVect :: [Integer],
ODESolverFormat -> [Expr]
constantVect :: [Expr]
}
instance HasUID DifferentialModel where uid :: Getter DifferentialModel UID
uid = (ConceptChunk -> f ConceptChunk)
-> DifferentialModel -> f DifferentialModel
Lens' DifferentialModel ConceptChunk
dmconc ((ConceptChunk -> f ConceptChunk)
-> DifferentialModel -> f DifferentialModel)
-> ((UID -> f UID) -> ConceptChunk -> f ConceptChunk)
-> (UID -> f UID)
-> DifferentialModel
-> f DifferentialModel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UID -> f UID) -> ConceptChunk -> f ConceptChunk
forall c. HasUID c => Getter c UID
Getter ConceptChunk UID
uid
instance Eq DifferentialModel where DifferentialModel
a == :: DifferentialModel -> DifferentialModel -> Bool
== DifferentialModel
b = (DifferentialModel
a DifferentialModel -> Getting UID DifferentialModel UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID DifferentialModel UID
forall c. HasUID c => Getter c UID
Getter DifferentialModel UID
uid) UID -> UID -> Bool
forall a. Eq a => a -> a -> Bool
== (DifferentialModel
b DifferentialModel -> Getting UID DifferentialModel UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID DifferentialModel UID
forall c. HasUID c => Getter c UID
Getter DifferentialModel UID
uid)
instance NamedIdea DifferentialModel where term :: Lens' DifferentialModel NP
term = (ConceptChunk -> f ConceptChunk)
-> DifferentialModel -> f DifferentialModel
Lens' DifferentialModel ConceptChunk
dmconc ((ConceptChunk -> f ConceptChunk)
-> DifferentialModel -> f DifferentialModel)
-> ((NP -> f NP) -> ConceptChunk -> f ConceptChunk)
-> (NP -> f NP)
-> DifferentialModel
-> f DifferentialModel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NP -> f NP) -> ConceptChunk -> f ConceptChunk
forall c. NamedIdea c => Lens' c NP
Lens' ConceptChunk NP
term
instance Idea DifferentialModel where getA :: DifferentialModel -> Maybe String
getA = ConceptChunk -> Maybe String
forall c. Idea c => c -> Maybe String
getA (ConceptChunk -> Maybe String)
-> (DifferentialModel -> ConceptChunk)
-> DifferentialModel
-> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting ConceptChunk DifferentialModel ConceptChunk
-> DifferentialModel -> ConceptChunk
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting ConceptChunk DifferentialModel ConceptChunk
Lens' DifferentialModel ConceptChunk
dmconc
instance Definition DifferentialModel where defn :: Lens' DifferentialModel Sentence
defn = (ConceptChunk -> f ConceptChunk)
-> DifferentialModel -> f DifferentialModel
Lens' DifferentialModel ConceptChunk
dmconc ((ConceptChunk -> f ConceptChunk)
-> DifferentialModel -> f DifferentialModel)
-> ((Sentence -> f Sentence) -> ConceptChunk -> f ConceptChunk)
-> (Sentence -> f Sentence)
-> DifferentialModel
-> f DifferentialModel
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sentence -> f Sentence) -> ConceptChunk -> f ConceptChunk
forall c. Definition c => Lens' c Sentence
Lens' ConceptChunk Sentence
defn
instance ConceptDomain DifferentialModel where cdom :: DifferentialModel -> [UID]
cdom = ConceptChunk -> [UID]
forall c. ConceptDomain c => c -> [UID]
cdom (ConceptChunk -> [UID])
-> (DifferentialModel -> ConceptChunk)
-> DifferentialModel
-> [UID]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting ConceptChunk DifferentialModel ConceptChunk
-> DifferentialModel -> ConceptChunk
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting ConceptChunk DifferentialModel ConceptChunk
Lens' DifferentialModel ConceptChunk
dmconc
instance Express DifferentialModel where express :: DifferentialModel -> ModelExpr
express = DifferentialModel -> ModelExpr
formStdODE
instance RequiresChecking DifferentialModel Expr Space where
requiredChecks :: DifferentialModel -> [(Expr, Space)]
requiredChecks DifferentialModel
dmo = (Expr -> (Expr, Space)) -> [Expr] -> [(Expr, Space)]
forall a b. (a -> b) -> [a] -> [b]
map (, DifferentialModel
dmo DifferentialModel -> Getting Space DifferentialModel Space -> Space
forall s a. s -> Getting a s a -> a
^. ((ConstrConcept -> Const Space ConstrConcept)
-> DifferentialModel -> Const Space DifferentialModel
Lens' DifferentialModel ConstrConcept
depVar ((ConstrConcept -> Const Space ConstrConcept)
-> DifferentialModel -> Const Space DifferentialModel)
-> ((Space -> Const Space Space)
-> ConstrConcept -> Const Space ConstrConcept)
-> Getting Space DifferentialModel Space
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Space -> Const Space Space)
-> ConstrConcept -> Const Space ConstrConcept
forall c. HasSpace c => Getter c Space
Getter ConstrConcept Space
typ)) ([Expr] -> [(Expr, Space)]) -> [Expr] -> [(Expr, Space)]
forall a b. (a -> b) -> a -> b
$ [[Expr]] -> [Unknown] -> [Expr] -> ConstrConcept -> [Expr]
formEquations (ODESolverFormat -> [[Expr]]
coeffVects ODESolverFormat
dm) (ODESolverFormat -> [Unknown]
unknownVect ODESolverFormat
dm) (ODESolverFormat -> [Expr]
constantVect ODESolverFormat
dm) (DifferentialModel -> ConstrConcept
_depVar DifferentialModel
dmo)
where dm :: ODESolverFormat
dm = DifferentialModel -> ODESolverFormat
makeAODESolverFormat DifferentialModel
dmo
formStdODE :: DifferentialModel -> ModelExpr
formStdODE :: DifferentialModel -> ModelExpr
formStdODE DifferentialModel
d
| Int
size Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = [Expr] -> [ModelExpr] -> [Expr] -> ModelExpr
formASingleODE ([[Expr]] -> [Expr]
forall a. HasCallStack => [a] -> a
head (DifferentialModel
d DifferentialModel
-> Getting [[Expr]] DifferentialModel [[Expr]] -> [[Expr]]
forall s a. s -> Getting a s a -> a
^. Getting [[Expr]] DifferentialModel [[Expr]]
Lens' DifferentialModel [[Expr]]
coefficients)) [ModelExpr]
unknownVec (DifferentialModel
d DifferentialModel
-> Getting [Expr] DifferentialModel [Expr] -> [Expr]
forall s a. s -> Getting a s a -> a
^. Getting [Expr] DifferentialModel [Expr]
Lens' DifferentialModel [Expr]
dmConstants)
| Bool
otherwise = [ModelExpr] -> ModelExpr
forall r. ModelExprC r => [r] -> r
equiv (ModelExpr
coeffsMatix ModelExpr -> ModelExpr -> ModelExpr
forall r. ExprC r => r -> r -> r
$. [ModelExpr] -> ModelExpr
forall r. ExprC r => [r] -> r
columnVec [ModelExpr]
unknownVec ModelExpr -> [ModelExpr] -> [ModelExpr]
forall a. a -> [a] -> [a]
: [ModelExpr]
constantVec)
where size :: Int
size = [[Expr]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (DifferentialModel
d DifferentialModel
-> Getting [[Expr]] DifferentialModel [[Expr]] -> [[Expr]]
forall s a. s -> Getting a s a -> a
^. Getting [[Expr]] DifferentialModel [[Expr]]
Lens' DifferentialModel [[Expr]]
coefficients)
coeffsMatix :: ModelExpr
coeffsMatix = Expr -> ModelExpr
forall c. Express c => c -> ModelExpr
express([[Expr]] -> Expr
forall r. ExprC r => [[r]] -> r
matrix (DifferentialModel
d DifferentialModel
-> Getting [[Expr]] DifferentialModel [[Expr]] -> [[Expr]]
forall s a. s -> Getting a s a -> a
^. Getting [[Expr]] DifferentialModel [[Expr]]
Lens' DifferentialModel [[Expr]]
coefficients))
unknownVec :: [ModelExpr]
unknownVec = [Unknown] -> ConstrConcept -> UnitalChunk -> [ModelExpr]
formAllUnknown (DifferentialModel
d DifferentialModel
-> Getting [Unknown] DifferentialModel [Unknown] -> [Unknown]
forall s a. s -> Getting a s a -> a
^. Getting [Unknown] DifferentialModel [Unknown]
Lens' DifferentialModel [Unknown]
unknowns) (DifferentialModel
d DifferentialModel
-> Getting ConstrConcept DifferentialModel ConstrConcept
-> ConstrConcept
forall s a. s -> Getting a s a -> a
^. Getting ConstrConcept DifferentialModel ConstrConcept
Lens' DifferentialModel ConstrConcept
depVar) (DifferentialModel
d DifferentialModel
-> Getting UnitalChunk DifferentialModel UnitalChunk -> UnitalChunk
forall s a. s -> Getting a s a -> a
^. Getting UnitalChunk DifferentialModel UnitalChunk
Lens' DifferentialModel UnitalChunk
indepVar)
constantVec :: [ModelExpr]
constantVec = [Expr -> ModelExpr
forall c. Express c => c -> ModelExpr
express ([Expr] -> Expr
forall r. ExprC r => [r] -> r
columnVec (DifferentialModel
d DifferentialModel
-> Getting [Expr] DifferentialModel [Expr] -> [Expr]
forall s a. s -> Getting a s a -> a
^. Getting [Expr] DifferentialModel [Expr]
Lens' DifferentialModel [Expr]
dmConstants))]
formASingleODE :: [Expr] -> [ModelExpr] -> [Expr] -> ModelExpr
formASingleODE :: [Expr] -> [ModelExpr] -> [Expr] -> ModelExpr
formASingleODE [Expr]
coeffs [ModelExpr]
unks [Expr]
consts = [ModelExpr] -> ModelExpr
forall r. ModelExprC r => [r] -> r
equiv (ModelExpr
lhs ModelExpr -> [ModelExpr] -> [ModelExpr]
forall a. a -> [a] -> [a]
: [ModelExpr]
rhs)
where lhs :: ModelExpr
lhs = (ModelExpr -> ModelExpr -> ModelExpr) -> [ModelExpr] -> ModelExpr
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 ModelExpr -> ModelExpr -> ModelExpr
forall r. ExprC r => r -> r -> r
($+) (((Expr, ModelExpr) -> ModelExpr)
-> [(Expr, ModelExpr)] -> [ModelExpr]
forall a b. (a -> b) -> [a] -> [b]
map (\(Expr, ModelExpr)
x-> Expr -> ModelExpr
forall c. Express c => c -> ModelExpr
express ((Expr, ModelExpr) -> Expr
forall a b. (a, b) -> a
fst (Expr, ModelExpr)
x) ModelExpr -> ModelExpr -> ModelExpr
forall r. ExprC r => r -> r -> r
$* (Expr, ModelExpr) -> ModelExpr
forall a b. (a, b) -> b
snd (Expr, ModelExpr)
x) ([(Expr, ModelExpr)] -> [ModelExpr])
-> [(Expr, ModelExpr)] -> [ModelExpr]
forall a b. (a -> b) -> a -> b
$ [Expr] -> [ModelExpr] -> [(Expr, ModelExpr)]
filterZeroCoeff [Expr]
coeffs [ModelExpr]
unks)
rhs :: [ModelExpr]
rhs = (Expr -> ModelExpr) -> [Expr] -> [ModelExpr]
forall a b. (a -> b) -> [a] -> [b]
map Expr -> ModelExpr
forall c. Express c => c -> ModelExpr
express [Expr]
consts
filterZeroCoeff :: [Expr] -> [ModelExpr] -> [(Expr, ModelExpr)]
filterZeroCoeff :: [Expr] -> [ModelExpr] -> [(Expr, ModelExpr)]
filterZeroCoeff [Expr]
es [ModelExpr]
mes = ((Expr, ModelExpr) -> Bool)
-> [(Expr, ModelExpr)] -> [(Expr, ModelExpr)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(Expr, ModelExpr)
x -> (Expr, ModelExpr) -> Expr
forall a b. (a, b) -> a
fst (Expr, ModelExpr)
x Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
/= Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
0) ([(Expr, ModelExpr)] -> [(Expr, ModelExpr)])
-> [(Expr, ModelExpr)] -> [(Expr, ModelExpr)]
forall a b. (a -> b) -> a -> b
$ [Expr] -> [ModelExpr] -> [(Expr, ModelExpr)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Expr]
es [ModelExpr]
mes
formAllUnknown :: [Unknown] -> ConstrConcept -> UnitalChunk -> [ModelExpr]
formAllUnknown :: [Unknown] -> ConstrConcept -> UnitalChunk -> [ModelExpr]
formAllUnknown [Unknown]
unks ConstrConcept
dep UnitalChunk
ind = (Unknown -> ModelExpr) -> [Unknown] -> [ModelExpr]
forall a b. (a -> b) -> [a] -> [b]
map (\Unknown
x -> Unknown -> ConstrConcept -> UnitalChunk -> ModelExpr
formAUnknown Unknown
x ConstrConcept
dep UnitalChunk
ind) [Unknown]
unks
formAUnknown :: Unknown -> ConstrConcept-> UnitalChunk -> ModelExpr
formAUnknown :: Unknown -> ConstrConcept -> UnitalChunk -> ModelExpr
formAUnknown Unknown
unk'' ConstrConcept
dep = Unknown -> ModelExpr -> UnitalChunk -> ModelExpr
forall c.
(HasUID c, HasSymbol c) =>
Unknown -> ModelExpr -> c -> ModelExpr
forall r c.
(ModelExprC r, HasUID c, HasSymbol c) =>
Unknown -> r -> c -> r
nthderiv (Unknown -> Unknown
forall a. Integral a => a -> Unknown
toInteger Unknown
unk'') (DefinedQuantityDict -> ModelExpr
forall c. (HasUID c, HasSymbol c) => c -> ModelExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy (ConstrConcept -> DefinedQuantityDict
forall c.
(Quantity c, Concept c, MayHaveUnit c) =>
c -> DefinedQuantityDict
dqdWr ConstrConcept
dep))
makeASystemDE :: UnitalChunk -> ConstrConcept -> [[Expr]] -> [Unknown] -> [Expr]-> String -> NP -> Sentence -> DifferentialModel
makeASystemDE :: UnitalChunk
-> ConstrConcept
-> [[Expr]]
-> [Unknown]
-> [Expr]
-> String
-> NP
-> Sentence
-> DifferentialModel
makeASystemDE UnitalChunk
indepVar' ConstrConcept
depVar' [[Expr]]
coeffs [Unknown]
unks [Expr]
const' String
id' NP
term' Sentence
defn'
| [[Expr]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Expr]]
coeffs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [Expr] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expr]
const' =
String -> DifferentialModel
forall a. HasCallStack => String -> a
error String
"Length of coefficients matrix should equal to the length of the constant vector"
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [[Expr]] -> [Unknown] -> Bool
isCoeffsMatchUnknowns [[Expr]]
coeffs [Unknown]
unks =
String -> DifferentialModel
forall a. HasCallStack => String -> a
error String
"The length of each row vector in coefficients need to equal to the length of unknowns vector"
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Unknown] -> Bool
isUnknownDescending [Unknown]
unks =
String -> DifferentialModel
forall a. HasCallStack => String -> a
error String
"The order of giving unknowns need to be descending"
| Bool
otherwise = UnitalChunk
-> ConstrConcept
-> [[Expr]]
-> [Unknown]
-> [Expr]
-> ConceptChunk
-> DifferentialModel
SystemOfLinearODEs UnitalChunk
indepVar' ConstrConcept
depVar' [[Expr]]
coeffs [Unknown]
unks [Expr]
const'(String -> NP -> Sentence -> ConceptChunk
dccWDS String
id' NP
term' Sentence
defn')
makeASingleDE :: UnitalChunk -> ConstrConcept -> LHS -> Expr-> String -> NP -> Sentence -> DifferentialModel
makeASingleDE :: UnitalChunk
-> ConstrConcept
-> [Term]
-> Expr
-> String
-> NP
-> Sentence
-> DifferentialModel
makeASingleDE UnitalChunk
indepVar'' ConstrConcept
depVar'' [Term]
lhs Expr
const'' String
id'' NP
term'' Sentence
defn''
| [[Expr]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Expr]]
coeffs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [Expr] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expr
const''] =
String -> DifferentialModel
forall a. HasCallStack => String -> a
error String
"Length of coefficients matrix should equal to the length of the constant vector"
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [[Expr]] -> [Unknown] -> Bool
isCoeffsMatchUnknowns [[Expr]]
coeffs [Unknown]
unks =
String -> DifferentialModel
forall a. HasCallStack => String -> a
error String
"The length of each row vector in coefficients need to equal to the length of unknowns vector"
| Bool
otherwise = UnitalChunk
-> ConstrConcept
-> [[Expr]]
-> [Unknown]
-> [Expr]
-> ConceptChunk
-> DifferentialModel
SystemOfLinearODEs UnitalChunk
indepVar'' ConstrConcept
depVar'' [[Expr]]
coeffs [Unknown]
unks [Expr
const''](String -> NP -> Sentence -> ConceptChunk
dccWDS String
id'' NP
term'' Sentence
defn'')
where unks :: [Unknown]
unks = Unknown -> ConstrConcept -> [Unknown]
createAllUnknowns([Term] -> Term
findHighestOrder [Term]
lhs Term -> Getting Unknown Term Unknown -> Unknown
forall s a. s -> Getting a s a -> a
^. Getting Unknown Term Unknown
Lens' Term Unknown
unk) ConstrConcept
depVar''
coeffs :: [[Expr]]
coeffs = [[Term] -> [Unknown] -> [Expr]
createCoefficients [Term]
lhs [Unknown]
unks]
isCoeffsMatchUnknowns :: [[Expr]] -> [Unknown] -> Bool
isCoeffsMatchUnknowns :: [[Expr]] -> [Unknown] -> Bool
isCoeffsMatchUnknowns [] [Unknown]
_ = String -> Bool
forall a. HasCallStack => String -> a
error String
"Coefficients matrix can not be empty"
isCoeffsMatchUnknowns [[Expr]]
_ [] = String -> Bool
forall a. HasCallStack => String -> a
error String
"Unknowns column vector can not be empty"
isCoeffsMatchUnknowns [[Expr]]
coeffs [Unknown]
unks = ([Expr] -> Bool -> Bool) -> Bool -> [[Expr]] -> Bool
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\ [Expr]
x -> Bool -> Bool -> Bool
(&&) ([Expr] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Expr]
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Unknown] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Unknown]
unks)) Bool
True [[Expr]]
coeffs
isUnknownDescending :: [Unknown] -> Bool
isUnknownDescending :: [Unknown] -> Bool
isUnknownDescending [] = Bool
True
isUnknownDescending [Unknown
_] = Bool
True
isUnknownDescending (Unknown
x:Unknown
y:[Unknown]
xs) = Unknown
x Unknown -> Unknown -> Bool
forall a. Ord a => a -> a -> Bool
> Unknown
y Bool -> Bool -> Bool
&& [Unknown] -> Bool
isUnknownDescending [Unknown]
xs
findHighestOrder :: LHS -> Term
findHighestOrder :: [Term] -> Term
findHighestOrder = (Term -> Term -> Term) -> [Term] -> Term
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (\Term
x Term
y -> if Term
x Term -> Getting Unknown Term Unknown -> Unknown
forall s a. s -> Getting a s a -> a
^. Getting Unknown Term Unknown
Lens' Term Unknown
unk Unknown -> Unknown -> Bool
forall a. Ord a => a -> a -> Bool
>= Term
y Term -> Getting Unknown Term Unknown -> Unknown
forall s a. s -> Getting a s a -> a
^. Getting Unknown Term Unknown
Lens' Term Unknown
unk then Term
x else Term
y)
createAllUnknowns :: Unknown -> ConstrConcept -> [Unknown]
createAllUnknowns :: Unknown -> ConstrConcept -> [Unknown]
createAllUnknowns Unknown
highestUnk ConstrConcept
depv
| Unknown
highestUnk Unknown -> Unknown -> Bool
forall a. Eq a => a -> a -> Bool
== Unknown
0 = [Unknown
highestUnk]
| Bool
otherwise = Unknown
highestUnk Unknown -> [Unknown] -> [Unknown]
forall a. a -> [a] -> [a]
: Unknown -> ConstrConcept -> [Unknown]
createAllUnknowns (Unknown
highestUnk Unknown -> Unknown -> Unknown
forall a. Num a => a -> a -> a
- Unknown
1) ConstrConcept
depv
createCoefficients :: LHS -> [Unknown] -> [Expr]
createCoefficients :: [Term] -> [Unknown] -> [Expr]
createCoefficients [] [Unknown]
_ = String -> [Expr]
forall a. HasCallStack => String -> a
error String
"Left hand side is an empty list"
createCoefficients [Term]
_ [] = []
createCoefficients [Term]
lhs (Unknown
x:[Unknown]
xs) = Maybe Term -> Expr
genCoefficient (Unknown -> [Term] -> Maybe Term
findCoefficient Unknown
x [Term]
lhs) Expr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
: [Term] -> [Unknown] -> [Expr]
createCoefficients [Term]
lhs [Unknown]
xs
genCoefficient :: Maybe Term -> Expr
genCoefficient :: Maybe Term -> Expr
genCoefficient Maybe Term
Nothing = Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
0
genCoefficient (Just Term
x) = Term
x Term -> Getting Expr Term Expr -> Expr
forall s a. s -> Getting a s a -> a
^. Getting Expr Term Expr
Lens' Term Expr
coeff
findCoefficient :: Unknown -> LHS -> Maybe Term
findCoefficient :: Unknown -> [Term] -> Maybe Term
findCoefficient Unknown
u = (Term -> Bool) -> [Term] -> Maybe Term
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find(\Term
x -> Term
x Term -> Getting Unknown Term Unknown -> Unknown
forall s a. s -> Getting a s a -> a
^. Getting Unknown Term Unknown
Lens' Term Unknown
unk Unknown -> Unknown -> Bool
forall a. Eq a => a -> a -> Bool
== Unknown
u)
transUnknowns :: [Unknown] -> [Unknown]
transUnknowns :: [Unknown] -> [Unknown]
transUnknowns = [Unknown] -> [Unknown]
forall a. HasCallStack => [a] -> [a]
tail
transCoefficients :: [Expr] -> [Expr]
transCoefficients :: [Expr] -> [Expr]
transCoefficients [Expr]
es
| [Expr] -> Expr
forall a. HasCallStack => [a] -> a
head [Expr]
es Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
== Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
1 = [Expr] -> [Expr]
mapNeg ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [Expr] -> [Expr]
forall a. HasCallStack => [a] -> [a]
tail [Expr]
es
| Bool
otherwise = [Expr] -> [Expr]
mapNeg ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [Expr] -> [Expr]
forall a. HasCallStack => [a] -> [a]
tail ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ (Expr -> Expr) -> [Expr] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (Expr -> Expr -> Expr
forall r. ExprC r => r -> r -> r
$/ [Expr] -> Expr
forall a. HasCallStack => [a] -> a
head [Expr]
es) [Expr]
es
where mapNeg :: [Expr] -> [Expr]
mapNeg = (Expr -> Expr) -> [Expr] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (\Expr
x -> if Expr
x Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
== Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
0 then Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
0 else Expr -> Expr
forall r. ExprC r => r -> r
neg Expr
x)
addIdentityCoeffs :: [[Expr]] -> Int -> Int -> [[Expr]]
addIdentityCoeffs :: [[Expr]] -> Int -> Int -> [[Expr]]
addIdentityCoeffs [[Expr]]
es Int
len Int
index
| Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 = [[Expr]]
es
| Bool
otherwise = [[Expr]] -> Int -> Int -> [[Expr]]
addIdentityCoeffs (Int -> Int -> [Expr]
constIdentityRowVect Int
len Int
index [Expr] -> [[Expr]] -> [[Expr]]
forall a. a -> [a] -> [a]
: [[Expr]]
es) Int
len (Int
index Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
constIdentityRowVect :: Int -> Int -> [Expr]
constIdentityRowVect :: Int -> Int -> [Expr]
constIdentityRowVect Int
len Int
index = Int -> [Expr] -> [Expr]
addIdentityValue Int
index ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ Int -> Expr -> [Expr]
forall a. Int -> a -> [a]
replicate Int
len (Expr -> [Expr]) -> Expr -> [Expr]
forall a b. (a -> b) -> a -> b
$ Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
0
addIdentityValue :: Int -> [Expr] -> [Expr]
addIdentityValue :: Int -> [Expr] -> [Expr]
addIdentityValue Int
n [Expr]
es = ([Expr], [Expr]) -> [Expr]
forall a b. (a, b) -> a
fst ([Expr], [Expr])
splits [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
1] [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [Expr] -> [Expr]
forall a. HasCallStack => [a] -> [a]
tail (([Expr], [Expr]) -> [Expr]
forall a b. (a, b) -> b
snd ([Expr], [Expr])
splits)
where splits :: ([Expr], [Expr])
splits = Int -> [Expr] -> ([Expr], [Expr])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n [Expr]
es
addIdentityConsts :: [Expr] -> Int -> [Expr]
addIdentityConsts :: [Expr] -> Int -> [Expr]
addIdentityConsts [Expr]
expr Int
len = Int -> Expr -> [Expr]
forall a. Int -> a -> [a]
replicate (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
0) [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [Expr]
expr
divideConstant :: Expr -> Expr -> Expr
divideConstant :: Expr -> Expr -> Expr
divideConstant Expr
a Expr
b
| Expr
b Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
== Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
0 = String -> Expr
forall a. HasCallStack => String -> a
error String
"Divisor can't be zero"
| Expr
b Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
== Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
1 = Expr
a
| Bool
otherwise = Expr
a Expr -> Expr -> Expr
forall r. ExprC r => r -> r -> r
$/ Expr
b
makeAODESolverFormat :: DifferentialModel -> ODESolverFormat
makeAODESolverFormat :: DifferentialModel -> ODESolverFormat
makeAODESolverFormat DifferentialModel
dm = [[Expr]] -> [Unknown] -> [Expr] -> ODESolverFormat
X' [[Expr]]
transEs [Unknown]
transUnks [Expr]
transConsts
where transUnks :: [Unknown]
transUnks = [Unknown] -> [Unknown]
transUnknowns ([Unknown] -> [Unknown]) -> [Unknown] -> [Unknown]
forall a b. (a -> b) -> a -> b
$ DifferentialModel
dm DifferentialModel
-> Getting [Unknown] DifferentialModel [Unknown] -> [Unknown]
forall s a. s -> Getting a s a -> a
^. Getting [Unknown] DifferentialModel [Unknown]
Lens' DifferentialModel [Unknown]
unknowns
transEs :: [[Expr]]
transEs = [[Expr]] -> Int -> Int -> [[Expr]]
addIdentityCoeffs [[Expr] -> [Expr]
transCoefficients ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ [[Expr]] -> [Expr]
forall a. HasCallStack => [a] -> a
head (DifferentialModel
dm DifferentialModel
-> Getting [[Expr]] DifferentialModel [[Expr]] -> [[Expr]]
forall s a. s -> Getting a s a -> a
^. Getting [[Expr]] DifferentialModel [[Expr]]
Lens' DifferentialModel [[Expr]]
coefficients)] ([Unknown] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Unknown]
transUnks) Int
0
transConsts :: [Expr]
transConsts = [Expr] -> Int -> [Expr]
addIdentityConsts [[Expr] -> Expr
forall a. HasCallStack => [a] -> a
head (DifferentialModel
dm DifferentialModel
-> Getting [Expr] DifferentialModel [Expr] -> [Expr]
forall s a. s -> Getting a s a -> a
^. Getting [Expr] DifferentialModel [Expr]
Lens' DifferentialModel [Expr]
dmConstants) Expr -> Expr -> Expr
`divideConstant` [Expr] -> Expr
forall a. HasCallStack => [a] -> a
head ([[Expr]] -> [Expr]
forall a. HasCallStack => [a] -> a
head (DifferentialModel
dm DifferentialModel
-> Getting [[Expr]] DifferentialModel [[Expr]] -> [[Expr]]
forall s a. s -> Getting a s a -> a
^. Getting [[Expr]] DifferentialModel [[Expr]]
Lens' DifferentialModel [[Expr]]
coefficients))] ([Unknown] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Unknown]
transUnks)
formEquations :: [[Expr]] -> [Unknown] -> [Expr] -> ConstrConcept-> [Expr]
formEquations :: [[Expr]] -> [Unknown] -> [Expr] -> ConstrConcept -> [Expr]
formEquations [] [Unknown]
_ [Expr]
_ ConstrConcept
_ = []
formEquations [[Expr]]
_ [] [Expr]
_ ConstrConcept
_ = []
formEquations [[Expr]]
_ [Unknown]
_ [] ConstrConcept
_ = []
formEquations ([Expr]
ex:[[Expr]]
exs) [Unknown]
unks (Expr
y:[Expr]
ys) ConstrConcept
depVa =
(if Expr
y Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
== Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
0 then Expr
finalExpr else Expr
finalExpr Expr -> Expr -> Expr
forall r. ExprC r => r -> r -> r
$+ Expr
y) Expr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
: [[Expr]] -> [Unknown] -> [Expr] -> ConstrConcept -> [Expr]
formEquations [[Expr]]
exs [Unknown]
unks [Expr]
ys ConstrConcept
depVa
where indexUnks :: [Expr]
indexUnks = (Unknown -> Expr) -> [Unknown] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (Expr -> Expr -> Expr
forall r. ExprC r => r -> r -> r
idx (ConstrConcept -> Expr
forall c. (HasUID c, HasSymbol c) => c -> Expr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ConstrConcept
depVa) (Expr -> Expr) -> (Unknown -> Expr) -> Unknown -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Unknown -> Expr
forall r. LiteralC r => Unknown -> r
int) [Unknown]
unks
filteredExprs :: [(Expr, Expr)]
filteredExprs = ((Expr, Expr) -> Bool) -> [(Expr, Expr)] -> [(Expr, Expr)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(Expr, Expr)
x -> (Expr, Expr) -> Expr
forall a b. (a, b) -> a
fst (Expr, Expr)
x Expr -> Expr -> Bool
forall a. Eq a => a -> a -> Bool
/= Unknown -> Expr
forall r. LiteralC r => Unknown -> r
exactDbl Unknown
0) ([Expr] -> [Expr] -> [(Expr, Expr)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Expr]
ex [Expr]
indexUnks)
termExprs :: [Expr]
termExprs = ((Expr, Expr) -> Expr) -> [(Expr, Expr)] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map ((Expr -> Expr -> Expr) -> (Expr, Expr) -> Expr
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Expr -> Expr -> Expr
forall r. ExprC r => r -> r -> r
($*)) [(Expr, Expr)]
filteredExprs
finalExpr :: Expr
finalExpr = (Expr -> Expr -> Expr) -> [Expr] -> Expr
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 Expr -> Expr -> Expr
forall r. ExprC r => r -> r -> r
($+) [Expr]
termExprs
makeAIVP :: Expr -> Expr -> [Expr] -> InitialValueProblem
makeAIVP :: Expr -> Expr -> [Expr] -> InitialValueProblem
makeAIVP = Expr -> Expr -> [Expr] -> InitialValueProblem
IVP