@@ -179,6 +179,15 @@ function MOI.supports_constraint(
179
179
return true
180
180
end
181
181
182
+ # This should be a valid idxint, but not one of the constants ECOS uses.
183
+ const _ECOS_INVALID_MODEL = - 9999
184
+
185
+ function _set_errored_solution_status (dest:: Optimizer , status)
186
+ dest. sol = _Solution ()
187
+ dest. sol. ret_val = status
188
+ return
189
+ end
190
+
182
191
function _optimize! (dest:: Optimizer , src:: OptimizerCache )
183
192
MOI. empty! (dest)
184
193
Ab = MOI. Utilities. constraints (
@@ -202,6 +211,10 @@ function _optimize!(dest::Optimizer, src::OptimizerCache)
202
211
)
203
212
q = MOI. dimension .(MOI. get .(Gh, MOI. ConstraintSet (), soc_indices))
204
213
@assert A. n == G. n
214
+ if A. n == 0
215
+ _set_errored_solution_status (dest, _ECOS_INVALID_MODEL)
216
+ return
217
+ end
205
218
max_sense = MOI. get (src, MOI. ObjectiveSense ()) == MOI. MAX_SENSE
206
219
obj =
207
220
MOI. get (src, MOI. ObjectiveFunction {MOI.ScalarAffineFunction{pfloat}} ())
@@ -247,7 +260,8 @@ function _optimize!(dest::Optimizer, src::OptimizerCache)
247
260
Ab. constants,
248
261
)
249
262
if inner == C_NULL
250
- error (" ECOS failed to construct problem." )
263
+ _set_errored_solution_status (dest, ECOS_FATAL)
264
+ return
251
265
end
252
266
unsafe_add_settings (inner, options)
253
267
ret_val = ECOS_solve (inner)
@@ -331,9 +345,11 @@ function MOI.get(optimizer::Optimizer, ::MOI.RawStatusString)
331
345
return " s or z got outside the cone, numerics?"
332
346
elseif flag == ECOS_SIGINT
333
347
return " solver interrupted by a signal/ctrl-c"
334
- else
335
- @assert flag == ECOS_FATAL
348
+ elseif flag == ECOS_FATAL
336
349
return " Unknown problem in solver"
350
+ else
351
+ @assert flag == _ECOS_INVALID_MODEL
352
+ return " Invalid model: you must have at least one variable"
337
353
end
338
354
end
339
355
@@ -360,9 +376,11 @@ function MOI.get(optimizer::Optimizer, ::MOI.TerminationStatus)
360
376
return MOI. ALMOST_OPTIMAL
361
377
elseif flag == ECOS_PINF + ECOS_INACC_OFFSET
362
378
return MOI. ALMOST_INFEASIBLE
363
- else
364
- @assert flag == ECOS_DINF + ECOS_INACC_OFFSET
379
+ elseif flag == ECOS_DINF + ECOS_INACC_OFFSET
365
380
return MOI. ALMOST_DUAL_INFEASIBLE
381
+ else
382
+ @assert flag == _ECOS_INVALID_MODEL
383
+ return MOI. INVALID_MODEL
366
384
end
367
385
end
368
386
@@ -395,6 +413,10 @@ function MOI.get(optimizer::Optimizer, attr::MOI.PrimalStatus)
395
413
return MOI. INFEASIBLE_POINT
396
414
elseif flag == ECOS_DINF + ECOS_INACC_OFFSET
397
415
return MOI. NEARLY_INFEASIBILITY_CERTIFICATE
416
+ elseif flag == ECOS_FATAL
417
+ return MOI. NO_SOLUTION
418
+ elseif flag == _ECOS_INVALID_MODEL
419
+ return MOI. NO_SOLUTION
398
420
else
399
421
return MOI. OTHER_RESULT_STATUS
400
422
end
@@ -446,6 +468,10 @@ function MOI.get(optimizer::Optimizer, attr::MOI.DualStatus)
446
468
return MOI. NEARLY_INFEASIBILITY_CERTIFICATE
447
469
elseif flag == ECOS_DINF + ECOS_INACC_OFFSET
448
470
return MOI. INFEASIBLE_POINT
471
+ elseif flag == ECOS_FATAL
472
+ return MOI. NO_SOLUTION
473
+ elseif flag == _ECOS_INVALID_MODEL
474
+ return MOI. NO_SOLUTION
449
475
end
450
476
return MOI. OTHER_RESULT_STATUS
451
477
end
0 commit comments