Gurobi produces conic quadratic dual values with low precision.
The testbench failures are:
./test.py -s gurobi -c RSOCP -n dual
======================================================================
FAIL: Rotated SOCP (RSOCP): Dual [GUROBI]
----------------------------------------------------------------------
Traceback (most recent call last):
File "…/src/picos/tests/ptest_socp.py", line 136, in testDual
self.expectObjective(self.D, 2*6**0.5)
File "…/src/picos/tests/ptest.py", line 410, in expectObjective
self.assertAlmostEqual(obj_value, should, self.to.objPlaces,
File "…/src/picos/tests/ptest.py", line 334, in assertAlmostEqual
super(ProductionTestCase, self).assertAlmostEqual(
AssertionError: 4.898980504672822 != 4.898979485566356 within 6 places (1.0191064658826576e-06 difference) : Objective value.
----------------------------------------------------------------------
And, with dualize=True
:
% ./test.py -s gurobi -o dualize=True -c MINCCV MATRIX_1_2_NORM MATRIX_2dot5_1dot5_NORM BALLUNCSOCP ISQP
======================================================================
FAIL: Maximize the minimum of concave functions (MINCCV): Solution [GUROBI with dualize=True]
----------------------------------------------------------------------
Traceback (most recent call last):
File "…/src/picos/tests/ptest_extremum.py", line 58, in testSolution
self.expectObjective(self.P, -9) # -x[0]**2 attains the minium.
File "…/src/picos/tests/ptest.py", line 410, in expectObjective
self.assertAlmostEqual(obj_value, should, self.to.objPlaces,
File "…/src/picos/tests/ptest.py", line 334, in assertAlmostEqual
super(ProductionTestCase, self).assertAlmostEqual(
AssertionError: -9.000000551733384 != -9.0 within 6 places (5.517333843130245e-07 difference) : Objective value.
======================================================================
FAIL: (1,2)-Matrix Norm problem (MATRIX_1_2_NORM): Solution [GUROBI with dualize=True]
----------------------------------------------------------------------
Traceback (most recent call last):
File "…/src/picos/tests/ptest_norm.py", line 65, in testSolution
self.primalSolve(self.P)
File "…/src/picos/tests/ptest.py", line 287, in primalSolve
self.assertAlmostEqual(infeasibility, 0, self.to.objPlaces,
File "…/src/picos/tests/ptest.py", line 334, in assertAlmostEqual
super(ProductionTestCase, self).assertAlmostEqual(
AssertionError: 8.067491360996826e-05 != 0.0 within 6 places (8.067491360996826e-05 difference) : Primal solution claimed optimal but found infeasible.
======================================================================
FAIL: (2.5,1.5)-Matrix Norm problem (MATRIX_2dot5_1dot5_NORM): Solution [GUROBI with dualize=True]
----------------------------------------------------------------------
Traceback (most recent call last):
File "…/src/picos/tests/ptest_norm.py", line 90, in testSolution
self.expectObjective(self.P, cvx.matrix([opt]))
File "…/src/picos/tests/ptest.py", line 410, in expectObjective
self.assertAlmostEqual(obj_value, should, self.to.objPlaces,
File "…/src/picos/tests/ptest.py", line 353, in assertAlmostEqual
super(ProductionTestCase, self).assertAlmostEqual(
AssertionError: 31.510709735170565 != 31.510636237862514 within 4 places (7.34973080511736e-05 difference) : Objective value.
======================================================================
FAIL: SOCP with unit ball uncertainty (BALLUNCSOCP): Nominal [GUROBI with dualize=True]
----------------------------------------------------------------------
Traceback (most recent call last):
File "…/src/picos/tests/ptest_robust_socp.py", line 43, in testNominal
self.expectObjective(P, 2*(n**(-0.5))*n)
File "…/src/picos/tests/ptest.py", line 410, in expectObjective
self.assertAlmostEqual(obj_value, should, self.to.objPlaces,
File "…/src/picos/tests/ptest.py", line 334, in assertAlmostEqual
super(ProductionTestCase, self).assertAlmostEqual(
AssertionError: 3.999998307675951 != 4.0 within 6 places (1.6923240488964097e-06 difference) : Objective value.
======================================================================
FAIL: Inequality Scalar QP (ISQP): Solution [GUROBI with dualize=True]
----------------------------------------------------------------------
Traceback (most recent call last):
File "…/src/picos/tests/ptest_quad.py", line 63, in testSolution
self.expectObjective(self.P, 3.0)
File "…/src/picos/tests/ptest.py", line 410, in expectObjective
self.assertAlmostEqual(obj_value, should, self.to.objPlaces,
File "…/src/picos/tests/ptest.py", line 334, in assertAlmostEqual
super(ProductionTestCase, self).assertAlmostEqual(
AssertionError: 3.0000009725140124 != 3.0 within 6 places (9.725140124317022e-07 difference) : Objective value.
----------------------------------------------------------------------
Note that for BALLUNCSOCP
, only the nominal problem is tested.
Notice that all of these failures are related to the dual solution of a conic quadratic problem. I have written to Gurobi support about this in 2018 but I don't recall a resolution. I will append my report here later.
This issue is about tolerance failures, see #282 for more serious failures cocnerning Gurobi.