Skip to content

Commit 5384bb4

Browse files
committed
Finished pushing changes & tests to remaining system types.
1 parent 91fa1e0 commit 5384bb4

File tree

6 files changed

+68
-24
lines changed

6 files changed

+68
-24
lines changed

src/systems/jumps/jumpsystem.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ end
158158

159159
function generate_rate_function(js::JumpSystem, rate)
160160
consts = collect_constants(rate)
161-
if !isempty(consts) # The SymbolicUtils._build_function method of this case doesn't support preprocessing
161+
if !isempty(consts) # The SymbolicUtils._build_function method of this case doesn't support postprocess_fbody
162162
csubs = Dict(c => getdefault(c) for c in consts)
163163
rate = substitute(rate, csubs)
164164
end
@@ -170,7 +170,7 @@ end
170170

171171
function generate_affect_function(js::JumpSystem, affect, outputidxs)
172172
consts = collect_constants(affect)
173-
if !isempty(consts) # The SymbolicUtils._build_function method of this case doesn't support preprocessing
173+
if !isempty(consts) # The SymbolicUtils._build_function method of this case doesn't support postprocess_fbody
174174
csubs = Dict(c => getdefault(c) for c in consts)
175175
affect = substitute(affect, csubs)
176176
end

src/systems/nonlinear/nonlinearsystem.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ end
148148
function generate_jacobian(sys::NonlinearSystem, vs = states(sys), ps = parameters(sys);
149149
sparse = false, simplify = false, kwargs...)
150150
jac = calculate_jacobian(sys, sparse = sparse, simplify = simplify)
151-
return build_function(jac, vs, ps; kwargs...)
151+
pre = get_preprocess_constants(jac)
152+
return build_function(jac, vs, ps; postprocess_fbody = pre, kwargs...)
152153
end
153154

154155
function calculate_hessian(sys::NonlinearSystem; sparse = false, simplify = false)
@@ -165,7 +166,8 @@ end
165166
function generate_hessian(sys::NonlinearSystem, vs = states(sys), ps = parameters(sys);
166167
sparse = false, simplify = false, kwargs...)
167168
hess = calculate_hessian(sys, sparse = sparse, simplify = simplify)
168-
return build_function(hess, vs, ps; kwargs...)
169+
pre = get_preprocess_constants(hess)
170+
return build_function(hess, vs, ps; postprocess_fbody = pre, kwargs...)
169171
end
170172

171173
function generate_function(sys::NonlinearSystem, dvs = states(sys), ps = parameters(sys);

src/systems/optimization/optimizationsystem.jl

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ end
100100
function generate_gradient(sys::OptimizationSystem, vs = states(sys), ps = parameters(sys);
101101
kwargs...)
102102
grad = calculate_gradient(sys)
103-
return build_function(grad, vs, ps;
103+
pre = get_preprocess_constants(grad)
104+
return build_function(grad, vs, ps; postprocess_fbody = pre,
104105
conv = AbstractSysToExpr(sys), kwargs...)
105106
end
106107

@@ -115,13 +116,20 @@ function generate_hessian(sys::OptimizationSystem, vs = states(sys), ps = parame
115116
else
116117
hess = calculate_hessian(sys)
117118
end
118-
return build_function(hess, vs, ps;
119+
pre = get_preprocess_constants(hess)
120+
return build_function(hess, vs, ps; postprocess_fbody = pre,
119121
conv = AbstractSysToExpr(sys), kwargs...)
120122
end
121123

122124
function generate_function(sys::OptimizationSystem, vs = states(sys), ps = parameters(sys);
123125
kwargs...)
124-
return build_function(equations(sys), vs, ps;
126+
eqs = equations(sys)
127+
consts = collect_constants(eqs)
128+
if !isempty(consts) # The SymbolicUtils._build_function method of this case doesn't support postprocess_fbody
129+
csubs = Dict(c => getdefault(c) for c in consts)
130+
eqs = substitute(eqs, csubs)
131+
end
132+
return build_function(eqs, vs, ps;
125133
conv = AbstractSysToExpr(sys), kwargs...)
126134
end
127135

@@ -186,7 +194,6 @@ symbolically calculating numerical enhancements.
186194
function DiffEqBase.OptimizationProblem(sys::OptimizationSystem, args...; kwargs...)
187195
DiffEqBase.OptimizationProblem{true}(sys::OptimizationSystem, args...; kwargs...)
188196
end
189-
190197
function DiffEqBase.OptimizationProblem{iip}(sys::OptimizationSystem, u0map,
191198
parammap = DiffEqBase.NullParameters();
192199
lb = nothing, ub = nothing,
@@ -211,8 +218,13 @@ function DiffEqBase.OptimizationProblem{iip}(sys::OptimizationSystem, u0map,
211218

212219
f = generate_function(sys, checkbounds = checkbounds, linenumbers = linenumbers,
213220
expression = Val{false})
214-
215-
obj_expr = toexpr(equations(sys))
221+
eqs = equations(sys)
222+
cs = collect_constants(eqs)
223+
if !isempty(cs)
224+
cmap = map(x -> x => getdefault(x), cs)
225+
eqs = substitute(eqs, cmap)
226+
end
227+
obj_expr = toexpr(eqs)
216228
pairs_arr = p isa SciMLBase.NullParameters ?
217229
[Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)] :
218230
[
@@ -254,8 +266,13 @@ function DiffEqBase.OptimizationProblem{iip}(sys::OptimizationSystem, u0map,
254266
expression = Val{false})[2]
255267
cons_j = generate_jacobian(cons_sys; expression = Val{false}, sparse = sparse)[2]
256268
cons_h = generate_hessian(cons_sys; expression = Val{false}, sparse = sparse)[2]
257-
258-
cons_expr = toexpr(equations(cons_sys))
269+
eqs = equations(cons_sys)
270+
cs = collect_constants(eqs)
271+
if !isempty(cs)
272+
cmap = map(x -> x => getdefault(x), cs)
273+
eqs = map(x -> x.lhs ~ substitute(x.rhs, cmap), eqs)
274+
end
275+
cons_expr = toexpr(eqs)
259276
rep_pars_vals!.(cons_expr, Ref(pairs_arr))
260277

261278
if sparse
@@ -265,7 +282,6 @@ function DiffEqBase.OptimizationProblem{iip}(sys::OptimizationSystem, u0map,
265282
cons_jac_prototype = nothing
266283
cons_hess_prototype = nothing
267284
end
268-
269285
_f = DiffEqBase.OptimizationFunction{iip}(f,
270286
sys = sys,
271287
syms = nameof.(states(sys)),
@@ -360,16 +376,23 @@ function OptimizationProblemExpr{iip}(sys::OptimizationSystem, u0,
360376
lb = varmap_to_vars(lb, dvs; check = false, tofloat = false, use_union)
361377
ub = varmap_to_vars(ub, dvs; check = false, tofloat = false, use_union)
362378

363-
obj_expr = toexpr(equations(sys))
379+
eqs = equations(sys)
380+
cs = collect_constants(eqs)
381+
if !isempty(cs)
382+
cmap = map(x -> x => getdefault(x), cs)
383+
eqs = substitute(eqs, cmap)
384+
end
385+
obj_expr = toexpr(eqs)
364386
pairs_arr = p isa SciMLBase.NullParameters ?
365387
[Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)] :
366388
[
367389
[Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)]...,
368390
[Symbol(_p) => p[i] for (i, _p) in enumerate(ps)]...,
369391
]
370392
rep_pars_vals!(obj_expr, pairs_arr)
371-
393+
@show sys.constraints
372394
if length(sys.constraints) > 0
395+
373396
@named cons_sys = NonlinearSystem(sys.constraints, dvs, ps)
374397
cons = generate_function(cons_sys, checkbounds = checkbounds,
375398
linenumbers = linenumbers,
@@ -378,7 +401,13 @@ function OptimizationProblemExpr{iip}(sys::OptimizationSystem, u0,
378401

379402
cons_h = generate_hessian(cons_sys; expression = Val{false}, sparse = sparse)[2]
380403

381-
cons_expr = toexpr(equations(cons_sys))
404+
eqs = equations(cons_sys)
405+
cs = collect_constants(eqs)
406+
if !isempty(cs)
407+
cmap = map(x -> x => getdefault(x), cs)
408+
eqs = map(x -> x.lhs ~ substitute(x.rhs, cmap), eqs)
409+
end
410+
cons_expr = toexpr(eqs)
382411
rep_pars_vals!.(cons_expr, Ref(pairs_arr))
383412

384413
if sparse

src/utils.jl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,14 +513,25 @@ function collect_constants(eqs::Vector{Equation}) #For get_substitutions_and_sol
513513
return constants
514514
end
515515

516-
function collect_constants(eqs::AbstractArray{T}) where {T} # For generate_tgrad / generate_jacobian / generate_difference_cb
516+
function collect_constants(eqs::AbstractArray{T}) where {T <: Union{Num, Symbolic}} # For generate_tgrad / generate_jacobian / generate_difference_cb
517517
constants = T[]
518518
for eq in eqs
519519
collect_constants!(constants, unwrap(eq))
520520
end
521521
return constants
522522
end
523523

524+
function collect_constants(eqs::Vector{Matrix{Num}}) # For nonlinear hessian
525+
constants = Num[]
526+
for m in eqs
527+
for n in m
528+
collect_constants!(constants, unwrap(n))
529+
end
530+
end
531+
return constants
532+
end
533+
534+
524535
collect_constants(x::Num) = collect_constants(unwrap(x))
525536
function collect_constants(expr::Symbolic{T}) where {T} # For jump system affect / rate
526537
constants = Symbolic[]

test/optimizationsystem.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ using ModelingToolkit, SparseArrays, Test, Optimization, OptimizationOptimJL,
22
OptimizationMOI, Ipopt, AmplNLWriter, Ipopt_jll
33

44
@variables x y
5+
@constants h=1
56
@parameters a b
6-
loss = (a - x)^2 + b * (y - x^2)^2
7+
loss = (a - x)^2 + b * (y * h - x^2)^2
78
sys1 = OptimizationSystem(loss, [x, y], [a, b], name = :sys1)
89

9-
cons2 = [x^2 + y^2 ~ 0, y * sin(x) - x ~ 0]
10+
cons2 = [x^2 + y^2 ~ 0, y * sin(x) - x * h ~ 0]
1011
sys2 = OptimizationSystem(loss, [x, y], [a, b], name = :sys2, constraints = cons2)
1112

1213
@variables z
1314
@parameters β
14-
loss2 = sys1.x - sys2.y + z * β
15+
loss2 = sys1.x - sys2.y + z * β * h
1516
combinedsys = OptimizationSystem(loss2, [z], [β], systems = [sys1, sys2],
1617
name = :combinedsys)
1718

@@ -64,7 +65,7 @@ sol = solve(prob, AmplNLWriter.Optimizer(Ipopt_jll.amplexe))
6465
@test sol.minimum < 1.0
6566

6667
#equality constraint, lcons == ucons
67-
cons2 = [0.0 ~ x^2 + y^2]
68+
cons2 = [0.0 ~ h * x^2 + y^2]
6869
out = zeros(1)
6970
sys2 = OptimizationSystem(loss, [x, y], [a, b], name = :sys2, constraints = cons2)
7071
prob = OptimizationProblem(sys2, [x => 0.0, y => 0.0], [a => 1.0, b => 1.0], lcons = [1.0],
@@ -98,7 +99,7 @@ end
9899

99100
# observed variable handling
100101
@variables OBS
101-
@named sys2 = OptimizationSystem(loss, [x, y], [a, b]; observed = [OBS ~ x + y])
102+
@named sys2 = OptimizationSystem(loss, [x, y], [a, b]; observed = [OBS ~ x * h + y])
102103
OBS2 = OBS
103104
@test isequal(OBS2, @nonamespace sys2.OBS)
104105
@unpack OBS = sys2

test/pde.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ using ModelingToolkit, DiffEqBase, LinearAlgebra
22

33
# Define some variables
44
@parameters t x
5+
@constants h=1
56
@variables u(..)
67
Dt = Differential(t)
78
Dxx = Differential(x)^2
8-
eq = Dt(u(t, x)) ~ Dxx(u(t, x))
9-
bcs = [u(0, x) ~ -x * (x - 1) * sin(x),
9+
eq = Dt(u(t, x)) ~ h * Dxx(u(t, x))
10+
bcs = [u(0, x) ~ -h * x * (x - 1) * sin(x),
1011
u(t, 0) ~ 0, u(t, 1) ~ 0]
1112

1213
domains = [t (0.0, 1.0),

0 commit comments

Comments
 (0)