Jump.jl: Problem with Empty Summations

Created on 6 May 2019  Â·  7Comments  Â·  Source: jump-dev/JuMP.jl

In the following example the constraint x == sum(1.0 for i in 1:0) raises a loading error, Variable MathOptInterface.VariableIndex(1) is fixed. Cannot also set lower bound.. An equivalent form of the constraint x == 0.0 works fine.

using JuMP
using Ipopt

m = Model()

@variable(m, 0.0 <= x <= 1.0)

# works fine
# @constraint(m, x == 0.0)

# breaks
@constraint(m, x == sum(1.0 for i in 1:0))

println(m)

optimize!(m, with_optimizer(Ipopt.Optimizer))
bug

Most helpful comment

I agree we should generally try to be consistent with Julia. However, replacing an error with what's obviously intended isn't that much of a stretch. Users don't need to know about the internals of the macros. Sums over empty sets are universally defined to be zero (https://en.wikipedia.org/wiki/Empty_sum).

The motivation for Julia to throw an error is because Julia is bound to be type generic. In JuMP there's no harm in saying that an empty sum is Int(0) or 0.0 because we already have conversions to Float64 in numerous places.

All 7 comments

To clarify,

@constraint(m, x == sum(1.0 for i in 1:0))

adds a constraint x == 0 of type SingleVariable-in-EqualTo (leading to the variable bounds already exist error), but the expected behavior is to throw the following error (from the empty sum):

ERROR: ArgumentError: reducing over an empty collection is not allowed

@odow the above is a valid JuMP v0.18 program. JuMP v0.18, supports empty collections, and I think the JuMP AML should as well. It is standard in AMPL and others. The alternative is to have conditional statements when defining constraints to determine if the collections are non-empty.

I don't immediately see any negative side effects of JuMP interpreting a sum over an empty collection to be 0, especially if this worked on 0.18 already.

My immediate concern was

julia> sum(1.0 for i in 1:0)
ERROR: ArgumentError: reducing over an empty collection is not allowed
Stacktrace:
 [1] _empty_reduce_error() at ./reduce.jl:216
 [2] mapreduce_empty_iter(::Function, ::Function, ::Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##3#4"))}, ::Base.EltypeUnknown) at ./reduce.jl:261
 [3] mapfoldl_impl at ./reduce.jl:57 [inlined]
 [4] #mapfoldl#187 at ./reduce.jl:72 [inlined]
 [5] mapfoldl at ./reduce.jl:72 [inlined]
 [6] #mapreduce#191 at ./reduce.jl:205 [inlined]
 [7] mapreduce at ./reduce.jl:205 [inlined]
 [8] sum at ./reduce.jl:399 [inlined]
 [9] sum(::Base.Generator{UnitRange{Int64},getfield(Main, Symbol("##3#4"))}) at ./reduce.jl:416
 [10] top-level scope at none:0

and that it isn't obvious to users that JuMP re-writes the sum to be

y = 0
for i in 1:0
    y += 1
end
y

I agree we should generally try to be consistent with Julia. However, replacing an error with what's obviously intended isn't that much of a stretch. Users don't need to know about the internals of the macros. Sums over empty sets are universally defined to be zero (https://en.wikipedia.org/wiki/Empty_sum).

The motivation for Julia to throw an error is because Julia is bound to be type generic. In JuMP there's no harm in saying that an empty sum is Int(0) or 0.0 because we already have conversions to Float64 in numerous places.

I have some time today so I'll look into this.

Thanks!!!

On Tue, May 7, 2019 at 9:24 AM Oscar Dowson notifications@github.com
wrote:

I have some time today so I'll look into this.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/JuliaOpt/JuMP.jl/issues/1954#issuecomment-490127198,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIN5KUKWGEUNWBP7F4QPE3PUGNKNANCNFSM4HLCY2KA
.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

loylobo picture loylobo  Â·  5Comments

mlubin picture mlubin  Â·  5Comments

jrevels picture jrevels  Â·  4Comments

igormcoelho picture igormcoelho  Â·  3Comments

IssamT picture IssamT  Â·  4Comments