@@ -11,14 +11,16 @@ $(FIELDS)
11
11
```
12
12
using ModelingToolkit
13
13
14
- @parameters σ ρ β
15
- @variables t x(t) y(t) z(t) next_x(t) next_y(t) next_z(t)
14
+ @parameters σ=28.0 ρ=10.0 β=8/3 δt=0.1
15
+ @variables t x(t)=1.0 y(t)=0.0 z(t)=0.0
16
+ D = Difference(t; dt=δt)
16
17
17
- eqs = [next_x ~ σ*(y-x),
18
- next_y ~ x*(ρ-z)-y,
19
- next_z ~ x*y - β*z]
18
+ eqs = [D(x) ~ σ*(y-x),
19
+ D(y) ~ x*(ρ-z)-y,
20
+ D(z) ~ x*y - β*z]
20
21
21
- @named de = DiscreteSystem(eqs,t,[x,y,z],[σ,ρ,β])
22
+ @named de = DiscreteSystem(eqs,t,[x,y,z],[σ,ρ,β]) # or
23
+ @named de = DiscreteSystem(eqs)
22
24
```
23
25
"""
24
26
struct DiscreteSystem <: AbstractTimeDependentSystem
@@ -45,26 +47,21 @@ struct DiscreteSystem <: AbstractTimeDependentSystem
45
47
"""
46
48
systems:: Vector{DiscreteSystem}
47
49
"""
48
- default_u0 : The default initial conditions to use when initial conditions
49
- are not supplied in `DiscreteSystem `.
50
+ defaults : The default values to use when initial conditions and/or
51
+ parameters are not supplied in `DiscreteProblem `.
50
52
"""
51
- default_u0:: Dict
52
- """
53
- default_p: The default parameters to use when parameters are not supplied
54
- in `DiscreteSystem`.
55
- """
56
- default_p:: Dict
53
+ defaults:: Dict
57
54
"""
58
55
type: type of the system
59
56
"""
60
57
connection_type:: Any
61
- function DiscreteSystem (discreteEqs, iv, dvs, ps, var_to_name, ctrls, observed, name, systems, default_u0, default_p , connection_type; checks:: Bool = true )
58
+ function DiscreteSystem (discreteEqs, iv, dvs, ps, var_to_name, ctrls, observed, name, systems, defaults , connection_type; checks:: Bool = true )
62
59
if checks
63
60
check_variables (dvs, iv)
64
61
check_parameters (ps, iv)
65
62
all_dimensionless ([dvs;ps;iv;ctrls]) || check_units (discreteEqs)
66
63
end
67
- new (discreteEqs, iv, dvs, ps, var_to_name, ctrls, observed, name, systems, default_u0, default_p , connection_type)
64
+ new (discreteEqs, iv, dvs, ps, var_to_name, ctrls, observed, name, systems, defaults , connection_type)
68
65
end
69
66
end
70
67
@@ -93,7 +90,7 @@ function DiscreteSystem(
93
90
ctrl′ = value .(controls)
94
91
95
92
if ! (isempty (default_u0) && isempty (default_p))
96
- Base. depwarn (" `default_u0` and `default_p` are deprecated. Use `defaults` instead." , :ODESystem , force= true )
93
+ Base. depwarn (" `default_u0` and `default_p` are deprecated. Use `defaults` instead." , :DiscreteSystem , force= true )
97
94
end
98
95
defaults = todict (defaults)
99
96
defaults = Dict (value (k) => value (v) for (k, v) in pairs (defaults))
@@ -106,7 +103,46 @@ function DiscreteSystem(
106
103
if length (unique (sysnames)) != length (sysnames)
107
104
throw (ArgumentError (" System names must be unique." ))
108
105
end
109
- DiscreteSystem (eqs, iv′, dvs′, ps′, var_to_name, ctrl′, observed, name, systems, default_u0, default_p, connection_type, kwargs... )
106
+ DiscreteSystem (eqs, iv′, dvs′, ps′, var_to_name, ctrl′, observed, name, systems, defaults, connection_type, kwargs... )
107
+ end
108
+
109
+
110
+ function DiscreteSystem (eqs, iv= nothing ; kwargs... )
111
+ eqs = collect (eqs)
112
+ # NOTE: this assumes that the order of algebric equations doesn't matter
113
+ diffvars = OrderedSet ()
114
+ allstates = OrderedSet ()
115
+ ps = OrderedSet ()
116
+ # reorder equations such that it is in the form of `diffeq, algeeq`
117
+ diffeq = Equation[]
118
+ algeeq = Equation[]
119
+ # initial loop for finding `iv`
120
+ if iv === nothing
121
+ for eq in eqs
122
+ if ! (eq. lhs isa Number) # assume eq.lhs is either Differential or Number
123
+ iv = iv_from_nested_difference (eq. lhs)
124
+ break
125
+ end
126
+ end
127
+ end
128
+ iv = value (iv)
129
+ iv === nothing && throw (ArgumentError (" Please pass in independent variables." ))
130
+ for eq in eqs
131
+ collect_vars_difference! (allstates, ps, eq. lhs, iv)
132
+ collect_vars_difference! (allstates, ps, eq. rhs, iv)
133
+ if isdifferenceeq (eq)
134
+ diffvar, _ = var_from_nested_difference (eq. lhs)
135
+ isequal (iv, iv_from_nested_difference (eq. lhs)) || throw (ArgumentError (" A DiscreteSystem can only have one independent variable." ))
136
+ diffvar in diffvars && throw (ArgumentError (" The difference variable $diffvar is not unique in the system of equations." ))
137
+ push! (diffvars, diffvar)
138
+ push! (diffeq, eq)
139
+ else
140
+ push! (algeeq, eq)
141
+ end
142
+ end
143
+ algevars = setdiff (allstates, diffvars)
144
+ # the orders here are very important!
145
+ return DiscreteSystem (append! (diffeq, algeeq), iv, vcat (collect (diffvars), collect (algevars)), ps; kwargs... )
110
146
end
111
147
112
148
"""
@@ -123,16 +159,37 @@ function DiffEqBase.DiscreteProblem(sys::DiscreteSystem,u0map,tspan,
123
159
ps = parameters (sys)
124
160
eqs = equations (sys)
125
161
eqs = linearize_eqs (sys, eqs)
126
- # defs = defaults(sys)
127
- t = get_iv (sys)
128
- u0 = varmap_to_vars (u0map,dvs)
162
+ defs = defaults (sys)
163
+ iv = get_iv (sys)
164
+
165
+ if parammap isa Dict
166
+ u0defs = merge (parammap, defs)
167
+ elseif eltype (parammap) <: Pair
168
+ u0defs = merge (Dict (parammap), defs)
169
+ elseif eltype (parammap) <: Number
170
+ u0defs = merge (Dict (zip (ps, parammap)), defs)
171
+ else
172
+ u0defs = defs
173
+ end
174
+ if u0map isa Dict
175
+ pdefs = merge (u0map, defs)
176
+ elseif eltype (u0map) <: Pair
177
+ pdefs = merge (Dict (u0map), defs)
178
+ elseif eltype (u0map) <: Number
179
+ pdefs = merge (Dict (zip (dvs, u0map)), defs)
180
+ else
181
+ pdefs = defs
182
+ end
183
+
184
+ u0 = varmap_to_vars (u0map,dvs; defaults= u0defs)
185
+
129
186
rhss = [eq. rhs for eq in eqs]
130
187
u = dvs
131
- p = varmap_to_vars (parammap,ps)
188
+ p = varmap_to_vars (parammap,ps; defaults = pdefs )
132
189
133
190
f_gen = generate_function (sys; expression= Val{eval_expression}, expression_module= eval_module)
134
191
f_oop, _ = (@RuntimeGeneratedFunction (eval_module, ex) for ex in f_gen)
135
- f (u,p,t ) = f_oop (u,p,t )
192
+ f (u,p,iv ) = f_oop (u,p,iv )
136
193
DiscreteProblem (f,u0,tspan,p;kwargs... )
137
194
end
138
195
0 commit comments