From 83666cb341057ff455dd762429cf94756bc1ef20 Mon Sep 17 00:00:00 2001 From: "Klamkin, Michael" Date: Wed, 7 Jan 2026 18:41:12 -0500 Subject: [PATCH 1/4] fix NLP bounds --- src/NonLinearProgram/NonLinearProgram.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NonLinearProgram/NonLinearProgram.jl b/src/NonLinearProgram/NonLinearProgram.jl index f7a04b1e..c31eb2e7 100644 --- a/src/NonLinearProgram/NonLinearProgram.jl +++ b/src/NonLinearProgram/NonLinearProgram.jl @@ -574,13 +574,13 @@ function DiffOpt.reverse_differentiate!(model::Model; tol = 1e-6) end end for (i, var_idx) in enumerate(cache.primal_vars[cache.has_low]) - idx = form.constraint_lower_bounds[var_idx.value].value + idx = form.constraint_lower_bounds[var_idx.value] if haskey(model.input_cache.dy, idx) Δdual[num_constraints+i] = model.input_cache.dy[idx] end end for (i, var_idx) in enumerate(cache.primal_vars[cache.has_up]) - idx = form.constraint_upper_bounds[var_idx.value].value + idx = form.constraint_upper_bounds[var_idx.value] if haskey(model.input_cache.dy, idx) Δdual[num_constraints+num_low+i] = model.input_cache.dy[idx] end From 603f76a1b7846dde8779a8ab717acc8df8261b2a Mon Sep 17 00:00:00 2001 From: "Klamkin, Michael" Date: Thu, 8 Jan 2026 06:09:35 -0500 Subject: [PATCH 2/4] add test --- test/nlp_program.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/nlp_program.jl b/test/nlp_program.jl index c9dbbc73..8e00a333 100644 --- a/test/nlp_program.jl +++ b/test/nlp_program.jl @@ -977,6 +977,22 @@ function test_changing_factorization() ) end +function test_reverse_bounds() + model = DiffOpt.nonlinear_diff_model(Ipopt.Optimizer) + set_silent(model) + @variable(model, x[1:3] >= 0) # x[3] ≥ 0 is active + @variable(model, p in MOI.Parameter(4.5)) + @constraint(model, 6x[1] + 3x[2] + 2x[3] == p) + @constraint(model, x[1] + x[2] - x[3] == 1) + @objective(model, Min, sum(x.^2)) + optimize!(model) + MOI.set(model, DiffOpt.ReverseConstraintDual(), LowerBoundRef(x[3]), 1.0) + DiffOpt.reverse_differentiate!(model) + dp = MOI.get(model, DiffOpt.ReverseConstraintSet(), ParameterRef(p)).value + @test abs(dp) > 0.0 # test contribution is not ignored + @test isapprox(dp, -2.88888; atol = 1e-4) +end + end # module TestNLPProgram.runtests() From 2935dc8d9e1683cd45e641c7b41369a017f138de Mon Sep 17 00:00:00 2001 From: Michael Klamkin Date: Thu, 8 Jan 2026 07:58:26 -0500 Subject: [PATCH 3/4] Remove redundant test --- test/nlp_program.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/nlp_program.jl b/test/nlp_program.jl index 8e00a333..b0b9a445 100644 --- a/test/nlp_program.jl +++ b/test/nlp_program.jl @@ -989,7 +989,6 @@ function test_reverse_bounds() MOI.set(model, DiffOpt.ReverseConstraintDual(), LowerBoundRef(x[3]), 1.0) DiffOpt.reverse_differentiate!(model) dp = MOI.get(model, DiffOpt.ReverseConstraintSet(), ParameterRef(p)).value - @test abs(dp) > 0.0 # test contribution is not ignored @test isapprox(dp, -2.88888; atol = 1e-4) end From 73186f4428cd4d95c33b5a64ad35f8724be2932a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 9 Jan 2026 11:16:29 +0100 Subject: [PATCH 4/4] Fix format --- test/nlp_program.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nlp_program.jl b/test/nlp_program.jl index b0b9a445..c08b925e 100644 --- a/test/nlp_program.jl +++ b/test/nlp_program.jl @@ -984,7 +984,7 @@ function test_reverse_bounds() @variable(model, p in MOI.Parameter(4.5)) @constraint(model, 6x[1] + 3x[2] + 2x[3] == p) @constraint(model, x[1] + x[2] - x[3] == 1) - @objective(model, Min, sum(x.^2)) + @objective(model, Min, sum(x .^ 2)) optimize!(model) MOI.set(model, DiffOpt.ReverseConstraintDual(), LowerBoundRef(x[3]), 1.0) DiffOpt.reverse_differentiate!(model)