From 8f10e3be5c3232272f0d3795dac9f6284649bba0 Mon Sep 17 00:00:00 2001 From: Dimitri Alston <123396563+DimitriAlston@users.noreply.github.com> Date: Thu, 7 Nov 2024 09:11:56 -0500 Subject: [PATCH 1/2] Add support for `MOI.UserDefinedFunction` --- src/eago_optimizer/moi_wrapper.jl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/eago_optimizer/moi_wrapper.jl b/src/eago_optimizer/moi_wrapper.jl index 6727a4e0..a1c0dafe 100644 --- a/src/eago_optimizer/moi_wrapper.jl +++ b/src/eago_optimizer/moi_wrapper.jl @@ -314,4 +314,21 @@ function MOI.get(m::Optimizer, ::Type{VI}, name::String) else return index_storage end -end \ No newline at end of file +end + +##### +##### Support and set user-defined functions +##### +MOI.supports(m::Optimizer, ::MOI.UserDefinedFunction) = true + +function MOI.set(m::Optimizer, udf::MOI.UserDefinedFunction, f) + if isnothing(m._input_problem._nlp_data) + model = MOI.Nonlinear.Model() + backend = MOI.Nonlinear.SparseReverseMode() + vars = MOI.get(m, MOI.ListOfVariableIndices()) + evaluator = MOI.Nonlinear.Evaluator(model, backend, vars) + m._input_problem._nlp_data = MOI.NLPBlockData(evaluator) + end + MOI.Nonlinear.register_operator(m._input_problem._nlp_data.evaluator.model, udf.name, udf.arity, f...) + return nothing +end From 8c92cab748fb9ff558abc1255c45435f7bd6c49b Mon Sep 17 00:00:00 2001 From: Dimitri Alston <123396563+DimitriAlston@users.noreply.github.com> Date: Thu, 7 Nov 2024 10:18:12 -0500 Subject: [PATCH 2/2] Update stack_management.jl --- .../optimize/nonconvex/stack_management.jl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/eago_optimizer/optimize/nonconvex/stack_management.jl b/src/eago_optimizer/optimize/nonconvex/stack_management.jl index a321404c..fbe1aa8e 100644 --- a/src/eago_optimizer/optimize/nonconvex/stack_management.jl +++ b/src/eago_optimizer/optimize/nonconvex/stack_management.jl @@ -236,27 +236,26 @@ $(TYPEDSIGNATURES) Check the optimization problem for unbounded branching variables, which would interfere with EAGO's branch-and-bound routine since there are no well-defined branching rules for cases where the interval bounds contain `-Inf` or `Inf`. If any branching variables -are missing bounds, add the missing bound at +/- 1E10 and warn the user. +are missing bounds, add the missing bound at +/- 1E6 and warn the user. """ function unbounded_check!(m::GlobalOptimizer) if m._parameters.unbounded_check unbounded_flag = false wp = m._working_problem - epigraph_flag = _variable_num(FullVar(), m) != m._input_problem._variable_count - for i = 1:_variable_num(BranchVar(), m) - epigraph_flag #Not including epigraph reformulation variable + for i = 1:_variable_num(BranchVar(), m) if !wp._variable_info[i].has_lower_bound unbounded_flag = true - wp._variable_info[i] = VariableInfo(wp._variable_info[i], GT(-1E10)) + wp._variable_info[i] = VariableInfo(wp._variable_info[i], GT(-1E6)) # Some solvers break if bounds are too large end if !wp._variable_info[i].has_upper_bound unbounded_flag = true - wp._variable_info[i] = VariableInfo(wp._variable_info[i], LT(1E10)) + wp._variable_info[i] = VariableInfo(wp._variable_info[i], LT(1E6)) # Some solvers break if bounds are too large end end unbounded_flag && @warn(""" At least one branching variable is unbounded. This will interfere with EAGO's global optimization routine and may cause unexpected results. Bounds have been automatically - generated at +/- 1E10 for all unbounded variables, but tighter user-defined bounds are + generated at +/- 1E6 for all unbounded variables, but tighter user-defined bounds are highly recommended. To disable this warning and the automatic generation of bounds, use the option `unbounded_check = false`.""") end