def test_psd_nsd_parameters(self): # Test valid rank-deficeint PSD parameter. np.random.seed(42) a = np.random.normal(size=(100, 95)) a2 = a.dot(a.T) # This must be a PSD matrix. p = Parameter((100, 100), PSD=True) p.value = a2 self.assertItemsAlmostEqual(p.value, a2, places=10) # Test positive definite matrix with non-distinct eigenvalues m, n = 10, 5 A = np.random.randn( m, n) + 1j * np.random.randn(m, n) # a random complex matrix A = np.dot(A.T.conj(), A) # a random Hermitian positive definite matrix A = np.vstack([ np.hstack([np.real(A), -np.imag(A)]), np.hstack([np.imag(A), np.real(A)]) ]) p = Parameter(shape=(2 * n, 2 * n), PSD=True) p.value = A self.assertItemsAlmostEqual(p.value, A) # Test invalid PSD parameter with self.assertRaises(Exception) as cm: p = Parameter((2, 2), PSD=True, value=[[1, 0], [0, -1]]) self.assertEqual(str(cm.exception), "Parameter value must be positive semidefinite.") # Test invalid NSD parameter with self.assertRaises(Exception) as cm: p = Parameter((2, 2), NSD=True, value=[[1, 0], [0, -1]]) self.assertEqual(str(cm.exception), "Parameter value must be negative semidefinite.")
def test_parameter_expressions(self): """Test that expressions with parameters are updated properly. """ x = Variable() y = Variable() x0 = Parameter() xSquared = x0*x0 + 2*x0*(x - x0) # initial guess for x x0.value = 2 # make the constraint x**2 - y == 0 g = xSquared - y # set up the problem obj = abs(x - 1) prob = Problem( Minimize( obj ), [ g == 0 ] ) prob.solve() x0.value = 1 prob.solve() self.assertAlmostEqual(g.value, 0) # Test multiplication. prob = Problem( Minimize( x0*x ), [ x == 1 ] ) x0.value = 2 prob.solve() x0.value = 1 prob.solve() self.assertAlmostEqual(prob.value, 1)
def test_parameters(self): p = Parameter(name='p') self.assertEqual(p.name(), "p") self.assertEqual(p.size, (1, 1)) p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = 1 self.assertEqual(str(cm.exception), "Invalid dimensions (1,1) for Parameter value.") val = -np.ones((4, 3)) val[0, 0] = 2 p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") p = Parameter(4, 3, sign="negative") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") # No error for unknown sign. p = Parameter(4, 3) p.value = val
def test_parameter(self): """Test the parameter class. """ x = Parameter(2, complex=False) y = Parameter(2, complex=True) z = Parameter(2, imag=True) assert not x.is_complex() assert not x.is_imag() assert y.is_complex() assert not y.is_imag() assert z.is_complex() assert z.is_imag() with self.assertRaises(Exception) as cm: x.value = np.array([1j, 0.]) self.assertEqual(str(cm.exception), "Parameter value must be real.") y.value = np.array([1., 0.]) y.value = np.array([1j, 0.]) with self.assertRaises(Exception) as cm: z.value = np.array([1., 0.]) self.assertEqual(str(cm.exception), "Parameter value must be imaginary.")
def test_parameter_expressions(self): """Test that expressions with parameters are updated properly. """ x = Variable() y = Variable() x0 = Parameter() xSquared = x0 * x0 + 2 * x0 * (x - x0) # initial guess for x x0.value = 2 # make the constraint x**2 - y == 0 g = xSquared - y # set up the problem obj = abs(x - 1) prob = Problem(Minimize(obj), [g == 0]) prob.solve() x0.value = 1 prob.solve() self.assertAlmostEqual(g.value, 0) # Test multiplication. prob = Problem(Minimize(x0 * x), [x == 1]) x0.value = 2 prob.solve() x0.value = 1 prob.solve() self.assertAlmostEqual(prob.value, 1)
def test_parameters_successes(self): # Parameter names and dimensions p = Parameter(name='p') self.assertEqual(p.name(), "p") self.assertEqual(p.shape, tuple()) # Entry-wise constraints on parameter values. val = -np.ones((4, 3)) val[0, 0] = 2 p = Parameter((4, 3)) p.value = val # Initialize a parameter with a value; later, set it to None. p = Parameter(value=10) self.assertEqual(p.value, 10) p.value = 10 p.value = None self.assertEqual(p.value, None) # Test parameter representation. p = Parameter((4, 3), nonpos=True) self.assertEqual(repr(p), 'Parameter((4, 3), nonpos=True)') # Test valid diagonal parameter. p = Parameter((2, 2), diag=True) p.value = sp.csc_matrix(np.eye(2)) self.assertItemsAlmostEqual(p.value.todense(), np.eye(2), places=10)
def test_parameters(self): p = Parameter(name='p') self.assertEqual(p.name(), "p") self.assertEqual(p.size, (1,1)) p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = 1 self.assertEqual(str(cm.exception), "Invalid dimensions (1,1) for Parameter value.") val = -np.ones((4,3)) val[0,0] = 2 p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") p = Parameter(4, 3, sign="negative") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") # No error for unknown sign. p = Parameter(4, 3) p.value = val
def test_div_expression(self): # Vectors exp = self.x/2 self.assertEqual(exp.curvature, s.AFFINE) self.assertEqual(exp.sign, s.UNKNOWN) # self.assertEqual(exp.canonical_form[0].shape, (2, 1)) # self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), c.name() + " * " + self.x.name()) self.assertEqual(exp.shape, (2,)) with self.assertRaises(Exception) as cm: (self.x/[2, 2, 3]) print(cm.exception) self.assertRegexpMatches(str(cm.exception), "Incompatible shapes for division.*") c = Constant([3.0, 4.0, 12.0]) self.assertItemsAlmostEqual( (c / Constant([1.0, 2.0, 3.0])).value, np.array([3.0, 2.0, 4.0])) # Constant expressions. c = Constant(2) exp = c/(3 - 5) self.assertEqual(exp.curvature, s.CONSTANT) self.assertEqual(exp.shape, tuple()) self.assertEqual(exp.sign, s.NONPOS) # Parameters. p = Parameter(nonneg=True) exp = 2/p p.value = 2 self.assertEqual(exp.value, 1) rho = Parameter(nonneg=True) rho.value = 1 self.assertEqual(rho.sign, s.NONNEG) self.assertEqual(Constant(2).sign, s.NONNEG) self.assertEqual((Constant(2)/Constant(2)).sign, s.NONNEG) self.assertEqual((Constant(2)*rho).sign, s.NONNEG) self.assertEqual((rho/2).sign, s.NONNEG) # Broadcasting. x = cp.Variable((3, 3)) c = np.arange(1, 4)[:, None] expr = x / c self.assertEqual((3, 3), expr.shape) x.value = np.ones((3, 3)) A = np.ones((3, 3)) / c self.assertItemsAlmostEqual(A, expr.value) with self.assertRaises(Exception) as cm: (x/c[:, 0]) print(cm.exception) self.assertRegexpMatches(str(cm.exception), "Incompatible shapes for division.*")
def test_parameters_failures(self): p = Parameter(name='p') self.assertEqual(p.name(), "p") self.assertEqual(p.shape, tuple()) p = Parameter((4, 3), nonneg=True) with self.assertRaises(Exception) as cm: p.value = 1 self.assertEqual(str(cm.exception), "Invalid dimensions () for Parameter value.") val = -np.ones((4, 3)) val[0, 0] = 2 p = Parameter((4, 3), nonneg=True) with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Parameter value must be nonnegative.") p = Parameter((4, 3), nonpos=True) with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Parameter value must be nonpositive.") with self.assertRaises(Exception) as cm: p = Parameter(2, 1, nonpos=True, value=[2, 1]) self.assertEqual(str(cm.exception), "Parameter value must be nonpositive.") with self.assertRaises(Exception) as cm: p = Parameter((4, 3), nonneg=True, value=[1, 2]) self.assertEqual(str(cm.exception), "Invalid dimensions (2,) for Parameter value.") with self.assertRaises(Exception) as cm: p = Parameter((2, 2), diag=True, symmetric=True) self.assertEqual(str(cm.exception), "Cannot set more than one special attribute in Parameter.") # Boolean with self.assertRaises(Exception) as cm: p = Parameter((2, 2), boolean=True, value=[[1, 1], [1, -1]]) self.assertEqual(str(cm.exception), "Parameter value must be boolean.") # Integer with self.assertRaises(Exception) as cm: p = Parameter((2, 2), integer=True, value=[[1, 1.5], [1, -1]]) self.assertEqual(str(cm.exception), "Parameter value must be integer.") # Diag. with self.assertRaises(Exception) as cm: p = Parameter((2, 2), diag=True, value=[[1, 1], [1, -1]]) self.assertEqual(str(cm.exception), "Parameter value must be diagonal.") # Symmetric. with self.assertRaises(Exception) as cm: p = Parameter((2, 2), symmetric=True, value=[[1, 1], [-1, -1]]) self.assertEqual(str(cm.exception), "Parameter value must be symmetric.")
def test_parameter_problems(self): """Test problems with parameters. """ p1 = Parameter() p2 = Parameter(3, sign="negative") p3 = Parameter(4, 4, sign="positive") p = Problem(Maximize(p1*self.a), [self.a + p1 <= p2, self.b <= p3 + p3 + 2]) p1.value = 2 p2.value = -numpy.ones((3,1)) p3.value = numpy.ones((4, 4)) result = p.solve() self.assertAlmostEqual(result, -6)
def test_psd_nsd_parameters(self) -> None: # Test valid rank-deficeint PSD parameter. np.random.seed(42) a = np.random.normal(size=(100, 95)) a2 = a.dot(a.T) # This must be a PSD matrix. p = Parameter((100, 100), PSD=True) p.value = a2 self.assertItemsAlmostEqual(p.value, a2, places=10) # Test positive definite matrix with non-distinct eigenvalues m, n = 10, 5 A = np.random.randn( m, n) + 1j * np.random.randn(m, n) # a random complex matrix A = np.dot(A.T.conj(), A) # a random Hermitian positive definite matrix A = np.vstack([ np.hstack([np.real(A), -np.imag(A)]), np.hstack([np.imag(A), np.real(A)]) ]) p = Parameter(shape=(2 * n, 2 * n), PSD=True) p.value = A self.assertItemsAlmostEqual(p.value, A) # Test arithmetic. p = Parameter(shape=(2, 2), PSD=True) self.assertTrue((2 * p).is_psd()) self.assertTrue((p + p).is_psd()) self.assertTrue((-p).is_nsd()) self.assertTrue(((-2) * (-p)).is_psd()) # Test invalid PSD and NSD parameters n = 5 P = Parameter(shape=(n, n), PSD=True) N = Parameter(shape=(n, n), NSD=True) np.random.randn(0) U = np.random.randn(n, n) U = U @ U.T (evals, U) = np.linalg.eigh(U) # U is now an orthogonal matrix v1 = np.array([3, 2, 1, 1e-8, -1]) v2 = np.array([3, 2, 2, 1e-6, -1]) v3 = np.array([3, 2, 2, 1e-4, -1e-6]) v4 = np.array([-1, 3, 0, 0, 0]) vs = [v1, v2, v3, v4] for vi in vs: with self.assertRaises(Exception) as cm: P.value = U @ np.diag(vi) @ U.T self.assertEqual(str(cm.exception), "Parameter value must be positive semidefinite.") with self.assertRaises(Exception) as cm: N.value = -U @ np.diag(vi) @ U.T self.assertEqual(str(cm.exception), "Parameter value must be negative semidefinite.")
def test_parameters(self): p = Parameter(name='p') self.assertEqual(p.name(), "p") self.assertEqual(p.size, (1, 1)) p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = 1 self.assertEqual(str(cm.exception), "Invalid dimensions (1, 1) for Parameter value.") val = -np.ones((4, 3)) val[0, 0] = 2 p = Parameter(4, 3, sign="positive") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") p = Parameter(4, 3, sign="negative") with self.assertRaises(Exception) as cm: p.value = val self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") # No error for unknown sign. p = Parameter(4, 3) p.value = val # Initialize a parameter with a value. p = Parameter(value=10) self.assertEqual(p.value, 10) # Test assigning None. p.value = 10 p.value = None assert p.value is None with self.assertRaises(Exception) as cm: p = Parameter(2, 1, sign="negative", value=[2, 1]) self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") with self.assertRaises(Exception) as cm: p = Parameter(4, 3, sign="positive", value=[1, 2]) self.assertEqual(str(cm.exception), "Invalid dimensions (2, 1) for Parameter value.") # Test repr. p = Parameter(4, 3, sign="negative") self.assertEqual(repr(p), 'Parameter(4, 3, sign="NEGATIVE")')
def test_presolve_parameters(self): """Test presolve with parameters. """ # Test with parameters. gamma = Parameter(sign="positive") x = Variable() obj = Minimize(x) prob = Problem(obj, [gamma == 1, x >= 0]) gamma.value = 0 prob.solve(solver=s.SCS) self.assertEqual(prob.status, s.INFEASIBLE) gamma.value = 1 prob.solve(solver=s.CVXOPT) self.assertEqual(prob.status, s.OPTIMAL)
def test_div_expression(self): # Vectors exp = self.x/2 self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) self.assertEqual(exp.canonical_form[0].size, (2,1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), c.name() + " * " + self.x.name()) self.assertEqual(exp.size, (2,1)) with self.assertRaises(Exception) as cm: (self.x/[2,2,3]) print cm.exception self.assertEqual(str(cm.exception), "Can only divide by a scalar constant.") # Constant expressions. c = Constant(2) exp = c/(3 - 5) self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY) self.assertEqual(exp.size, (1,1)) self.assertEqual(exp.sign, u.Sign.NEGATIVE_KEY) # Parameters. p = Parameter(sign="positive") exp = 2/p p.value = 2 self.assertEquals(exp.value, 1)
def test_broadcast_mul(self) -> None: """Test multiply broadcasting. """ y = Parameter((3, 1)) z = Variable((1, 3)) y.value = np.arange(3)[:, None] z.value = (np.arange(3) - 1)[None, :] expr = cp.multiply(y, z) self.assertItemsAlmostEqual(expr.value, y.value * z.value) prob = cp.Problem(cp.Minimize(cp.sum(expr)), [z == z.value]) prob.solve(solver=cp.SCS) self.assertItemsAlmostEqual(expr.value, y.value * z.value) np.random.seed(0) m, n = 3, 4 A = np.random.rand(m, n) col_scale = Variable(n) with self.assertRaises(ValueError) as cm: cp.multiply(A, col_scale) self.assertEqual(str(cm.exception), "Cannot broadcast dimensions (3, 4) (4,)") col_scale = Variable([1, n]) C = cp.multiply(A, col_scale) self.assertEqual(C.shape, (m, n)) row_scale = Variable([m, 1]) R = cp.multiply(A, row_scale) self.assertEqual(R.shape, (m, n))
def test_div_expression(self): # Vectors exp = self.x / 2 self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY) self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY) self.assertEqual(exp.canonical_form[0].size, (2, 1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), c.name() + " * " + self.x.name()) self.assertEqual(exp.size, (2, 1)) with self.assertRaises(Exception) as cm: (self.x / [2, 2, 3]) print cm.exception self.assertEqual(str(cm.exception), "Can only divide by a scalar constant.") # Constant expressions. c = Constant(2) exp = c / (3 - 5) self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY) self.assertEqual(exp.size, (1, 1)) self.assertEqual(exp.sign, u.Sign.NEGATIVE_KEY) # Parameters. p = Parameter(sign="positive") exp = 2 / p p.value = 2 self.assertEquals(exp.value, 1)
def test_huber(self): # Valid. huber(self.x, 1) with self.assertRaises(Exception) as cm: huber(self.x, -1) self.assertEqual(str(cm.exception), "M must be a non-negative scalar constant.") with self.assertRaises(Exception) as cm: huber(self.x, [1,1]) self.assertEqual(str(cm.exception), "M must be a non-negative scalar constant.") # M parameter. M = Parameter(sign="positive") # Valid. huber(self.x, M) M.value = 1 self.assertAlmostEquals(huber(2, M).value, 3) # Invalid. M = Parameter(sign="negative") with self.assertRaises(Exception) as cm: huber(self.x, M) self.assertEqual(str(cm.exception), "M must be a non-negative scalar constant.")
def test_broadcast_add(self): """Test addition broadcasting. """ y = Parameter((3, 1)) z = Variable((1, 3)) y.value = np.arange(3)[:, None] z.value = (np.arange(3) - 1)[None, :] expr = y + z self.assertItemsAlmostEqual(expr.value, y.value + z.value) prob = cp.Problem(cp.Minimize(cp.sum(expr)), [z == z.value]) prob.solve() self.assertItemsAlmostEqual(expr.value, y.value + z.value) np.random.seed(0) m, n = 3, 4 A = np.random.rand(m, n) col_scale = Variable(n) with self.assertRaises(ValueError) as cm: A + col_scale self.assertEqual(str(cm.exception), "Cannot broadcast dimensions (3, 4) (4,)") col_scale = Variable([1, n]) C = A + col_scale self.assertEqual(C.shape, (m, n)) row_scale = Variable([m, 1]) R = A + row_scale self.assertEqual(R.shape, (m, n))
def test_1D_array(self): """Test NumPy 1D arrays as constants. """ c = np.array([1, 2]) p = Parameter(2) p.value = [1, 1] self.assertEquals((c * p).value, 3) self.assertEqual((c * self.x).size, (1, 1))
def test_1D_array(self): """Test NumPy 1D arrays as constants. """ c = np.array([1, 2]) p = Parameter(2) p.value = [1, 1] self.assertEqual((c*p).value, 3) self.assertEqual((c*self.x).size, (1, 1))
def test_1D_array(self): """Test NumPy 1D arrays as constants. """ c = np.array([1, 2]) p = Parameter(2) p.value = [1, 1] self.assertEqual((c @ p).value, 3) self.assertEqual((c @ self.x).shape, tuple())
def test_div_expression(self): # Vectors exp = self.x / 2 self.assertEqual(exp.curvature, s.AFFINE) self.assertEqual(exp.sign, s.UNKNOWN) self.assertEqual(exp.canonical_form[0].size, (2, 1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), c.name() + " * " + self.x.name()) self.assertEqual(exp.size, (2, 1)) with self.assertRaises(Exception) as cm: (self.x / [2, 2, 3]) print(cm.exception) self.assertEqual(str(cm.exception), "Can only divide by a scalar constant.") # Constant expressions. c = Constant(2) exp = c / (3 - 5) self.assertEqual(exp.curvature, s.CONSTANT) self.assertEqual(exp.size, (1, 1)) self.assertEqual(exp.sign, s.NEGATIVE) # Parameters. p = Parameter(sign="positive") exp = 2 / p p.value = 2 self.assertEqual(exp.value, 1) rho = Parameter(sign="positive") rho.value = 1 self.assertEqual(rho.sign, s.POSITIVE) self.assertEqual(Constant(2).sign, s.POSITIVE) self.assertEqual((Constant(2) / Constant(2)).sign, s.POSITIVE) self.assertEqual((Constant(2) * rho).sign, s.POSITIVE) self.assertEqual((rho / 2).sign, s.POSITIVE)
def test_div_expression(self): # Vectors exp = self.x/2 self.assertEqual(exp.curvature, s.AFFINE) self.assertEqual(exp.sign, s.UNKNOWN) self.assertEqual(exp.canonical_form[0].size, (2, 1)) self.assertEqual(exp.canonical_form[1], []) # self.assertEqual(exp.name(), c.name() + " * " + self.x.name()) self.assertEqual(exp.size, (2, 1)) with self.assertRaises(Exception) as cm: (self.x/[2, 2, 3]) print(cm.exception) self.assertEqual(str(cm.exception), "Can only divide by a scalar constant.") # Constant expressions. c = Constant(2) exp = c/(3 - 5) self.assertEqual(exp.curvature, s.CONSTANT) self.assertEqual(exp.size, (1, 1)) self.assertEqual(exp.sign, s.NEGATIVE) # Parameters. p = Parameter(sign="positive") exp = 2/p p.value = 2 self.assertEqual(exp.value, 1) rho = Parameter(sign="positive") rho.value = 1 self.assertEqual(rho.sign, s.POSITIVE) self.assertEqual(Constant(2).sign, s.POSITIVE) self.assertEqual((Constant(2)/Constant(2)).sign, s.POSITIVE) self.assertEqual((Constant(2)*rho).sign, s.POSITIVE) self.assertEqual((rho/2).sign, s.POSITIVE)
def test_partial_optimize_params(self): """Test partial optimize with parameters. """ x, y = Variable(1), Variable(1) gamma = Parameter() # Solve the (simple) two-stage problem by "combining" the two stages (i.e., by solving a single linear program) p1 = Problem(Minimize(x+y), [x+y>=gamma, y>=4, x>=5]) gamma.value = 3 p1.solve() # Solve the two-stage problem via partial_optimize p2 = Problem(Minimize(y), [x+y>=gamma, y>=4]) g = partial_optimize(p2, [y], [x]) p3 = Problem(Minimize(x+g), [x>=5]) p3.solve() self.assertAlmostEqual(p1.value, p3.value)
def test_1D_array(self): """Test NumPy 1D arrays as constants. """ c = np.array([1,2]) p = Parameter(2) with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") # Trigger a warning. Constant(c) self.x + c p.value = c # Verify some things self.assertEqual(len(w), 3) for warning in w: self.assertEqual(str(warning.message), "NumPy 1D arrays are treated as column vectors.")
def test_huber(self): # Valid. huber(self.x, 1) with self.assertRaises(Exception) as cm: huber(self.x, -1) self.assertEqual(str(cm.exception), "M must be a non-negative scalar constant.") with self.assertRaises(Exception) as cm: huber(self.x, [1,1]) self.assertEqual(str(cm.exception), "M must be a non-negative scalar constant.") # M parameter. M = Parameter(sign="positive") # Valid. huber(self.x, M) M.value = 1 self.assertAlmostEquals(huber(2, M).value, 3) # Invalid. M = Parameter(sign="negative") with self.assertRaises(Exception) as cm: huber(self.x, M) self.assertEqual(str(cm.exception), "M must be a non-negative scalar constant.") # Test copy with args=None atom = huber(self.x, 2) copy = atom.copy() self.assertTrue(type(copy) is type(atom)) # A new object is constructed, so copy.args == atom.args but copy.args # is not atom.args. self.assertEqual(copy.args, atom.args) self.assertFalse(copy.args is atom.args) # As get_data() returns a Constant, we have to check the value self.assertEqual(copy.get_data().value, atom.get_data().value) # Test copy with new args copy = atom.copy(args=[self.y]) self.assertTrue(type(copy) is type(atom)) self.assertTrue(copy.args[0] is self.y) self.assertEqual(copy.get_data().value, atom.get_data().value)
def test_huber(self): # Valid. cp.huber(self.x, 1) with self.assertRaises(Exception) as cm: cp.huber(self.x, -1) self.assertEqual(str(cm.exception), "M must be a non-negative scalar constant.") with self.assertRaises(Exception) as cm: cp.huber(self.x, [1, 1]) self.assertEqual(str(cm.exception), "M must be a non-negative scalar constant.") # M parameter. M = Parameter(nonneg=True) # Valid. cp.huber(self.x, M) M.value = 1 self.assertAlmostEqual(cp.huber(2, M).value, 3) # Invalid. M = Parameter(nonpos=True) with self.assertRaises(Exception) as cm: cp.huber(self.x, M) self.assertEqual(str(cm.exception), "M must be a non-negative scalar constant.") # Test copy with args=None atom = cp.huber(self.x, 2) copy = atom.copy() self.assertTrue(type(copy) is type(atom)) # A new object is constructed, so copy.args == atom.args but copy.args # is not atom.args. self.assertEqual(copy.args, atom.args) self.assertFalse(copy.args is atom.args) # As get_data() returns a Constant, we have to check the value self.assertEqual(copy.get_data()[0].value, atom.get_data()[0].value) # Test copy with new args copy = atom.copy(args=[self.y]) self.assertTrue(type(copy) is type(atom)) self.assertTrue(copy.args[0] is self.y) self.assertEqual(copy.get_data()[0].value, atom.get_data()[0].value)
def test_get_coefficients(self): """Test the get_coefficients function. """ size = (5, 4) # Eye x = create_var(size) coeffs = get_coefficients(x) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(id_, x.data) self.assertItemsAlmostEqual(mat.todense(), sp.eye(20).todense()) # Eye with scalar mult. x = create_var(size) A = create_const(5, (1, 1)) coeffs = get_coefficients(mul_expr(A, x, size)) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertItemsAlmostEqual(mat.todense(), 5 * sp.eye(20).todense()) # Promoted x = create_var((1, 1)) coeffs = get_coefficients(promote(x, size)) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (20, 1)) self.assertItemsAlmostEqual(mat, np.ones((20, 1))) # Normal size = (5, 5) x = create_var((5, 1)) A = create_const(np.ones(size), size) coeffs = get_coefficients(mul_expr(A, x, (5, 1))) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (5, 5)) self.assertItemsAlmostEqual(mat.todense(), A.data) # Blocks size = (5, 5) x = create_var(size) A = create_const(np.ones(size), size) coeffs = get_coefficients(mul_expr(A, x, size)) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (25, 25)) self.assertItemsAlmostEqual( mat.todense(), sp.block_diag(5 * [np.ones(size)]).todense()) # Scalar constant size = (1, 1) A = create_const(5, size) coeffs = get_coefficients(A) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(intf.size(mat), (1, 1)) self.assertEqual(mat, 5) # Dense constant size = (5, 4) A = create_const(np.ones(size), size) coeffs = get_coefficients(A) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (size[0] * size[1], 1)) self.assertItemsAlmostEqual(mat, np.ones(size)) # Sparse constant size = (5, 5) A = create_const(sp.eye(5), size) coeffs = get_coefficients(A) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (size[0] * size[1], 1)) self.assertItemsAlmostEqual(mat, sp.eye(5).todense()) # Parameter size = (5, 4) param = Parameter(*size) param.value = np.ones(size) A = create_param(param, size) coeffs = get_coefficients(A) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (size[0] * size[1], 1)) self.assertItemsAlmostEqual(mat, param.value)
def test_index(self): """Test the get_coefficients function for index. """ size = (5, 4) # Eye key = (slice(0,2,None), slice(0,2,None)) x = create_var(size) expr = index(x, (2, 2), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(id_, x.data) self.assertEqual(mat.shape, (4, 20)) test_mat = np.mat(range(20)).T self.assertItemsAlmostEqual((mat*test_mat).reshape((2, 2), order='F'), test_mat.reshape(size, order='F')[key]) # Eye with scalar mult. key = (slice(0,2,None), slice(0,2,None)) x = create_var(size) A = create_const(5, (1, 1)) expr = mul_expr(A, x, size) expr = index(expr, (2, 2), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] test_mat = np.mat(range(20)).T self.assertItemsAlmostEqual((mat*test_mat).reshape((2, 2), order='F'), 5*test_mat.reshape(size, order='F')[key]) # Promoted key = (slice(0,2,None), slice(0,2,None)) x = create_var((1, 1)) value = np.array(range(20)).reshape(size) A = create_const(value, size) prom_x = promote(x, (size[1], 1)) expr = mul_expr(A, diag_vec(prom_x), size) expr = index(expr, (2, 2), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (4, 1)) self.assertItemsAlmostEqual(mat, value[key]) # Normal size = (5, 5) key = (slice(0,2,None), slice(0,1,None)) x = create_var((5, 1)) A = create_const(np.ones(size), size) expr = mul_expr(A, x, (5, 1)) expr = index(expr, (2, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (2, 5)) self.assertItemsAlmostEqual(mat.todense(), A.data[slice(0,2,None)]) # Blocks size = (5, 5) key = (slice(0,2,None), slice(0,2,None)) x = create_var(size) value = np.array(range(25)).reshape(size) A = create_const(value, size) expr = mul_expr(A, x, size) expr = index(expr, (2, 2), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (4, 25)) test_mat = np.mat(range(25)).T self.assertItemsAlmostEqual((mat*test_mat).reshape((2, 2), order='F'), (A.data*test_mat.reshape(size, order='F'))[key]) # Scalar constant size = (1, 1) A = create_const(5, size) key = (slice(0,1,None), slice(0,1,None)) expr = index(A, (1, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(intf.size(mat), (1, 1)) self.assertEqual(mat, 5) # Dense constant size = (5, 4) key = (slice(0,2,None), slice(0,1,None)) value = np.array(range(20)).reshape(size) A = create_const(value, size) expr = index(A, (2, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (2, 1)) self.assertItemsAlmostEqual(mat, value[key]) # Sparse constant size = (5, 5) key = (slice(0,2,None), slice(0,1,None)) A = create_const(sp.eye(5), size) expr = index(A, (2, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (2, 1)) self.assertItemsAlmostEqual(mat, sp.eye(5).todense()[key]) # Parameter size = (5, 4) key = (slice(0,2,None), slice(0,1,None)) param = Parameter(*size) value = np.array(range(20)).reshape(size) param.value = value A = create_param(param, size) expr = index(A, (2, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (2, 1)) self.assertItemsAlmostEqual(mat, param.value[key])
def test_get_coefficients(self): """Test the get_coefficients function. """ size = (5, 4) # Eye x = create_var(size) coeffs = get_coefficients(x) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(id_, x.data) self.assertItemsAlmostEqual(mat.todense(), sp.eye(20).todense()) # Eye with scalar mult. x = create_var(size) A = create_const(5, (1, 1)) coeffs = get_coefficients(mul_expr(A, x, size)) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertItemsAlmostEqual(mat.todense(), 5*sp.eye(20).todense()) # Promoted x = create_var((1, 1)) coeffs = get_coefficients(promote(x, size)) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (20, 1)) self.assertItemsAlmostEqual(mat, np.ones((20, 1))) # Normal size = (5, 5) x = create_var((5, 1)) A = create_const(np.ones(size), size) coeffs = get_coefficients(mul_expr(A, x, (5, 1))) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (5, 5)) self.assertItemsAlmostEqual(mat.todense(), A.data) # Blocks size = (5, 5) x = create_var(size) A = create_const(np.ones(size), size) coeffs = get_coefficients(mul_expr(A, x, size)) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (25, 25)) self.assertItemsAlmostEqual(mat.todense(), sp.block_diag(5*[np.ones(size)]).todense()) # Scalar constant size = (1, 1) A = create_const(5, size) coeffs = get_coefficients(A) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(intf.size(mat), (1, 1)) self.assertEqual(mat, 5) # Dense constant size = (5, 4) A = create_const(np.ones(size), size) coeffs = get_coefficients(A) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (size[0]*size[1], 1)) self.assertItemsAlmostEqual(mat, np.ones(size)) # Sparse constant size = (5, 5) A = create_const(sp.eye(5), size) coeffs = get_coefficients(A) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (size[0]*size[1], 1)) self.assertItemsAlmostEqual(mat, sp.eye(5).todense()) # Parameter size = (5, 4) param = Parameter(*size) param.value = np.ones(size) A = create_param(param, size) coeffs = get_coefficients(A) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (size[0]*size[1], 1)) self.assertItemsAlmostEqual(mat, param.value)
def test_index(self): """Test the get_coefficients function for index. """ size = (5, 4) # Eye key = (slice(0, 2, None), slice(0, 2, None)) x = create_var(size) expr = index(x, (2, 2), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(id_, x.data) self.assertEqual(mat.shape, (4, 20)) test_mat = np.mat(range(20)).T self.assertItemsAlmostEqual((mat * test_mat).reshape((2, 2), order='F'), test_mat.reshape(size, order='F')[key]) # Eye with scalar mult. key = (slice(0, 2, None), slice(0, 2, None)) x = create_var(size) A = create_const(5, (1, 1)) expr = mul_expr(A, x, size) expr = index(expr, (2, 2), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] test_mat = np.mat(range(20)).T self.assertItemsAlmostEqual((mat * test_mat).reshape( (2, 2), order='F'), 5 * test_mat.reshape(size, order='F')[key]) # Promoted key = (slice(0, 2, None), slice(0, 2, None)) x = create_var((1, 1)) value = np.array(range(20)).reshape(size) A = create_const(value, size) prom_x = promote(x, (size[1], 1)) expr = mul_expr(A, diag_vec(prom_x), size) expr = index(expr, (2, 2), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (4, 1)) self.assertItemsAlmostEqual(mat, value[key]) # Normal size = (5, 5) key = (slice(0, 2, None), slice(0, 1, None)) x = create_var((5, 1)) A = create_const(np.ones(size), size) expr = mul_expr(A, x, (5, 1)) expr = index(expr, (2, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (2, 5)) self.assertItemsAlmostEqual(mat.todense(), A.data[slice(0, 2, None)]) # Blocks size = (5, 5) key = (slice(0, 2, None), slice(0, 2, None)) x = create_var(size) value = np.array(range(25)).reshape(size) A = create_const(value, size) expr = mul_expr(A, x, size) expr = index(expr, (2, 2), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (4, 25)) test_mat = np.mat(range(25)).T self.assertItemsAlmostEqual( (mat * test_mat).reshape((2, 2), order='F'), (A.data * test_mat.reshape(size, order='F'))[key]) # Scalar constant size = (1, 1) A = create_const(5, size) key = (slice(0, 1, None), slice(0, 1, None)) expr = index(A, (1, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(intf.size(mat), (1, 1)) self.assertEqual(mat, 5) # Dense constant size = (5, 4) key = (slice(0, 2, None), slice(0, 1, None)) value = np.array(range(20)).reshape(size) A = create_const(value, size) expr = index(A, (2, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (2, 1)) self.assertItemsAlmostEqual(mat, value[key]) # Sparse constant size = (5, 5) key = (slice(0, 2, None), slice(0, 1, None)) A = create_const(sp.eye(5), size) expr = index(A, (2, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (2, 1)) self.assertItemsAlmostEqual(mat, sp.eye(5).todense()[key]) # Parameter size = (5, 4) key = (slice(0, 2, None), slice(0, 1, None)) param = Parameter(*size) value = np.array(range(20)).reshape(size) param.value = value A = create_param(param, size) expr = index(A, (2, 1), key) coeffs = get_coefficients(expr) assert len(coeffs) == 1 id_, mat = coeffs[0] self.assertEqual(mat.shape, (2, 1)) self.assertItemsAlmostEqual(mat, param.value[key])
def test_readme_examples(self): import cvxopt import numpy # Problem data. m = 30 n = 20 A = cvxopt.normal(m,n) b = cvxopt.normal(m) # Construct the problem. x = Variable(n) objective = Minimize(sum(square(A*x - b))) constraints = [0 <= x, x <= 1] p = Problem(objective, constraints) # The optimal objective is returned by p.solve(). result = p.solve() # The optimal value for x is stored in x.value. print x.value # The optimal Lagrange multiplier for a constraint # is stored in constraint.dual_value. print constraints[0].dual_value #################################################### # Scalar variable. a = Variable() # Column vector variable of length 5. x = Variable(5) # Matrix variable with 4 rows and 7 columns. A = Variable(4,7) #################################################### # Positive scalar parameter. m = Parameter(sign="positive") # Column vector parameter with unknown sign (by default). c = Parameter(5) # Matrix parameter with negative entries. G = Parameter(4,7,sign="negative") # Assigns a constant value to G. G.value = -numpy.ones((4,7)) # Raises an error for assigning a value with invalid sign. with self.assertRaises(Exception) as cm: G.value = numpy.ones((4,7)) self.assertEqual(str(cm.exception), "Invalid sign for Parameter value.") #################################################### a = Variable() x = Variable(5) # expr is an Expression object after each assignment. expr = 2*x expr = expr - a expr = sum(expr) + norm2(x) #################################################### import numpy as np import cvxopt from multiprocessing import Pool # Problem data. n = 10 m = 5 A = cvxopt.normal(n,m) b = cvxopt.normal(n) gamma = Parameter(sign="positive") # Construct the problem. x = Variable(m) objective = Minimize(sum(square(A*x - b)) + gamma*norm1(x)) p = Problem(objective) # Assign a value to gamma and find the optimal x. def get_x(gamma_value): gamma.value = gamma_value result = p.solve() return x.value gammas = np.logspace(-1, 2, num=2) # Serial computation. x_values = [get_x(value) for value in gammas] #################################################### n = 10 mu = cvxopt.normal(1, n) sigma = cvxopt.normal(n,n) sigma = sigma.T*sigma gamma = Parameter(sign="positive") gamma.value = 1 x = Variable(n) # Constants: # mu is the vector of expected returns. # sigma is the covariance matrix. # gamma is a Parameter that trades off risk and return. # Variables: # x is a vector of stock holdings as fractions of total assets. expected_return = mu*x risk = quad_form(x, sigma) objective = Maximize(expected_return - gamma*risk) p = Problem(objective, [sum(x) == 1]) result = p.solve() # The optimal expected return. print expected_return.value # The optimal risk. print risk.value # # Risk return tradeoff curve # def test_risk_return_tradeoff(self): # from math import sqrt # from cvxopt import matrix # from cvxopt.blas import dot # from cvxopt.solvers import qp, options # import scipy # n = 4 # S = matrix( [[ 4e-2, 6e-3, -4e-3, 0.0 ], # [ 6e-3, 1e-2, 0.0, 0.0 ], # [-4e-3, 0.0, 2.5e-3, 0.0 ], # [ 0.0, 0.0, 0.0, 0.0 ]] ) # pbar = matrix([.12, .10, .07, .03]) # N = 100 # # CVXPY # Sroot = numpy.asmatrix(scipy.linalg.sqrtm(S)) # x = Variable(n, name='x') # mu = Parameter(name='mu') # mu.value = 1 # TODO Parameter("positive") # objective = Minimize(-pbar*x + mu*quad_over_lin(Sroot*x,1)) # constraints = [sum(x) == 1, x >= 0] # p = Problem(objective, constraints) # mus = [ 10**(5.0*t/N-1.0) for t in range(N) ] # xs = [] # for mu_val in mus: # mu.value = mu_val # p.solve() # xs.append(x.value) # returns = [ dot(pbar,x) for x in xs ] # risks = [ sqrt(dot(x, S*x)) for x in xs ] # # QP solver
def test_parameter_promotion(self): a = Parameter() exp = [[1,2],[3,4]]*a a.value = 2 assert not (exp.value - 2*numpy.array([[1,2],[3,4]]).T).any()
def test_parameter_promotion(self): a = Parameter() exp = [[1, 2], [3, 4]] * a a.value = 2 assert not (exp.value - 2 * numpy.array([[1, 2], [3, 4]]).T).any()