@@ -163,8 +163,139 @@ end
163
163
hs071_test (model, config) = hs071test_template (model, config, HS071 (true ))
164
164
hs071_no_hessian_test (model, config) = hs071test_template (model, config, HS071 (false ))
165
165
166
- # TODO : HS071 version without hessians.
166
+ # Test for FeasibilitySense.
167
+ # Find x satisfying x^2 == 1.
168
+ struct FeasibilitySenseEvaluator <: MOI.AbstractNLPEvaluator
169
+ enable_hessian:: Bool
170
+ end
171
+
172
+ function MOI. initialize! (d:: FeasibilitySenseEvaluator ,
173
+ requested_features:: Vector{Symbol} )
174
+ for feat in requested_features
175
+ if ! (feat in MOI. features_available (d))
176
+ error (" Unsupported feature $feat " )
177
+ # TODO : implement Jac-vec and Hess-vec products
178
+ # for solvers that need them
179
+ end
180
+ end
181
+ end
182
+
183
+ function MOI. features_available (d:: FeasibilitySenseEvaluator )
184
+ if d. enable_hessian
185
+ return [:Grad , :Jac , :Hess ]
186
+ else
187
+ return [:Grad , :Jac ]
188
+ end
189
+ end
190
+
191
+
192
+ MOI. eval_objective (d:: FeasibilitySenseEvaluator , x) = 0.0
193
+
194
+ function MOI. eval_constraint (d:: FeasibilitySenseEvaluator , g, x)
195
+ g[1 ] = x[1 ]^ 2
196
+ end
197
+
198
+ function MOI. eval_objective_gradient (d:: FeasibilitySenseEvaluator , grad_f, x)
199
+ grad_f[1 ] = 0.0
200
+ end
201
+
202
+ function MOI. jacobian_structure (d:: FeasibilitySenseEvaluator )
203
+ return Tuple{Int64,Int64}[(1 ,1 )]
204
+ end
205
+
206
+ function MOI. hessian_lagrangian_structure (d:: FeasibilitySenseEvaluator )
207
+ @assert d. enable_hessian
208
+ return Tuple{Int64,Int64}[(1 ,1 )]
209
+ end
210
+
211
+ function MOI. eval_constraint_jacobian (d:: FeasibilitySenseEvaluator , J, x)
212
+ J[1 ] = 2 x[1 ]
213
+ end
214
+
215
+ function MOI. eval_hessian_lagrangian (d:: FeasibilitySenseEvaluator , H, x, σ, μ)
216
+ @assert d. enable_hessian
217
+ H[1 ] = 2 μ[1 ] # 1,1
218
+ end
219
+
220
+ function feasibility_sense_test_template (model:: MOI.ModelLike ,
221
+ config:: TestConfig ,
222
+ set_has_objective:: Bool ,
223
+ evaluator:: FeasibilitySenseEvaluator )
224
+ atol = config. atol
225
+ rtol = config. rtol
226
+
227
+ @test MOI. supports (model, MOI. NLPBlock ())
228
+ @test MOI. canset (model, MOI. VariablePrimalStart (), MOI. VariableIndex)
229
+
230
+ MOI. empty! (model)
231
+ @test MOI. isempty (model)
232
+
233
+ lb = [1.0 ]
234
+ ub = [1.0 ]
235
+
236
+ block_data = MOI. NLPBlockData (MOI. NLPBoundsPair .(lb, ub), evaluator,
237
+ set_has_objective)
238
+
239
+ x = MOI. addvariable! (model)
240
+ @test MOI. get (model, MOI. NumberOfVariables ()) == 1
241
+
242
+ # Avoid starting at zero because it's a critial point.
243
+ MOI. set! (model, MOI. VariablePrimalStart (), x, 1.5 )
244
+
245
+ MOI. set! (model, MOI. NLPBlock (), block_data)
246
+ MOI. set! (model, MOI. ObjectiveSense (), MOI. FeasibilitySense)
247
+
248
+ # TODO : config.query tests
249
+
250
+ if config. solve
251
+ MOI. optimize! (model)
252
+
253
+ @test MOI. canget (model, MOI. TerminationStatus ())
254
+ @test MOI. get (model, MOI. TerminationStatus ()) == MOI. Success
255
+
256
+ @test MOI. canget (model, MOI. ResultCount ())
257
+ @test MOI. get (model, MOI. ResultCount ()) >= 1
258
+
259
+ @test MOI. canget (model, MOI. PrimalStatus ())
260
+ @test MOI. get (model, MOI. PrimalStatus ()) == MOI. FeasiblePoint
261
+
262
+ @test MOI. canget (model, MOI. ObjectiveValue ())
263
+ @test MOI. get (model, MOI. ObjectiveValue ()) ≈ 0.0 atol= atol rtol= rtol
264
+
265
+ @test MOI. canget (model, MOI. VariablePrimal (), MOI. VariableIndex)
266
+ @test MOI. get (model, MOI. VariablePrimal (), x) ≈ 1.0 atol= atol rtol= rtol
267
+ end
268
+ end
269
+
270
+ function feasibility_sense_with_objective_and_hessian_test (model, config)
271
+ feasibility_sense_test_template (model, config, true ,
272
+ FeasibilitySenseEvaluator (true ))
273
+ end
274
+
275
+ function feasibility_sense_with_objective_and_no_hessian_test (model, config)
276
+ feasibility_sense_test_template (model, config, true ,
277
+ FeasibilitySenseEvaluator (false ))
278
+ end
279
+
280
+ function feasibility_sense_with_no_objective_and_with_hessian_test (model, config)
281
+ feasibility_sense_test_template (model, config, false ,
282
+ FeasibilitySenseEvaluator (true ))
283
+ end
284
+
285
+ function feasibility_sense_with_no_objective_and_no_hessian_test (model, config)
286
+ feasibility_sense_test_template (model, config, false ,
287
+ FeasibilitySenseEvaluator (false ))
288
+ end
167
289
168
- const nlptests = Dict (" hs071" => hs071_test, " hs071_no_hessian" => hs071_no_hessian_test)
290
+ const nlptests = Dict (" hs071" => hs071_test,
291
+ " hs071_no_hessian" => hs071_no_hessian_test,
292
+ " feasibility_sense_with_objective_and_hessian" =>
293
+ feasibility_sense_with_objective_and_hessian_test,
294
+ " feasibility_sense_with_objective_and_no_hessian" =>
295
+ feasibility_sense_with_objective_and_no_hessian_test,
296
+ " feasibility_sense_with_no_objective_and_with_hessian" =>
297
+ feasibility_sense_with_no_objective_and_with_hessian_test,
298
+ " feasibility_sense_with_no_objective_and_no_hessian" =>
299
+ feasibility_sense_with_no_objective_and_no_hessian_test)
169
300
170
301
@moitestset nlp
0 commit comments