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:

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?

Correct according to which definition ? We use the following definition: 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.

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.

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

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.

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.

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?