Hello dear Julia-community,
I am having an issue in using BARON for a nonlinear optimization problem. The problem includes nonlinearities in the constraints with a registered user-defined function. I define the function and its gradient.
Here is a snippet of how the constraints are defined, where mvnormcdf is from this library, inputs
contains the parameters of the model, T is an index set T = [i for i in 1:24]
and r, v
are defined model variables:
# Define the mvnormcdf and its gradient
function distribution(j, inputs)
norm_pdf(k) = exp(-(k^2) / 2) / sqrt(2 * pi)
f(x...) = mvnormcdf(inputs.Σ[j:j+3, j:j+3], inputs.a[j:j+3]- inputs.μ[j:j+3], vec([x[i] for i in eachindex(x)])- inputs.μ[j:j+3])[1]
function ∇f(g::AbstractVector{T}, x::T...) where {T}
μ_j = inputs.μ[j:j+3]
σ_j = inputs.σ[j:j+3]
Σ_j = inputs.Σ[j:j+3, j:j+3]
a_j = inputs.a[j:j+3]
for i in eachindex(x)
Σ_new = # new definition based on above defined variables
μ_new = # new definition based on above defined variables
g[i] = # new definition based on the previous two lines
end
return
end
return f, ∇f
end
# Register functions and define nonlinear constraints
for j in eachindex(T)
register(m, Symbol("mvncdf_$j"), 4, distribution(j, inputs)[1], distribution(j, inputs)[2])
x = []
for i in j:j+3
append!(x, [r[i] + v[i]])
end
# Use the mvncdf in the nonlinear constraints
add_nonlinear_constraint(m, :($(Symbol("mvncdf_$j"))($(x...)) >= $(inputs.p)))
end
BARON’s error output is the following:
ERROR: UnrecognizedExpressionException: unrecognized function call expression: mvncdf_1(x[190] + x[136], x[191] + x[137], x[192] + x[138], x[193] + x[139])
Stacktrace:
[1] to_str(c::Expr)
@ BARON ~/.julia/packages/BARON/xgWzt/src/util.jl:156
[2] (::BARON.var"#8#10")(d::Expr)
@ BARON ./none:0
[3] iterate(::Base.Generator{Vector{Any}, BARON.var"#8#10"})
@ Base ./generator.jl:47
[4] collect(itr::Base.Generator{Vector{Any}, BARON.var"#8#10"})
@ Base ./array.jl:787
[5] to_str(c::Expr)
@ BARON ~/.julia/packages/BARON/xgWzt/src/util.jl:130
[6] (::BARON.var"#11#20"{BARON.BaronModel})(fp::IOStream)
@ BARON ~/.julia/packages/BARON/xgWzt/src/util.jl:230
[7] open(::BARON.var"#11#20"{BARON.BaronModel}, ::String, ::Vararg{String}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ Base ./io.jl:384
[8] open
@ ./io.jl:381 [inlined]
[9] write_bar_file
@ ~/.julia/packages/BARON/xgWzt/src/util.jl:172 [inlined]
[10] optimize!(model::BARON.Optimizer)
@ BARON ~/.julia/packages/BARON/xgWzt/src/MOI_wrapper.jl:56
[11] optimize!
@ ~/.julia/packages/MathOptInterface/cl3eR/src/Bridges/bridge_optimizer.jl:376 [inlined]
[12] optimize!
@ ~/.julia/packages/MathOptInterface/cl3eR/src/MathOptInterface.jl:83 [inlined]
[13] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{BARON.Optimizer}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
@ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/cl3eR/src/Utilities/cachingoptimizer.jl:316
[14] optimize!(model::Model; ignore_optimize_hook::Bool, _differentiation_backend::MathOptInterface.Nonlinear.SparseReverseMode, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ JuMP ~/.julia/packages/JuMP/yYfHy/src/optimizer_interface.jl:480
[15] optimize!(model::Model)
@ JuMP ~/.julia/packages/JuMP/yYfHy/src/optimizer_interface.jl:450
[16] top-level scope
@ ~/project/Code/Main.jl:61
I am not sure why BARON iterates from 190 and 136 for mvncdf_1, the expression for j = 1 should be:
mvncdf_1(r[1] + v[1], r[2] + v[2], r[3] + v[3], r[4] + v[4])
Is it a problem with my definition or with how BARON interprets this user-defined function with a given first derivative?
IPOPT managed to solve the model with this exact definition of the nonlinear constraints without any issues and with fast convergence. It is when I modify my linear objective function (to include the variable r and v in a simple summation term) that IPOPT doesn’t converge. This is why I turned to BARON, but had the error described above.
I appreciate any thoughts and suggestions!