-- | Define and collect information about ODEs and ODE solvers from various libraries.
module Data.Drasil.ExternalLibraries.ODELibraries (
  -- * SciPy Library (Python)
  scipyODEPckg, scipyODESymbols,
  -- * Oslo Library (C#)
  osloPckg, osloSymbols, arrayVecDepVar,
  -- * Apache Commons (Java)
  apacheODEPckg, apacheODESymbols,
  -- * Odeint (C++)
  odeintPckg, odeintSymbols
) where

import Language.Drasil (HasSymbol(symbol), HasUID(uid), MayHaveUnit(getUnit),
  QuantityDict, HasSpace(typ), Space (Actor, Natural, Real, Void, Boolean, String, Array, Vect), implVar,
  implVarUID, implVarUID', qw, compoundPhrase, nounPhrase, nounPhraseSP, label,
  sub, Idea(getA), NamedIdea(term), Stage(..), (+++))
import Language.Drasil.Display (Symbol(Label, Concat))

import Language.Drasil.Code (Lang(..), ExternalLibrary, Step, Argument,
  externalLib, mandatoryStep, mandatorySteps, choiceSteps, choiceStep,
  callStep, libFunction, libMethod, libFunctionWithResult, libMethodWithResult,
  libConstructor, libConstructorMultiReqs, constructAndReturn, lockedArg,
  lockedNamedArg, inlineArg, inlineNamedArg, preDefinedArg, functionArg,
  customObjArg, recordArg, lockedParam, unnamedParam, customClass,
  implementation, constructorInfo, methodInfo, methodInfoNoReturn,
  appendCurrSol, populateSolList, assignArrayIndex, assignSolFromObj,
  initSolListFromArray, initSolListWithVal, solveAndPopulateWhile,
  returnExprList, fixedReturn',
  ExternalLibraryCall, externalLibCall, choiceStepsFill, choiceStepFill,
  mandatoryStepFill, mandatoryStepsFill, callStepFill, libCallFill,
  userDefinedArgFill, basicArgFill, functionArgFill, customObjArgFill,
  recordArgFill, unnamedParamFill, unnamedParamPBVFill, userDefinedParamFill,
  customClassFill, implementationFill, constructorInfoFill, methodInfoFill,
  appendCurrSolFill, populateSolListFill, assignArrayIndexFill,
  assignSolFromObjFill, initSolListFromArrayFill, initSolListWithValFill,
  solveAndPopulateWhileFill, returnExprListFill, fixedStatementFill',
  CodeVarChunk, CodeFuncChunk, quantvar, quantfunc, listToArray,
  ODEInfo(..), ODEOptions(..), ODEMethod(..), ODELibPckg, mkODELib,
  mkODELibNoPath, pubStateVar, privStateVar,
  NamedArgument, narg)
import Language.Drasil.CodeExpr
import Language.Drasil.CodeExpr.Development

import Control.Lens ((^.), _1, _2, over)

-- SciPy Library (Python)

-- | [SciPy](https://www.scipy.org/) ODE library package.
scipyODEPckg :: ODELibPckg
scipyODEPckg :: ODELibPckg
scipyODEPckg = Name
-> Name
-> ExternalLibrary
-> (ODEInfo -> ExternalLibraryCall)
-> [Lang]
-> ODELibPckg
mkODELibNoPath Name
"SciPy" Name
"1.4.1" ExternalLibrary
scipyODE ODEInfo -> ExternalLibraryCall
scipyCall [Lang
Python]

scipyODE :: ExternalLibrary
scipyODE :: ExternalLibrary
scipyODE = ExternalLibrary -> ExternalLibrary
externalLib [
  Step -> StepGroup
mandatoryStep (Step -> StepGroup) -> Step -> StepGroup
forall a b. (a -> b) -> a -> b
$ FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libFunctionWithResult Name
scipyImport
    CodeFuncChunk
odefunc [
      CodeFuncChunk -> [Parameter] -> Step -> Argument
functionArg CodeFuncChunk
f ((Space -> Parameter) -> [Space] -> [Parameter]
forall a b. (a -> b) -> [a] -> [b]
map Space -> Parameter
unnamedParam [Space
Real, Space -> Space
Array Space
Real])
      Step
returnExprList] CodeVarChunk
r,
  [Step] -> StepGroup
choiceStep [
    [Argument] -> Step
setIntegratorMethod [Argument
vode, Name -> Argument
methodArg Name
"adams", Argument
atol, Argument
rtol],
    [Argument] -> Step
setIntegratorMethod [Argument
vode, Name -> Argument
methodArg Name
"bdf", Argument
atol, Argument
rtol],
    [Argument] -> Step
setIntegratorMethod [CodeExpr -> Argument
lockedArg (Name -> CodeExpr
forall r. LiteralC r => Name -> r
str Name
"dopri5"), Argument
atol, Argument
rtol]],
  [Step] -> StepGroup
mandatorySteps [FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeVarChunk -> CodeFuncChunk -> [Argument] -> FunctionInterface
libMethod Name
scipyImport CodeVarChunk
r
      CodeFuncChunk
setInitVal [Space -> Argument
inlineArg Space
Real, Space -> Argument
inlineArg Space
Real],
    Step
initSolListWithVal,
    FunctionInterface
-> CodeVarChunk
-> CodeVarChunk
-> FunctionInterface
-> CodeVarChunk
-> Step
solveAndPopulateWhile (Name
-> CodeVarChunk -> CodeFuncChunk -> [Argument] -> FunctionInterface
libMethod Name
scipyImport CodeVarChunk
r CodeFuncChunk
successful []) CodeVarChunk
r CodeVarChunk
t
      (Name
-> CodeVarChunk -> CodeFuncChunk -> [Argument] -> FunctionInterface
libMethod Name
scipyImport CodeVarChunk
r CodeFuncChunk
integrateStep [Space -> Argument
inlineArg Space
Real]) CodeVarChunk
y]]

scipyCall :: ODEInfo -> ExternalLibraryCall
scipyCall :: ODEInfo -> ExternalLibraryCall
scipyCall ODEInfo
info = ExternalLibraryCall -> ExternalLibraryCall
externalLibCall [
  StepFill -> StepGroupFill
mandatoryStepFill (StepFill -> StepGroupFill) -> StepFill -> StepGroupFill
forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill [[ParameterFill] -> StepFill -> ArgumentFill
functionArgFill
    ((CodeVarChunk -> ParameterFill)
-> [CodeVarChunk] -> [ParameterFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> ParameterFill
unnamedParamFill [ODEInfo -> CodeVarChunk
indepVar ODEInfo
info, ODEInfo -> CodeVarChunk
depVar ODEInfo
info])
    ([CodeExpr] -> StepFill
returnExprListFill ([CodeExpr] -> StepFill) -> [CodeExpr] -> StepFill
forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeExpr]
odeSyst ODEInfo
info)],
  (Int -> StepFill -> StepGroupFill)
-> (Int, StepFill) -> StepGroupFill
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> StepFill -> StepGroupFill
choiceStepFill (ODEMethod -> (Int, StepFill)
forall {a}. Num a => ODEMethod -> (a, StepFill)
chooseMethod (ODEMethod -> (Int, StepFill)) -> ODEMethod -> (Int, StepFill)
forall a b. (a -> b) -> a -> b
$ ODEOptions -> ODEMethod
solveMethod (ODEOptions -> ODEMethod) -> ODEOptions -> ODEMethod
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info),
  [StepFill] -> StepGroupFill
mandatoryStepsFill [FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill ([ArgumentFill] -> FunctionIntFill)
-> [ArgumentFill] -> FunctionIntFill
forall a b. (a -> b) -> a -> b
$ (CodeExpr -> ArgumentFill) -> [CodeExpr] -> [ArgumentFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill
      [[[CodeExpr]] -> CodeExpr
forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
initVal ODEInfo
info], ODEInfo -> CodeExpr
tInit ODEInfo
info],
    CodeVarChunk -> CodeExpr -> StepFill
initSolListWithValFill (ODEInfo -> CodeVarChunk
depVar ODEInfo
info) ([[CodeExpr]] -> CodeExpr
forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
initVal ODEInfo
info]),
    FunctionIntFill
-> CodeExpr -> FunctionIntFill -> CodeVarChunk -> StepFill
solveAndPopulateWhileFill ([ArgumentFill] -> FunctionIntFill
libCallFill []) (ODEInfo -> CodeExpr
tFinal ODEInfo
info)
    ([ArgumentFill] -> FunctionIntFill
libCallFill [CodeExpr -> ArgumentFill
basicArgFill (CodeVarChunk -> CodeVarChunk -> CodeExpr
forall r. CodeExprC r => CodeVarChunk -> CodeVarChunk -> r
field CodeVarChunk
r CodeVarChunk
t CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$+ ODEOptions -> CodeExpr
stepSize (ODEInfo -> ODEOptions
odeOpts ODEInfo
info))])
    (ODEInfo -> CodeVarChunk
depVar ODEInfo
info)]]
  where chooseMethod :: ODEMethod -> (a, StepFill)
chooseMethod ODEMethod
Adams = (a
0, StepFill
solveMethodFill)
        chooseMethod ODEMethod
BDF = (a
1, StepFill
solveMethodFill)
        chooseMethod ODEMethod
RK45 = (a
2, StepFill
solveMethodFill)
        solveMethodFill :: StepFill
solveMethodFill = FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill ([ArgumentFill] -> FunctionIntFill)
-> [ArgumentFill] -> FunctionIntFill
forall a b. (a -> b) -> a -> b
$ (CodeExpr -> ArgumentFill) -> [CodeExpr] -> [ArgumentFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill
          [ODEOptions -> CodeExpr
absTol (ODEOptions -> CodeExpr) -> ODEOptions -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info, ODEOptions -> CodeExpr
relTol (ODEOptions -> CodeExpr) -> ODEOptions -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info]

scipyImport :: String
scipyImport :: Name
scipyImport = Name
"scipy.integrate"

atol, rtol, vode :: Argument
vode :: Argument
vode = CodeExpr -> Argument
lockedArg (Name -> CodeExpr
forall r. LiteralC r => Name -> r
str Name
"vode")
atol :: Argument
atol = NamedArgument -> Space -> Argument
inlineNamedArg NamedArgument
atolArg Space
Real
rtol :: Argument
rtol = NamedArgument -> Space -> Argument
inlineNamedArg NamedArgument
rtolArg Space
Real

methodArg :: String -> Argument
methodArg :: Name -> Argument
methodArg = NamedArgument -> CodeExpr -> Argument
lockedNamedArg NamedArgument
mthdArg (CodeExpr -> Argument) -> (Name -> CodeExpr) -> Name -> Argument
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> CodeExpr
forall r. LiteralC r => Name -> r
str

setIntegratorMethod :: [Argument] -> Step
setIntegratorMethod :: [Argument] -> Step
setIntegratorMethod = FunctionInterface -> Step
callStep (FunctionInterface -> Step)
-> ([Argument] -> FunctionInterface) -> [Argument] -> Step
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name
-> CodeVarChunk -> CodeFuncChunk -> [Argument] -> FunctionInterface
libMethod Name
scipyImport CodeVarChunk
r CodeFuncChunk
setIntegrator

odeT, numpyArrayT :: Space
odeT :: Space
odeT = Name -> Space
Actor Name
"ode"
numpyArrayT :: Space
numpyArrayT = Name -> Space
Actor Name
"numpyArray"

-- | Collects variables needed for SciPy's ODEs as 'QuantityDict's.
scipyODESymbols :: [QuantityDict]
scipyODESymbols :: [QuantityDict]
scipyODESymbols = (NamedArgument -> QuantityDict)
-> [NamedArgument] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map NamedArgument -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [NamedArgument
mthdArg, NamedArgument
atolArg, NamedArgument
rtolArg]
  [QuantityDict] -> [QuantityDict] -> [QuantityDict]
forall a. [a] -> [a] -> [a]
++ (CodeVarChunk -> QuantityDict) -> [CodeVarChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [CodeVarChunk
r, CodeVarChunk
t, CodeVarChunk
y, CodeVarChunk
xAxis, CodeVarChunk
ut, CodeVarChunk
transpose]
  [QuantityDict] -> [QuantityDict] -> [QuantityDict]
forall a. [a] -> [a] -> [a]
++ (CodeFuncChunk -> QuantityDict)
-> [CodeFuncChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map CodeFuncChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [CodeFuncChunk
f, CodeFuncChunk
odefunc, CodeFuncChunk
setIntegrator, CodeFuncChunk
setInitVal, CodeFuncChunk
successful, CodeFuncChunk
integrateStep,
  CodeFuncChunk
arange, CodeFuncChunk
odeintFunc]

mthdArg, atolArg, rtolArg :: NamedArgument
mthdArg :: NamedArgument
mthdArg = QuantityDict -> NamedArgument
forall q. (Quantity q, MayHaveUnit q) => q -> NamedArgument
narg (QuantityDict -> NamedArgument) -> QuantityDict -> NamedArgument
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"method_scipy" (Name -> Name -> NP
nounPhrase
  Name
"chosen method for solving ODE" Name
"chosen methods for solving ODE")
  Space
String (Name -> Symbol
label Name
"method")
atolArg :: NamedArgument
atolArg = QuantityDict -> NamedArgument
forall q. (Quantity q, MayHaveUnit q) => q -> NamedArgument
narg (QuantityDict -> NamedArgument) -> QuantityDict -> NamedArgument
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"atol_scipy" (Name -> Name -> NP
nounPhrase
  Name
"absolute tolerance for ODE solution" Name
"absolute tolerances for ODE solution")
  Space
Real (Name -> Symbol
label Name
"atol")
rtolArg :: NamedArgument
rtolArg = QuantityDict -> NamedArgument
forall q. (Quantity q, MayHaveUnit q) => q -> NamedArgument
narg (QuantityDict -> NamedArgument) -> QuantityDict -> NamedArgument
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"rtol_scipy" (Name -> Name -> NP
nounPhrase
  Name
"relative tolerance for ODE solution" Name
"relative tolerances for ODE solution")
  Space
Real (Name -> Symbol
label Name
"rtol")


r, xAxis, ut, transpose :: CodeVarChunk
r :: CodeVarChunk
r = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"r_scipy" (Name -> Name -> NP
nounPhrase Name
"ODE object" Name
"ODE objects")
  Space
odeT (Name -> Symbol
label Name
"r")
xAxis :: CodeVarChunk
xAxis = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"x_numpy" (Name -> Name -> NP
nounPhrase Name
"Numpy value" Name
"Numpy value")
  (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"x_axis")
ut :: CodeVarChunk
ut = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"ut_scipy"
  (Name -> Name -> NP
nounPhrase Name
"Scipy integrated value" Name
"Scipy integrated value")
  Space
numpyArrayT (Name -> Symbol
label Name
"u_t")
transpose :: CodeVarChunk
transpose = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"transpose_numpy"
  (Name -> Name -> NP
nounPhrase Name
"Numpy Array Transpose" Name
"Numpy Array Transpose")
  (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"u_t.T") -- (ccObjVar ut transpose) does not seem to work.


f, odefunc, setIntegrator, setInitVal, successful,
  integrateStep, arange, odeintFunc :: CodeFuncChunk
f :: CodeFuncChunk
f = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"f_scipy" (Name -> Name -> NP
nounPhrase Name
"function representing ODE system"
  Name
"functions representing ODE system") (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"f")
odefunc :: CodeFuncChunk
odefunc = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"ode_scipy" (Name -> Name -> NP
nounPhrase
  Name
"function for defining an ODE for SciPy"
  Name
"functions for defining an ODE for SciPy") Space
odeT (Name -> Symbol
label Name
"ode")
setIntegrator :: CodeFuncChunk
setIntegrator = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"set_integrator_scipy" (Name -> Name -> NP
nounPhrase
  Name
"method for setting SciPy integrator" Name
"methods for setting SciPy integrator")
  Space
Void (Name -> Symbol
label Name
"set_integrator")
setInitVal :: CodeFuncChunk
setInitVal = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"set_initial_value_scipy" (Name -> Name -> NP
nounPhrase
  Name
"method for setting initial value for ODE for SciPy"
  Name
"methods for setting initial value for ODE for SciPy")
  Space
Void (Name -> Symbol
label Name
"set_initial_value")
successful :: CodeFuncChunk
successful = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"successful_scipy" (Name -> Name -> NP
nounPhrase
  Name
"method returning True if integration is current successful"
  Name
"methods returning True if integration is current successful")
  Space
Boolean (Name -> Symbol
label Name
"successful")
integrateStep :: CodeFuncChunk
integrateStep = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"integrate_scipy" (Name -> Name -> NP
nounPhrase
  Name
"method that performs one integration step on an ODE"
  Name
"methods that perform one integration step on an ODE")
  Space
Void (Name -> Symbol
label Name
"integrate")
arange :: CodeFuncChunk
arange = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"arrange_numpy" (Name -> Name -> NP
nounPhrase
  Name
"method that returns evenly spaced numbers over a specified interval."
  Name
"method that returns evenly spaced numbers over a specified interval.")
  (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"arange")
odeintFunc :: CodeFuncChunk
odeintFunc = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"odeint_scipy" (Name -> Name -> NP
nounPhrase
  Name
"method that solves a system of ODE using lsoda from the FORTRAN library odepack."
  Name
"method that solves a system of ODE using lsoda from the FORTRAN library odepack.")
  (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"odeint")

-- Oslo Library (C#)

-- | [Oslo](https://www.microsoft.com/en-us/research/project/open-solving-library-for-odes/) ODE library package.
osloPckg :: ODELibPckg
osloPckg :: ODELibPckg
osloPckg = Name
-> Name
-> ExternalLibrary
-> (ODEInfo -> ExternalLibraryCall)
-> Name
-> [Lang]
-> ODELibPckg
mkODELib Name
"OSLO" Name
"1.2" ExternalLibrary
oslo ODEInfo -> ExternalLibraryCall
osloCall Name
"Microsoft.Research.Oslo.dll" [Lang
CSharp]

oslo :: ExternalLibrary
oslo :: ExternalLibrary
oslo = ExternalLibrary -> ExternalLibrary
externalLib [
  Step -> StepGroup
mandatoryStep (Step -> StepGroup) -> Step -> StepGroup
forall a b. (a -> b) -> a -> b
$ FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libConstructor Name
osloImport
    CodeFuncChunk
vector [Space -> Argument
inlineArg Space
Real] CodeVarChunk
initv,
  [Step] -> StepGroup
choiceStep ([Step] -> StepGroup) -> [Step] -> StepGroup
forall a b. (a -> b) -> a -> b
$ (CodeFuncChunk -> Step) -> [CodeFuncChunk] -> [Step]
forall a b. (a -> b) -> [a] -> [b]
map (\CodeFuncChunk
s -> FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libFunctionWithResult Name
osloImport CodeFuncChunk
s [Argument]
odeArgs
    CodeVarChunk
sol) [CodeFuncChunk
rk547m, CodeFuncChunk
gearBDF],
  [Step] -> StepGroup
mandatorySteps (FunctionInterface -> Step
callStep (Name
-> CodeVarChunk
-> CodeFuncChunk
-> [Argument]
-> CodeVarChunk
-> FunctionInterface
libMethodWithResult Name
osloImport CodeVarChunk
sol
      CodeFuncChunk
solveFromToStep ((Space -> Argument) -> [Space] -> [Argument]
forall a b. (a -> b) -> [a] -> [b]
map Space -> Argument
inlineArg [Space
Real, Space
Real, Space
Real]) CodeVarChunk
points) Step -> [Step] -> [Step]
forall a. a -> [a] -> [a]
:
    CodeVarChunk -> CodeVarChunk -> CodeVarChunk -> [Step]
populateSolList CodeVarChunk
points CodeVarChunk
sp CodeVarChunk
x)]

osloCall :: ODEInfo -> ExternalLibraryCall
osloCall :: ODEInfo -> ExternalLibraryCall
osloCall ODEInfo
info = ExternalLibraryCall -> ExternalLibraryCall
externalLibCall [
  StepFill -> StepGroupFill
mandatoryStepFill (StepFill -> StepGroupFill) -> StepFill -> StepGroupFill
forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill [CodeExpr -> ArgumentFill
basicArgFill (CodeExpr -> ArgumentFill) -> CodeExpr -> ArgumentFill
forall a b. (a -> b) -> a -> b
$ [[CodeExpr]] -> CodeExpr
forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
initVal ODEInfo
info]],
  Int -> StepFill -> StepGroupFill
choiceStepFill (ODEMethod -> Int
forall {a}. Num a => ODEMethod -> a
chooseMethod (ODEMethod -> Int) -> ODEMethod -> Int
forall a b. (a -> b) -> a -> b
$ ODEOptions -> ODEMethod
solveMethod (ODEOptions -> ODEMethod) -> ODEOptions -> ODEMethod
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info) (StepFill -> StepGroupFill) -> StepFill -> StepGroupFill
forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$
    [ArgumentFill] -> FunctionIntFill
libCallFill [CodeExpr -> ArgumentFill
basicArgFill (CodeExpr -> ArgumentFill) -> CodeExpr -> ArgumentFill
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeExpr
tInit ODEInfo
info,
      [ParameterFill] -> StepFill -> ArgumentFill
functionArgFill ((CodeVarChunk -> ParameterFill)
-> [CodeVarChunk] -> [ParameterFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> ParameterFill
unnamedParamFill [ODEInfo -> CodeVarChunk
indepVar ODEInfo
info, ODEInfo -> CodeVarChunk
vecDepVar ODEInfo
info]) (StepFill -> ArgumentFill) -> StepFill -> ArgumentFill
forall a b. (a -> b) -> a -> b
$
        FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill ([ArgumentFill] -> FunctionIntFill)
-> [ArgumentFill] -> FunctionIntFill
forall a b. (a -> b) -> a -> b
$ (CodeExpr -> ArgumentFill) -> [CodeExpr] -> [ArgumentFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
userDefinedArgFill (Name -> ODEInfo -> [CodeExpr]
modifiedODESyst Name
"arrayvec" ODEInfo
info),
      [CodeExpr] -> ArgumentFill
recordArgFill [ODEOptions -> CodeExpr
absTol (ODEOptions -> CodeExpr) -> ODEOptions -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info, ODEOptions -> CodeExpr
relTol (ODEOptions -> CodeExpr) -> ODEOptions -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info]],
  [StepFill] -> StepGroupFill
mandatoryStepsFill (FunctionIntFill -> StepFill
callStepFill ([ArgumentFill] -> FunctionIntFill
libCallFill ([ArgumentFill] -> FunctionIntFill)
-> [ArgumentFill] -> FunctionIntFill
forall a b. (a -> b) -> a -> b
$ (CodeExpr -> ArgumentFill) -> [CodeExpr] -> [ArgumentFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill
      [ODEInfo -> CodeExpr
tInit ODEInfo
info, ODEInfo -> CodeExpr
tFinal ODEInfo
info, ODEOptions -> CodeExpr
stepSize (ODEOptions -> CodeExpr) -> ODEOptions -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info]) StepFill -> [StepFill] -> [StepFill]
forall a. a -> [a] -> [a]
:
    CodeVarChunk -> [StepFill]
populateSolListFill (ODEInfo -> CodeVarChunk
depVar ODEInfo
info))]
  where chooseMethod :: ODEMethod -> a
chooseMethod ODEMethod
RK45 = a
0
        chooseMethod ODEMethod
BDF = a
1
        chooseMethod ODEMethod
_ = Name -> a
forall a. HasCallStack => Name -> a
error Name
odeMethodUnavailable

odeArgs :: [Argument]
odeArgs :: [Argument]
odeArgs = [Space -> Argument
inlineArg Space
Real, CodeExpr -> Argument
lockedArg (CodeVarChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy CodeVarChunk
initv),
  CodeFuncChunk -> [Parameter] -> Step -> Argument
functionArg CodeFuncChunk
fOslo ((Space -> Parameter) -> [Space] -> [Parameter]
forall a b. (a -> b) -> [a] -> [b]
map Space -> Parameter
unnamedParam [Space
Real, Space
vecT])
    (FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name -> CodeFuncChunk -> [Argument] -> FunctionInterface
constructAndReturn Name
osloImport CodeFuncChunk
vector []),
  Name -> CodeFuncChunk -> CodeVarChunk -> [CodeVarChunk] -> Argument
recordArg Name
osloImport CodeFuncChunk
options CodeVarChunk
opts [CodeVarChunk
aTol, CodeVarChunk
rTol]]

solT, vecT, optT :: Space
solT :: Space
solT = Name -> Space
Actor Name
"IEnumerable<SolPoint>"
vecT :: Space
vecT = Name -> Space
Actor Name
"Vector"
optT :: Space
optT = Name -> Space
Actor Name
"Options"

osloImport :: String
osloImport :: Name
osloImport = Name
"Microsoft.Research.Oslo"

-- | Collects variables needed for Oslo's ODEs as 'QuantityDict's.
osloSymbols :: [QuantityDict]
osloSymbols :: [QuantityDict]
osloSymbols = (CodeVarChunk -> QuantityDict) -> [CodeVarChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [CodeVarChunk
initv, CodeVarChunk
opts, CodeVarChunk
aTol, CodeVarChunk
rTol, CodeVarChunk
sol, CodeVarChunk
points, CodeVarChunk
sp, CodeVarChunk
x] [QuantityDict] -> [QuantityDict] -> [QuantityDict]
forall a. [a] -> [a] -> [a]
++
  (CodeFuncChunk -> QuantityDict)
-> [CodeFuncChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map CodeFuncChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [CodeFuncChunk
fOslo, CodeFuncChunk
options, CodeFuncChunk
vector, CodeFuncChunk
rk547m, CodeFuncChunk
gearBDF, CodeFuncChunk
solveFromToStep]

initv, opts, aTol, rTol, sol, points, sp, x :: CodeVarChunk
initv :: CodeVarChunk
initv = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"initv_oslo" (Name -> Name -> NP
nounPhrase
  Name
"vector containing the initial values of the dependent variables"
  Name
"vectors containing the initial values of the dependent variables")
  Space
vecT (Name -> Symbol
label Name
"initv")
opts :: CodeVarChunk
opts = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"opts_oslo" (Name -> Name -> NP
nounPhrase
  Name
"record containing options for ODE solving"
  Name
"records containing options for ODE solving") Space
optT (Name -> Symbol
label Name
"opts")
aTol :: CodeVarChunk
aTol = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"aTol_oslo" (Name -> Name -> NP
nounPhrase
  Name
"absolute tolerance for ODE solution" Name
"absolute tolerances for ODE solution")
  Space
Real (Name -> Symbol
label Name
"AbsoluteTolerance")
rTol :: CodeVarChunk
rTol = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"rTol_oslo" (Name -> Name -> NP
nounPhrase
  Name
"relative tolerance for ODE solution" Name
"relative tolerances for ODE solution")
  Space
Real (Name -> Symbol
label Name
"RelativeTolerance")
sol :: CodeVarChunk
sol = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"sol_oslo" (Name -> Name -> NP
nounPhrase Name
"container for ODE information"
  Name
"containers for ODE information") Space
solT (Name -> Symbol
label Name
"sol")
points :: CodeVarChunk
points = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"points_oslo" (Name -> Name -> NP
nounPhrase
  Name
"container holding ODE solution" Name
"containers holding ODE solution")
  Space
solT (Name -> Symbol
label Name
"points")
sp :: CodeVarChunk
sp = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"sp_oslo" (Name -> Name -> NP
nounPhrase Name
"ODE solution point"
  Name
"ODE solution points") (Name -> Space
Actor Name
"SolPoint") (Name -> Symbol
label Name
"sp")
x :: CodeVarChunk
x = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"X_oslo" (Name -> Name -> NP
nounPhrase Name
"dependent variable"
  Name
"dependent variables") (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"X")

fOslo, options, vector, rk547m, gearBDF, solveFromToStep :: CodeFuncChunk
fOslo :: CodeFuncChunk
fOslo = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"f_oslo" (Name -> Name -> NP
nounPhrase
  Name
"function representing ODE system" Name
"functions representing ODE system")
  Space
vecT (Name -> Symbol
label Name
"f")
options :: CodeFuncChunk
options = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"Options_oslo" (Name -> Name -> NP
nounPhrase
  Name
"constructor for Options record" Name
"constructors for Options record")
  Space
optT (Name -> Symbol
label Name
"Options")
vector :: CodeFuncChunk
vector = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"Vector_oslo" (Name -> Name -> NP
nounPhrase
  Name
"constructor for an OSLO Vector" Name
"constructors for an OSLO Vector")
  Space
vecT (Name -> Symbol
label Name
"Vector")
rk547m :: CodeFuncChunk
rk547m = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"RK547M_oslo" (Name -> Name -> NP
nounPhrase
  Name
"function for initiating an ODE to be solved by Runge-Kutta method"
  Name
"functions for initiating an ODE to be solved by Runge-Kutta method")
  Space
solT (Name -> Symbol
label Name
"Ode.RK547M")
gearBDF :: CodeFuncChunk
gearBDF = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"GearBDF_oslo" (Name -> Name -> NP
nounPhrase
  Name
"function for initiating an ODE to be solved by Gear's BDF method"
  Name
"functions for initiating an ODE to be solved by Gear's BDF method")
  Space
solT (Name -> Symbol
label Name
"Ode.GearBDF")
solveFromToStep :: CodeFuncChunk
solveFromToStep = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"SolveFromToStep_oslo" (Name -> Name -> NP
nounPhrase
  Name
"method for solving an ODE given a time range"
  Name
"methods for solving an ODE given a time range")
  Space
solT (Name -> Symbol
label Name
"SolveFromToStep")

vecDepVar :: ODEInfo -> CodeVarChunk
vecDepVar :: ODEInfo -> CodeVarChunk
vecDepVar ODEInfo
info = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ UID -> NP -> Space -> Symbol -> QuantityDict
implVarUID (CodeVarChunk
dv CodeVarChunk -> Getting UID CodeVarChunk UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID CodeVarChunk UID
forall c. HasUID c => Getter c UID
Getter CodeVarChunk UID
uid) (CodeVarChunk
dv CodeVarChunk -> Getting NP CodeVarChunk NP -> NP
forall s a. s -> Getting a s a -> a
^. Getting NP CodeVarChunk NP
forall c. NamedIdea c => Lens' c NP
Lens' CodeVarChunk NP
term) Space
vecT
  (Symbol -> Symbol -> Symbol
sub (CodeVarChunk -> Stage -> Symbol
forall c. HasSymbol c => c -> Stage -> Symbol
symbol CodeVarChunk
dv Stage
Implementation) (Name -> Symbol
label Name
"vec"))
  where dv :: CodeVarChunk
dv = ODEInfo -> CodeVarChunk
depVar ODEInfo
info

-- Hack required because
-- | Oslo's Vector type behaves like an array, so needs to
-- be represented as one or else will hit type errors in GOOL.
arrayVecDepVar :: ODEInfo -> CodeVarChunk
arrayVecDepVar :: ODEInfo -> CodeVarChunk
arrayVecDepVar ODEInfo
info = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ UID -> NP -> Space -> Symbol -> QuantityDict
implVarUID (CodeVarChunk
dv CodeVarChunk -> Name -> UID
forall a. HasUID a => a -> Name -> UID
+++ Name
"vec") (CodeVarChunk
dv CodeVarChunk -> Getting NP CodeVarChunk NP -> NP
forall s a. s -> Getting a s a -> a
^. Getting NP CodeVarChunk NP
forall c. NamedIdea c => Lens' c NP
Lens' CodeVarChunk NP
term)
  (CodeVarChunk
dv CodeVarChunk -> Getting Space CodeVarChunk Space -> Space
forall s a. s -> Getting a s a -> a
^. Getting Space CodeVarChunk Space
forall c. HasSpace c => Getter c Space
Getter CodeVarChunk Space
typ) (Symbol -> Symbol -> Symbol
sub (CodeVarChunk -> Stage -> Symbol
forall c. HasSymbol c => c -> Stage -> Symbol
symbol CodeVarChunk
dv Stage
Implementation) (Name -> Symbol
label Name
"vec"))
  where dv :: CodeVarChunk
dv = CodeVarChunk -> CodeVarChunk
listToArray (CodeVarChunk -> CodeVarChunk) -> CodeVarChunk -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info

-- Apache Commons (Java)

-- | [Apache Commons](https://commons.apache.org/) ODE library package.
apacheODEPckg :: ODELibPckg
apacheODEPckg :: ODELibPckg
apacheODEPckg = Name
-> Name
-> ExternalLibrary
-> (ODEInfo -> ExternalLibraryCall)
-> Name
-> [Lang]
-> ODELibPckg
mkODELib Name
"Apache" Name
"3.6.1" ExternalLibrary
apacheODE ODEInfo -> ExternalLibraryCall
apacheODECall
  Name
"lib/commons-math3-3.6.1.jar" [Lang
Java]

apacheODE :: ExternalLibrary
apacheODE :: ExternalLibrary
apacheODE = ExternalLibrary -> ExternalLibrary
externalLib [
  [Step] -> StepGroup
choiceStep [
    FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ [Name]
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libConstructorMultiReqs [Name
apacheImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"nonstiff." Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
adams,
      Name
foiImp] CodeFuncChunk
adamsC (CodeExpr -> Argument
lockedArg (Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
int Integer
3) Argument -> [Argument] -> [Argument]
forall a. a -> [a] -> [a]
: [Argument]
itArgs) CodeVarChunk
it,
    FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ [Name]
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libConstructorMultiReqs [Name
apacheImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"nonstiff." Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
dp54,
      Name
foiImp] CodeFuncChunk
dp54C [Argument]
itArgs CodeVarChunk
it],
  [Step] -> StepGroup
mandatorySteps [FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeVarChunk -> CodeFuncChunk -> [Argument] -> FunctionInterface
libMethod Name
foiImp CodeVarChunk
it CodeFuncChunk
addStepHandler [
      [Name]
-> Name -> CodeVarChunk -> CodeFuncChunk -> ClassInfo -> Argument
customObjArg [Name
shImp, Name
siImp]
        Name
"Class defining additional behaviour for each step of an ODE solution"
        CodeVarChunk
stepHandler CodeFuncChunk
stepHandlerCtor (Name -> [MethodInfo] -> ClassInfo
implementation Name
sh [
          CodeFuncChunk -> Name -> [Parameter] -> [Step] -> MethodInfo
methodInfoNoReturn CodeFuncChunk
initMethod
            Name
"initializes step handler with initial conditions"
            ((CodeVarChunk -> Parameter) -> [CodeVarChunk] -> [Parameter]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> Parameter
lockedParam [CodeVarChunk
t0, CodeVarChunk
y0, CodeVarChunk
t]) [CodeVarChunk -> Step
initSolListFromArray CodeVarChunk
y0],
          CodeFuncChunk -> Name -> [Parameter] -> [Step] -> MethodInfo
methodInfoNoReturn CodeFuncChunk
handleStep
            Name
"appends solution point at each ODE solution step"
            ((CodeVarChunk -> Parameter) -> [CodeVarChunk] -> [Parameter]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> Parameter
lockedParam [CodeVarChunk
interpolator, CodeVarChunk
isLast])
            [FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeVarChunk
-> CodeFuncChunk
-> [Argument]
-> CodeVarChunk
-> FunctionInterface
libMethodWithResult Name
siImp CodeVarChunk
interpolator CodeFuncChunk
getInterpState
              [] CodeVarChunk
curr,
            CodeExpr -> Step
appendCurrSol (CodeVarChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy CodeVarChunk
curr)]])],
    FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeVarChunk -> CodeFuncChunk -> [Argument] -> FunctionInterface
libMethod Name
foiImp CodeVarChunk
it CodeFuncChunk
integrate ([Name]
-> Name -> CodeVarChunk -> CodeFuncChunk -> ClassInfo -> Argument
customObjArg [Name
apacheImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++
      Name
fode] Name
"Class representing an ODE system" CodeVarChunk
ode CodeFuncChunk
odeCtor (Name -> [MethodInfo] -> ClassInfo
implementation Name
fode
        [CodeFuncChunk -> [Parameter] -> [Step] -> MethodInfo
constructorInfo CodeFuncChunk
odeCtor [] [],
        CodeFuncChunk
-> Name -> [Parameter] -> Name -> [Step] -> MethodInfo
methodInfo CodeFuncChunk
getDimension Name
"returns the ODE system dimension"
          [] Name
"dimension of the ODE system" [Step
fixedReturn'],
        CodeFuncChunk -> Name -> [Parameter] -> [Step] -> MethodInfo
methodInfoNoReturn CodeFuncChunk
computeDerivatives
          Name
"function representation of an ODE system"
          [CodeVarChunk -> Parameter
lockedParam CodeVarChunk
t, Space -> Parameter
unnamedParam (Space -> Space
Array Space
Real), Space -> Parameter
unnamedParam (Space -> Space
Array Space
Real)]
          [Step
assignArrayIndex]]) Argument -> [Argument] -> [Argument]
forall a. a -> [a] -> [a]
:
      [Space -> Argument
inlineArg Space
Real, CodeVarChunk -> Argument
preDefinedArg CodeVarChunk
currVals, Space -> Argument
inlineArg Space
Real,
        CodeVarChunk -> Argument
preDefinedArg CodeVarChunk
currVals]),
    CodeVarChunk -> Step
assignSolFromObj CodeVarChunk
stepHandler]]

apacheODECall :: ODEInfo -> ExternalLibraryCall
apacheODECall :: ODEInfo -> ExternalLibraryCall
apacheODECall ODEInfo
info = ExternalLibraryCall -> ExternalLibraryCall
externalLibCall [
  Int -> StepFill -> StepGroupFill
choiceStepFill (ODEMethod -> Int
forall {a}. Num a => ODEMethod -> a
chooseMethod (ODEMethod -> Int) -> ODEMethod -> Int
forall a b. (a -> b) -> a -> b
$ ODEOptions -> ODEMethod
solveMethod (ODEOptions -> ODEMethod) -> ODEOptions -> ODEMethod
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info) (StepFill -> StepGroupFill) -> StepFill -> StepGroupFill
forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$
    [ArgumentFill] -> FunctionIntFill
libCallFill (((ODEOptions -> CodeExpr) -> ArgumentFill)
-> [ODEOptions -> CodeExpr] -> [ArgumentFill]
forall a b. (a -> b) -> [a] -> [b]
map (CodeExpr -> ArgumentFill
basicArgFill (CodeExpr -> ArgumentFill)
-> ((ODEOptions -> CodeExpr) -> CodeExpr)
-> (ODEOptions -> CodeExpr)
-> ArgumentFill
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ODEOptions -> CodeExpr) -> ODEOptions -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info)) [ODEOptions -> CodeExpr
stepSize, ODEOptions -> CodeExpr
stepSize, ODEOptions -> CodeExpr
absTol, ODEOptions -> CodeExpr
relTol]),
  [StepFill] -> StepGroupFill
mandatoryStepsFill [FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill [
      [StateVariable] -> ClassInfoFill -> ArgumentFill
customObjArgFill [CodeVarChunk -> StateVariable
pubStateVar (CodeVarChunk -> StateVariable) -> CodeVarChunk -> StateVariable
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info] ([MethodInfoFill] -> ClassInfoFill
implementationFill [
        [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill [] [CodeVarChunk -> StepFill
initSolListFromArrayFill (CodeVarChunk -> StepFill) -> CodeVarChunk -> StepFill
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info], [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill []
          [FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill [], CodeVarChunk -> StepFill
appendCurrSolFill (CodeVarChunk -> StepFill) -> CodeVarChunk -> StepFill
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info]])],
    FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill ([ArgumentFill] -> FunctionIntFill)
-> [ArgumentFill] -> FunctionIntFill
forall a b. (a -> b) -> a -> b
$ [StateVariable] -> ClassInfoFill -> ArgumentFill
customObjArgFill
      ((CodeVarChunk -> StateVariable)
-> [CodeVarChunk] -> [StateVariable]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> StateVariable
privStateVar ([CodeVarChunk] -> [StateVariable])
-> [CodeVarChunk] -> [StateVariable]
forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)
      ([MethodInfoFill] -> ClassInfoFill
implementationFill [
        [ParameterFill] -> [Initializer] -> [StepFill] -> MethodInfoFill
constructorInfoFill ((CodeVarChunk -> ParameterFill)
-> [CodeVarChunk] -> [ParameterFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> ParameterFill
userDefinedParamFill ([CodeVarChunk] -> [ParameterFill])
-> [CodeVarChunk] -> [ParameterFill]
forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)
          ([CodeVarChunk] -> [CodeExpr] -> [Initializer]
forall a b. [a] -> [b] -> [(a, b)]
zip (ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info) ((CodeVarChunk -> CodeExpr) -> [CodeVarChunk] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ([CodeVarChunk] -> [CodeExpr]) -> [CodeVarChunk] -> [CodeExpr]
forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)) [],
        [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill [] [CodeExpr -> StepFill
fixedStatementFill' (CodeExpr -> StepFill) -> CodeExpr -> StepFill
forall a b. (a -> b) -> a -> b
$ Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
int (Integer -> CodeExpr) -> Integer -> CodeExpr
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ [CodeExpr] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([CodeExpr] -> Int) -> [CodeExpr] -> Int
forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeExpr]
initVal ODEInfo
info],
        [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill ((CodeVarChunk -> ParameterFill)
-> [CodeVarChunk] -> [ParameterFill]
forall a b. (a -> b) -> [a] -> [b]
map (CodeVarChunk -> ParameterFill
unnamedParamFill (CodeVarChunk -> ParameterFill)
-> (CodeVarChunk -> CodeVarChunk) -> CodeVarChunk -> ParameterFill
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CodeVarChunk -> CodeVarChunk
listToArray) [ODEInfo -> CodeVarChunk
depVar ODEInfo
info, CodeVarChunk
ddep])
          [CodeVarChunk -> [CodeExpr] -> StepFill
assignArrayIndexFill (CodeVarChunk -> CodeVarChunk
listToArray CodeVarChunk
ddep) (Name -> ODEInfo -> [CodeExpr]
modifiedODESyst Name
"array" ODEInfo
info)]])
      ArgumentFill -> [ArgumentFill] -> [ArgumentFill]
forall a. a -> [a] -> [a]
: (CodeExpr -> ArgumentFill) -> [CodeExpr] -> [ArgumentFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill [ODEInfo -> CodeExpr
tInit ODEInfo
info, [[CodeExpr]] -> CodeExpr
forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
initVal ODEInfo
info], ODEInfo -> CodeExpr
tFinal ODEInfo
info,
        [[CodeExpr]] -> CodeExpr
forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
initVal ODEInfo
info]],
    CodeVarChunk -> StepFill
assignSolFromObjFill (CodeVarChunk -> StepFill) -> CodeVarChunk -> StepFill
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info]]
  where chooseMethod :: ODEMethod -> a
chooseMethod ODEMethod
Adams = a
0
        chooseMethod ODEMethod
RK45 = a
1
        chooseMethod ODEMethod
_ = Name -> a
forall a. HasCallStack => Name -> a
error Name
odeMethodUnavailable
        ddep :: CodeVarChunk
ddep = CodeVarChunk -> CodeVarChunk
diffCodeChunk (CodeVarChunk -> CodeVarChunk) -> CodeVarChunk -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info

itArgs :: [Argument]
itArgs :: [Argument]
itArgs = (Space -> Argument) -> [Space] -> [Argument]
forall a b. (a -> b) -> [a] -> [b]
map Space -> Argument
inlineArg [Space
Real, Space
Real, Space
Real, Space
Real]

apacheImport, adams, dp54, foi, foiImp, sampling, sh, shImp, si, siImp, fode :: String
apacheImport :: Name
apacheImport = Name
"org.apache.commons.math3.ode."
adams :: Name
adams = Name
"AdamsBashforthIntegrator"
dp54 :: Name
dp54 = Name
"DormandPrince54Integrator"
foi :: Name
foi = Name
"FirstOrderIntegrator"
foiImp :: Name
foiImp = Name
apacheImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
foi
sampling :: Name
sampling = Name
"sampling"
sh :: Name
sh = Name
"StepHandler"
shImp :: Name
shImp = Name
apacheImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
sampling Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"." Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
sh
si :: Name
si = Name
"StepInterpolator"
siImp :: Name
siImp = Name
apacheImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
sampling Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"." Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
si
fode :: Name
fode = Name
"FirstOrderDifferentialEquations"

-- | Collects variables needed for Apache's ODEs as 'QuantityDict's.
apacheODESymbols :: [QuantityDict]
apacheODESymbols :: [QuantityDict]
apacheODESymbols = (CodeVarChunk -> QuantityDict) -> [CodeVarChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [CodeVarChunk
it, CodeVarChunk
currVals, CodeVarChunk
stepHandler, CodeVarChunk
t0, CodeVarChunk
y0, CodeVarChunk
t, CodeVarChunk
interpolator,
  CodeVarChunk
isLast, CodeVarChunk
curr, CodeVarChunk
ode] [QuantityDict] -> [QuantityDict] -> [QuantityDict]
forall a. [a] -> [a] -> [a]
++ (CodeFuncChunk -> QuantityDict)
-> [CodeFuncChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map CodeFuncChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [CodeFuncChunk
adamsC, CodeFuncChunk
dp54C, CodeFuncChunk
stepHandlerCtor, CodeFuncChunk
addStepHandler,
  CodeFuncChunk
initMethod, CodeFuncChunk
handleStep, CodeFuncChunk
getInterpState, CodeFuncChunk
integrate, CodeFuncChunk
odeCtor, CodeFuncChunk
getDimension,
  CodeFuncChunk
computeDerivatives]

it, currVals, stepHandler, t0, y0, interpolator, isLast, curr :: CodeVarChunk
it :: CodeVarChunk
it = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"it_apache" (Name -> Name -> NP
nounPhrase Name
"integrator for solving ODEs"
  Name
"integrators for solving ODEs") (Name -> Space
Actor Name
foi) (Name -> Symbol
label Name
"it")
currVals :: CodeVarChunk
currVals = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"curr_vals_apache" (Name -> Name -> NP
nounPhrase
  Name
"array holding ODE solution values for the current step"
  Name
"arrays holding ODE solution values for the current step")
  (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"curr_vals")
stepHandler :: CodeVarChunk
stepHandler = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"stepHandler_apache" (Name -> Name -> NP
nounPhrase
  Name
"ODE step handler" Name
"ODE step handlers") (Name -> Space
Actor (Name -> Space) -> Name -> Space
forall a b. (a -> b) -> a -> b
$ Name
"ODE" Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
sh)
  (Name -> Symbol
label Name
"stepHandler")
t0 :: CodeVarChunk
t0 = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"t0_apache" (Name -> Name -> NP
nounPhrase Name
"initial time for ODE solving"
  Name
"intial times for ODE solving") Space
Real (Name -> Symbol
label Name
"t0")
y0 :: CodeVarChunk
y0 = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"y0_apache" (Name -> Name -> NP
nounPhrase
  Name
"array of initial values for ODE solving"
  Name
"arrays of initial values for ODE solving") (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"y0")
interpolator :: CodeVarChunk
interpolator = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"interpolator_apache" (Name -> Name -> NP
nounPhrase
  Name
"step interpolator for ODE solving" Name
"step interpolator for ODE solving")
  (Name -> Space
Actor Name
si) (Name -> Symbol
label Name
"interpolator")
isLast :: CodeVarChunk
isLast = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"isLast_apache" (Name -> Name -> NP
nounPhrase
  Name
"boolean for whether the current step is the last step"
  Name
"booleans for whether the current step is the last step")
  Space
Boolean (Name -> Symbol
label Name
"isLast")
curr :: CodeVarChunk
curr = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"curr_apache" (Name -> Name -> NP
nounPhrase
  Name
"ODE solution array for current step" Name
"ODE solution arrays for current step")
  (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"curr")

adamsC, dp54C, stepHandlerCtor, addStepHandler, initMethod, handleStep,
  getInterpState, integrate, getDimension, computeDerivatives :: CodeFuncChunk
adamsC :: CodeFuncChunk
adamsC = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"adams_ctor_apache" (Name -> Name -> NP
nounPhrase
  Name
"constructor for an Adams-Bashforth integrator"
  Name
"constructors for an Adams-Bashforth integrator") (Name -> Space
Actor Name
adams) (Name -> Symbol
Label Name
adams)
dp54C :: CodeFuncChunk
dp54C = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"dp54_ctor_apache" (Name -> Name -> NP
nounPhrase
  Name
"constructor for a Dormand-Prince 5-4 integrator"
  Name
"constructors for a Dormand-Prince 5-4 integrator")
  (Name -> Space
Actor Name
dp54) (Name -> Symbol
Label Name
dp54)
stepHandlerCtor :: CodeFuncChunk
stepHandlerCtor = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"StepHandler_ctor_apache" (Name -> Name -> NP
nounPhrase
  Name
"constructor for StepHandler" Name
"constructors for StepHandler")
  (Name -> Space
Actor (Name -> Space) -> Name -> Space
forall a b. (a -> b) -> a -> b
$ Name
"ODE" Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
sh) (Name -> Symbol
Label (Name -> Symbol) -> Name -> Symbol
forall a b. (a -> b) -> a -> b
$ Name
"ODE" Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
sh)
addStepHandler :: CodeFuncChunk
addStepHandler = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"addStepHandler_apache" (Name -> Name -> NP
nounPhrase
  Name
"method for adding a step handler to an integrator"
  Name
"methods for adding a step handler to an integrator")
  Space
Void (Name -> Symbol
label Name
"addStepHandler")
initMethod :: CodeFuncChunk
initMethod = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"init_apache" (Name -> Name -> NP
nounPhrase
  Name
"method to initialize step handler" Name
"methods to initialize step handler")
  Space
Void (Name -> Symbol
label Name
"init")
handleStep :: CodeFuncChunk
handleStep = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"handleStep_apache" (Name -> Name -> NP
nounPhrase
  Name
"method to call at each ODE step" Name
"methods to call at each ODE step")
  Space
Void (Name -> Symbol
label Name
"handleStep")
getInterpState :: CodeFuncChunk
getInterpState = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"getInterpolatedState_apache" (Name -> Name -> NP
nounPhrase
  Name
"method for getting current state during ODE solving"
  Name
"methods for getting current state during ODE solving")
  (Space -> Space
Array Space
Real) (Name -> Symbol
label Name
"getInterpolatedState")
integrate :: CodeFuncChunk
integrate = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"integrate_apache" (Name -> Name -> NP
nounPhrase
  Name
"method for integrating an ODE" Name
"methods for integrating an ODE")
  Space
Void (Name -> Symbol
label Name
"integrate")
getDimension :: CodeFuncChunk
getDimension = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"getDimension_apache" (Name -> Name -> NP
nounPhrase
  Name
"method returning the dimension of an ODE system"
  Name
"methods returning the dimension of an ODE system")
  Space
Natural (Name -> Symbol
label Name
"getDimension")
computeDerivatives :: CodeFuncChunk
computeDerivatives = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"computeDerivatives_apache" (Name -> Name -> NP
nounPhrase
  Name
"method encoding an ODE system" Name
"methods encoding an ODE system")
  Space
Void (Name -> Symbol
label Name
"computeDerivatives")

-- odeint (C++)

-- | [odeint](https://headmyshoulder.github.io/odeint-v2/) ODE library package.
odeintPckg :: ODELibPckg
odeintPckg :: ODELibPckg
odeintPckg = Name
-> Name
-> ExternalLibrary
-> (ODEInfo -> ExternalLibraryCall)
-> Name
-> [Lang]
-> ODELibPckg
mkODELib Name
"odeint" Name
"v2" ExternalLibrary
odeint ODEInfo -> ExternalLibraryCall
odeintCall Name
"." [Lang
Cpp]

odeint :: ExternalLibrary
odeint :: ExternalLibrary
odeint = ExternalLibrary -> ExternalLibrary
externalLib [
  [[Step]] -> StepGroup
choiceSteps [
    [FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libConstructor (Name
odeintImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"/stepper/runge_kutta_dopri5") CodeFuncChunk
rkdp5C [] CodeVarChunk
rk,
    FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libFunctionWithResult (Name
odeintImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"/stepper/generation") CodeFuncChunk
makeControlled
      [Space -> Argument
inlineArg Space
Real, Space -> Argument
inlineArg Space
Real, CodeExpr -> Argument
lockedArg (CodeVarChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy CodeVarChunk
rk)] CodeVarChunk
stepper],
    [FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libConstructor (Name
odeintImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"/stepper/adams_bashforth") CodeFuncChunk
adamsBashC [] CodeVarChunk
stepper]],
  Step -> StepGroup
mandatoryStep (Step -> StepGroup) -> Step -> StepGroup
forall a b. (a -> b) -> a -> b
$ FunctionInterface -> Step
callStep (FunctionInterface -> Step) -> FunctionInterface -> Step
forall a b. (a -> b) -> a -> b
$ Name -> CodeFuncChunk -> [Argument] -> FunctionInterface
libFunction (Name
odeintImport Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"/integrate/integrate_const")
    CodeFuncChunk
integrateConst [
      CodeExpr -> Argument
lockedArg (CodeVarChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy CodeVarChunk
stepper),
      [Name]
-> Name -> CodeVarChunk -> CodeFuncChunk -> ClassInfo -> Argument
customObjArg [] Name
"Class representing an ODE system" CodeVarChunk
ode CodeFuncChunk
odeCtor
        ([MethodInfo] -> ClassInfo
customClass [CodeFuncChunk -> [Parameter] -> [Step] -> MethodInfo
constructorInfo CodeFuncChunk
odeCtor [] [],
          CodeFuncChunk -> Name -> [Parameter] -> [Step] -> MethodInfo
methodInfoNoReturn CodeFuncChunk
odeOp Name
"function representation of ODE system"
            [Space -> Parameter
unnamedParam (Space -> Space
Vect Space
Real), Space -> Parameter
unnamedParam (Space -> Space
Vect Space
Real), CodeVarChunk -> Parameter
lockedParam CodeVarChunk
t]
            [Step
assignArrayIndex]]),
      -- Need to declare variable holding initial value because odeint will update this variable at each step
      CodeVarChunk -> Argument
preDefinedArg CodeVarChunk
odeintCurrVals,
      Space -> Argument
inlineArg Space
Real, Space -> Argument
inlineArg Space
Real, Space -> Argument
inlineArg Space
Real,
      [Name]
-> Name -> CodeVarChunk -> CodeFuncChunk -> ClassInfo -> Argument
customObjArg []
        Name
"Class for populating a list during an ODE solution process"
        CodeVarChunk
pop CodeFuncChunk
popCtor ([MethodInfo] -> ClassInfo
customClass [
          CodeFuncChunk -> [Parameter] -> [Step] -> MethodInfo
constructorInfo CodeFuncChunk
popCtor [Space -> Parameter
unnamedParam (Space -> Space
Vect Space
Real)] [],
          CodeFuncChunk -> Name -> [Parameter] -> [Step] -> MethodInfo
methodInfoNoReturn CodeFuncChunk
popOp
            Name
"appends solution point for current ODE solution step"
            [CodeVarChunk -> Parameter
lockedParam CodeVarChunk
y, CodeVarChunk -> Parameter
lockedParam CodeVarChunk
t] [CodeExpr -> Step
appendCurrSol (CodeVarChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy CodeVarChunk
y)]])]]

odeintCall :: ODEInfo -> ExternalLibraryCall
odeintCall :: ODEInfo -> ExternalLibraryCall
odeintCall ODEInfo
info = ExternalLibraryCall -> ExternalLibraryCall
externalLibCall [
  (Int -> [StepFill] -> StepGroupFill)
-> (Int, [StepFill]) -> StepGroupFill
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> [StepFill] -> StepGroupFill
choiceStepsFill (ODEMethod -> (Int, [StepFill])
forall {a}. Num a => ODEMethod -> (a, [StepFill])
chooseMethod (ODEMethod -> (Int, [StepFill])) -> ODEMethod -> (Int, [StepFill])
forall a b. (a -> b) -> a -> b
$ ODEOptions -> ODEMethod
solveMethod (ODEOptions -> ODEMethod) -> ODEOptions -> ODEMethod
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info),
  StepFill -> StepGroupFill
mandatoryStepFill (StepFill -> StepGroupFill) -> StepFill -> StepGroupFill
forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill ([ArgumentFill] -> FunctionIntFill)
-> [ArgumentFill] -> FunctionIntFill
forall a b. (a -> b) -> a -> b
$
    [StateVariable] -> ClassInfoFill -> ArgumentFill
customObjArgFill ((CodeVarChunk -> StateVariable)
-> [CodeVarChunk] -> [StateVariable]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> StateVariable
privStateVar ([CodeVarChunk] -> [StateVariable])
-> [CodeVarChunk] -> [StateVariable]
forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info) ([MethodInfoFill] -> ClassInfoFill
customClassFill [
      [ParameterFill] -> [Initializer] -> [StepFill] -> MethodInfoFill
constructorInfoFill ((CodeVarChunk -> ParameterFill)
-> [CodeVarChunk] -> [ParameterFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> ParameterFill
userDefinedParamFill ([CodeVarChunk] -> [ParameterFill])
-> [CodeVarChunk] -> [ParameterFill]
forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)
        ([CodeVarChunk] -> [CodeExpr] -> [Initializer]
forall a b. [a] -> [b] -> [(a, b)]
zip (ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info) ((CodeVarChunk -> CodeExpr) -> [CodeVarChunk] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ([CodeVarChunk] -> [CodeExpr]) -> [CodeVarChunk] -> [CodeExpr]
forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)) [],
      [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill [CodeVarChunk -> ParameterFill
unnamedParamPBVFill (CodeVarChunk -> ParameterFill) -> CodeVarChunk -> ParameterFill
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info, CodeVarChunk -> ParameterFill
unnamedParamFill CodeVarChunk
ddep]
        [CodeVarChunk -> [CodeExpr] -> StepFill
assignArrayIndexFill CodeVarChunk
ddep (ODEInfo -> [CodeExpr]
odeSyst ODEInfo
info)]]) ArgumentFill -> [ArgumentFill] -> [ArgumentFill]
forall a. a -> [a] -> [a]
:
    (CodeExpr -> ArgumentFill) -> [CodeExpr] -> [ArgumentFill]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill [[[CodeExpr]] -> CodeExpr
forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
initVal ODEInfo
info], ODEInfo -> CodeExpr
tInit ODEInfo
info, ODEInfo -> CodeExpr
tFinal ODEInfo
info,
      ODEOptions -> CodeExpr
stepSize (ODEOptions -> CodeExpr) -> ODEOptions -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info] [ArgumentFill] -> [ArgumentFill] -> [ArgumentFill]
forall a. [a] -> [a] -> [a]
++ [
    [StateVariable] -> ClassInfoFill -> ArgumentFill
customObjArgFill [CodeVarChunk -> StateVariable
privStateVar (CodeVarChunk -> StateVariable) -> CodeVarChunk -> StateVariable
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info] ([MethodInfoFill] -> ClassInfoFill
customClassFill [
      [ParameterFill] -> [Initializer] -> [StepFill] -> MethodInfoFill
constructorInfoFill [CodeVarChunk -> ParameterFill
unnamedParamFill (CodeVarChunk -> ParameterFill) -> CodeVarChunk -> ParameterFill
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info]
        [(ODEInfo -> CodeVarChunk
depVar ODEInfo
info, CodeVarChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy (CodeVarChunk -> CodeExpr) -> CodeVarChunk -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info)] [],
      [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill [] [CodeVarChunk -> StepFill
appendCurrSolFill (CodeVarChunk -> StepFill) -> CodeVarChunk -> StepFill
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info]])]]
  where chooseMethod :: ODEMethod -> (a, [StepFill])
chooseMethod ODEMethod
RK45 = (a
0, ([CodeExpr] -> StepFill) -> [[CodeExpr]] -> [StepFill]
forall a b. (a -> b) -> [a] -> [b]
map (FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill)
-> ([CodeExpr] -> FunctionIntFill) -> [CodeExpr] -> StepFill
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ArgumentFill] -> FunctionIntFill
libCallFill ([ArgumentFill] -> FunctionIntFill)
-> ([CodeExpr] -> [ArgumentFill]) -> [CodeExpr] -> FunctionIntFill
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CodeExpr -> ArgumentFill) -> [CodeExpr] -> [ArgumentFill]
forall a b. (a -> b) -> [a] -> [b]
map
          CodeExpr -> ArgumentFill
basicArgFill) [[], [ODEOptions -> CodeExpr
absTol (ODEOptions -> CodeExpr) -> ODEOptions -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info, ODEOptions -> CodeExpr
relTol (ODEOptions -> CodeExpr) -> ODEOptions -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info]])
        chooseMethod ODEMethod
Adams = (a
1, [FunctionIntFill -> StepFill
callStepFill (FunctionIntFill -> StepFill) -> FunctionIntFill -> StepFill
forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill []])
        chooseMethod ODEMethod
_ = Name -> (a, [StepFill])
forall a. HasCallStack => Name -> a
error Name
odeMethodUnavailable
        ddep :: CodeVarChunk
ddep = CodeVarChunk -> CodeVarChunk
diffCodeChunk (CodeVarChunk -> CodeVarChunk) -> CodeVarChunk -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info

odeintImport, odeNameSpace, rkdp5, adamsBash :: String
odeintImport :: Name
odeintImport = Name
"boost/numeric/odeint"
odeNameSpace :: Name
odeNameSpace = Name
"boost::numeric::odeint::"
rkdp5 :: Name
rkdp5 = Name
odeNameSpace Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"runge_kutta_dopri5<vector<double>>"
adamsBash :: Name
adamsBash = Name
odeNameSpace Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"adams_bashforth<3,vector<double>>"

popT :: Space
popT :: Space
popT = Name -> Space
Actor Name
"Populate"

-- | Collects variables needed for odeint's ODEs as 'QuantityDict's.
odeintSymbols :: [QuantityDict]
odeintSymbols :: [QuantityDict]
odeintSymbols = (CodeVarChunk -> QuantityDict) -> [CodeVarChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [CodeVarChunk
odeintCurrVals, CodeVarChunk
rk, CodeVarChunk
stepper, CodeVarChunk
pop, CodeVarChunk
t, CodeVarChunk
y, CodeVarChunk
ode] [QuantityDict] -> [QuantityDict] -> [QuantityDict]
forall a. [a] -> [a] -> [a]
++ (CodeFuncChunk -> QuantityDict)
-> [CodeFuncChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map CodeFuncChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw
  [CodeFuncChunk
rkdp5C, CodeFuncChunk
makeControlled, CodeFuncChunk
adamsBashC, CodeFuncChunk
integrateConst, CodeFuncChunk
odeCtor, CodeFuncChunk
odeOp, CodeFuncChunk
popCtor,
  CodeFuncChunk
popOp]

odeintCurrVals, rk, stepper, pop :: CodeVarChunk
odeintCurrVals :: CodeVarChunk
odeintCurrVals = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"currVals_odeint" (Name -> Name -> NP
nounPhrase
  Name
"vector holding ODE solution values for the current step"
  Name
"vectors holding ODE solution values for the current step")
  (Space -> Space
Vect Space
Real) (Name -> Symbol
label Name
"currVals")
rk :: CodeVarChunk
rk = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"rk_odeint" (Name -> Name -> NP
nounPhrase
  Name
"stepper for solving ODE system using Runge-Kutta-Dopri5 method"
  Name
"steppers for solving ODE system using Runge-Kutta-Dopri5 method")
  (Name -> Space
Actor Name
rkdp5) (Name -> Symbol
label Name
"rk")
stepper :: CodeVarChunk
stepper = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"stepper_odeint" (Name -> Name -> NP
nounPhrase
  Name
"stepper for solving ODE system" Name
"steppers for solving ODE system")
  (Name -> Space
Actor Name
"auto") (Name -> Symbol
label Name
"stepper")
pop :: CodeVarChunk
pop = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"pop_odeint" (Name -> Name -> NP
nounPhrase
  Name
"object to populate ODE solution vector"
  Name
"objects to populate ODE solution vector") Space
popT (Name -> Symbol
label Name
"pop")

rkdp5C, makeControlled, adamsBashC, integrateConst, odeOp, popCtor,
  popOp :: CodeFuncChunk
rkdp5C :: CodeFuncChunk
rkdp5C = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"rkdp5_odeint" (Name -> Name -> NP
nounPhrase
  Name
"constructor for stepper using Runge-Kutta-Dopri5 method"
  Name
"constructors for stepper using Runge-Kutta-Dopri5 method")
  (Name -> Space
Actor Name
rkdp5) (Name -> Symbol
Label Name
rkdp5)
makeControlled :: CodeFuncChunk
makeControlled = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"make_controlled_odeint" (Name -> Name -> NP
nounPhrase
  Name
"function for adding error control to a stepper"
  Name
"functions for adding error control to a stepper")
  (Name -> Space
Actor Name
"auto") (Name -> Symbol
Label (Name -> Symbol) -> Name -> Symbol
forall a b. (a -> b) -> a -> b
$ Name
odeNameSpace Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"make_controlled")
adamsBashC :: CodeFuncChunk
adamsBashC = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"adamsBash_odeint" (Name -> Name -> NP
nounPhrase
  Name
"constructor for stepper using Adams-Bashforth method"
  Name
"constructors for stepper using Adams-Bashforth method")
  (Name -> Space
Actor Name
adamsBash) (Name -> Symbol
Label Name
adamsBash)
integrateConst :: CodeFuncChunk
integrateConst = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"integrate_const_odeint" (Name -> Name -> NP
nounPhrase
  Name
"function for integrating with a constant step size"
  Name
"functions for integrating with a constant step size")
  Space
Void (Name -> Symbol
Label (Name -> Symbol) -> Name -> Symbol
forall a b. (a -> b) -> a -> b
$ Name
odeNameSpace Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
"integrate_const")
odeOp :: CodeFuncChunk
odeOp = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"ode_operator_odeint" (Name -> Name -> NP
nounPhrase
  Name
"method defining override for calling ODE object"
  Name
"methods defining override for calling ODE object") Space
Void
  (Name -> Symbol
label Name
"operator()")
popCtor :: CodeFuncChunk
popCtor = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"Populate_odeint" (Name -> Name -> NP
nounPhrase
  Name
"constructor for Populate object for ODE solving with odeint"
  Name
"constructors for Populate object for ODE solving with odeint")
  Space
popT (Name -> Symbol
label Name
"Populate")
popOp :: CodeFuncChunk
popOp = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"pop_operator_odeint" (Name -> Name -> NP
nounPhrase
  Name
"method defining override for calling Populate object"
  Name
"methods defining override for calling Populate object") Space
Void
  (Name -> Symbol
label Name
"operator()")

-- 'CodeChunk's used in multiple external ODE libraries

ode, t, y :: CodeVarChunk
-- | ODE object & definition.
ode :: CodeVarChunk
ode = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"ode_obj" (Name -> Name -> NP
nounPhrase
  Name
"object representing an ODE system" Name
"objects representing an ODE system")
  Space
odeObj (Name -> Symbol
label Name
"ode")
-- | Independent variable in an ODE.
t :: CodeVarChunk
t = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"t_ode" (Name -> Name -> NP
nounPhrase
  Name
"current independent variable value in ODE solution"
  Name
"current independent variable value in ODE solution")
  Space
Real (Name -> Symbol
label Name
"t")
-- | Dependent variable in an ODE.
y :: CodeVarChunk
y = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"y_ode" (Name -> Name -> NP
nounPhrase
  Name
"current dependent variable value in ODE solution"
  Name
"current dependent variable value in ODE solution")
  (Space -> Space
Vect Space
Real) (Name -> Symbol
label Name
"y")

-- | ODE object constructor.
odeCtor :: CodeFuncChunk
odeCtor :: CodeFuncChunk
odeCtor = QuantityDict -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (QuantityDict -> CodeFuncChunk) -> QuantityDict -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ Name -> NP -> Space -> Symbol -> QuantityDict
implVar Name
"ODE_constructor" (Name -> Name -> NP
nounPhrase
  Name
"constructor for ODE object" Name
"constructors for ODE object") Space
odeObj
  (Name -> Symbol
label Name
"ODE")

-- | ODE object.
odeObj :: Space
odeObj :: Space
odeObj = Name -> Space
Actor Name
"ODE"

-- | ODE method unavailable message.
odeMethodUnavailable :: String
odeMethodUnavailable :: Name
odeMethodUnavailable = Name
"Chosen ODE solving method is not available" Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++
          Name
" in chosen ODE solving library"

-- | Change in @X@ chunk constructor (where @X@ is a given argument).
diffCodeChunk :: CodeVarChunk -> CodeVarChunk
diffCodeChunk :: CodeVarChunk -> CodeVarChunk
diffCodeChunk CodeVarChunk
c = QuantityDict -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar (QuantityDict -> CodeVarChunk) -> QuantityDict -> CodeVarChunk
forall a b. (a -> b) -> a -> b
$ UID
-> NP
-> Maybe Name
-> Space
-> Symbol
-> Maybe UnitDefn
-> QuantityDict
implVarUID' (CodeVarChunk
c CodeVarChunk -> Name -> UID
forall a. HasUID a => a -> Name -> UID
+++ Name
"d" )
  (NP -> NP -> NP
forall a b. (NounPhrase a, NounPhrase b) => a -> b -> NP
compoundPhrase (Name -> NP
nounPhraseSP Name
"change in") (CodeVarChunk
c CodeVarChunk -> Getting NP CodeVarChunk NP -> NP
forall s a. s -> Getting a s a -> a
^. Getting NP CodeVarChunk NP
forall c. NamedIdea c => Lens' c NP
Lens' CodeVarChunk NP
term)) (CodeVarChunk -> Maybe Name
forall c. Idea c => c -> Maybe Name
getA CodeVarChunk
c) (CodeVarChunk
c CodeVarChunk -> Getting Space CodeVarChunk Space -> Space
forall s a. s -> Getting a s a -> a
^. Getting Space CodeVarChunk Space
forall c. HasSpace c => Getter c Space
Getter CodeVarChunk Space
typ)
  ([Symbol] -> Symbol
Concat [Name -> Symbol
label Name
"d", CodeVarChunk -> Stage -> Symbol
forall c. HasSymbol c => c -> Stage -> Symbol
symbol CodeVarChunk
c Stage
Implementation]) (CodeVarChunk -> Maybe UnitDefn
forall u. MayHaveUnit u => u -> Maybe UnitDefn
getUnit CodeVarChunk
c)

-- FIXME: This is surely a hack, but I can't think of a better way right now.
-- | Some libraries use an array instead of a list to internally represent the ODE.
-- So we need a way to switch the dependent variable from list to array,
-- and the array version must have a distinct UID so it can be stored in the DB.
modifiedODESyst :: String -> ODEInfo -> [CodeExpr]
modifiedODESyst :: Name -> ODEInfo -> [CodeExpr]
modifiedODESyst Name
sufx ODEInfo
info = (CodeExpr -> CodeExpr) -> [CodeExpr] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar (ODEInfo -> [CodeExpr]
odeSyst ODEInfo
info)
  where
    replaceDepVar :: CodeExpr -> CodeExpr
replaceDepVar cc :: CodeExpr
cc@(C UID
c) | UID
c UID -> UID -> Bool
forall a. Eq a => a -> a -> Bool
== ODEInfo -> CodeVarChunk
depVar ODEInfo
info CodeVarChunk -> Getting UID CodeVarChunk UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID CodeVarChunk UID
forall c. HasUID c => Getter c UID
Getter CodeVarChunk UID
uid = UID -> CodeExpr
C (UID -> CodeExpr) -> UID -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info CodeVarChunk -> Name -> UID
forall a. HasUID a => a -> Name -> UID
+++ (Name
"_" Name -> Name -> Name
forall a. [a] -> [a] -> [a]
++ Name
sufx)
                           | Bool
otherwise               = CodeExpr
cc
    replaceDepVar (AssocA AssocArithOper
a [CodeExpr]
es)           = AssocArithOper -> [CodeExpr] -> CodeExpr
AssocA AssocArithOper
a ((CodeExpr -> CodeExpr) -> [CodeExpr] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar [CodeExpr]
es)
    replaceDepVar (AssocB AssocBoolOper
b [CodeExpr]
es)           = AssocBoolOper -> [CodeExpr] -> CodeExpr
AssocB AssocBoolOper
b ((CodeExpr -> CodeExpr) -> [CodeExpr] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar [CodeExpr]
es)
    replaceDepVar (FCall UID
u [CodeExpr]
es [(UID, CodeExpr)]
nes)        = UID -> [CodeExpr] -> [(UID, CodeExpr)] -> CodeExpr
FCall UID
u ((CodeExpr -> CodeExpr) -> [CodeExpr] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar [CodeExpr]
es)
      (((UID, CodeExpr) -> (UID, CodeExpr))
-> [(UID, CodeExpr)] -> [(UID, CodeExpr)]
forall a b. (a -> b) -> [a] -> [b]
map (ASetter (UID, CodeExpr) (UID, CodeExpr) CodeExpr CodeExpr
-> (CodeExpr -> CodeExpr) -> (UID, CodeExpr) -> (UID, CodeExpr)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter (UID, CodeExpr) (UID, CodeExpr) CodeExpr CodeExpr
forall s t a b. Field2 s t a b => Lens s t a b
Lens (UID, CodeExpr) (UID, CodeExpr) CodeExpr CodeExpr
_2 CodeExpr -> CodeExpr
replaceDepVar) [(UID, CodeExpr)]
nes)
    replaceDepVar (New UID
u [CodeExpr]
es [(UID, CodeExpr)]
nes)          = UID -> [CodeExpr] -> [(UID, CodeExpr)] -> CodeExpr
New UID
u ((CodeExpr -> CodeExpr) -> [CodeExpr] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar [CodeExpr]
es)
      (((UID, CodeExpr) -> (UID, CodeExpr))
-> [(UID, CodeExpr)] -> [(UID, CodeExpr)]
forall a b. (a -> b) -> [a] -> [b]
map (ASetter (UID, CodeExpr) (UID, CodeExpr) CodeExpr CodeExpr
-> (CodeExpr -> CodeExpr) -> (UID, CodeExpr) -> (UID, CodeExpr)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter (UID, CodeExpr) (UID, CodeExpr) CodeExpr CodeExpr
forall s t a b. Field2 s t a b => Lens s t a b
Lens (UID, CodeExpr) (UID, CodeExpr) CodeExpr CodeExpr
_2 CodeExpr -> CodeExpr
replaceDepVar) [(UID, CodeExpr)]
nes)
    replaceDepVar (Message UID
au UID
mu [CodeExpr]
es [(UID, CodeExpr)]
nes)  = UID -> UID -> [CodeExpr] -> [(UID, CodeExpr)] -> CodeExpr
Message UID
au UID
mu ((CodeExpr -> CodeExpr) -> [CodeExpr] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar [CodeExpr]
es)
      (((UID, CodeExpr) -> (UID, CodeExpr))
-> [(UID, CodeExpr)] -> [(UID, CodeExpr)]
forall a b. (a -> b) -> [a] -> [b]
map (ASetter (UID, CodeExpr) (UID, CodeExpr) CodeExpr CodeExpr
-> (CodeExpr -> CodeExpr) -> (UID, CodeExpr) -> (UID, CodeExpr)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter (UID, CodeExpr) (UID, CodeExpr) CodeExpr CodeExpr
forall s t a b. Field2 s t a b => Lens s t a b
Lens (UID, CodeExpr) (UID, CodeExpr) CodeExpr CodeExpr
_2 CodeExpr -> CodeExpr
replaceDepVar) [(UID, CodeExpr)]
nes)
    replaceDepVar (Case Completeness
c [(CodeExpr, CodeExpr)]
cs)             = Completeness -> [(CodeExpr, CodeExpr)] -> CodeExpr
Case Completeness
c (((CodeExpr, CodeExpr) -> (CodeExpr, CodeExpr))
-> [(CodeExpr, CodeExpr)] -> [(CodeExpr, CodeExpr)]
forall a b. (a -> b) -> [a] -> [b]
map (ASetter (CodeExpr, CodeExpr) (CodeExpr, CodeExpr) CodeExpr CodeExpr
-> (CodeExpr -> CodeExpr)
-> (CodeExpr, CodeExpr)
-> (CodeExpr, CodeExpr)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter (CodeExpr, CodeExpr) (CodeExpr, CodeExpr) CodeExpr CodeExpr
forall s t a b. Field1 s t a b => Lens s t a b
Lens (CodeExpr, CodeExpr) (CodeExpr, CodeExpr) CodeExpr CodeExpr
_1 CodeExpr -> CodeExpr
replaceDepVar) [(CodeExpr, CodeExpr)]
cs)
    replaceDepVar (Matrix [[CodeExpr]]
es)             = [[CodeExpr]] -> CodeExpr
Matrix ([[CodeExpr]] -> CodeExpr) -> [[CodeExpr]] -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ([CodeExpr] -> [CodeExpr]) -> [[CodeExpr]] -> [[CodeExpr]]
forall a b. (a -> b) -> [a] -> [b]
map ((CodeExpr -> CodeExpr) -> [CodeExpr] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar) [[CodeExpr]]
es
    replaceDepVar (UnaryOp UFunc
u CodeExpr
e)           = UFunc -> CodeExpr -> CodeExpr
UnaryOp UFunc
u (CodeExpr -> CodeExpr) -> CodeExpr -> CodeExpr
forall a b. (a -> b) -> a -> b
$ CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e
    replaceDepVar (UnaryOpB UFuncB
u CodeExpr
e)          = UFuncB -> CodeExpr -> CodeExpr
UnaryOpB UFuncB
u (CodeExpr -> CodeExpr) -> CodeExpr -> CodeExpr
forall a b. (a -> b) -> a -> b
$ CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e
    replaceDepVar (UnaryOpVV UFuncVV
u CodeExpr
e)         = UFuncVV -> CodeExpr -> CodeExpr
UnaryOpVV UFuncVV
u (CodeExpr -> CodeExpr) -> CodeExpr -> CodeExpr
forall a b. (a -> b) -> a -> b
$ CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e
    replaceDepVar (UnaryOpVN UFuncVN
u CodeExpr
e)         = UFuncVN -> CodeExpr -> CodeExpr
UnaryOpVN UFuncVN
u (CodeExpr -> CodeExpr) -> CodeExpr -> CodeExpr
forall a b. (a -> b) -> a -> b
$ CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e
    replaceDepVar (ArithBinaryOp ArithBinOp
b CodeExpr
e1 CodeExpr
e2) = ArithBinOp -> CodeExpr -> CodeExpr -> CodeExpr
ArithBinaryOp ArithBinOp
b
      (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e1) (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e2)
    replaceDepVar (BoolBinaryOp BoolBinOp
b CodeExpr
e1 CodeExpr
e2)  = BoolBinOp -> CodeExpr -> CodeExpr -> CodeExpr
BoolBinaryOp BoolBinOp
b
      (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e1) (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e2)
    replaceDepVar (EqBinaryOp EqBinOp
b CodeExpr
e1 CodeExpr
e2)    = EqBinOp -> CodeExpr -> CodeExpr -> CodeExpr
EqBinaryOp EqBinOp
b
      (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e1) (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e2)
    replaceDepVar (LABinaryOp LABinOp
b CodeExpr
e1 CodeExpr
e2)    = LABinOp -> CodeExpr -> CodeExpr -> CodeExpr
LABinaryOp LABinOp
b
      (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e1) (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e2)
    replaceDepVar (OrdBinaryOp OrdBinOp
b CodeExpr
e1 CodeExpr
e2)   = OrdBinOp -> CodeExpr -> CodeExpr -> CodeExpr
OrdBinaryOp OrdBinOp
b
      (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e1) (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e2)
    replaceDepVar (VVNBinaryOp VVNBinOp
b CodeExpr
e1 CodeExpr
e2)   = VVNBinOp -> CodeExpr -> CodeExpr -> CodeExpr
VVNBinaryOp VVNBinOp
b
      (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e1) (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e2)
    replaceDepVar (VVVBinaryOp VVVBinOp
b CodeExpr
e1 CodeExpr
e2)   = VVVBinOp -> CodeExpr -> CodeExpr -> CodeExpr
VVVBinaryOp VVVBinOp
b
      (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e1) (CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e2)
    replaceDepVar (Operator AssocArithOper
ao DiscreteDomainDesc CodeExpr CodeExpr
dd CodeExpr
e)      = AssocArithOper
-> DiscreteDomainDesc CodeExpr CodeExpr -> CodeExpr -> CodeExpr
Operator AssocArithOper
ao DiscreteDomainDesc CodeExpr CodeExpr
dd (CodeExpr -> CodeExpr) -> CodeExpr -> CodeExpr
forall a b. (a -> b) -> a -> b
$ CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e
    replaceDepVar CodeExpr
e = CodeExpr
e