@@ -3,6 +3,7 @@ module OptimizationNLopt
33using Reexport
44@reexport using NLopt, Optimization
55using Optimization. SciMLBase
6+ using Optimization: deduce_retcode
67
78(f:: NLopt.Algorithm )() = f
89
@@ -63,6 +64,38 @@ function SciMLBase.requiresconsjac(opt::Union{NLopt.Algorithm, NLopt.Opt}) #http
6364 end
6465end
6566
67+ function SciMLBase. allowsconstraints (opt:: NLopt.Algorithm )
68+ str_opt = string (opt)
69+ if occursin (" AUGLAG" , str_opt) || occursin (" CCSA" , str_opt) ||
70+ occursin (" MMA" , str_opt) || occursin (" COBYLA" , str_opt) ||
71+ occursin (" ISRES" , str_opt) || occursin (" AGS" , str_opt) ||
72+ occursin (" ORIG_DIRECT" , str_opt) || occursin (" SLSQP" , str_opt)
73+ return true
74+ else
75+ return false
76+ end
77+ end
78+
79+ function SciMLBase. requiresconsjac (opt:: NLopt.Algorithm )
80+ str_opt = string (opt)
81+ if occursin (" AUGLAG" , str_opt) || occursin (" CCSA" , str_opt) ||
82+ occursin (" MMA" , str_opt) || occursin (" COBYLA" , str_opt) ||
83+ occursin (" ISRES" , str_opt) || occursin (" AGS" , str_opt) ||
84+ occursin (" ORIG_DIRECT" , str_opt) || occursin (" SLSQP" , str_opt)
85+ return true
86+ else
87+ return false
88+ end
89+ end
90+
91+ function SciMLBase. __init (prob:: SciMLBase.OptimizationProblem , opt:: NLopt.Algorithm ,
92+ ; cons_tol = 1e-6 ,
93+ callback = (args... ) -> (false ),
94+ progress = false , kwargs... )
95+ return OptimizationCache (prob, opt; cons_tol, callback, progress,
96+ kwargs... )
97+ end
98+
6699function __map_optimizer_args! (cache:: OptimizationCache , opt:: NLopt.Opt ;
67100 callback = nothing ,
68101 maxiters:: Union{Number, Nothing} = nothing ,
@@ -103,7 +136,9 @@ function __map_optimizer_args!(cache::OptimizationCache, opt::NLopt.Opt;
103136
104137 # add optimiser options from kwargs
105138 for j in kwargs
106- eval (Meta. parse (" NLopt." * string (j. first) * " !" ))(opt, j. second)
139+ if j. first != :cons_tol
140+ eval (Meta. parse (" NLopt." * string (j. first) * " !" ))(opt, j. second)
141+ end
107142 end
108143
109144 if cache. ub != = nothing
@@ -132,31 +167,6 @@ function __map_optimizer_args!(cache::OptimizationCache, opt::NLopt.Opt;
132167 return nothing
133168end
134169
135- function __nlopt_status_to_ReturnCode (status:: Symbol )
136- if status in Symbol .([
137- NLopt. SUCCESS,
138- NLopt. STOPVAL_REACHED,
139- NLopt. FTOL_REACHED,
140- NLopt. XTOL_REACHED,
141- NLopt. ROUNDOFF_LIMITED
142- ])
143- return ReturnCode. Success
144- elseif status == Symbol (NLopt. MAXEVAL_REACHED)
145- return ReturnCode. MaxIters
146- elseif status == Symbol (NLopt. MAXTIME_REACHED)
147- return ReturnCode. MaxTime
148- elseif status in Symbol .([
149- NLopt. OUT_OF_MEMORY,
150- NLopt. INVALID_ARGS,
151- NLopt. FAILURE,
152- NLopt. FORCED_STOP
153- ])
154- return ReturnCode. Failure
155- else
156- return ReturnCode. Default
157- end
158- end
159-
160170function SciMLBase. __solve (cache:: OptimizationCache {
161171 F,
162172 RC,
@@ -219,6 +229,39 @@ function SciMLBase.__solve(cache::OptimizationCache{
219229 NLopt. min_objective! (opt_setup, fg!)
220230 end
221231
232+ if cache. f. cons != = nothing
233+ eqinds = map ((y) -> y[1 ] == y[2 ], zip (cache. lcons, cache. ucons))
234+ ineqinds = map ((y) -> y[1 ] != y[2 ], zip (cache. lcons, cache. ucons))
235+ if sum (ineqinds) > 0
236+ ineqcons = function (res, θ, J)
237+ cons_cache = zeros (eltype (res), sum (eqinds) + sum (ineqinds))
238+ cache. f. cons (cons_cache, θ)
239+ res .= @view (cons_cache[ineqinds])
240+ if length (J) > 0
241+ Jcache = zeros (eltype (J), sum (ineqinds) + sum (eqinds), length (θ))
242+ cache. f. cons_j (Jcache, θ)
243+ J .= @view (Jcache[ineqinds, :])'
244+ end
245+ end
246+ NLopt. inequality_constraint! (
247+ opt_setup, ineqcons, [cache. solver_args. cons_tol for i in 1 : sum (ineqinds)])
248+ end
249+ if sum (eqinds) > 0
250+ eqcons = function (res, θ, J)
251+ cons_cache = zeros (eltype (res), sum (eqinds) + sum (ineqinds))
252+ cache. f. cons (cons_cache, θ)
253+ res .= @view (cons_cache[eqinds])
254+ if length (J) > 0
255+ Jcache = zeros (eltype (res), sum (eqinds) + sum (ineqinds), length (θ))
256+ cache. f. cons_j (Jcache, θ)
257+ J .= @view (Jcache[eqinds, :])'
258+ end
259+ end
260+ NLopt. equality_constraint! (
261+ opt_setup, eqcons, [cache. solver_args. cons_tol for i in 1 : sum (eqinds)])
262+ end
263+ end
264+
222265 maxiters = Optimization. _check_and_convert_maxiters (cache. solver_args. maxiters)
223266 maxtime = Optimization. _check_and_convert_maxtime (cache. solver_args. maxtime)
224267
@@ -229,7 +272,7 @@ function SciMLBase.__solve(cache::OptimizationCache{
229272 t0 = time ()
230273 (minf, minx, ret) = NLopt. optimize (opt_setup, cache. u0)
231274 t1 = time ()
232- retcode = __nlopt_status_to_ReturnCode (ret)
275+ retcode = deduce_retcode (ret)
233276
234277 if retcode == ReturnCode. Failure
235278 @warn " NLopt failed to converge: $(ret) "
0 commit comments