# Costates and Hamiltonian in JuMP and MathProgbase

**URL:** <https://discourse.julialang.org/t/costates-and-hamiltonian-in-jump-and-mathprogbase/6160>\
**Category:** Optimization (Mathematical)\
**Created:** [September 29, 2017, 11:09pm UTC](https://discourse.julialang.org/t/costates-and-hamiltonian-in-jump-and-mathprogbase/6160 "2017-09-29T23:09:44Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [September 30, 2017, 5:36am UTC](https://discourse.julialang.org/t/costates-and-hamiltonian-in-jump-and-mathprogbase/6160/2 "2017-09-30T05:36:06Z")

</div>

Well, there’s this comment in [a post about upcoming changes in JuMP](https://discourse.julialang.org/t/mathoptinterface-and-upcoming-breaking-changes-in-jump-0-19/4874):

> - Duality. MOI aims to define consistent conventions for duals across problem classes. In some cases, the signs may differ from the current MPB conventions.

Another possibility (just guessing), but maybe the sign change could be due to an internal rewrite of the constraints in a canonical form. If you have, say, `@constraint(m, x == 1)` in your code, it could be that while setting up the internal model, the constraint is rewritten as `1 - x == 0`, with the Lagrange multiplier (dual variable) acting on `1 - x`, while you were maybe expecting the Lagrange multiplier to act on `x - 1`.

JuMP defines `getdual` methods for `ConstraintRef`s as well by the way; I don’t think you should have to access the internal model:

```julia
julia> methods(getdual)
# 7 methods for generic function "getdual":
getdual(c::JuMP.ConstraintRef{JuMP.Model,JuMP.GenericRangeConstraint{JuMP.NonlinearExprData}}) in JuMP at /Users/twan/code/julia/RigidBodyDynamics/v0.6/JuMP/src/nlp.jl:56
getdual(c::JuMP.ConstraintRef{JuMP.Model,JuMP.SDConstraint}) in JuMP at /Users/twan/code/julia/RigidBodyDynamics/v0.6/JuMP/src/JuMP.jl:715
getdual(c::JuMP.ConstraintRef{JuMP.Model,JuMP.GenericSOCConstraint{JuMP.GenericNormExpr{2,Float64,JuMP.Variable}}}) in JuMP at /Users/twan/code/julia/RigidBodyDynamics/v0.6/JuMP/src/JuMP.jl:676
getdual(c::JuMP.ConstraintRef{JuMP.Model,JuMP.GenericRangeConstraint{JuMP.GenericAffExpr{Float64,JuMP.Variable}}}) in JuMP at /Users/twan/code/julia/RigidBodyDynamics/v0.6/JuMP/src/JuMP.jl:586
getdual(v::JuMP.Variable) in JuMP at /Users/twan/code/julia/RigidBodyDynamics/v0.6/JuMP/src/JuMP.jl:466
getdual(x::AbstractArray) in JuMP at /Users/twan/code/julia/RigidBodyDynamics/v0.6/JuMP/src/JuMPContainer.jl:109
getdual(x::JuMP.JuMPContainer) in JuMP at /Users/twan/code/julia/RigidBodyDynamics/v0.6/JuMP/src/JuMPContainer.jl:114

```

So you can do e.g.:

```julia
julia> m = Model(solver = GurobiSolver(OutputFlag = 0));

julia> @variable(m, x);

julia> @constraint(m, c, x == 1)
x = 1

julia> @objective(m, :Min, x)
x

julia> solve(m)
:Optimal

julia> getdual(c)
1.0

```

---

_[View the full topic](https://discourse.julialang.org/t/costates-and-hamiltonian-in-jump-and-mathprogbase/6160)._
