Skip to content

Commit 3b5f706

Browse files
Separate tests for inequality and equality constraints
1 parent d009682 commit 3b5f706

File tree

2 files changed

+59
-28
lines changed

2 files changed

+59
-28
lines changed

src/systems/optimization/optimizationsystem.jl

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,12 @@ function DiffEqBase.OptimizationProblem{iip}(sys::OptimizationSystem, u0map,
177177
expression = Val{false})
178178

179179
obj_expr = toexpr(equations(sys))
180-
pairs_arr = p isa SciMLBase.NullParameters ? [Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)] : [[Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)]..., [Symbol(_p) => p[i] for (i, _p) in enumerate(ps)]...]
180+
pairs_arr = p isa SciMLBase.NullParameters ?
181+
[Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)] :
182+
[
183+
[Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)]...,
184+
[Symbol(_p) => p[i] for (i, _p) in enumerate(ps)]...,
185+
]
181186
rep_pars_vals!(obj_expr, pairs_arr)
182187
if grad
183188
grad_oop, grad_iip = generate_gradient(sys, checkbounds = checkbounds,
@@ -208,10 +213,11 @@ function DiffEqBase.OptimizationProblem{iip}(sys::OptimizationSystem, u0map,
208213

209214
if length(sys.constraints) > 0
210215
@named cons_sys = NonlinearSystem(sys.constraints, dvs, ps)
211-
cons = generate_function(cons_sys, checkbounds = checkbounds, linenumbers = linenumbers,
212-
expression = Val{false})[1]
213-
cons_j = generate_jacobian(cons_sys; expression=Val{false}, sparse=sparse)[2]
214-
cons_h = generate_hessian(cons_sys; expression = Val{false}, sparse =sparse)[2]
216+
cons = generate_function(cons_sys, checkbounds = checkbounds,
217+
linenumbers = linenumbers,
218+
expression = Val{false})[1]
219+
cons_j = generate_jacobian(cons_sys; expression = Val{false}, sparse = sparse)[2]
220+
cons_h = generate_hessian(cons_sys; expression = Val{false}, sparse = sparse)[2]
215221

216222
cons_expr = toexpr(equations(cons_sys))
217223
rep_pars_vals!.(cons_expr, Ref(pairs_arr))
@@ -225,24 +231,24 @@ function DiffEqBase.OptimizationProblem{iip}(sys::OptimizationSystem, u0map,
225231
end
226232

227233
_f = DiffEqBase.OptimizationFunction{iip}(f,
228-
SciMLBase.NoAD();
229-
grad = _grad,
230-
hess = _hess,
231-
hess_prototype = hess_prototype,
232-
cons = cons,
233-
cons_j = cons_j,
234-
cons_h = cons_h,
235-
cons_jac_prototype = cons_jac_prototype,
236-
cons_hess_prototype = cons_hess_prototype,
237-
expr = obj_expr,
238-
cons_expr = cons_expr)
234+
SciMLBase.NoAD();
235+
grad = _grad,
236+
hess = _hess,
237+
hess_prototype = hess_prototype,
238+
cons = cons,
239+
cons_j = cons_j,
240+
cons_h = cons_h,
241+
cons_jac_prototype = cons_jac_prototype,
242+
cons_hess_prototype = cons_hess_prototype,
243+
expr = obj_expr,
244+
cons_expr = cons_expr)
239245
else
240246
_f = DiffEqBase.OptimizationFunction{iip}(f,
241-
SciMLBase.NoAD();
242-
grad = _grad,
243-
hess = _hess,
244-
hess_prototype = hess_prototype,
245-
expr = obj_expr)
247+
SciMLBase.NoAD();
248+
grad = _grad,
249+
hess = _hess,
250+
hess_prototype = hess_prototype,
251+
expr = obj_expr)
246252
end
247253

248254
OptimizationProblem{iip}(_f, u0, p; lb = lb, ub = ub, kwargs...)
@@ -315,16 +321,22 @@ function OptimizationProblemExpr{iip}(sys::OptimizationSystem, u0,
315321
ub = varmap_to_vars(ub, dvs; check = false, tofloat = false, use_union)
316322

317323
obj_expr = toexpr(equations(sys))
318-
pairs_arr = p isa SciMLBase.NullParameters ? [Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)] : [[Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)]..., [Symbol(_p) => p[i] for (i, _p) in enumerate(ps)]...]
324+
pairs_arr = p isa SciMLBase.NullParameters ?
325+
[Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)] :
326+
[
327+
[Symbol(_s) => Expr(:ref, :x, i) for (i, _s) in enumerate(dvs)]...,
328+
[Symbol(_p) => p[i] for (i, _p) in enumerate(ps)]...,
329+
]
319330
rep_pars_vals!(obj_expr, pairs_arr)
320331

321332
if length(sys.constraints) > 0
322333
@named cons_sys = NonlinearSystem(sys.constraints, dvs, ps)
323-
cons = generate_function(cons_sys, checkbounds = checkbounds, linenumbers = linenumbers,
324-
expression = Val{false})[1]
325-
cons_j = generate_jacobian(cons_sys; expression=Val{false}, sparse=sparse)[2]
334+
cons = generate_function(cons_sys, checkbounds = checkbounds,
335+
linenumbers = linenumbers,
336+
expression = Val{false})[1]
337+
cons_j = generate_jacobian(cons_sys; expression = Val{false}, sparse = sparse)[2]
326338

327-
cons_h = generate_hessian(cons_sys; expression = Val{false}, sparse =sparse)[2]
339+
cons_h = generate_hessian(cons_sys; expression = Val{false}, sparse = sparse)[2]
328340

329341
cons_expr = toexpr(equations(cons_sys))
330342
rep_pars_vals!.(cons_expr, Ref(pairs_arr))

test/optimizationsystem.jl

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using ModelingToolkit, SparseArrays, Test, Optimization, OptimizationOptimJL, OptimizationMOI, Ipopt, AmplNLWriter, Ipopt_jll
1+
using ModelingToolkit, SparseArrays, Test, Optimization, OptimizationOptimJL,
2+
OptimizationMOI, Ipopt, AmplNLWriter, Ipopt_jll
23

34
@variables x y
45
@parameters a b
@@ -49,14 +50,32 @@ sol = solve(prob, BFGS(initial_stepnorm = 0.0001), allow_f_increases = true)
4950
sol = solve(prob2, BFGS(initial_stepnorm = 0.0001), allow_f_increases = true)
5051
@test sol.minimum < -1e9
5152

52-
prob = OptimizationProblem(sys2, [x => 0.0, y => 0.0], [a => 1.0, b => 100.0], lcons = [-1.0, -1.0], ucons = [500.0, 500.0], grad = true, hess = true)
53+
#inequality constraint
54+
prob = OptimizationProblem(sys2, [x => 0.0, y => 0.0], [a => 1.0, b => 100.0],
55+
lcons = [-1.0, -1.0], ucons = [500.0, 500.0], grad = true,
56+
hess = true)
5357
sol = solve(prob, IPNewton(), allow_f_increases = true)
5458
@test sol.minimum < 1.0
5559
sol = solve(prob, Ipopt.Optimizer())
5660
@test sol.minimum < 1.0
5761
sol = solve(prob, AmplNLWriter.Optimizer(Ipopt_jll.amplexe))
5862
@test sol.minimum < 1.0
5963

64+
#equality constraint
65+
cons2 = [0.0 ~ x^2 + y^2]
66+
sys2 = OptimizationSystem(loss, [x, y], [a, b], name = :sys2, constraints = cons2)
67+
prob = OptimizationProblem(sys2, [x => 0.0, y => 0.0], [a => 1.0, b => 1.0], lcons = [1.0],
68+
ucons = [1.0], grad = true, hess = true)
69+
sol = solve(prob, IPNewton())
70+
@test sol.minimum < 1.0
71+
@test prob.f.cons(sol.minimizer, [1.0, 1.0]) [1.0]
72+
sol = solve(prob, Ipopt.Optimizer())
73+
@test sol.minimum < 1.0
74+
@test prob.f.cons(sol.minimizer, [1.0, 1.0]) [1.0]
75+
sol = solve(prob, AmplNLWriter.Optimizer(Ipopt_jll.amplexe))
76+
@test sol.minimum < 1.0
77+
@test prob.f.cons(sol.minimizer, [1.0, 1.0]) [1.0]
78+
6079
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
6180
x0 = zeros(2)
6281
_p = [1.0, 100.0]

0 commit comments

Comments
 (0)