Search code examples
julia-jump

Using a simple linear function or expresion within nonlinear constraint in Julia/JuMP


I have the following function in JuMP/Julia:

T=1:6

function Vini(t)
if t==1
    return V0
else
    return V[t-1]
end
end

where:

@variable(model, 6000 <= V[T] <= 18000)

and V0 is a scalar.

When using the above function within a linear constraint, the model works well. However, when using the same function within a nonlinear constraint, it doesn't.

@constraint(model, c2[t in 1:6], V[t] == Vini(t) + n*(INF-Q[t]))

The above constraint works well. When using:

@NLconstraint(model, c5_2[t=1:6], PH[t] == 20000*(Q[t]-260*W[t])/(220000-(V[t]+Vini(t))))

It doesn't work. PH, Q and W are also variables and INF is a scalar. I want to kind of reproduce the simple approach in AMPL, which is:

subject to c5_2{t in T}: PH[t] = 20000*(Q[t]-260*W[t])/(220000-(V[t]+(if t=1 then V0 else V[t-1])) 

Any idea would be much appreciated.

Below is what I get:

LoadError: Unsupported operation Vini in expression starting at C:\Users\clopezsalgado\Documents\JULIA Models\Jump Models\second_optexample.jl:57 error(s::String) at error.jl:33 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:434 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, args::Vector{Any}) at NLExpr.jl:446 _process_expr!(expr::MathOptInterface.FileFormats.NL._NLExpr, arg::Expr) at NLExpr.jl:397 MathOptInterface.FileFormats.NL._NLExpr(expr::Expr) at NLExpr.jl:365 MathOptInterface.FileFormats.NL._NLConstraint(expr::Expr, bound::MathOptInterface.NLPBoundsPair) at NL.jl:75 copy_to(dest::MathOptInterface.FileFormats.NL.Model, model::MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}) at NL.jl:280 copy_to at AmplNLWriter.jl:248 [inlined] optimize! at MathOptInterface.jl:86 [inlined] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{AmplNLWriter.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}) at cachingoptimizer.jl:316


Solution

  • This is a limitation of user-defined functions in nonlinear constraints.

    Do instead:

    Vini_array = [Vini(t) for t in 1:6]
    @NLconstraint(model, c5_2[t=1:6], PH[t] == 20000*(Q[t]-260*W[t])/(220000-(V[t]+Vini_array[t])))
    

    Now instead of a function call, it's a (supported) index into a vector.