jump-dev / JuMP.jl

Modeling language for Mathematical Optimization (linear, mixed-integer, conic, semidefinite, nonlinear)
http://jump.dev/JuMP.jl/
Other
2.22k stars 393 forks source link

Constant in sum and prod #2097

Closed blegat closed 3 years ago

blegat commented 4 years ago
julia> using JuMP

julia> model = Model();

julia> @variable(model, x)
x

julia> @variable(model, y)
y

julia> a = [1, x, y]
3-element Array{GenericAffExpr{Float64,VariableRef},1}:
 1
 x
 y

julia> @NLexpression(model, prod(a[i] for i in 1:3))
ERROR: Unexpected affine expression 1 in nonlinear expression. Affine expressions (e.g., created using @expression) and nonlinear expressions cannot be mixed.
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] _parse_NL_expr_runtime(::Model, ::GenericAffExpr{Float64,VariableRef}, ::Array{JuMP._Derivatives.NodeData,1}, ::Int64, ::Array{Float64,1}) at /home/blegat/.julia/packages/JuMP/MsUSY/src/parse_nlp.jl:213
 [3] top-level scope at /home/blegat/.julia/packages/JuMP/MsUSY/src/parse_nlp.jl:243

julia> @NLexpression(model, sum(a[i] for i in 1:3))
ERROR: Unexpected affine expression 1 in nonlinear expression. Affine expressions (e.g., created using @expression) and nonlinear expressions cannot be mixed.
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] _parse_NL_expr_runtime(::Model, ::GenericAffExpr{Float64,VariableRef}, ::Array{JuMP._Derivatives.NodeData,1}, ::Int64, ::Array{Float64,1}) at /home/blegat/.julia/packages/JuMP/MsUSY/src/parse_nlp.jl:213
 [3] top-level scope at /home/blegat/.julia/packages/JuMP/MsUSY/src/parse_nlp.jl:243

cc @tweisser

odow commented 3 years ago

So the issue is that a = [1, x, y] promotes each element to an affine expression. a = Any[1, x, y] works fine.

One fix would be to check if the expression a contains any terms, or if the constant is zero and it contains a single term, and return the appropriate constant or variable index: https://github.com/jump-dev/JuMP.jl/blob/52b1b385b6a02bb08964b35403b6d7aee4252281/src/parse_nlp.jl#L216-L220