Skip to content

Commit 6149898

Browse files
committed
add nlp tests for FeasibilitySense
1 parent 9738f62 commit 6149898

File tree

1 file changed

+133
-2
lines changed

1 file changed

+133
-2
lines changed

src/Test/nlp.jl

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,139 @@ end
163163
hs071_test(model, config) = hs071test_template(model, config, HS071(true))
164164
hs071_no_hessian_test(model, config) = hs071test_template(model, config, HS071(false))
165165

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] = 2x[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
167289

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)
169300

170301
@moitestset nlp

0 commit comments

Comments
 (0)