@@ -360,46 +360,46 @@ def test_circle_packing_formulation_one(self, solver):
360360 checker = DerivativeChecker (problem )
361361 checker .run_and_assert ()
362362
363- # comment this out for now because UNo computes a different point
364- # def test_circle_packing_formulation_two(self, solver):
365- # """Using norm_inf. This test revealed a very subtle bug in the unpacking of
366- # the ipopt solution. Some variables were mistakenly reordered. It was fixed
367- # in https://github.com/cvxgrp/cvxpy-ipopt/pull/82"""
368- # rng = np.random.default_rng(5)
369- # n = 3
370- # radius = rng.uniform(1.0, 3.0, n)
371- #
372- # centers = cp.Variable((2, n), name='c')
373- # constraints = []
374- # for i in range(n - 1):
375- # for j in range(i + 1, n):
376- # constraints += [cp.sum(cp.square(centers[:, i] - centers[:, j])) >=
377- # (radius[i] + radius[j]) ** 2]
378- #
379- # centers.value = rng.uniform(-5.0, 5.0, (2, n))
380- # obj = cp.Minimize(cp.max(cp.norm_inf(centers, axis=0) + radius))
381- # prob = cp.Problem(obj, constraints)
382- # prob.solve(solver=solver, nlp=True)
383- #
384- # assert np.allclose(obj.value, 4.602738956101437)
385- #
386- # residuals = []
387- # for i in range(n - 1):
388- # for j in range(i + 1, n):
389- # dist_sq = np.linalg.norm(centers.value[:, i] - centers.value[:, j]) ** 2
390- # min_dist_sq = (radius[i] + radius[j]) ** 2
391- # residuals.append(dist_sq - min_dist_sq)
392- #
393- # assert(np.all(np.array(residuals) <= 1e-6))
394- #
395- # # Ipopt finds these centers, but Knitro rotates them (but finds the same
396- # # objective value)
397- # #true_sol = np.array([[1.73655994, -1.98685738, 2.57208783],
398- # # [1.99273311, -1.67415425, -2.57208783]])
399- # #assert np.allclose(centers.value, true_sol)
400- #
401- # checker = DerivativeChecker(prob)
402- # checker.run_and_assert()
363+ @ pytest . mark . skipif ( 'UNO' in INSTALLED_SOLVERS , reason = 'UNO finds a KKT point with worse obj' )
364+ def test_circle_packing_formulation_two (self , solver ):
365+ """Using norm_inf. This test revealed a very subtle bug in the unpacking of
366+ the ipopt solution. Some variables were mistakenly reordered. It was fixed
367+ in https://github.com/cvxgrp/cvxpy-ipopt/pull/82"""
368+ rng = np .random .default_rng (5 )
369+ n = 3
370+ radius = rng .uniform (1.0 , 3.0 , n )
371+
372+ centers = cp .Variable ((2 , n ), name = 'c' )
373+ constraints = []
374+ for i in range (n - 1 ):
375+ for j in range (i + 1 , n ):
376+ constraints += [cp .sum (cp .square (centers [:, i ] - centers [:, j ])) >=
377+ (radius [i ] + radius [j ]) ** 2 ]
378+
379+ centers .value = rng .uniform (- 5.0 , 5.0 , (2 , n ))
380+ obj = cp .Minimize (cp .max (cp .norm_inf (centers , axis = 0 ) + radius ))
381+ prob = cp .Problem (obj , constraints )
382+ prob .solve (solver = solver , nlp = True )
383+
384+ assert np .allclose (obj .value , 4.602738956101437 )
385+
386+ residuals = []
387+ for i in range (n - 1 ):
388+ for j in range (i + 1 , n ):
389+ dist_sq = np .linalg .norm (centers .value [:, i ] - centers .value [:, j ]) ** 2
390+ min_dist_sq = (radius [i ] + radius [j ]) ** 2
391+ residuals .append (dist_sq - min_dist_sq )
392+
393+ assert (np .all (np .array (residuals ) <= 1e-6 ))
394+
395+ # Ipopt finds these centers, but Knitro rotates them (but finds the same
396+ # objective value)
397+ #true_sol = np.array([[1.73655994, -1.98685738, 2.57208783],
398+ # [1.99273311, -1.67415425, -2.57208783]])
399+ #assert np.allclose(centers.value, true_sol)
400+
401+ checker = DerivativeChecker (prob )
402+ checker .run_and_assert ()
403403
404404 def test_circle_packing_formulation_three (self , solver ):
405405 """Using max max abs."""
@@ -428,31 +428,31 @@ def test_circle_packing_formulation_three(self, solver):
428428 checker = DerivativeChecker (prob )
429429 checker .run_and_assert ()
430430
431- # temporarily comment this out as uno fails
432- # def test_geo_mean(self, solver):
433- # x = cp.Variable(3, nonneg=True)
434- # geo_mean = cp.geo_mean(x)
435- # objective = cp.Maximize(geo_mean)
436- # constraints = [cp.sum(x) == 1]
437- # problem = cp.Problem(objective, constraints)
438- # problem.solve(solver=solver, nlp=True)
439- # assert problem.status == cp.OPTIMAL
440- # assert np.allclose(x.value, np.array([1/3, 1/3, 1/3]))
431+ @ pytest . mark . skipif ( 'UNO' in INSTALLED_SOLVERS , reason = 'UNO reaches iteration limit' )
432+ def test_geo_mean (self , solver ):
433+ x = cp .Variable (3 , nonneg = True )
434+ geo_mean = cp .geo_mean (x )
435+ objective = cp .Maximize (geo_mean )
436+ constraints = [cp .sum (x ) == 1 ]
437+ problem = cp .Problem (objective , constraints )
438+ problem .solve (solver = solver , nlp = True )
439+ assert problem .status == cp .OPTIMAL
440+ assert np .allclose (x .value , np .array ([1 / 3 , 1 / 3 , 1 / 3 ]))
441441
442- # checker = DerivativeChecker(problem)
443- # checker.run_and_assert()
442+ checker = DerivativeChecker (problem )
443+ checker .run_and_assert ()
444444
445- # temporarily comment this out as uno fails
446- # def test_geo_mean2(self, solver):
447- # p = np.array([.07, .12, .23, .19, .39])
448- # x = cp.Variable(5, nonneg=True)
449- # prob = cp.Problem(cp.Maximize(cp.geo_mean(x, p)), [cp.sum(x) <= 1])
450- # prob.solve(solver=solver, nlp=True)
451- # x_true = p/sum(p)
452- # assert prob.status == cp.OPTIMAL
453- # assert np.allclose(x.value, x_true)
454- # checker = DerivativeChecker(prob)
455- # checker.run_and_assert()
445+ @ pytest . mark . skipif ( 'UNO' in INSTALLED_SOLVERS , reason = 'UNO reaches iteration limit' )
446+ def test_geo_mean2 (self , solver ):
447+ p = np .array ([.07 , .12 , .23 , .19 , .39 ])
448+ x = cp .Variable (5 , nonneg = True )
449+ prob = cp .Problem (cp .Maximize (cp .geo_mean (x , p )), [cp .sum (x ) <= 1 ])
450+ prob .solve (solver = solver , nlp = True )
451+ x_true = p / sum (p )
452+ assert prob .status == cp .OPTIMAL
453+ assert np .allclose (x .value , x_true )
454+ checker = DerivativeChecker (prob )
455+ checker .run_and_assert ()
456456
457457 def test_div_composition (self , solver ):
458458 x = cp .Variable (nonneg = True , bounds = [1 , 5 ])
0 commit comments