-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dual convention #40
Comments
Uno and IPOPT/ASL (AMPL Solver Library) have a different Lagrangian definition:
For the Hessian evaluation, Uno's call to the ASL function Can you post the nl file? I can't reproduce at the moment since ASL transforms the constraint into a bound. Uno finds the following primal-dual solution:
so there has to be something wrong in the way Uno calls ASL's |
|
Different dual conventions are the bane of my life. Each time I hook up a new solver, I always encounter issues. I generally solve it by randomly whacking a bunch of What do you do if the objective sense is Maximization? |
If I maximize, I flip the sign of the objective (and its derivatives).
So I think I should do another call to |
Here's the current
I think we're looking for
|
Got it. |
Did you try |
|
So the dual now matches AMPL for minimization. But not for maximization. We should also think about returning suffixes for the dual of the variable bounds. julia> using JuMP, AmplNLWriter, Uno_jll, Ipopt_jll, Test
julia> function main(args...)
@testset "main" begin
@testset "Model 1" begin
model = Model(
() -> AmplNLWriter.Optimizer(args...; directory = "/tmp"),
)
@variable(model, x)
@objective(model, Min, x)
c1 = @constraint(model, x >= 1)
optimize!(model)
@test dual(c1) ≈ 1.0 atol=1e-6
@info "Model 1"
@info " model.nl"
print(read("/tmp/model.nl", String))
@info " model.sol"
print(read("/tmp/model.sol", String))
end
@testset "Model 2" begin
model = Model(
() -> AmplNLWriter.Optimizer(args...; directory = "/tmp"),
)
@variable(model, x)
@objective(model, Max, x)
c1 = @constraint(model, x <= 1)
optimize!(model)
@test dual(c1) ≈ -1.0 atol=1e-6
@info "Model 2"
@info " model.nl"
print(read("/tmp/model.nl", String))
@info " model.sol"
print(read("/tmp/model.sol", String))
end
@testset "Model 3" begin
model = Model(
() -> AmplNLWriter.Optimizer(args...; directory = "/tmp"),
)
@variable(model, x >= 1)
@objective(model, Min, x)
optimize!(model)
@test dual(LowerBoundRef(x)) ≈ 1.0 atol=1e-6
@info "Model 3"
@info " model.nl"
print(read("/tmp/model.nl", String))
@info " model.sol"
print(read("/tmp/model.sol", String))
end
@testset "Model 4" begin
model = Model(
() -> AmplNLWriter.Optimizer(args...; directory = "/tmp"),
)
@variable(model, x <= 1)
@objective(model, Max, x)
optimize!(model)
@test dual(UpperBoundRef(x)) ≈ -1.0 atol=1e-6
@info "Model 4"
@info " model.nl"
print(read("/tmp/model.nl", String))
@info " model.sol"
print(read("/tmp/model.sol", String))
end
end
return
end
main (generic function with 1 method)
julia> main(Ipopt_jll.amplexe, ["print_level=0", "sb=yes"])
Ipopt 3.14.16: print_level=0
sb=yes
[ Info: Model 1
[ Info: model.nl
g3 1 1 0
1 1 1 0 0 0
0 1
0 0
0 0 0
0 0 0 1
0 0 0 0 0
1 1
0 0
0 0 0 0 0
C0
n0
O0 0
n0
x1
0 0
r
2 1
b
3
k0
J0 1
0 1
G0 1
0 1
[ Info: model.sol
Ipopt 3.14.16: Optimal Solution Found
Options
3
1
1
0
1
1
1
1
1
0.9999999925059035
objno 0 0
suffix 4 0 13 0 0
ipopt_zU_out
suffix 4 0 13 0 0
ipopt_zL_out
Ipopt 3.14.16: print_level=0
sb=yes
[ Info: Model 2
[ Info: model.nl
g3 1 1 0
1 1 1 0 0 0
0 1
0 0
0 0 0
0 0 0 1
0 0 0 0 0
1 1
0 0
0 0 0 0 0
C0
n0
O0 1
n0
x1
0 0
r
1 1
b
3
k0
J0 1
0 1
G0 1
0 1
[ Info: model.sol
Ipopt 3.14.16: Optimal Solution Found
Options
3
1
1
0
1
1
1
1
1
1.0000000074940965
objno 0 0
suffix 4 0 13 0 0
ipopt_zU_out
suffix 4 0 13 0 0
ipopt_zL_out
Ipopt 3.14.16: print_level=0
sb=yes
[ Info: Model 3
[ Info: model.nl
g3 1 1 0
1 0 1 0 0 0
0 1
0 0
0 0 0
0 0 0 1
0 0 0 0 0
0 1
0 0
0 0 0 0 0
O0 0
n0
x1
0 0
b
2 1
G0 1
0 1
[ Info: model.sol
Ipopt 3.14.16: Optimal Solution Found
Options
3
1
1
0
0
0
1
1
0.9999999925059035
objno 0 0
suffix 4 0 13 0 0
ipopt_zU_out
suffix 4 1 13 0 0
ipopt_zL_out
0 1.000000000000025
Ipopt 3.14.16: print_level=0
sb=yes
[ Info: Model 4
[ Info: model.nl
g3 1 1 0
1 0 1 0 0 0
0 1
0 0
0 0 0
0 0 0 1
0 0 0 0 0
0 1
0 0
0 0 0 0 0
O0 1
n0
x1
0 0
b
1 1
G0 1
0 1
[ Info: model.sol
Ipopt 3.14.16: Optimal Solution Found
Options
3
1
1
0
0
0
1
1
1.0000000074940965
objno 0 0
suffix 4 1 13 0 0
ipopt_zU_out
0 1.000000000000025
suffix 4 0 13 0 0
ipopt_zL_out
Test Summary: | Pass Total Time
main | 4 4 0.6s
julia> main(Uno_jll.amplexe, ["logger=SILENT"])
[ Info: Model 1
[ Info: model.nl
g3 1 1 0
1 1 1 0 0 0
0 1
0 0
0 0 0
0 0 0 1
0 0 0 0 0
1 1
0 0
0 0 0 0 0
C0
n0
O0 0
n0
x1
0 0
r
2 1
b
3
k0
J0 1
0 1
G0 1
0 1
[ Info: model.sol
Uno 1.1.0: Converged with feasible KKT point
Options
3
1
1
0
1
1
1
1
1
0.9999999925059035
objno 0 0
Model 2: Test Failed at REPL[61]:26
Expression: ≈(dual(c1), -1.0, atol = 1.0e-6)
Evaluated: 1.0 ≈ -1.0 (atol=1.0e-6)
Stacktrace:
[1] macro expansion
@ ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Test/src/Test.jl:672 [inlined]
[2] macro expansion
@ ./REPL[61]:26 [inlined]
[3] macro expansion
@ ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Test/src/Test.jl:1577 [inlined]
[4] macro expansion
@ ./REPL[61]:19 [inlined]
[5] macro expansion
@ ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Test/src/Test.jl:1577 [inlined]
[6] main(::Function, ::Vararg{Any})
@ Main ./REPL[61]:3
[7] top-level scope
@ REPL[63]:1
[8] eval
@ ./boot.jl:385 [inlined]
[9] eval_user_input(ast::Any, backend::REPL.REPLBackend, mod::Module)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:150
[10] repl_backend_loop(backend::REPL.REPLBackend, get_module::Function)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:246
[11] start_repl_backend(backend::REPL.REPLBackend, consumer::Any; get_module::Function)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:231
[12] run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool, backend::Any)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:389
[13] run_repl(repl::REPL.AbstractREPL, consumer::Any)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:375
[14] (::Base.var"#1013#1015"{Bool, Bool, Bool})(REPL::Module)
@ Base ./client.jl:432
[15] #invokelatest#2
@ ./essentials.jl:892 [inlined]
[16] invokelatest
@ ./essentials.jl:889 [inlined]
[17] run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool)
@ Base ./client.jl:416
[18] exec_options(opts::Base.JLOptions)
@ Base ./client.jl:333
[19] _start()
@ Base ./client.jl:552
[ Info: Model 2
[ Info: model.nl
g3 1 1 0
1 1 1 0 0 0
0 1
0 0
0 0 0
0 0 0 1
0 0 0 0 0
1 1
0 0
0 0 0 0 0
C0
n0
O0 1
n0
x1
0 0
r
1 1
b
3
k0
J0 1
0 1
G0 1
0 1
[ Info: model.sol
Uno 1.1.0: Converged with feasible KKT point
Options
3
1
1
0
1
1
1
1
-1
1.0000000074940965
objno 0 0
Model 3: Test Failed at REPL[61]:40
Expression: ≈(dual(LowerBoundRef(x)), 1.0, atol = 1.0e-6)
Evaluated: 0.0 ≈ 1.0 (atol=1.0e-6)
Stacktrace:
[1] macro expansion
@ ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Test/src/Test.jl:672 [inlined]
[2] macro expansion
@ ./REPL[61]:40 [inlined]
[3] macro expansion
@ ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Test/src/Test.jl:1577 [inlined]
[4] macro expansion
@ ./REPL[61]:34 [inlined]
[5] macro expansion
@ ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Test/src/Test.jl:1577 [inlined]
[6] main(::Function, ::Vararg{Any})
@ Main ./REPL[61]:3
[7] top-level scope
@ REPL[63]:1
[8] eval
@ ./boot.jl:385 [inlined]
[9] eval_user_input(ast::Any, backend::REPL.REPLBackend, mod::Module)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:150
[10] repl_backend_loop(backend::REPL.REPLBackend, get_module::Function)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:246
[11] start_repl_backend(backend::REPL.REPLBackend, consumer::Any; get_module::Function)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:231
[12] run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool, backend::Any)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:389
[13] run_repl(repl::REPL.AbstractREPL, consumer::Any)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:375
[14] (::Base.var"#1013#1015"{Bool, Bool, Bool})(REPL::Module)
@ Base ./client.jl:432
[15] #invokelatest#2
@ ./essentials.jl:892 [inlined]
[16] invokelatest
@ ./essentials.jl:889 [inlined]
[17] run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool)
@ Base ./client.jl:416
[18] exec_options(opts::Base.JLOptions)
@ Base ./client.jl:333
[19] _start()
@ Base ./client.jl:552
[ Info: Model 3
[ Info: model.nl
g3 1 1 0
1 0 1 0 0 0
0 1
0 0
0 0 0
0 0 0 1
0 0 0 0 0
0 1
0 0
0 0 0 0 0
O0 0
n0
x1
0 0
b
2 1
G0 1
0 1
[ Info: model.sol
Uno 1.1.0: Converged with feasible KKT point
Options
3
1
1
0
0
0
1
1
0.9999999925059035
objno 0 0
Model 4: Test Failed at REPL[61]:54
Expression: ≈(dual(UpperBoundRef(x)), -1.0, atol = 1.0e-6)
Evaluated: -0.0 ≈ -1.0 (atol=1.0e-6)
Stacktrace:
[1] macro expansion
@ ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Test/src/Test.jl:672 [inlined]
[2] macro expansion
@ ./REPL[61]:54 [inlined]
[3] macro expansion
@ ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Test/src/Test.jl:1577 [inlined]
[4] macro expansion
@ ./REPL[61]:48 [inlined]
[5] macro expansion
@ ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/Test/src/Test.jl:1577 [inlined]
[6] main(::Function, ::Vararg{Any})
@ Main ./REPL[61]:3
[7] top-level scope
@ REPL[63]:1
[8] eval
@ ./boot.jl:385 [inlined]
[9] eval_user_input(ast::Any, backend::REPL.REPLBackend, mod::Module)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:150
[10] repl_backend_loop(backend::REPL.REPLBackend, get_module::Function)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:246
[11] start_repl_backend(backend::REPL.REPLBackend, consumer::Any; get_module::Function)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:231
[12] run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool, backend::Any)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:389
[13] run_repl(repl::REPL.AbstractREPL, consumer::Any)
@ REPL ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/REPL/src/REPL.jl:375
[14] (::Base.var"#1013#1015"{Bool, Bool, Bool})(REPL::Module)
@ Base ./client.jl:432
[15] #invokelatest#2
@ ./essentials.jl:892 [inlined]
[16] invokelatest
@ ./essentials.jl:889 [inlined]
[17] run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool)
@ Base ./client.jl:416
[18] exec_options(opts::Base.JLOptions)
@ Base ./client.jl:333
[19] _start()
@ Base ./client.jl:552
[ Info: Model 4
[ Info: model.nl
g3 1 1 0
1 0 1 0 0 0
0 1
0 0
0 0 0
0 0 0 1
0 0 0 0 0
0 1
0 0
0 0 0 0 0
O0 1
n0
x1
0 0
b
1 1
G0 1
0 1
[ Info: model.sol
Uno 1.1.0: Converged with feasible KKT point
Options
3
1
1
0
0
0
1
1
1.0000000074940965
objno 0 0
Test Summary: | Pass Fail Total Time
main | 1 3 4 0.3s
Model 1 | 1 1 0.1s
Model 2 | 1 1 0.1s
Model 3 | 1 1 0.1s
Model 4 | 1 1 0.1s
ERROR: Some tests did not pass: 1 passed, 3 failed, 0 errored, 0 broken. |
The duals should now match IPOPT's for minimization and maximization (commit 117641e). |
Just confirming that I think we have this correct now: |
Great, thanks! |
What is Uno's dual convention? Currently, Uno returns the negative of the Ipopt dual:
See the
and
parts of the output.
Uno
Ipopt
The text was updated successfully, but these errors were encountered: