Skip to content

Commit 7d8926e

Browse files
Fix parameterized sparse constraint Jacobians in Ipopt
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
1 parent 1378450 commit 7d8926e

2 files changed

Lines changed: 41 additions & 3 deletions

File tree

lib/OptimizationIpopt/src/evaluator.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,13 @@ function eval_constraint_jacobian(evaluator::IpoptEvaluator, j, x)
119119
)
120120
end
121121
J = evaluator.J
122-
if _accepts_live_p(evaluator)
123-
evaluator.cache.f.cons_j(J, x, evaluator.cache.p)
122+
cons_j = evaluator.cache.f.cons_j
123+
p = evaluator.cache.p
124+
# Sparse instantiation can capture `p` in a two-argument `cons_j` wrapper.
125+
if _accepts_live_p(evaluator) && applicable(cons_j, J, x, p)
126+
cons_j(J, x, p)
124127
else
125-
evaluator.cache.f.cons_j(J, x)
128+
cons_j(J, x)
126129
end
127130
if J isa SparseMatrixCSC
128131
nnz = nonzeros(J)

lib/OptimizationIpopt/test/core_tests.jl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,41 @@ end
7171
end
7272
end
7373

74+
@testset "sparse explicit constraint Jacobian with parameters" begin
75+
objective(x, p) = (x[1] - p[1])^2 + x[2]^2
76+
77+
function gradient!(G, x, p)
78+
G[1] = 2 * (x[1] - p[1])
79+
G[2] = 2 * x[2]
80+
return
81+
end
82+
83+
function constraints!(res, x, p)
84+
res[1] = x[1] + x[2] - p[1]
85+
return
86+
end
87+
88+
function constraint_jacobian!(J, x, p)
89+
J[1, 1] = 1
90+
J[1, 2] = 1
91+
return
92+
end
93+
94+
f = OptimizationFunction(
95+
objective,
96+
AutoSparse(AutoForwardDiff());
97+
grad = gradient!,
98+
cons = constraints!,
99+
cons_j = constraint_jacobian!,
100+
cons_jac_prototype = sparse([1, 1], [1, 2], [1.0, 1.0], 1, 2)
101+
)
102+
prob = OptimizationProblem(f, [0.0, 0.0], [1.0]; lcons = [0.0], ucons = [0.0])
103+
sol = solve(prob, IpoptOptimizer(hessian_approximation = "limited-memory"))
104+
105+
@test SciMLBase.successful_retcode(sol)
106+
@test sol.u [1.0, 0.0] atol = 1.0e-6
107+
end
108+
74109
include("additional_tests.jl")
75110
include("advanced_features.jl")
76111
include("problem_types.jl")

0 commit comments

Comments
 (0)