Skip to content

Commit 101d4df

Browse files
docs: add tutorial for callable parameters
1 parent 41de08f commit 101d4df

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

docs/pages.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ pages = [
1212
"tutorials/parameter_identifiability.md",
1313
"tutorials/bifurcation_diagram_computation.md",
1414
"tutorials/SampledData.md",
15-
"tutorials/domain_connections.md"],
15+
"tutorials/domain_connections.md",
16+
"tutorials/callable_params.md"],
1617
"Examples" => Any[
1718
"Basic Examples" => Any["examples/higher_order.md",
1819
"examples/spring_mass.md",

docs/src/tutorials/callable_params.md

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Callable parameters and interpolating data
2+
3+
ModelingToolkit.jl allows creating parameters that represent functions to be called. This
4+
is especially useful for including interpolants and/or lookup tables inside ODEs. In this
5+
tutorial we will create an `ODESystem` which employs callable parameters to interpolate data
6+
inside an ODE and go over the various syntax options and their implications.
7+
8+
## Callable parameter syntax
9+
10+
The syntax for callable parameters declared via `@parameters` must be one of the following
11+
12+
1. `(fn::FType)(..)`
13+
2. `fn(::argType1, ::argType2, ...)`
14+
15+
In the first case, the parameter is callable with any number/combination of arguments, and
16+
has a type of `FType` (the callable must be a subtype of `FType`). In the second case,
17+
the parameter is callable with as many arguments as declared, and all must match the
18+
declared types.
19+
20+
By default, the return type of the callable symbolic is inferred to be `Real`. To change
21+
this, a `::retType` annotation can be added at the end.
22+
23+
To declare a function that returns an array of values, the same array syntax can be used
24+
as for normal variables:
25+
26+
```julia
27+
@parameters (foo::FType)(..)[1:3]::retType
28+
@parameters foo(::argType1, ::argType2)[1:3]::retType
29+
```
30+
31+
`retType` here is the `eltype` of the returned array.
32+
33+
## Storage of callable parameters
34+
35+
Callable parameters declared with the `::FType` syntax will be stored in a `Vector{FType}`.
36+
Thus, if `FType` is non-concrete, the buffer will also be non-concrete. This is sometimes
37+
necessary to allow the value of the callable to be switched out for a different type without
38+
rebuilding the model. Typically this syntax is preferable when `FType` is concrete or
39+
a small union.
40+
41+
Callable parameters declared with the `::argType1, ...` syntax will be stored in a
42+
`Vector{FunctionWrappers.FunctionWrapper{retType, Tuple{argType1, ...}}}`. This suffers
43+
the small overhead of a `FunctionWrapper` and restricts the signature of the callable,
44+
symbolic, but allows storing the parameter in a type-stable manner and swapping it out.
45+
This is preferable when the values that the callable can take do not share a common
46+
subtype. For example, when a callable can represent the activation of a neural network
47+
and can be `tanh`, `sigmoid`, etc. which have a common ancestor of `Function`.
48+
49+
If both `::FType` and `::argType`s are specified, `::FType` takes priority. For example,
50+
51+
```julia
52+
@parameters (p::LinearInterpolation)(::Real)
53+
```
54+
55+
`p` will be stored in a `Vector{LinearInterpolation}`. If `::LinearInterpolation` was not
56+
specified, it would be stored in a `Vector{FunctionWrapper{Real, Tuple{Real}}}`.
57+
58+
## Example using interpolations
59+
60+
```@example callable
61+
using ModelingToolkit
62+
using OrdinaryDiffEq
63+
using DataInterpolations
64+
using ModelingToolkit: t_nounits as t, D_nounits as D
65+
66+
ts = collect(0.0:0.1:10.0)
67+
spline = LinearInterpolation(ts .^ 2, ts)
68+
Tspline = typeof(spline)
69+
@variables x(t)
70+
@parameters (interp::Tspline)(..)
71+
72+
@mtkbuild sys = ODESystem(D(x) ~ interp(t), t)
73+
```
74+
75+
The derivative of `x` is obtained via an interpolation from DataInterpolations.jl. Note
76+
the parameter syntax. The `(..)` marks the parameter as callable. `(interp::Tspline)`
77+
indicates that the parameter is of type `Tspline`.
78+
79+
```@example callable
80+
prob = ODEProblem(sys, [x => 0.0], (0.0, 1.0), [interp => spline])
81+
solve(prob)
82+
```
83+
84+
Note that the the following will not work:
85+
86+
```julia
87+
ODEProblem(
88+
sys; [x => 0.0], (0.0, 1.0), [interp => LinearInterpolation(0.0:0.1:1.0, 0.0:0.1:1.0)])
89+
```
90+
91+
Since the type of the spline doesn't match.

0 commit comments

Comments
 (0)