diff --git a/ext/OptimizationMTKExt.jl b/ext/OptimizationMTKExt.jl index 8c1472e81..9c47ed426 100644 --- a/ext/OptimizationMTKExt.jl +++ b/ext/OptimizationMTKExt.jl @@ -48,6 +48,7 @@ function Optimization.instantiate_function(f, x, adtype::AutoModelingToolkit, p, cons_hess_prototype = f.cons_hess_prototype, expr = Optimization.symbolify(f.expr), cons_expr = Optimization.symbolify.(f.cons_expr), + sys = sys, observed = f.observed) end @@ -93,6 +94,7 @@ function Optimization.instantiate_function(f, cache::Optimization.ReInitCache, cons_hess_prototype = f.cons_hess_prototype, expr = Optimization.symbolify(f.expr), cons_expr = Optimization.symbolify.(f.cons_expr), + sys = sys, observed = f.observed) end diff --git a/lib/OptimizationMOI/src/OptimizationMOI.jl b/lib/OptimizationMOI/src/OptimizationMOI.jl index cefcf33e7..6a30b7860 100644 --- a/lib/OptimizationMOI/src/OptimizationMOI.jl +++ b/lib/OptimizationMOI/src/OptimizationMOI.jl @@ -273,9 +273,17 @@ function SciMLBase.__init(prob::OptimizationProblem, maxtime::Union{Number, Nothing} = nothing, abstol::Union{Number, Nothing} = nothing, reltol::Union{Number, Nothing} = nothing, + mtkize = false, kwargs...) cache = if MOI.supports(_create_new_optimizer(opt), MOI.NLPBlock()) - MOIOptimizationNLPCache(prob, opt; maxiters, maxtime, abstol, reltol, kwargs...) + MOIOptimizationNLPCache(prob, + opt; + maxiters, + maxtime, + abstol, + reltol, + mtkize, + kwargs...) else MOIOptimizationCache(prob, opt; maxiters, maxtime, abstol, reltol, kwargs...) end diff --git a/lib/OptimizationMOI/src/nlp.jl b/lib/OptimizationMOI/src/nlp.jl index 9ef2995b2..0984ce430 100644 --- a/lib/OptimizationMOI/src/nlp.jl +++ b/lib/OptimizationMOI/src/nlp.jl @@ -107,6 +107,7 @@ end function MOIOptimizationNLPCache(prob::OptimizationProblem, opt; + mtkize = false, callback = nothing, kwargs...) reinit_cache = Optimization.ReInitCache(prob.u0, prob.p) # everything that can be changed via `reinit` @@ -139,8 +140,13 @@ function MOIOptimizationNLPCache(prob::OptimizationProblem, lcons = prob.lcons === nothing ? fill(T(-Inf), num_cons) : prob.lcons ucons = prob.ucons === nothing ? fill(T(Inf), num_cons) : prob.ucons - if f.sys isa SymbolicIndexingInterface.SymbolCache{Nothing, Nothing, Nothing} - sys = MTK.modelingtoolkitize(prob) + if f.sys isa SymbolicIndexingInterface.SymbolCache{Nothing, Nothing, Nothing} && mtkize + try + sys = MTK.modelingtoolkitize(prob) + catch err + throw(ArgumentError("Automatic symbolic expression generation with ModelingToolkit failed with error: $err. + Try by setting `mtkize = false` instead if the solver doesn't require symbolic expressions.")) + end if !isnothing(prob.p) && !(prob.p isa SciMLBase.NullParameters) unames = variable_symbols(sys) pnames = parameter_symbols(sys) @@ -156,22 +162,32 @@ function MOIOptimizationNLPCache(prob::OptimizationProblem, obj_expr = sysprob.f.expr cons_expr = sysprob.f.cons_expr else - sys = f.sys + sys = f.sys isa SymbolicIndexingInterface.SymbolCache{Nothing, Nothing, Nothing} ? + nothing : f.sys obj_expr = f.expr cons_expr = f.cons_expr end - expr_map = get_expr_map(sys) - expr = convert_to_expr(obj_expr, expr_map; expand_expr = false) - expr = repl_getindex!(expr) - cons = MTK.constraints(sys) - _cons_expr = Vector{Expr}(undef, length(cons)) - for i in eachindex(cons) - _cons_expr[i] = repl_getindex!(convert_to_expr(cons_expr[i], - expr_map; - expand_expr = false)) + if sys === nothing + expr = obj_expr + _cons_expr = cons_expr + else + expr_map = get_expr_map(sys) + expr = convert_to_expr(obj_expr, expr_map; expand_expr = false) + expr = repl_getindex!(expr) + cons = MTK.constraints(sys) + @show cons + _cons_expr = Vector{Expr}(undef, length(cons)) + for i in eachindex(cons) + _cons_expr[i] = repl_getindex!(convert_to_expr(cons_expr[i], + expr_map; + expand_expr = false)) + end end + @show expr + @show _cons_expr + evaluator = MOIOptimizationNLPEvaluator(f, reinit_cache, prob.lb, @@ -387,11 +403,24 @@ end function MOI.constraint_expr(evaluator::MOIOptimizationNLPEvaluator, i) # expr has the form f(x,p) == 0 or f(x,p) <= 0 cons_expr = deepcopy(evaluator.cons_expr[i].args[2]) - compop = Symbol(evaluator.cons_expr[i].args[1]) repl_getindex!(cons_expr) _replace_parameter_indices!(cons_expr, evaluator.p) _replace_variable_indices!(cons_expr) - return Expr(:call, compop, cons_expr, 0.0) + lb, ub = Float64(evaluator.lcons[i]), Float64(evaluator.ucons[i]) + @show lb + @show ub + @show cons_expr + if lb == ub + return Expr(:call, :(==), cons_expr, lb) + else + if lb == -Inf + return Expr(:call, :(<=), cons_expr, ub) + elseif ub == Inf + return Expr(:call, :(>=), cons_expr, lb) + else + return Expr(:call, :between, cons_expr, lb, ub) + end + end end function _add_moi_variables!(opt_setup, evaluator::MOIOptimizationNLPEvaluator)