# Lagrange multipliers (duals) in JuMP 0.19

**URL:** <https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328>\
**Category:** Optimization (Mathematical)\
**Tags:** question\
**Created:** [September 3, 2019, 2:53pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328 "2019-09-03T14:53:21Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![ko56](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ko56/32/2684_2.png) [@ko56](https://discourse.julialang.org/u/ko56)\
**Post date:** [September 3, 2019, 2:53pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/1 "2019-09-03T14:53:21Z")

</div>

I have Julia 1.1.1 and JuMP 0.19. I am solving a concave maximization problem with linear constraints with Ipopt. I am confused with what is happening to the signs of the Lagrange multipliers:

The correct multipliers are

[0.20964, -0.0655815]  
[2.39447, 2.21215, 2.64144, 2.58729, -1.37699e-6]

where the first vector is corresponds to equality constraints, the second to inequalities (all inequalities are in the form \<= ).

If I use dual(), I get these vectors:

[-0.209641, 0.0655802]  
[-2.39447, -2.21215, -2.64144, -2.58729, 4.53964e-9]

And if I use shadow\_price() I get

[0.209641, 0.0655802]  
[2.39447, 2.21215, 2.64144, 2.58729, -4.53964e-9]

I’ve read the documentation a few times, but I find it less than clear, and I still don’t understand what’s happening.  
My provisional conclusion is that I should be using the negatives of the duals.  
Is this because I’m maximizing? And what about the shadow\_prices?

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [September 3, 2019, 3:06pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/2 "2019-09-03T15:06:28Z")

</div>

> The correct multipliers are

Correct according to which definition ? We use the following definition: [Manual · MathOptInterface](http://www.juliaopt.org/MathOptInterface.jl/v0.9.1/apimanual/#Duals-1)  
The dual does not depend on the objective sense (you can imagine it to be minimization) which is very useful when writing solver wrappers as you can swap the objective without having to worry about changing the dual.  
You can see in the manual that the dual of a `<=` constraint (22) is a nonpositive variable (27) so what Ipopt returns makes sense.

---

<div class="post-metadata">

**Author:** ![ko56](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ko56/32/2684_2.png) [@ko56](https://discourse.julialang.org/u/ko56)\
**Post date:** [September 3, 2019, 3:18pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/3 "2019-09-03T15:18:59Z")

</div>

My definition of “correct” is the textbook definition of the multipliers as sensitivity parameters. So with maximizing an objective and inequalities of the form \<=, the corresponding multipliers should be \>= 0.  
I understand that JuMP doesn’t use the textbook definition, and I’m ok with that, as long as I understand what the proper “conversion” is. That’s why I asked if the negative of the dual is the right thing.

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [September 3, 2019, 3:45pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/4 "2019-09-03T15:45:46Z")

</div>

> My definition of “correct” is the textbook definition of the multipliers as sensitivity parameters

Then the `shadow_price` should be what you are looking for, the difference in sign for the second equality constraint might be due to the following in JuMP doc: [Constraints · JuMP](http://www.juliaopt.org/JuMP.jl/v0.20.0/constraints/#JuMP.shadow_price)

> - Relaxation of equality constraints (and hence the shadow price) is defined based on which sense of the equality constraint is active.

---

<div class="post-metadata">

**Author:** ![ko56](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ko56/32/2684_2.png) [@ko56](https://discourse.julialang.org/u/ko56)\
**Post date:** [September 3, 2019, 4:07pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/5 "2019-09-03T16:07:17Z")

</div>

Yes, thanks, I had noticed that remark in the documentation.  
But how do I find out which direction of the equality constraint is active?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 3, 2019, 4:50pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/6 "2019-09-03T16:50:48Z")

</div>

See:

```nohighlight
julia> using JuMP, Gurobi

julia> model = Model(with_optimizer(Gurobi.Optimizer, OutputFlag=0));
Academic license - for non-commercial use only

julia> @variable(model, x)
x

julia> @constraint(model, con, x == 2)
 con : x = 2.0

julia> @objective(model, Min, x)
x

julia> optimize!(model)
Academic license - for non-commercial use only

julia> shadow_price(con)
-1.0

julia> @objective(model, Max, x)
x

julia> optimize!(model)

julia> shadow_price(con)
1.0

```

---

<div class="post-metadata">

**Author:** ![ko56](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ko56/32/2684_2.png) [@ko56](https://discourse.julialang.org/u/ko56)\
**Post date:** [September 3, 2019, 5:43pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/7 "2019-09-03T17:43:17Z")

</div>

For a fixed problem, the correct multiplier for an equality constraint (according to the defn. I gave) can have either sign.  
So it can’t be determined just by whether you’re minimizing or maximizing, which I think is what you are proposing.

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [September 4, 2019, 11:48am UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/8 "2019-09-04T11:48:51Z")

</div>

What you need seems to be either `dual` if you are minimizing or `-dual` if you are maximizing. This is what `shadow_price` does except that `shadow_price` also does a correction for equality you don’t need so just use `dual` and multiply it by `-1` if you are maximizing.

---

<div class="post-metadata">

**Author:** ![ko56](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ko56/32/2684_2.png) [@ko56](https://discourse.julialang.org/u/ko56)\
**Post date:** [September 4, 2019, 12:56pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/9 "2019-09-04T12:56:43Z")

</div>

Yes, I’ve concluded the same thing. It would be very helpful if the documentation were better as far as this point is concerned …

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 4, 2019, 1:21pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/10 "2019-09-04T13:21:41Z")

</div>

> It would be very helpful if the documentation were better as far as this point is concerned …

You can help edit the documentation!

1. Go to [https://github.com/JuliaOpt/JuMP.jl/blob/master/docs/src/constraints.md](https://github.com/JuliaOpt/JuMP.jl/blob/master/docs/src/constraints.md)
2. Click the pencil “Edit this file”
3. Make changes
4. Scroll to the bottom and follow the steps to “Propose file change”

---

<div class="post-metadata">

**Author:** ![g001234](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/g001234/32/2956_2.png) [@g001234](https://discourse.julialang.org/u/g001234)\
**Post date:** [September 5, 2019, 1:41am UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/11 "2019-09-05T01:41:01Z")

</div>

I was also confused about this some time ago. I remember the documentation mentioned JuMP is using conic dual, which may be different from the textbook dual. Is the sign difference a result of that?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 5, 2019, 1:15pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/12 "2019-09-05T13:15:21Z")

</div>

> Is the sign difference a result of that?

Yes, exactly.

---

<div class="post-metadata">

**Author:** ![ko56](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ko56/32/2684_2.png) [@ko56](https://discourse.julialang.org/u/ko56)\
**Post date:** [September 5, 2019, 11:18pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/13 "2019-09-05T23:18:43Z")

</div>

Thanks, I just did that. Do I now need to create a pull request, or am I done?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 5, 2019, 11:35pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/14 "2019-09-05T23:35:55Z")

</div>

Oops. I missed a step. Continue and make a pull request.

---

<div class="post-metadata">

**Author:** ![ko56](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ko56/32/2684_2.png) [@ko56](https://discourse.julialang.org/u/ko56)\
**Post date:** [September 9, 2019, 5:42pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/15 "2019-09-09T17:42:14Z")

</div>

Ok, I did that. There was one comment on the request last Thursday, to which I replied. Nothing since then. What happens next?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 9, 2019, 6:06pm UTC](https://discourse.julialang.org/t/lagrange-multipliers-duals-in-jump-0-19/28328/16 "2019-09-09T18:06:59Z")

</div>

Thanks for your input. I’ve replied to the PR. I believe Miles is on vacation.
