1+ module OptimMOIExt
2+
3+ using Optim
4+ using LinearAlgebra
15import MathOptInterface as MOI
26
7+ function __init__ ()
8+ @static if VERSION >= v " 1.9"
9+ @eval Optim begin
10+ OptimMOIExt = Base. get_extension (@__MODULE__ , :OptimMOIExt )
11+ const Optimizer = OptimMOIExt. Optimizer
12+ end
13+ # setglobal!(Optim, :Optimizer, Optimizer)
14+ else
15+ @eval Optim begin
16+ using . OptimMOIExt
17+ const Optimizer = OptimMOIExt. Optimizer
18+ end
19+ end
20+ end
21+
322mutable struct Optimizer{T} <: MOI.AbstractOptimizer
423 # Problem data.
524 variables:: MOI.Utilities.VariablesContainer{T}
@@ -8,12 +27,12 @@ mutable struct Optimizer{T} <: MOI.AbstractOptimizer
827 sense:: MOI.OptimizationSense
928
1029 # Parameters.
11- method:: Union{AbstractOptimizer,Nothing}
30+ method:: Union{Optim. AbstractOptimizer,Nothing}
1231 silent:: Bool
1332 options:: Dict{Symbol,Any}
1433
1534 # Solution attributes.
16- results:: Union{Nothing,MultivariateOptimizationResults}
35+ results:: Union{Nothing,Optim. MultivariateOptimizationResults}
1736end
1837
1938function Optimizer {T} () where {T}
@@ -37,7 +56,7 @@ function MOI.supports(::Optimizer, ::Union{MOI.ObjectiveSense,MOI.ObjectiveFunct
3756end
3857MOI. supports (:: Optimizer , :: MOI.Silent ) = true
3958function MOI. supports (:: Optimizer , p:: MOI.RawOptimizerAttribute )
40- return p. name == " method" || hasfield (Options, Symbol (p. name))
59+ return p. name == " method" || hasfield (Optim . Options, Symbol (p. name))
4160end
4261
4362function MOI. supports (:: Optimizer , :: MOI.VariablePrimalStart , :: Type{MOI.VariableIndex} )
@@ -103,7 +122,7 @@ function MOI.get(model::Optimizer, ::MOI.TimeLimitSec)
103122 return get (model. options, Symbol (TIME_LIMIT), nothing )
104123end
105124
106- MOI. Utilities. map_indices (:: Function , opt:: AbstractOptimizer ) = opt
125+ MOI. Utilities. map_indices (:: Function , opt:: Optim. AbstractOptimizer ) = opt
107126
108127function MOI. set (model:: Optimizer , p:: MOI.RawOptimizerAttribute , value)
109128 if p. name == " method"
@@ -151,7 +170,11 @@ function MOI.is_valid(model::Optimizer, index::Union{MOI.VariableIndex,MOI.Const
151170 return MOI. is_valid (model. variables, index)
152171end
153172
154- function MOI. add_constraint (model:: Optimizer{T} , vi:: MOI.VariableIndex , set:: BOUNDS{T} ) where {T}
173+ function MOI. add_constraint (
174+ model:: Optimizer{T} ,
175+ vi:: MOI.VariableIndex ,
176+ set:: BOUNDS{T} ,
177+ ) where {T}
155178 return MOI. add_constraint (model. variables, vi, set)
156179end
157180
@@ -187,17 +210,17 @@ function MOI.set(
187210 return
188211end
189212
190- function requested_features (:: ZerothOrderOptimizer , has_constraints)
213+ function requested_features (:: Optim. ZerothOrderOptimizer , has_constraints)
191214 return Symbol[]
192215end
193- function requested_features (:: FirstOrderOptimizer , has_constraints)
216+ function requested_features (:: Optim. FirstOrderOptimizer , has_constraints)
194217 features = [:Grad ]
195218 if has_constraints
196219 push! (features, :Jac )
197220 end
198221 return features
199222end
200- function requested_features (:: Union{IPNewton,SecondOrderOptimizer} , has_constraints)
223+ function requested_features (:: Union{IPNewton,Optim. SecondOrderOptimizer} , has_constraints)
201224 features = [:Grad , :Hess ]
202225 if has_constraints
203226 push! (features, :Jac )
@@ -255,7 +278,12 @@ function MOI.optimize!(model::Optimizer{T}) where {T}
255278 method = model. method
256279 nl_constrained = ! isempty (nlp_data. constraint_bounds)
257280 features = MOI. features_available (evaluator)
258- has_bounds = any (vi -> isfinite (model. variables. lower[vi. value]) || isfinite (model. variables. upper[vi. value]), vars)
281+ has_bounds = any (
282+ vi ->
283+ isfinite (model. variables. lower[vi. value]) ||
284+ isfinite (model. variables. upper[vi. value]),
285+ vars,
286+ )
259287 if method === nothing
260288 if nl_constrained
261289 method = IPNewton ()
@@ -264,12 +292,12 @@ function MOI.optimize!(model::Optimizer{T}) where {T}
264292 # are variable bounds, `Newton` is not supported. On the other hand,
265293 # `fallback_method(f, g!)` returns `LBFGS` which is supported if `has_bounds`.
266294 if :Hess in features && ! has_bounds
267- method = fallback_method (f, g!, h!)
295+ method = Optim . fallback_method (f, g!, h!)
268296 else
269- method = fallback_method (f, g!)
297+ method = Optim . fallback_method (f, g!)
270298 end
271299 else
272- method = fallback_method (f)
300+ method = Optim . fallback_method (f)
273301 end
274302 end
275303 used_features = requested_features (method, nl_constrained)
@@ -283,22 +311,35 @@ function MOI.optimize!(model::Optimizer{T}) where {T}
283311 initial_x = starting_value .(model, eachindex (model. starting_values))
284312 options = copy (model. options)
285313 if ! nl_constrained && has_bounds && ! (method isa IPNewton)
286- options = Options (; options... )
287- model. results = optimize (f, g!, model. variables. lower, model. variables. upper, initial_x, Fminbox (method), options; inplace = true )
314+ options = Optim. Options (; options... )
315+ model. results = optimize (
316+ f,
317+ g!,
318+ model. variables. lower,
319+ model. variables. upper,
320+ initial_x,
321+ Fminbox (method),
322+ options;
323+ inplace = true ,
324+ )
288325 else
289- d = promote_objtype (method, initial_x, :finite , true , f, g!, h!)
290- add_default_opts! (options, method)
291- options = Options (; options... )
326+ d = Optim . promote_objtype (method, initial_x, :finite , true , f, g!, h!)
327+ Optim . add_default_opts! (options, method)
328+ options = Optim . Options (; options... )
292329 if nl_constrained || has_bounds
293330 if nl_constrained
294331 lc = [b. lower for b in nlp_data. constraint_bounds]
295332 uc = [b. upper for b in nlp_data. constraint_bounds]
296333 c! (c, x) = MOI. eval_constraint (evaluator, c, x)
297334 if ! (:Jac in features)
298- error (" Nonlinear constraints should be differentiable to be used with Optim." )
335+ error (
336+ " Nonlinear constraints should be differentiable to be used with Optim." ,
337+ )
299338 end
300339 if ! (:Hess in features)
301- error (" Nonlinear constraints should be twice differentiable to be used with Optim." )
340+ error (
341+ " Nonlinear constraints should be twice differentiable to be used with Optim." ,
342+ )
302343 end
303344 jacobian_structure = MOI. jacobian_structure (evaluator)
304345 J_nzval = zeros (T, length (jacobian_structure))
@@ -315,13 +356,20 @@ function MOI.optimize!(model::Optimizer{T}) where {T}
315356 return H
316357 end
317358 c = TwiceDifferentiableConstraints (
318- c!, jacobian!, con_hessian!,
319- model. variables. lower, model. variables. upper, lc, uc,
359+ c!,
360+ jacobian!,
361+ con_hessian!,
362+ model. variables. lower,
363+ model. variables. upper,
364+ lc,
365+ uc,
320366 )
321367 else
322368 @assert has_bounds
323369 c = TwiceDifferentiableConstraints (
324- model. variables. lower, model. variables. upper)
370+ model. variables. lower,
371+ model. variables. upper,
372+ )
325373 end
326374 model. results = optimize (d, c, initial_x, method, options)
327375 else
334382function MOI. get (model:: Optimizer , :: MOI.TerminationStatus )
335383 if model. results === nothing
336384 return MOI. OPTIMIZE_NOT_CALLED
337- elseif converged (model. results)
385+ elseif Optim . converged (model. results)
338386 return MOI. LOCALLY_SOLVED
339387 else
340388 return MOI. OTHER_ERROR
@@ -354,7 +402,7 @@ function MOI.get(model::Optimizer, attr::MOI.PrimalStatus)
354402 if ! (1 <= attr. result_index <= MOI. get (model, MOI. ResultCount ()))
355403 return MOI. NO_SOLUTION
356404 end
357- if converged (model. results)
405+ if Optim . converged (model. results)
358406 return MOI. FEASIBLE_POINT
359407 else
360408 return MOI. UNKNOWN_RESULT_STATUS
374422function MOI. get (model:: Optimizer , attr:: MOI.VariablePrimal , vi:: MOI.VariableIndex )
375423 MOI. check_result_index_bounds (model, attr)
376424 MOI. throw_if_not_valid (model, vi)
377- return minimizer (model. results)[vi. value]
425+ return Optim . minimizer (model. results)[vi. value]
378426end
379427
380428function MOI. get (
@@ -384,5 +432,6 @@ function MOI.get(
384432) where {T}
385433 MOI. check_result_index_bounds (model, attr)
386434 MOI. throw_if_not_valid (model, ci)
387- return minimizer (model. results)[ci. value]
435+ return Optim . minimizer (model. results)[ci. value]
388436end
437+ end # module
0 commit comments