def test_partial_optimize_numeric_fn(self): x, y = Variable(1), Variable(1) xval = 4 # Solve the (simple) two-stage problem by "combining" the two stages (i.e., by solving a single linear program) p1 = Problem(Minimize(y), [xval + y >= 3]) p1.solve() # Solve the two-stage problem via partial_optimize constr = [y >= -100] p2 = Problem(Minimize(y), [x + y >= 3] + constr) g = cvxpy.partial_optimize(p2, [y], [x]) x.value = xval y.value = 42 constr[0].dual_variable.value = 42 result = g.value self.assertAlmostEqual(result, p1.value) self.assertAlmostEqual(y.value, 42) self.assertAlmostEqual(constr[0].dual_value, 42) # No variables optimized over. p2 = Problem(Minimize(y), [x + y >= 3]) g = cvxpy.partial_optimize(p2, [], [x, y]) x.value = xval y.value = 42 p2.constraints[0].dual_variable.value = 42 result = g.value self.assertAlmostEqual(result, y.value) self.assertAlmostEqual(y.value, 42) self.assertAlmostEqual(p2.constraints[0].dual_value, 42)
def test_assign_var_value(self): """Test assigning a value to a variable. """ # Scalar variable. a = Variable() a.value = 1 self.assertEqual(a.value, 1) with self.assertRaises(Exception) as cm: a.value = [2, 1] self.assertEqual(str(cm.exception), "Invalid dimensions (2, 1) for Variable value.") # Test assigning None. a.value = 1 a.value = None assert a.value is None # Vector variable. x = Variable(2) x.value = [2, 1] self.assertItemsAlmostEqual(x.value, [2, 1]) # Matrix variable. A = Variable(3, 2) A.value = np.ones((3, 2)) self.assertItemsAlmostEqual(A.value, np.ones((3, 2)))
def test_partial_optimize_numeric_fn(self): x, y = Variable(1), Variable(1) xval = 4 # Solve the (simple) two-stage problem by "combining" the two stages (i.e., by solving a single linear program) p1 = Problem(Minimize(y), [xval+y >= 3]) p1.solve() # Solve the two-stage problem via partial_optimize constr = [y >= -100] p2 = Problem(Minimize(y), [x+y >= 3] + constr) g = cvxpy.partial_optimize(p2, [y], [x]) x.value = xval y.value = 42 constr[0].dual_variable.value = 42 result = g.value self.assertAlmostEqual(result, p1.value) self.assertAlmostEqual(y.value, 42) self.assertAlmostEqual(constr[0].dual_value, 42) # No variables optimized over. p2 = Problem(Minimize(y), [x+y >= 3]) g = cvxpy.partial_optimize(p2, [], [x, y]) x.value = xval y.value = 42 p2.constraints[0].dual_variable.value = 42 result = g.value self.assertAlmostEqual(result, y.value) self.assertAlmostEqual(y.value, 42) self.assertAlmostEqual(p2.constraints[0].dual_value, 42)
def test_affine(self): """Test grad for affine atoms. """ expr = -self.a self.a.value = 2 self.assertAlmostEquals(expr.grad[self.a], -1) expr = -(self.x) self.x.value = [3, 4] val = np.zeros((2, 2)) - np.diag([1, 1]) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) expr = -(self.A) self.A.value = [[1, 2], [3, 4]] val = np.zeros((4, 4)) - np.diag([1, 1, 1, 1]) self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) expr = self.A[0, 1] self.A.value = [[1, 2], [3, 4]] val = np.zeros((4, 1)) val[2] = 1 self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) z = Variable(3) expr = vstack(self.x, z) self.x.value = [1, 2] z.value = [1, 2, 3] val = np.zeros((2, 5)) val[:, 0:2] = np.eye(2) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) val = np.zeros((3, 5)) val[:, 2:] = np.eye(3) self.assertItemsAlmostEqual(expr.grad[z].todense(), val)
def test_affine(self): """Test grad for affine atoms. """ expr = -self.a self.a.value = 2 self.assertAlmostEquals(expr.grad[self.a], -1) expr = -(self.x) self.x.value = [3,4] val = np.zeros((2,2)) - np.diag([1,1]) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) expr = -(self.A) self.A.value = [[1,2], [3,4]] val = np.zeros((4,4)) - np.diag([1,1,1,1]) self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) expr = self.A[0,1] self.A.value = [[1,2], [3,4]] val = np.zeros((4,1)) val[2] = 1 self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) z = Variable(3) expr = vstack(self.x, z) self.x.value = [1,2] z.value = [1,2,3] val = np.zeros((2,5)) val[:,0:2] = np.eye(2) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) val = np.zeros((3,5)) val[:,2:] = np.eye(3) self.assertItemsAlmostEqual(expr.grad[z].todense(), val)
def test_log_det(self): """Test gradient for log_det """ expr = log_det(self.A) self.A.value = 2 * np.eye(2) self.assertItemsAlmostEqual(expr.grad[self.A].todense(), 1.0 / 2 * np.eye(2)) mat = np.matrix([[1, 2], [3, 5]]) self.A.value = mat.T * mat val = np.linalg.inv(self.A.value).T self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) self.A.value = np.zeros((2, 2)) self.assertAlmostEqual(expr.grad[self.A], None) self.A.value = -np.matrix([[1, 2], [3, 4]]) self.assertAlmostEqual(expr.grad[self.A], None) K = Variable(8, 8) expr = log_det(K[[1, 2]][:, [1, 2]]) K.value = np.eye(8) val = np.zeros((8, 8)) val[[1, 2], [1, 2]] = 1 self.assertItemsAlmostEqual(expr.grad[K].todense(), val)
def test_min_elemwise(self): """Test domain for min_elemwise. """ b = Variable() expr = min_elemwise(self.a, b) self.a.value = 2 b.value = 4 self.assertAlmostEqual(expr.grad[self.a], 1) self.assertAlmostEqual(expr.grad[b], 0) self.a.value = 3 b.value = 0 self.assertAlmostEqual(expr.grad[self.a], 0) self.assertAlmostEqual(expr.grad[b], 1) self.a.value = -1 b.value = 2 self.assertAlmostEqual(expr.grad[self.a], 1) self.assertAlmostEqual(expr.grad[b], 0) y = Variable(2) expr = min_elemwise(self.x, y) self.x.value = [3, 4] y.value = [5, -5] val = np.zeros((2, 2)) + np.diag([1, 0]) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) val = np.zeros((2, 2)) + np.diag([0, 1]) self.assertItemsAlmostEqual(expr.grad[y].todense(), val) expr = min_elemwise(self.x, y) self.x.value = [-1e-9, 4] y.value = [1, 4] val = np.zeros((2, 2)) + np.diag([1, 1]) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) val = np.zeros((2, 2)) + np.diag([0, 0]) self.assertItemsAlmostEqual(expr.grad[y].todense(), val) expr = min_elemwise(self.A, self.B) self.A.value = [[1, 2], [3, 4]] self.B.value = [[5, 1], [3, 2.3]] div = (self.A.value / self.B.value).A.ravel(order='F') val = np.zeros((4, 4)) + np.diag([1, 0, 1, 0]) self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) val = np.zeros((4, 4)) + np.diag([0, 1, 0, 1]) self.assertItemsAlmostEqual(expr.grad[self.B].todense(), val)
def test_assign_var_value(self): """Test assigning a value to a variable. """ # Scalar variable. a = Variable() a.value = 1 self.assertEqual(a.value, 1) with self.assertRaises(Exception) as cm: a.value = [2, 1] self.assertEqual(str(cm.exception), "Invalid dimensions (2, 1) for Variable value.") # Test assigning None. a.value = 1 a.value = None assert a.value is None # Vector variable. x = Variable(2) x.value = [2, 1] self.assertItemsAlmostEqual(x.value, [2, 1]) # Matrix variable. A = Variable(3, 2) A.value = np.ones((3, 2)) self.assertItemsAlmostEqual(A.value, np.ones((3, 2))) # Test assigning negative val to nonnegative variable. x = NonNegative() with self.assertRaises(Exception) as cm: x.value = -2 self.assertEqual(str(cm.exception), "Invalid sign for NonNegative value.") # Small negative values are rounded to 0. x.value = -1e-8 self.assertEqual(x.value, 0)
def test_min_elemwise(self): """Test domain for min_elemwise. """ b = Variable() expr = min_elemwise(self.a, b) self.a.value = 2 b.value = 4 self.assertAlmostEqual(expr.grad[self.a], 1) self.assertAlmostEqual(expr.grad[b], 0) self.a.value = 3 b.value = 0 self.assertAlmostEqual(expr.grad[self.a], 0) self.assertAlmostEqual(expr.grad[b], 1) self.a.value = -1 b.value = 2 self.assertAlmostEqual(expr.grad[self.a], 1) self.assertAlmostEqual(expr.grad[b], 0) y = Variable(2) expr = min_elemwise(self.x, y) self.x.value = [3, 4] y.value = [5, -5] val = np.zeros((2, 2)) + np.diag([1, 0]) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) val = np.zeros((2, 2)) + np.diag([0, 1]) self.assertItemsAlmostEqual(expr.grad[y].todense(), val) expr = min_elemwise(self.x, y) self.x.value = [-1e-9, 4] y.value = [1, 4] val = np.zeros((2, 2)) + np.diag([1, 1]) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) val = np.zeros((2, 2)) + np.diag([0, 0]) self.assertItemsAlmostEqual(expr.grad[y].todense(), val) expr = min_elemwise(self.A, self.B) self.A.value = [[1, 2], [3, 4]] self.B.value = [[5, 1], [3, 2.3]] div = (self.A.value/self.B.value).A.ravel(order='F') val = np.zeros((4, 4)) + np.diag([1, 0, 1, 0]) self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) val = np.zeros((4, 4)) + np.diag([0, 1, 0, 1]) self.assertItemsAlmostEqual(expr.grad[self.B].todense(), val)
def test_assign_var_value(self): """Test assigning a value to a variable. """ # Scalar variable. a = Variable() a.value = 1 self.assertEqual(a.value, 1) with self.assertRaises(Exception) as cm: a.value = [2, 1] self.assertEqual(str(cm.exception), "Invalid dimensions (2, 1) for Variable value.") # Vector variable. x = Variable(2) x.value = [2, 1] self.assertItemsAlmostEqual(x.value, [2, 1]) # Matrix variable. A = Variable(3, 2) A.value = np.ones((3, 2)) self.assertItemsAlmostEqual(A.value, np.ones((3, 2)))
def test_kl_div(self): """Test domain for kl_div. """ b = Variable() expr = kl_div(self.a, b) self.a.value = 2 b.value = 4 self.assertAlmostEqual(expr.grad[self.a], np.log(2 / 4)) self.assertAlmostEqual(expr.grad[b], 1 - (2 / 4)) self.a.value = 3 b.value = 0 self.assertAlmostEqual(expr.grad[self.a], None) self.assertAlmostEqual(expr.grad[b], None) self.a.value = -1 b.value = 2 self.assertAlmostEqual(expr.grad[self.a], None) self.assertAlmostEqual(expr.grad[b], None) y = Variable(2) expr = kl_div(self.x, y) self.x.value = [3, 4] y.value = [5, 8] val = np.zeros((2, 2)) + np.diag(np.log([3, 4]) - np.log([5, 8])) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) val = np.zeros((2, 2)) + np.diag([1 - 3 / 5, 1 - 4 / 8]) self.assertItemsAlmostEqual(expr.grad[y].todense(), val) expr = kl_div(self.x, y) self.x.value = [-1e-9, 4] y.value = [1, 2] self.assertAlmostEqual(expr.grad[self.x], None) self.assertAlmostEqual(expr.grad[y], None) expr = kl_div(self.A, self.B) self.A.value = [[1, 2], [3, 4]] self.B.value = [[5, 1], [3.5, 2.3]] div = (self.A.value / self.B.value).A.ravel(order='F') val = np.zeros((4, 4)) + np.diag(np.log(div)) self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) val = np.zeros((4, 4)) + np.diag(1 - div) self.assertItemsAlmostEqual(expr.grad[self.B].todense(), val)
def test_kl_div(self): """Test domain for kl_div. """ b = Variable() expr = kl_div(self.a, b) self.a.value = 2 b.value = 4 self.assertAlmostEqual(expr.grad[self.a], np.log(2/4)) self.assertAlmostEqual(expr.grad[b], 1 - (2/4)) self.a.value = 3 b.value = 0 self.assertAlmostEqual(expr.grad[self.a], None) self.assertAlmostEqual(expr.grad[b], None) self.a.value = -1 b.value = 2 self.assertAlmostEqual(expr.grad[self.a], None) self.assertAlmostEqual(expr.grad[b], None) y = Variable(2) expr = kl_div(self.x, y) self.x.value = [3, 4] y.value = [5, 8] val = np.zeros((2, 2)) + np.diag(np.log([3, 4]) - np.log([5, 8])) self.assertItemsAlmostEqual(expr.grad[self.x].todense(), val) val = np.zeros((2, 2)) + np.diag([1 - 3/5, 1 - 4/8]) self.assertItemsAlmostEqual(expr.grad[y].todense(), val) expr = kl_div(self.x, y) self.x.value = [-1e-9, 4] y.value = [1, 2] self.assertAlmostEqual(expr.grad[self.x], None) self.assertAlmostEqual(expr.grad[y], None) expr = kl_div(self.A, self.B) self.A.value = [[1, 2], [3, 4]] self.B.value = [[5, 1], [3.5, 2.3]] div = (self.A.value/self.B.value).A.ravel(order='F') val = np.zeros((4, 4)) + np.diag(np.log(div)) self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) val = np.zeros((4, 4)) + np.diag(1 - div) self.assertItemsAlmostEqual(expr.grad[self.B].todense(), val)
def test_partial_optimize_numeric_fn(self): x,y = Variable(1), Variable(1) xval = 4 # Solve the (simple) two-stage problem by "combining" the two stages (i.e., by solving a single linear program) p1 = Problem(Minimize(y), [xval+y>=3]) p1.solve() # Solve the two-stage problem via partial_optimize p2 = Problem(Minimize(y), [x+y>=3]) g = partial_optimize(p2, [y], [x]) x.value = xval result = g.value self.assertAlmostEqual(result, p1.value)
def test_log_det(self): """Test gradient for log_det """ expr = log_det(self.A) self.A.value = 2*np.eye(2) self.assertItemsAlmostEqual(expr.grad[self.A].todense(), 1.0/2*np.eye(2)) mat = np.matrix([[1, 2], [3, 5]]) self.A.value = mat.T*mat val = np.linalg.inv(self.A.value).T self.assertItemsAlmostEqual(expr.grad[self.A].todense(), val) self.A.value = np.zeros((2, 2)) self.assertAlmostEqual(expr.grad[self.A], None) self.A.value = -np.matrix([[1, 2], [3, 4]]) self.assertAlmostEqual(expr.grad[self.A], None) K = Variable(8, 8) expr = log_det(K[[1,2]][:,[1,2]]) K.value = np.eye(8) val = np.zeros((8,8)) val[[1,2],[1,2]] = 1 self.assertItemsAlmostEqual(expr.grad[K].todense(), val)