@@ -3,6 +3,7 @@ module OptimizationNLopt
3
3
using Reexport
4
4
@reexport using NLopt, Optimization
5
5
using Optimization. SciMLBase
6
+ using Optimization: deduce_retcode
6
7
7
8
(f:: NLopt.Algorithm )() = f
8
9
@@ -63,6 +64,38 @@ function SciMLBase.requiresconsjac(opt::Union{NLopt.Algorithm, NLopt.Opt}) #http
63
64
end
64
65
end
65
66
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
+
66
99
function __map_optimizer_args! (cache:: OptimizationCache , opt:: NLopt.Opt ;
67
100
callback = nothing ,
68
101
maxiters:: Union{Number, Nothing} = nothing ,
@@ -103,7 +136,9 @@ function __map_optimizer_args!(cache::OptimizationCache, opt::NLopt.Opt;
103
136
104
137
# add optimiser options from kwargs
105
138
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
107
142
end
108
143
109
144
if cache. ub != = nothing
@@ -132,31 +167,6 @@ function __map_optimizer_args!(cache::OptimizationCache, opt::NLopt.Opt;
132
167
return nothing
133
168
end
134
169
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
-
160
170
function SciMLBase. __solve (cache:: OptimizationCache {
161
171
F,
162
172
RC,
@@ -219,6 +229,39 @@ function SciMLBase.__solve(cache::OptimizationCache{
219
229
NLopt. min_objective! (opt_setup, fg!)
220
230
end
221
231
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
+
222
265
maxiters = Optimization. _check_and_convert_maxiters (cache. solver_args. maxiters)
223
266
maxtime = Optimization. _check_and_convert_maxtime (cache. solver_args. maxtime)
224
267
@@ -229,7 +272,7 @@ function SciMLBase.__solve(cache::OptimizationCache{
229
272
t0 = time ()
230
273
(minf, minx, ret) = NLopt. optimize (opt_setup, cache. u0)
231
274
t1 = time ()
232
- retcode = __nlopt_status_to_ReturnCode (ret)
275
+ retcode = deduce_retcode (ret)
233
276
234
277
if retcode == ReturnCode. Failure
235
278
@warn " NLopt failed to converge: $(ret) "
0 commit comments