Skip to content

Commit 53b53aa

Browse files
committed
Add DiscreteFunctionExpr, DiscreteProblemExpr and docs
Signed-off-by: ErikQQY <2283984853@qq.com>
1 parent 478627d commit 53b53aa

File tree

6 files changed

+149
-14
lines changed

6 files changed

+149
-14
lines changed

docs/pages.jl

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pages = [
2828
"systems/JumpSystem.md",
2929
"systems/NonlinearSystem.md",
3030
"systems/OptimizationSystem.md",
31+
"systems/DiscreteSystem.md",
3132
"systems/PDESystem.md"],
3233
"comparison.md",
3334
"internals.md",

docs/src/systems/DiscreteSystem.md

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# DiscreteSystem
2+
3+
## System Constructors
4+
5+
```@docs
6+
DiscreteSystem
7+
```
8+
9+
## Composition and Accessor Functions
10+
11+
- `get_eqs(sys)` or `equations(sys)`: The equations that define the Discrete System.
12+
- `get_delay_val(sys)`: The delay of the Discrete System.
13+
- `get_iv(sys)`: The independent variable of the Discrete System.
14+
15+
## Transformations
16+
17+
## Analyses
18+
19+
## Applicable Calculation and Generation Functions
20+
21+
## Standard Problem Constructors
22+
23+
```@docs
24+
DiscreteFunction(sys::ModelingToolkit.DiscreteSystem, args...)
25+
DiscreteProblem(sys::ModelingToolkit.DiscreteSystem, args...)
26+
```
27+
28+
## Expression Constructors
29+
30+
```@docs
31+
DiscreteFunctionExpr
32+
DiscreteProblemExpr
33+
```

src/ModelingToolkit.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ export SymScope, LocalScope, ParentScope, DelayParentScope, GlobalScope
192192
export independent_variable, equations, controls,
193193
observed, structure, full_equations
194194
export structural_simplify, expand_connections, linearize, linearization_function
195-
export DiscreteSystem, DiscreteProblem, DiscreteFunction
195+
export DiscreteSystem, DiscreteProblem, DiscreteProblemExpr, DiscreteFunction,
196+
DiscreteFunctionExpr
196197

197198
export calculate_jacobian, generate_jacobian, generate_function
198199
export calculate_control_jacobian, generate_control_jacobian

src/systems/discrete_system/discrete_system.jl

+93
Original file line numberDiff line numberDiff line change
@@ -361,3 +361,96 @@ function SciMLBase.DiscreteFunction{iip, specialize}(sys::DiscreteSystem,
361361
observed = observedfun,
362362
analytic = analytic)
363363
end
364+
365+
"""
366+
```julia
367+
DiscreteFunctionExpr{iip}(sys::DiscreteSystem, dvs = states(sys),
368+
ps = parameters(sys);
369+
version = nothing,
370+
kwargs...) where {iip}
371+
```
372+
373+
Create a Julia expression for an `DiscreteFunction` from the [`DiscreteSystem`](@ref).
374+
The arguments `dvs` and `ps` are used to set the order of the dependent
375+
variable and parameter vectors, respectively.
376+
"""
377+
struct DiscreteFunctionExpr{iip} end
378+
struct DiscreteFunctionClosure{O, I} <: Function
379+
f_oop::O
380+
f_iip::I
381+
end
382+
(f::DiscreteFunctionClosure)(u, p, t) = f.f_oop(u, p, t)
383+
(f::DiscreteFunctionClosure)(du, u, p, t) = f.f_iip(du, u, p, t)
384+
385+
function DiscreteFunctionExpr{iip}(sys::DiscreteSystem, dvs = states(sys),
386+
ps = parameters(sys), u0 = nothing;
387+
version = nothing, p = nothing,
388+
linenumbers = false,
389+
simplify = false,
390+
kwargs...) where {iip}
391+
f_oop, f_iip = generate_function(sys, dvs, ps; expression = Val{true}, kwargs...)
392+
393+
fsym = gensym(:f)
394+
_f = :($fsym = $DiscreteFunctionClosure($f_oop, $f_iip))
395+
396+
ex = quote
397+
$_f
398+
DiscreteFunction{$iip}($fsym,
399+
syms = $(Symbol.(states(sys))),
400+
indepsym = $(QuoteNode(Symbol(get_iv(sys)))),
401+
paramsyms = $(Symbol.(parameters(sys))))
402+
end
403+
!linenumbers ? striplines(ex) : ex
404+
end
405+
406+
function DiscreteFunctionExpr(sys::DiscreteSystem, args...; kwargs...)
407+
DiscreteFunctionExpr{true}(sys, args...; kwargs...)
408+
end
409+
410+
function process_DiscreteProblem(constructor, sys::DiscreteSystem, u0map, parammap;
411+
version = nothing,
412+
linenumbers = true, parallel = SerialForm(),
413+
eval_expression = true,
414+
use_union = false,
415+
kwargs...)
416+
eqs = equations(sys)
417+
dvs = states(sys)
418+
ps = parameters(sys)
419+
420+
defs = defaults(sys)
421+
defs = mergedefaults(defs, parammap, ps)
422+
defs = mergedefaults(defs, u0map, dvs)
423+
424+
u0 = varmap_to_vars(u0map, dvs; defaults = defs, tofloat = true)
425+
p = varmap_to_vars(parammap, ps; defaults = defs, tofloat = !use_union, use_union)
426+
427+
check_eqs_u0(eqs, dvs, u0; kwargs...)
428+
429+
f = constructor(sys, dvs, ps, u0;
430+
linenumbers = linenumbers, parallel = parallel,
431+
syms = Symbol.(dvs), paramsyms = Symbol.(ps),
432+
eval_expression = eval_expression, kwargs...)
433+
return f, u0, p
434+
end
435+
436+
function DiscreteProblemExpr(sys::DiscreteSystem, args...; kwargs...)
437+
DiscreteProblemExpr{true}(sys, args...; kwargs...)
438+
end
439+
440+
function DiscreteProblemExpr{iip}(sys::DiscreteSystem, u0map, tspan,
441+
parammap = DiffEqBase.NullParameters();
442+
check_length = true,
443+
kwargs...) where {iip}
444+
f, u0, p = process_DiscreteProblem(DiscreteFunctionExpr{iip}, sys, u0map, parammap;
445+
check_length, kwargs...)
446+
linenumbers = get(kwargs, :linenumbers, true)
447+
448+
ex = quote
449+
f = $f
450+
u0 = $u0
451+
p = $p
452+
tspan = $tspan
453+
DiscreteProblem(f, u0, tspan, p; $(filter_kwargs(kwargs)...))
454+
end
455+
!linenumbers ? striplines(ex) : ex
456+
end

src/systems/jumps/jumpsystem.jl

+6-4
Original file line numberDiff line numberDiff line change
@@ -340,10 +340,12 @@ tspan = (0.0, 250.0)
340340
dprob = DiscreteProblem(js, u₀map, tspan, parammap)
341341
```
342342
"""
343-
function DiscreteProblemExpr(sys::JumpSystem, u0map, tspan::Union{Tuple, Nothing},
344-
parammap = DiffEqBase.NullParameters();
345-
use_union = false,
346-
kwargs...)
343+
struct DiscreteProblemExpr{iip} end
344+
345+
function DiscreteProblemExpr{iip}(sys::JumpSystem, u0map, tspan::Union{Tuple, Nothing},
346+
parammap = DiffEqBase.NullParameters();
347+
use_union = false,
348+
kwargs...) where {iip}
347349
dvs = states(sys)
348350
ps = parameters(sys)
349351
defs = defaults(sys)

test/discretesystem.jl

+14-9
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,22 @@ eqs = [D(S) ~ S - infection * h,
2828
@named sys = DiscreteSystem(eqs, t, [S, I, R], [c, nsteps, δt, β, γ]; controls = [β, γ])
2929
syss = structural_simplify(sys)
3030
@test syss == syss
31-
df = DiscreteFunction(sys)
3231

33-
# iip
34-
du = zeros(3)
35-
u = collect(1:3)
36-
p = collect(1:5)
37-
df.f(du, u, p, 0)
38-
@test du [0.01831563888873422, 0.9816849729159067, 4.999999388195359]
32+
for df in [
33+
DiscreteFunction(sys, [S, I, R], [c, nsteps, δt, β, γ]),
34+
eval(DiscreteFunctionExpr(sys, [S, I, R], [c, nsteps, δt, β, γ])),
35+
]
36+
37+
# iip
38+
du = zeros(3)
39+
u = collect(1:3)
40+
p = collect(1:5)
41+
df.f(du, u, p, 0)
42+
@test du [0.01831563888873422, 0.9816849729159067, 4.999999388195359]
3943

40-
# oop
41-
@test df.f(u, p, 0) [0.01831563888873422, 0.9816849729159067, 4.999999388195359]
44+
# oop
45+
@test df.f(u, p, 0) [0.01831563888873422, 0.9816849729159067, 4.999999388195359]
46+
end
4247

4348
# Problem
4449
u0 = [S => 990.0, I => 10.0, R => 0.0]

0 commit comments

Comments
 (0)