Esempio n. 1
0
    def test_partial_optimize_numeric_fn(self):
        x, y = Variable(), Variable()
        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 = partial_optimize(p2, [y], [x])
        x.value = xval
        y.value = 42
        constr[0].dual_variables[0].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 = partial_optimize(p2, [], [x, y])
        x.value = xval
        y.value = 42
        p2.constraints[0].dual_variables[0].value = 42
        result = g.value
        self.assertAlmostEqual(result, y.value)
        self.assertAlmostEqual(y.value, 42)
        self.assertAlmostEqual(p2.constraints[0].dual_value, 42)
Esempio n. 2
0
    def test_variable(self):
        """Test the Variable class.
        """
        x = Variable(2, complex=False)
        y = Variable(2, complex=True)
        z = Variable(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), "Variable 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),
                         "Variable value must be imaginary.")
Esempio n. 3
0
    def test_maximum(self) -> None:
        """Test domain for maximum.
        """
        b = Variable()
        expr = cp.maximum(self.a, b)
        self.a.value = 2
        b.value = 4
        self.assertAlmostEqual(expr.grad[self.a], 0)
        self.assertAlmostEqual(expr.grad[b], 1)

        self.a.value = 3
        b.value = 0
        self.assertAlmostEqual(expr.grad[self.a], 1)
        self.assertAlmostEqual(expr.grad[b], 0)

        self.a.value = -1
        b.value = 2
        self.assertAlmostEqual(expr.grad[self.a], 0)
        self.assertAlmostEqual(expr.grad[b], 1)

        y = Variable(2)
        expr = cp.maximum(self.x, y)
        self.x.value = [3, 4]
        y.value = [5, -5]
        val = np.zeros((2, 2)) + np.diag([0, 1])
        self.assertItemsAlmostEqual(expr.grad[self.x].toarray(), val)
        val = np.zeros((2, 2)) + np.diag([1, 0])
        self.assertItemsAlmostEqual(expr.grad[y].toarray(), val)

        expr = cp.maximum(self.x, y)
        self.x.value = [-1e-9, 4]
        y.value = [1, 4]
        val = np.zeros((2, 2)) + np.diag([0, 1])
        self.assertItemsAlmostEqual(expr.grad[self.x].toarray(), val)
        val = np.zeros((2, 2)) + np.diag([1, 0])
        self.assertItemsAlmostEqual(expr.grad[y].toarray(), val)

        expr = cp.maximum(self.A, self.B)
        self.A.value = [[1, 2], [3, 4]]
        self.B.value = [[5, 1], [3, 2.3]]
        val = np.zeros((4, 4)) + np.diag([0, 1, 1, 1])
        self.assertItemsAlmostEqual(expr.grad[self.A].toarray(), val)
        val = np.zeros((4, 4)) + np.diag([1, 0, 0, 0])
        self.assertItemsAlmostEqual(expr.grad[self.B].toarray(), val)

        # cummax
        expr = cp.cummax(self.x)
        self.x.value = [2, 1]
        val = np.zeros((2, 2))
        val[0, 0] = 1
        self.assertItemsAlmostEqual(expr.grad[self.x].toarray(), val)

        expr = cp.cummax(self.x[:, None], axis=1)
        self.x.value = [2, 1]
        val = np.eye(2)
        self.assertItemsAlmostEqual(expr.grad[self.x].toarray(), val)
Esempio n. 4
0
    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].toarray(),
                                    1.0 / 2 * np.eye(2))

        mat = np.array([[1, 2], [3, 5]])
        self.A.value = mat.T.dot(mat)
        val = np.linalg.inv(self.A.value).T
        self.assertItemsAlmostEqual(expr.grad[self.A].toarray(), val)

        self.A.value = np.zeros((2, 2))
        self.assertAlmostEqual(expr.grad[self.A], None)

        self.A.value = -np.array([[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].toarray(), val)
Esempio n. 5
0
 def test_nonneg_constraints_end_user(self):
     x = Variable(shape=(2,), name='x')
     objective = Minimize(-4 * x[0] - 5 * x[1])
     constr_expr = hstack([3 - (2 * x[0] + x[1]),
                           3 - (x[0] + 2 * x[1]),
                           x[0],
                           x[1]])
     constraints = [NonNeg(constr_expr)]
     expect_dual_var = np.array([1, 2, 0, 0])
     con_pairs = [(constraints[0], expect_dual_var)]
     var_pairs = [(x, np.array([1, 1]))]
     obj_pair = (objective, -9)
     # Check that the problem compiles correctly, and that
     # dual variables are recovered correctly.
     sth = SolverTestHelper(obj_pair, var_pairs, con_pairs)
     sth.solve(solver='ECOS')
     sth.verify_primal_values(places=4)
     sth.verify_dual_values(places=4)
     # Check that violations are computed properly
     expr_val = constr_expr.value  # want >= 0
     expr_val[expr_val >= 0] = 0
     manual_viol = np.linalg.norm(expr_val, ord=2)
     reported_viol = constraints[0].violation()
     self.assertAlmostEqual(manual_viol, reported_viol, places=4)
     # Check that residuals are computed properly
     x.value = np.array([-1, -2])
     expr_val = constraints[0].residual
     self.assertItemsAlmostEqual(
         expr_val,  # first two constraints are feasible.
         np.array([0, 0, 1, 2])
     )
     # Run a second check for violations
     reported_viol = constraints[0].violation()
     expected_viol = np.sqrt(5.0)
     self.assertAlmostEqual(reported_viol, expected_viol)
Esempio n. 6
0
 def test_pownd_constraint(self) -> None:
     n = 4
     W, z = Variable(n), Variable()
     np.random.seed(0)
     alpha = 0.5 + np.random.rand(n)
     alpha /= np.sum(alpha)
     with self.assertRaises(ValueError):
         # entries don't sum to one
         con = PowConeND(W, z, alpha + 0.01)
     with self.assertRaises(ValueError):
         # shapes don't match exactly
         con = PowConeND(W, z, alpha.reshape((n, 1)))
     with self.assertRaises(ValueError):
         # wrong axis
         con = PowConeND(reshape_atom(W, (n, 1)),
                         z,
                         alpha.reshape((n, 1)),
                         axis=1)
     # Compute a violation
     con = PowConeND(W, z, alpha)
     W0 = 0.1 + np.random.rand(n)
     z0 = np.prod(np.power(W0, alpha)) + 0.05
     W.value, z.value = W0, z0
     viol = con.violation()
     self.assertGreaterEqual(viol, 0.01)
     self.assertLessEqual(viol, 0.06)
    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))
Esempio n. 8
0
    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))
Esempio n. 9
0
    def test_minimum(self):
        """Test domain for minimum.
        """
        b = Variable()
        expr = minimum(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 = minimum(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].toarray(), val)
        val = np.zeros((2, 2)) + np.diag([0, 1])
        self.assertItemsAlmostEqual(expr.grad[y].toarray(), val)

        expr = minimum(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].toarray(), val)
        val = np.zeros((2, 2)) + np.diag([0, 0])
        self.assertItemsAlmostEqual(expr.grad[y].toarray(), val)

        expr = minimum(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).ravel(order='F')
        val = np.zeros((4, 4)) + np.diag([1, 0, 1, 0])
        self.assertItemsAlmostEqual(expr.grad[self.A].toarray(), val)
        val = np.zeros((4, 4)) + np.diag([0, 1, 0, 1])
        self.assertItemsAlmostEqual(expr.grad[self.B].toarray(), val)
Esempio n. 10
0
 def test_vec_to_upper_tri(self) -> None:
     from cvxpy.atoms.affine.upper_tri import vec_to_upper_tri
     x = Variable(shape=(3, ))
     X = vec_to_upper_tri(x)
     x.value = np.array([1, 2, 3])
     actual = X.value
     expect = np.array([[1, 2], [0, 3]])
     assert np.allclose(actual, expect)
     y = Variable(shape=(1, ))
     y.value = np.array([4])
     Y = vec_to_upper_tri(y, strict=True)
     actual = Y.value
     expect = np.array([[0, 4], [0, 0]])
     assert np.allclose(actual, expect)
     A_expect = np.array([[0, 11, 12, 13], [0, 0, 16, 17], [0, 0, 0, 21],
                          [0, 0, 0, 0]])
     a = np.array([11, 12, 13, 16, 17, 21])
     A_actual = vec_to_upper_tri(a, strict=True).value
     assert np.allclose(A_actual, A_expect)
Esempio n. 11
0
    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].toarray(), val)
        val = np.zeros((2, 2)) + np.diag([1 - 3 / 5, 1 - 4 / 8])
        self.assertItemsAlmostEqual(expr.grad[y].toarray(), 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).ravel(order='F')
        val = np.zeros((4, 4)) + np.diag(np.log(div))
        self.assertItemsAlmostEqual(expr.grad[self.A].toarray(), val)
        val = np.zeros((4, 4)) + np.diag(1 - div)
        self.assertItemsAlmostEqual(expr.grad[self.B].toarray(), val)
Esempio n. 12
0
    def test_affine(self):
        """Test grad for affine atoms.
        """
        expr = -self.a
        self.a.value = 2
        self.assertAlmostEqual(expr.grad[self.a], -1)

        expr = 2 * self.a
        self.a.value = 2
        self.assertAlmostEqual(expr.grad[self.a], 2)

        expr = self.a / 2
        self.a.value = 2
        self.assertAlmostEqual(expr.grad[self.a], 0.5)

        expr = -(self.x)
        self.x.value = [3, 4]
        val = np.zeros((2, 2)) - np.diag([1, 1])
        self.assertItemsAlmostEqual(expr.grad[self.x].toarray(), 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].toarray(), 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].toarray(), val)

        z = Variable(3)
        expr = hstack([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].toarray(), val)

        val = np.zeros((3, 5))
        val[:, 2:] = np.eye(3)
        self.assertItemsAlmostEqual(expr.grad[z].toarray(), val)

        # cumsum
        expr = cumsum(self.x)
        self.x.value = [1, 2]
        val = np.ones((2, 2))
        val[1, 0] = 0
        self.assertItemsAlmostEqual(expr.grad[self.x].toarray(), val)

        expr = cumsum(self.x[:, None], axis=1)
        self.x.value = [1, 2]
        val = np.eye(2)
        self.assertItemsAlmostEqual(expr.grad[self.x].toarray(), val)
Esempio n. 13
0
    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,) 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 = Variable(nonneg=True)
        with self.assertRaises(Exception) as cm:
            x.value = -2
        self.assertEqual(str(cm.exception),
                         "Variable value must be nonnegative.")
Esempio n. 14
0
 def test_pow3d_constraint(self) -> None:
     n = 3
     np.random.seed(0)
     alpha = 0.275
     x, y, z = Variable(n), Variable(n), Variable(n)
     con = PowCone3D(x, y, z, alpha)
     # check violation against feasible values
     x0, y0 = 0.1 + np.random.rand(n), 0.1 + np.random.rand(n)
     z0 = x0**alpha * y0**(1 - alpha)
     z0[1] *= -1
     x.value, y.value, z.value = x0, y0, z0
     viol = con.residual()
     self.assertLessEqual(viol, 1e-7)
     # check violation against infeasible values
     x1 = x0.copy()
     x1[0] *= -0.9
     x.value = x1
     viol = con.residual()
     self.assertGreaterEqual(viol, 0.99 * abs(x1[0]))
     # check invalid constraint data
     with self.assertRaises(ValueError):
         con = PowCone3D(x, y, z, 1.001)
     with self.assertRaises(ValueError):
         con = PowCone3D(x, y, z, -0.00001)