-- | 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 forall a b. (a -> b) -> a -> b
$ FunctionInterface -> Step
callStep forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libFunctionWithResult Name
scipyImport
    CodeFuncChunk
odefunc [
      CodeFuncChunk -> [Parameter] -> Step -> Argument
functionArg CodeFuncChunk
f (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 (forall r. LiteralC r => Name -> r
str Name
"dopri5"), Argument
atol, Argument
rtol]],
  [Step] -> StepGroup
mandatorySteps [FunctionInterface -> Step
callStep 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 forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill [[ParameterFill] -> StepFill -> ArgumentFill
functionArgFill
    (forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> ParameterFill
unnamedParamFill [ODEInfo -> CodeVarChunk
indepVar ODEInfo
info, ODEInfo -> CodeVarChunk
depVar ODEInfo
info])
    ([CodeExpr] -> StepFill
returnExprListFill forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeExpr]
odeSyst ODEInfo
info)],
  forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> StepFill -> StepGroupFill
choiceStepFill (forall {a}. Num a => ODEMethod -> (a, StepFill)
chooseMethod forall a b. (a -> b) -> a -> b
$ ODEOptions -> ODEMethod
solveMethod forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info),
  [StepFill] -> StepGroupFill
mandatoryStepsFill [FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill
      [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) (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 (forall r. ExprC r => r -> r -> r
addI (forall r. CodeExprC r => CodeVarChunk -> CodeVarChunk -> r
field CodeVarChunk
r CodeVarChunk
t) (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 forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill
          [ODEOptions -> CodeExpr
absTol forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info, ODEOptions -> CodeExpr
relTol 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 (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 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. LiteralC r => Name -> r
str

setIntegratorMethod :: [Argument] -> Step
setIntegratorMethod :: [Argument] -> Step
setIntegratorMethod = FunctionInterface -> Step
callStep 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 = forall a b. (a -> b) -> [a] -> [b]
map forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [NamedArgument
mthdArg, NamedArgument
atolArg, NamedArgument
rtolArg]
  forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [CodeVarChunk
r, CodeVarChunk
t, CodeVarChunk
y, CodeVarChunk
xAxis, CodeVarChunk
ut, CodeVarChunk
transpose]
  forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map 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 = forall q. (Quantity q, MayHaveUnit q) => q -> NamedArgument
narg 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 = forall q. (Quantity q, MayHaveUnit q) => q -> NamedArgument
narg 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 = forall q. (Quantity q, MayHaveUnit q) => q -> NamedArgument
narg 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 forall a b. (a -> b) -> a -> b
$ FunctionInterface -> Step
callStep 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 forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (\CodeFuncChunk
s -> FunctionInterface -> Step
callStep 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 (forall a b. (a -> b) -> [a] -> [b]
map Space -> Argument
inlineArg [Space
Real, Space
Real, Space
Real]) CodeVarChunk
points) 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 forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill [CodeExpr -> ArgumentFill
basicArgFill forall a b. (a -> b) -> a -> b
$ forall r. ExprC r => [[r]] -> r
matrix[ODEInfo -> [CodeExpr]
initVal ODEInfo
info]],
  Int -> StepFill -> StepGroupFill
choiceStepFill (forall {a}. Num a => ODEMethod -> a
chooseMethod forall a b. (a -> b) -> a -> b
$ ODEOptions -> ODEMethod
solveMethod forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info) forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$
    [ArgumentFill] -> FunctionIntFill
libCallFill [CodeExpr -> ArgumentFill
basicArgFill forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeExpr
tInit ODEInfo
info,
      [ParameterFill] -> StepFill -> ArgumentFill
functionArgFill (forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> ParameterFill
unnamedParamFill [ODEInfo -> CodeVarChunk
indepVar ODEInfo
info, ODEInfo -> CodeVarChunk
vecDepVar ODEInfo
info]) forall a b. (a -> b) -> a -> b
$
        FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill forall a b. (a -> b) -> a -> b
$ 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 forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info, ODEOptions -> CodeExpr
relTol forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info]],
  [StepFill] -> StepGroupFill
mandatoryStepsFill (FunctionIntFill -> StepFill
callStepFill ([ArgumentFill] -> FunctionIntFill
libCallFill forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill
      [ODEInfo -> CodeExpr
tInit ODEInfo
info, ODEInfo -> CodeExpr
tFinal ODEInfo
info, ODEOptions -> CodeExpr
stepSize forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info]) 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
_ = forall a. HasCallStack => Name -> a
error Name
odeMethodUnavailable

odeArgs :: [Argument]
odeArgs :: [Argument]
odeArgs = [Space -> Argument
inlineArg Space
Real, CodeExpr -> Argument
lockedArg (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy CodeVarChunk
initv),
  CodeFuncChunk -> [Parameter] -> Step -> Argument
functionArg CodeFuncChunk
fOslo (forall a b. (a -> b) -> [a] -> [b]
map Space -> Parameter
unnamedParam [Space
Real, Space
vecT])
    (FunctionInterface -> Step
callStep 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 = forall a b. (a -> b) -> [a] -> [b]
map 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] forall a. [a] -> [a] -> [a]
++
  forall a b. (a -> b) -> [a] -> [b]
map 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar forall a b. (a -> b) -> a -> b
$ UID -> NP -> Space -> Symbol -> QuantityDict
implVarUID (CodeVarChunk
dv forall s a. s -> Getting a s a -> a
^. forall c. HasUID c => Lens' c UID
uid) (CodeVarChunk
dv forall s a. s -> Getting a s a -> a
^. forall c. NamedIdea c => Lens' c NP
term) Space
vecT
  (Symbol -> Symbol -> Symbol
sub (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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar forall a b. (a -> b) -> a -> b
$ UID -> NP -> Space -> Symbol -> QuantityDict
implVarUID (CodeVarChunk
dv forall a. HasUID a => a -> Name -> UID
+++ Name
"vec") (CodeVarChunk
dv forall s a. s -> Getting a s a -> a
^. forall c. NamedIdea c => Lens' c NP
term)
  (CodeVarChunk
dv forall s a. s -> Getting a s a -> a
^. forall c. HasSpace c => Getter c Space
typ) (Symbol -> Symbol -> Symbol
sub (forall c. HasSymbol c => c -> Stage -> Symbol
symbol CodeVarChunk
dv Stage
Implementation) (Name -> Symbol
label Name
"vec"))
  where dv :: CodeVarChunk
dv = CodeVarChunk -> CodeVarChunk
listToArray 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 forall a b. (a -> b) -> a -> b
$ [Name]
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libConstructorMultiReqs [Name
apacheImport forall a. [a] -> [a] -> [a]
++ Name
"nonstiff." forall a. [a] -> [a] -> [a]
++ Name
adams,
      Name
foiImp] CodeFuncChunk
adamsC (CodeExpr -> Argument
lockedArg (forall r. LiteralC r => Integer -> r
int Integer
3) forall a. a -> [a] -> [a]
: [Argument]
itArgs) CodeVarChunk
it,
    FunctionInterface -> Step
callStep forall a b. (a -> b) -> a -> b
$ [Name]
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libConstructorMultiReqs [Name
apacheImport forall a. [a] -> [a] -> [a]
++ Name
"nonstiff." forall a. [a] -> [a] -> [a]
++ Name
dp54,
      Name
foiImp] CodeFuncChunk
dp54C [Argument]
itArgs CodeVarChunk
it],
  [Step] -> StepGroup
mandatorySteps [FunctionInterface -> Step
callStep 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"
            (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"
            (forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> Parameter
lockedParam [CodeVarChunk
interpolator, CodeVarChunk
isLast])
            [FunctionInterface -> Step
callStep 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 (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy CodeVarChunk
curr)]])],
    FunctionInterface -> Step
callStep 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 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]]) 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 (forall {a}. Num a => ODEMethod -> a
chooseMethod forall a b. (a -> b) -> a -> b
$ ODEOptions -> ODEMethod
solveMethod forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info) forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$
    [ArgumentFill] -> FunctionIntFill
libCallFill (forall a b. (a -> b) -> [a] -> [b]
map (CodeExpr -> ArgumentFill
basicArgFill forall b c a. (b -> c) -> (a -> b) -> a -> c
. (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 forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill [
      [StateVariable] -> ClassInfoFill -> ArgumentFill
customObjArgFill [CodeVarChunk -> StateVariable
pubStateVar forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info] ([MethodInfoFill] -> ClassInfoFill
implementationFill [
        [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill [] [CodeVarChunk -> StepFill
initSolListFromArrayFill forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info], [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill []
          [FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill [], CodeVarChunk -> StepFill
appendCurrSolFill forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info]])],
    FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill forall a b. (a -> b) -> a -> b
$ [StateVariable] -> ClassInfoFill -> ArgumentFill
customObjArgFill
      (forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> StateVariable
privStateVar forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)
      ([MethodInfoFill] -> ClassInfoFill
implementationFill [
        [ParameterFill] -> [Initializer] -> [StepFill] -> MethodInfoFill
constructorInfoFill (forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> ParameterFill
userDefinedParamFill forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)
          (forall a b. [a] -> [b] -> [(a, b)]
zip (ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info) (forall a b. (a -> b) -> [a] -> [b]
map forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)) [],
        [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill [] [CodeExpr -> StepFill
fixedStatementFill' forall a b. (a -> b) -> a -> b
$ forall r. LiteralC r => Integer -> r
int forall a b. (a -> b) -> a -> b
$ forall a. Integral a => a -> Integer
toInteger forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeExpr]
initVal ODEInfo
info],
        [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill (forall a b. (a -> b) -> [a] -> [b]
map (CodeVarChunk -> ParameterFill
unnamedParamFill 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)]])
      forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill [ODEInfo -> CodeExpr
tInit ODEInfo
info, forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
initVal ODEInfo
info], ODEInfo -> CodeExpr
tFinal ODEInfo
info,
        forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
initVal ODEInfo
info]],
    CodeVarChunk -> StepFill
assignSolFromObjFill 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
_ = forall a. HasCallStack => Name -> a
error Name
odeMethodUnavailable
        ddep :: CodeVarChunk
ddep = CodeVarChunk -> CodeVarChunk
diffCodeChunk forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info

itArgs :: [Argument]
itArgs :: [Argument]
itArgs = 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 forall a. [a] -> [a] -> [a]
++ Name
foi
sampling :: Name
sampling = Name
"sampling"
sh :: Name
sh = Name
"StepHandler"
shImp :: Name
shImp = Name
apacheImport forall a. [a] -> [a] -> [a]
++ Name
sampling forall a. [a] -> [a] -> [a]
++ Name
"." forall a. [a] -> [a] -> [a]
++ Name
sh
si :: Name
si = Name
"StepInterpolator"
siImp :: Name
siImp = Name
apacheImport forall a. [a] -> [a] -> [a]
++ Name
sampling forall a. [a] -> [a] -> [a]
++ 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 = forall a b. (a -> b) -> [a] -> [b]
map 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] forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 forall a b. (a -> b) -> a -> b
$ Name
"ODE" forall a. [a] -> [a] -> [a]
++ Name
sh)
  (Name -> Symbol
label Name
"stepHandler")
t0 :: CodeVarChunk
t0 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 forall a b. (a -> b) -> a -> b
$ Name
"ODE" forall a. [a] -> [a] -> [a]
++ Name
sh) (Name -> Symbol
Label forall a b. (a -> b) -> a -> b
$ Name
"ODE" forall a. [a] -> [a] -> [a]
++ Name
sh)
addStepHandler :: CodeFuncChunk
addStepHandler = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libConstructor (Name
odeintImport forall a. [a] -> [a] -> [a]
++ Name
"/stepper/runge_kutta_dopri5") CodeFuncChunk
rkdp5C [] CodeVarChunk
rk,
    FunctionInterface -> Step
callStep forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libFunctionWithResult (Name
odeintImport forall a. [a] -> [a] -> [a]
++ Name
"/stepper/generation") CodeFuncChunk
makeControlled
      [Space -> Argument
inlineArg Space
Real, Space -> Argument
inlineArg Space
Real, CodeExpr -> Argument
lockedArg (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy CodeVarChunk
rk)] CodeVarChunk
stepper],
    [FunctionInterface -> Step
callStep forall a b. (a -> b) -> a -> b
$ Name
-> CodeFuncChunk -> [Argument] -> CodeVarChunk -> FunctionInterface
libConstructor (Name
odeintImport forall a. [a] -> [a] -> [a]
++ Name
"/stepper/adams_bashforth") CodeFuncChunk
adamsBashC [] CodeVarChunk
stepper]],
  Step -> StepGroup
mandatoryStep forall a b. (a -> b) -> a -> b
$ FunctionInterface -> Step
callStep forall a b. (a -> b) -> a -> b
$ Name -> CodeFuncChunk -> [Argument] -> FunctionInterface
libFunction (Name
odeintImport forall a. [a] -> [a] -> [a]
++ Name
"/integrate/integrate_const")
    CodeFuncChunk
integrateConst [
      CodeExpr -> Argument
lockedArg (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 (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 [
  forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> [StepFill] -> StepGroupFill
choiceStepsFill (forall {a}. Num a => ODEMethod -> (a, [StepFill])
chooseMethod forall a b. (a -> b) -> a -> b
$ ODEOptions -> ODEMethod
solveMethod forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info),
  StepFill -> StepGroupFill
mandatoryStepFill forall a b. (a -> b) -> a -> b
$ FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill forall a b. (a -> b) -> a -> b
$
    [StateVariable] -> ClassInfoFill -> ArgumentFill
customObjArgFill (forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> StateVariable
privStateVar forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info) ([MethodInfoFill] -> ClassInfoFill
customClassFill [
      [ParameterFill] -> [Initializer] -> [StepFill] -> MethodInfoFill
constructorInfoFill (forall a b. (a -> b) -> [a] -> [b]
map CodeVarChunk -> ParameterFill
userDefinedParamFill forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)
        (forall a b. [a] -> [b] -> [(a, b)]
zip (ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info) (forall a b. (a -> b) -> [a] -> [b]
map forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy forall a b. (a -> b) -> a -> b
$ ODEInfo -> [CodeVarChunk]
otherVars ODEInfo
info)) [],
      [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill [CodeVarChunk -> ParameterFill
unnamedParamPBVFill 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)]]) forall a. a -> [a] -> [a]
:
    forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> ArgumentFill
basicArgFill [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 forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info] forall a. [a] -> [a] -> [a]
++ [
    [StateVariable] -> ClassInfoFill -> ArgumentFill
customObjArgFill [CodeVarChunk -> StateVariable
privStateVar forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info] ([MethodInfoFill] -> ClassInfoFill
customClassFill [
      [ParameterFill] -> [Initializer] -> [StepFill] -> MethodInfoFill
constructorInfoFill [CodeVarChunk -> ParameterFill
unnamedParamFill forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info]
        [(ODEInfo -> CodeVarChunk
depVar ODEInfo
info, forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info)] [],
      [ParameterFill] -> [StepFill] -> MethodInfoFill
methodInfoFill [] [CodeVarChunk -> StepFill
appendCurrSolFill forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info]])]]
  where chooseMethod :: ODEMethod -> (a, [StepFill])
chooseMethod ODEMethod
RK45 = (a
0, forall a b. (a -> b) -> [a] -> [b]
map (FunctionIntFill -> StepFill
callStepFill forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ArgumentFill] -> FunctionIntFill
libCallFill forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map
          CodeExpr -> ArgumentFill
basicArgFill) [[], [ODEOptions -> CodeExpr
absTol forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info, ODEOptions -> CodeExpr
relTol forall a b. (a -> b) -> a -> b
$ ODEInfo -> ODEOptions
odeOpts ODEInfo
info]])
        chooseMethod ODEMethod
Adams = (a
1, [FunctionIntFill -> StepFill
callStepFill forall a b. (a -> b) -> a -> b
$ [ArgumentFill] -> FunctionIntFill
libCallFill []])
        chooseMethod ODEMethod
_ = forall a. HasCallStack => Name -> a
error Name
odeMethodUnavailable
        ddep :: CodeVarChunk
ddep = CodeVarChunk -> CodeVarChunk
diffCodeChunk 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 forall a. [a] -> [a] -> [a]
++ Name
"runge_kutta_dopri5<vector<double>>"
adamsBash :: Name
adamsBash = Name
odeNameSpace 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 = forall a b. (a -> b) -> [a] -> [b]
map forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [CodeVarChunk
odeintCurrVals, CodeVarChunk
rk, CodeVarChunk
stepper, CodeVarChunk
pop, CodeVarChunk
t, CodeVarChunk
y, CodeVarChunk
ode] forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 forall a b. (a -> b) -> a -> b
$ Name
odeNameSpace forall a. [a] -> [a] -> [a]
++ Name
"make_controlled")
adamsBashC :: CodeFuncChunk
adamsBashC = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 forall a b. (a -> b) -> a -> b
$ Name
odeNameSpace forall a. [a] -> [a] -> [a]
++ Name
"integrate_const")
odeOp :: CodeFuncChunk
odeOp = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc 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" 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 = forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar forall a b. (a -> b) -> a -> b
$ UID
-> NP
-> Maybe Name
-> Space
-> Symbol
-> Maybe UnitDefn
-> QuantityDict
implVarUID' (CodeVarChunk
c forall a. HasUID a => a -> Name -> UID
+++ Name
"d" )
  (forall a b. (NounPhrase a, NounPhrase b) => a -> b -> NP
compoundPhrase (Name -> NP
nounPhraseSP Name
"change in") (CodeVarChunk
c forall s a. s -> Getting a s a -> a
^. forall c. NamedIdea c => Lens' c NP
term)) (forall c. Idea c => c -> Maybe Name
getA CodeVarChunk
c) (CodeVarChunk
c forall s a. s -> Getting a s a -> a
^. forall c. HasSpace c => Getter c Space
typ)
  ([Symbol] -> Symbol
Concat [Name -> Symbol
label Name
"d", forall c. HasSymbol c => c -> Stage -> Symbol
symbol CodeVarChunk
c Stage
Implementation]) (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 = 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 forall a. Eq a => a -> a -> Bool
== ODEInfo -> CodeVarChunk
depVar ODEInfo
info forall s a. s -> Getting a s a -> a
^. forall c. HasUID c => Lens' c UID
uid = UID -> CodeExpr
C forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info forall a. HasUID a => a -> Name -> UID
+++ (Name
"_" forall a. [a] -> [a] -> [a]
++ Name
sufx)
                           | Bool
otherwise               = CodeExpr
cc
    replaceDepVar (AssocA AssocArithOper
a [CodeExpr]
es)           = AssocArithOper -> [CodeExpr] -> CodeExpr
AssocA AssocArithOper
a (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 (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 (forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar [CodeExpr]
es)
      (forall a b. (a -> b) -> [a] -> [b]
map (forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall s t a b. Field2 s t a b => Lens s t a b
_2 CodeExpr -> CodeExpr
replaceDepVar) [(UID, CodeExpr)]
nes)
    replaceDepVar (New UID
u [CodeExpr]
es [(UID, CodeExpr)]
nes)          = UID -> [CodeExpr] -> [(UID, CodeExpr)] -> CodeExpr
New UID
u (forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar [CodeExpr]
es)
      (forall a b. (a -> b) -> [a] -> [b]
map (forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall s t a b. Field2 s t a b => Lens s t a b
_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 (forall a b. (a -> b) -> [a] -> [b]
map CodeExpr -> CodeExpr
replaceDepVar [CodeExpr]
es)
      (forall a b. (a -> b) -> [a] -> [b]
map (forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall s t a b. Field2 s t a b => Lens s t a b
_2 CodeExpr -> CodeExpr
replaceDepVar) [(UID, CodeExpr)]
nes)
    replaceDepVar (Case Completeness
c [(CodeExpr, CodeExpr)]
cs)             = Completeness -> [(CodeExpr, CodeExpr)] -> CodeExpr
Case Completeness
c (forall a b. (a -> b) -> [a] -> [b]
map (forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over forall s t a b. Field1 s t a b => Lens s t a b
_1 CodeExpr -> CodeExpr
replaceDepVar) [(CodeExpr, CodeExpr)]
cs)
    replaceDepVar (Matrix [[CodeExpr]]
es)             = [[CodeExpr]] -> CodeExpr
Matrix forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (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 forall a b. (a -> b) -> a -> b
$ CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e
    replaceDepVar (UnaryOpB UFuncB
u CodeExpr
e)          = UFuncB -> CodeExpr -> CodeExpr
UnaryOpB UFuncB
u forall a b. (a -> b) -> a -> b
$ CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e
    replaceDepVar (UnaryOpVV UFuncVV
u CodeExpr
e)         = UFuncVV -> CodeExpr -> CodeExpr
UnaryOpVV UFuncVV
u forall a b. (a -> b) -> a -> b
$ CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e
    replaceDepVar (UnaryOpVN UFuncVN
u CodeExpr
e)         = UFuncVN -> CodeExpr -> CodeExpr
UnaryOpVN UFuncVN
u 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 forall a b. (a -> b) -> a -> b
$ CodeExpr -> CodeExpr
replaceDepVar CodeExpr
e
    replaceDepVar CodeExpr
e = CodeExpr
e