Example #1
0
    def test_power(self):
        x = Variable(3)
        y = Variable(3)
        self.assertFalse(x.is_constant())
        self.assertTrue(x.is_affine())
        self.assertTrue(x.is_quadratic())

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            s = power(x.T*y, 0)
            self.assertTrue(s.is_constant())
            self.assertTrue(s.is_affine())
            self.assertTrue(s.is_quadratic())

        t = power(x-y, 1)
        self.assertFalse(t.is_constant())
        self.assertTrue(t.is_affine())
        self.assertTrue(t.is_quadratic())

        u = power(x+2*y, 2)
        self.assertFalse(u.is_constant())
        self.assertFalse(u.is_affine())
        self.assertTrue(u.is_quadratic())
        self.assertTrue(u.is_dcp())

        w = (x+2*y)**2
        self.assertFalse(w.is_constant())
        self.assertFalse(w.is_affine())
        self.assertTrue(w.is_quadratic())
        self.assertTrue(w.is_dcp())
Example #2
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, 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.")
Example #3
0
    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)
Example #4
0
    def test_consistency(self):
        """Test that variables and constraints keep a consistent order.
        """
        import itertools
        num_solves = 4
        vars_lists = []
        ineqs_lists = []
        for k in range(num_solves):
            sum = 0
            constraints = []
            for i in range(100):
                var = Variable(name=str(i))
                sum += var
                constraints.append(var >= i)
            obj = Minimize(sum)
            p = Problem(obj, constraints)
            objective, constr_map, dims = p.canonicalize()
            all_ineq = itertools.chain(constr_map[s.EQ], constr_map[s.INEQ])
            var_info = p._get_var_offsets(objective, all_ineq)
            sorted_vars, var_offsets, x_length = var_info
            vars_lists.append([int(v.name()) for v in sorted_vars])
            ineqs_lists.append(constr_map[s.INEQ])

        # Verify order of variables is consistent.
        for i in range(num_solves):
            self.assertEqual(range(100), vars_lists[i])
        for i in range(num_solves):
            for idx, constr in enumerate(ineqs_lists[i]):
                var = constr.variables()[0]
                self.assertEqual(idx, int(var.name()))
Example #5
0
    def test_scipy_sparse(self):
        """Test scipy sparse matrices."""
        # Constants.
        A = numpy.matrix( numpy.arange(8).reshape((4,2)) )
        A = sp.csc_matrix(A)
        A = sp.eye(2).tocsc()
        key = (slice(0, 1, None), slice(None, None, None))
        Aidx = intf.index(A, (slice(0, 2, None), slice(None, None, None)))
        Aidx = intf.index(Aidx, key)
        self.assertEqual(Aidx.shape, (1, 2))
        self.assertEqual(Aidx[0,0], 1)
        self.assertEqual(Aidx[0,1], 0)

        # Linear ops.
        var = Variable(4, 2)
        A = numpy.matrix( numpy.arange(8).reshape((4,2)) )
        A = sp.csc_matrix(A)
        B = sp.hstack([A, A])
        self.assertExpression(var + A, (4, 2))
        self.assertExpression(A + var, (4, 2))
        self.assertExpression(B * var, (4, 2))
        self.assertExpression(var - A, (4, 2))
        self.assertExpression(A - A - var, (4, 2))
        if PY35:
            self.assertExpression(var.__rmatmul__(B), (4,2))
Example #6
0
    def test_power(self):
        x = Variable(3)
        y = Variable(3)
        self.assertFalse(x.is_constant())
        self.assertTrue(x.is_affine())
        self.assertTrue(x.is_quadratic())

        s = power(x.T*y, 0)
        self.assertTrue(s.is_constant())
        self.assertTrue(s.is_affine())
        self.assertTrue(s.is_quadratic())

        t = power(x-y, 1)
        self.assertFalse(t.is_constant())
        self.assertTrue(t.is_affine())
        self.assertTrue(t.is_quadratic())

        u = power(x+2*y, 2)
        self.assertFalse(u.is_constant())
        self.assertFalse(u.is_affine())
        self.assertTrue(u.is_quadratic())
        self.assertTrue(u.is_dcp())

        w = (x+2*y)**2
        self.assertFalse(w.is_constant())
        self.assertFalse(w.is_affine())
        self.assertTrue(w.is_quadratic())
        self.assertTrue(w.is_dcp())
Example #7
0
    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)
Example #8
0
    def test_variable(self):
        x = Variable(2)
        y = Variable(2)
        assert y.name() != x.name()

        x = Variable(2, name='x')
        y = Variable()
        self.assertEqual(x.name(), 'x')
        self.assertEqual(x.size, (2,1))
        self.assertEqual(y.size, (1,1))
        self.assertEqual(x.curvature, u.Curvature.AFFINE)
        self.assertEqual(x.canonicalize()[0].size, (2,1))
        self.assertEqual(x.canonicalize()[1], [])

        # Scalar variable
        coeff = self.a.coefficients(self.intf)
        self.assertEqual(coeff[self.a], 1)

        # Vector variable.
        coeffs = x.coefficients(self.intf)
        self.assertItemsEqual(coeffs.keys(), [x])
        vec = coeffs[x]
        self.assertEqual(vec.size, (2,2))
        self.assertEqual(list(vec), [1,0,0,1])

        # Matrix variable.
        coeffs = self.A.coefficients(self.intf)
        self.assertItemsEqual(coeffs.keys(), [self.A])
        mat = coeffs[self.A]
        self.assertEqual(mat.size, (2,2))
        self.assertEqual(list(mat), [1,0,0,1])
Example #9
0
    def setUp(self):
        self.x = Variable(2, name='x')
        self.y = Variable(2, name='y')

        self.A = Variable(3,2, name='A')
        self.B = Variable(5,2, name='B')

        self.C = Constant([[1, 2], [1, 2]])
        self.intf = intf.DEFAULT_INTERFACE
Example #10
0
    def setUp(self):
        self.x = Variable(2, name="x")
        self.y = Variable(2, name="y")

        self.A = Variable(3, 2, name="A")
        self.B = Variable(5, 2, name="B")

        self.C = Constant([[1, 2], [1, 2]])
        self.intf = intf.DEFAULT_INTERFACE
Example #11
0
    def setUp(self):
        self.a = Variable()

        self.x = Variable(2, name='x')
        self.y = Variable(2, name='y')

        self.A = Variable(2,2)

        self.c = Constant(3)
        self.C = Constant([[1, 2], [1, 2]])
Example #12
0
    def setUp(self):
        self.x = Variable(2, name="x")
        self.y = Variable(2, name="y")

        self.A = Constant([[1, 2], [1, 2]])

        self.xAff = AffObjective([self.x], [deque([self.x])], u.Shape(2, 1))
        self.yAff = AffObjective([self.y], [deque([self.y])], u.Shape(2, 1))
        self.constAff = AffObjective([self.A], [deque([self.A])], u.Shape(2, 2))
        self.intf = intf.DEFAULT_INTERFACE
Example #13
0
    def setUp(self):
        self.a = Variable(name='a')
        self.b = Variable(name='b')

        self.x = Variable(2, name='x')
        self.y = Variable(3, name='y')
        self.z = Variable(2, name='z')

        self.A = Variable(2,2,name='A')
        self.B = Variable(2,2,name='B')
        self.C = Variable(3,2,name='C')
Example #14
0
    def test_var_copy(self):
        """Test the copy function for variable types.
        """
        x = Variable(3, 4, name="x")
        y = x.copy()
        self.assertEqual(y.size, (3, 4))
        self.assertEqual(y.name(), "x")

        x = Semidef(5, name="x")
        y = x.copy()
        self.assertEqual(y.size, (5, 5))
Example #15
0
    def setUp(self):
        self.a = Variable(name='a')

        self.x = Variable(2, name='x')
        self.y = Variable(3, name='y')
        self.z = Variable(2, name='z')

        self.A = Variable(2,2,name='A')
        self.B = Variable(2,2,name='B')
        self.C = Variable(3,2,name='C')
        self.intf = intf.DEFAULT_INTERFACE
Example #16
0
    def setUp(self):
        self.a = Variable(name="a")

        self.x = Variable(2, name="x")
        self.y = Variable(3, name="y")
        self.z = Variable(2, name="z")

        self.A = Variable(2, 2, name="A")
        self.B = Variable(2, 2, name="B")
        self.C = Variable(3, 2, name="C")
        self.intf = intf.DEFAULT_INTERFACE
Example #17
0
    def setUp(self):
        self.a = Variable(name="a")
        self.b = Variable(name="b")

        self.x = Variable(2, name="x")
        self.y = Variable(3, name="y")
        self.z = Variable(2, name="z")

        self.A = Variable(2, 2, name="A")
        self.B = Variable(2, 2, name="B")
        self.C = Variable(3, 2, name="C")
Example #18
0
    def test_matrix_multiplication(self):
        x = Variable(3, 5)
        y = Variable(3, 5)
        self.assertFalse(x.is_constant())
        self.assertTrue(x.is_affine())
        self.assertTrue(x.is_quadratic())

        s = x.T*y
        self.assertFalse(s.is_constant())
        self.assertFalse(s.is_affine())
        self.assertTrue(s.is_quadratic())
        self.assertFalse(s.is_dcp())
Example #19
0
    def test_partial_optimize_dcp(self):
        """Test DCP properties of partial optimize.
        """
        # Evaluate the 1-norm in the usual way (i.e., in epigraph form).
        dims = 3
        x, t = Variable(dims), Variable(dims)
        xval = [-5] * dims
        p2 = Problem(cvxpy.Minimize(sum_entries(t)), [-t <= x, x <= t])
        g = cvxpy.partial_optimize(p2, [t], [x])
        self.assertEquals(g.curvature, s.CONVEX)

        p2 = Problem(cvxpy.Maximize(sum_entries(t)), [-t <= x, x <= t])
        g = cvxpy.partial_optimize(p2, [t], [x])
        self.assertEquals(g.curvature, s.CONCAVE)
Example #20
0
    def test_variable(self):
        x = Variable(2)
        y = Variable(2)
        assert y.name() != x.name()

        x = Variable(2, name='x')
        y = Variable()
        self.assertEqual(x.name(), 'x')
        self.assertEqual(x.size, (2,1))
        self.assertEqual(y.size, (1,1))
        self.assertEqual(x.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(x.canonical_form[0].size, (2,1))
        self.assertEqual(x.canonical_form[1], [])

        # Scalar variable
        coeff = self.a.coefficients()
        self.assertEqual(coeff[self.a], [1])

        # Vector variable.
        coeffs = x.coefficients()
        self.assertItemsEqual(coeffs.keys(), [x])
        vec = coeffs[x][0]
        self.assertEqual(vec.size, (2,2))
        self.assertEqual(vec[0,0], 1)

        # Matrix variable.
        coeffs = self.A.coefficients()
        self.assertItemsEqual(coeffs.keys(), [self.A])
        self.assertEqual(len(coeffs[self.A]), 2)
        mat = coeffs[self.A][1]
        self.assertEqual(mat.size, (2,4))
        self.assertEqual(mat[0,2], 1)
Example #21
0
    def test_max_sign(self):
        # One arg.
        self.assertEquals(max(1).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals(max(-2).sign, u.Sign.NEGATIVE_KEY)
        self.assertEquals(max(Variable()).sign, u.Sign.UNKNOWN_KEY)
        self.assertEquals(max(0).sign, u.Sign.ZERO_KEY)

        # Two args.
        self.assertEquals(max(1, 2).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals(max(1, Variable()).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals(max(1, -2).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals(max(1, 0).sign, u.Sign.POSITIVE_KEY)

        self.assertEquals(max(Variable(), 0).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals(max(Variable(), Variable()).sign, u.Sign.UNKNOWN_KEY)
        self.assertEquals(max(Variable(), -2).sign, u.Sign.UNKNOWN_KEY)

        self.assertEquals(max(0, 0).sign, u.Sign.ZERO_KEY)
        self.assertEquals(max(0, -2).sign, u.Sign.ZERO_KEY)

        self.assertEquals(max(-3, -2).sign, u.Sign.NEGATIVE_KEY)

        # Many args.
        self.assertEquals(
            max(-2, Variable(), 0, -1, Variable(), 1).sign,
            u.Sign.POSITIVE_KEY)
Example #22
0
    def test_power(self):
        from fractions import Fraction

        for size in (1, 1), (3, 1), (2, 3):
            x = Variable(*size)
            y = Variable(*size)
            exp = x + y

            for p in 0, 1, 2, 3, 2.7, .67, -1, -2.3, Fraction(4, 5):
                atom = power(exp, p)

                self.assertEqual(atom.size, size)

                if p > 1 or p < 0:
                    self.assertEqual(atom.curvature, s.CONVEX)
                elif p == 1:
                    self.assertEqual(atom.curvature, s.AFFINE)
                elif p == 0:
                    self.assertEqual(atom.curvature, s.CONSTANT)
                else:
                    self.assertEqual(atom.curvature, s.CONCAVE)

                if p != 1:
                    self.assertEqual(atom.sign, s.POSITIVE)

                # Test copy with args=None
                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)
                self.assertEqual(copy.get_data(), atom.get_data())
                # 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(), atom.get_data())

        assert power(-1, 2).value == 1

        with self.assertRaises(Exception) as cm:
            power(-1, 3).value
        self.assertEqual(str(cm.exception),
                         "power(x, 3.0) cannot be applied to negative values.")

        with self.assertRaises(Exception) as cm:
            power(0, -1).value
        self.assertEqual(str(cm.exception),
                         "power(x, -1.0) cannot be applied to negative or zero values.")
Example #23
0
    def test_sum_entries(self):
        """Test the sum_entries atom.
        """
        self.assertEquals(sum_entries(1).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals(sum_entries([1, -1]).sign, u.Sign.UNKNOWN_KEY)
        self.assertEquals(
            sum_entries([1, -1]).curvature, u.Curvature.CONSTANT_KEY)
        self.assertEquals(sum_entries(Variable(2)).sign, u.Sign.UNKNOWN_KEY)
        self.assertEquals(sum_entries(Variable(2)).size, (1, 1))
        self.assertEquals(
            sum_entries(Variable(2)).curvature, u.Curvature.AFFINE_KEY)
        # Mixed curvature.
        mat = np.mat("1 -1")
        self.assertEquals(
            sum_entries(mat * square(Variable(2))).curvature,
            u.Curvature.UNKNOWN_KEY)

        # Test with axis argument.
        self.assertEquals(sum_entries(Variable(2), axis=0).size, (1, 1))
        self.assertEquals(sum_entries(Variable(2), axis=1).size, (2, 1))
        self.assertEquals(sum_entries(Variable(2, 3), axis=0).size, (1, 3))
        self.assertEquals(sum_entries(Variable(2, 3), axis=1).size, (2, 1))

        # Invalid axis.
        with self.assertRaises(Exception) as cm:
            sum_entries(self.x, axis=4)
        self.assertEqual(str(cm.exception), "Invalid argument for axis.")
Example #24
0
    def test_partial_optimize_stacked(self):
        # Minimize the 1-norm in the usual way
        dims = 3
        x, t = Variable(dims), Variable(dims)
        p1 = Problem(Minimize(sum_entries(t)), [-t <= x, x <= t])

        # Minimize the 1-norm via partial_optimize
        g = cvxpy.partial_optimize(p1, [t], [x])
        g2 = cvxpy.partial_optimize(Problem(Minimize(g)), [x])
        p2 = Problem(Minimize(g2))
        p2.solve()

        p1.solve()
        self.assertAlmostEqual(p1.value, p2.value)
Example #25
0
    def test_matrix_multiplication(self):
        x = Variable(3, 5)
        y = Variable(3, 5)
        self.assertFalse(x.is_constant())
        self.assertTrue(x.is_affine())
        self.assertTrue(x.is_quadratic())

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            s = x.T*y
        self.assertFalse(s.is_constant())
        self.assertFalse(s.is_affine())
        self.assertTrue(s.is_quadratic())
        self.assertFalse(s.is_dcp())
Example #26
0
    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 = cvxpy.partial_optimize(p2, [y], [x])
        x.value = xval
        result = g.value
        self.assertAlmostEqual(result, p1.value)
Example #27
0
    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)
Example #28
0
    def test_robust_svm(self):
        # Create problem data.
        m = 100  # num train points
        m_pos = math.floor(m / 2)
        m_neg = m - m_pos

        n = 2  # num dimensions
        mu_pos = 2 * numpy.ones(n)
        mu_neg = -2 * numpy.ones(n)
        sigma = 1
        X = numpy.matrix(
            numpy.vstack((mu_pos + sigma * numpy.random.randn(m_pos, n),
                          mu_neg + sigma * numpy.random.randn(m_neg, n))))

        y = numpy.hstack((numpy.ones(m_pos), -1 * numpy.ones(m_neg)))

        C = 1  # regularization trade-off parameter
        ns = 50
        eta = 0.1

        # Create and solve optimization problem.
        w, b, xi = Variable(n), Variable(), NonNegative(m)

        constr = []
        Sigma = 0.1 * numpy.eye(n)
        for i in range(m):
            mu = numpy.array(X[i])[0]
            x = NormalRandomVariable(mu, Sigma)
            chance = prob(-y[i] * (w.T * x + b) >= (xi[i] - 1), ns)
            constr += [chance <= eta]

        p = Problem(Minimize(norm(w, 2) + C * sum_entries(xi)), constr)
        p.solve(verbose=True)

        w_new = w.value
        b_new = b.value

        # Create and solve the canonical SVM problem.
        constr = []
        for i in range(m):
            constr += [y[i] * (X[i] * w + b) >= (1 - xi[i])]

        p2 = Problem(Minimize(norm(w, 2) + C * sum_entries(xi)), constr)
        p2.solve()

        w_old = w.value
        b_old = b.value

        self.assert_feas(p)
Example #29
0
    def setUp(self):
        self.a = Variable(name='a')

        self.x = Variable(2, name='x')
        self.y = Variable(3, name='y')
        self.z = Variable(2, name='z')

        self.A = Variable(2, 2, name='A')
        self.B = Variable(2, 2, name='B')
        self.C = Variable(3, 2, name='C')
        self.intf = intf.DEFAULT_INTF
Example #30
0
    def test_quad_over_lin(self):
        x = Variable(3, 5)
        y = Variable(3, 5)
        z = Variable()
        s = quad_over_lin(x-y, z)
        self.assertFalse(s.is_constant())
        self.assertFalse(s.is_affine())
        self.assertFalse(s.is_quadratic())
        self.assertTrue(s.is_dcp())

        t = quad_over_lin(x+2*y, 5)
        self.assertFalse(t.is_constant())
        self.assertFalse(t.is_affine())
        self.assertTrue(t.is_quadratic())
        self.assertTrue(t.is_dcp())
Example #31
0
    def test_non_quadratic(self):
        x = Variable()
        y = Variable()
        z = Variable()
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            with self.assertRaises(Exception) as cm:
                (x*y*z).is_quadratic()
            self.assertEqual(str(cm.exception), "Cannot multiply UNKNOWN and AFFINE.")

        s = max_entries(vstack(x, y, z))**2
        self.assertFalse(s.is_quadratic())

        t = max_entries(vstack(x**2, power(y, 2), z))
        self.assertFalse(t.is_quadratic())
Example #32
0
    def test_partial_optimize_eval_1norm(self):
        # Evaluate the 1-norm in the usual way (i.e., in epigraph form).
        dims = 3
        x, t = Variable(dims), Variable(dims)
        xval = [-5]*dims
        p1 = Problem(cvxpy.Minimize(sum_entries(t)), [-t <= xval, xval <= t])
        p1.solve()

        # Minimize the 1-norm via partial_optimize.
        p2 = Problem(cvxpy.Minimize(sum_entries(t)), [-t <= x, x <= t])
        g = cvxpy.partial_optimize(p2, [t], [x])
        p3 = Problem(cvxpy.Minimize(g), [x == xval])
        p3.solve()
        self.assertAlmostEqual(p1.value, p3.value)

        # Minimize the 1-norm using maximize.
        p2 = Problem(cvxpy.Maximize(sum_entries(-t)), [-t <= x, x <= t])
        g = cvxpy.partial_optimize(p2, opt_vars=[t])
        p3 = Problem(cvxpy.Maximize(g), [x == xval])
        p3.solve()
        self.assertAlmostEqual(p1.value, -p3.value)

        # Try leaving out args.

        # Minimize the 1-norm via partial_optimize.
        p2 = Problem(cvxpy.Minimize(sum_entries(t)), [-t <= x, x <= t])
        g = cvxpy.partial_optimize(p2, opt_vars=[t])
        p3 = Problem(cvxpy.Minimize(g), [x == xval])
        p3.solve()
        self.assertAlmostEqual(p1.value, p3.value)

        # Minimize the 1-norm via partial_optimize.
        g = cvxpy.partial_optimize(p2, dont_opt_vars=[x])
        p3 = Problem(cvxpy.Minimize(g), [x == xval])
        p3.solve()
        self.assertAlmostEqual(p1.value, p3.value)

        with self.assertRaises(Exception) as cm:
            g = cvxpy.partial_optimize(p2)
        self.assertEqual(str(cm.exception),
                         "partial_optimize called with neither opt_vars nor dont_opt_vars.")

        with self.assertRaises(Exception) as cm:
            g = cvxpy.partial_optimize(p2, [], [x])
        self.assertEqual(str(cm.exception),
                         ("If opt_vars and new_opt_vars are both specified, "
                          "they must contain all variables in the problem.")
                         )
Example #33
0
    def setUp(self):
        self.a = Variable(name='a')
        self.b = Variable(name='b')
        self.c = Variable(name='c')

        self.x = Variable(2, name='x')
        self.y = Variable(3, name='y')
        self.z = Variable(2, name='z')

        self.A = Variable(2, 2, name='A')
        self.B = Variable(2, 2, name='B')
        self.C = Variable(3, 2, name='C')
Example #34
0
 def test_sum_entries(self):
     """Test the sum_entries atom.
     """
     self.assertEquals(sum_entries(1).sign, u.Sign.POSITIVE_KEY)
     self.assertEquals(sum_entries([1, -1]).sign, u.Sign.UNKNOWN_KEY)
     self.assertEquals(
         sum_entries([1, -1]).curvature, u.Curvature.CONSTANT_KEY)
     self.assertEquals(sum_entries(Variable(2)).sign, u.Sign.UNKNOWN_KEY)
     self.assertEquals(sum_entries(Variable(2)).size, (1, 1))
     self.assertEquals(
         sum_entries(Variable(2)).curvature, u.Curvature.AFFINE_KEY)
     # Mixed curvature.
     mat = np.mat("1 -1")
     self.assertEquals(
         sum_entries(mat * square(Variable(2))).curvature,
         u.Curvature.UNKNOWN_KEY)
Example #35
0
    def test_sum_squares(self):
        X = Variable(5, 4)
        P = np.asmatrix(np.random.randn(3, 5))
        Q = np.asmatrix(np.random.randn(4, 7))
        M = np.asmatrix(np.random.randn(3, 7))

        y = P*X*Q + M
        self.assertFalse(y.is_constant())
        self.assertTrue(y.is_affine())
        self.assertTrue(y.is_quadratic())
        self.assertTrue(y.is_dcp())

        s = sum_squares(y)
        self.assertFalse(s.is_constant())
        self.assertFalse(s.is_affine())
        self.assertTrue(s.is_quadratic())
        self.assertTrue(s.is_dcp())

        # Frobenius norm squared is indeed quadratic
        # but can't show quadraticity using recursive rules
        t = norm(y, 'fro')**2
        self.assertFalse(t.is_constant())
        self.assertFalse(t.is_affine())
        self.assertFalse(t.is_quadratic())
        self.assertTrue(t.is_dcp())
Example #36
0
def test_atom():
    for atom_list, objective_type in atoms:
        for atom, obj_val in atom_list:
            for row in xrange(atom.size[0]):
                for col in xrange(atom.size[1]):
                    for solver in [ECOS, SCS, CVXOPT]:
                        # Atoms with Constant arguments.
                        yield (run_atom, atom,
                               Problem(objective_type(atom[row, col])),
                               obj_val[row, col].value, solver)
                        # Atoms with Variable arguments.
                        variables = []
                        constraints = []
                        for idx, expr in enumerate(atom.subexpressions):
                            # Special case for MulExpr because
                            # can't multiply two variables.
                            if (idx == 0 and isinstance(atom, MulExpression)):
                                variables.append(expr)
                            else:
                                variables.append(Variable(*expr.size))
                                constraints.append(variables[-1] == expr)
                        atom_func = atom.__class__
                        objective = objective_type(
                            atom_func(*variables)[row, col])
                        yield (run_atom, atom, Problem(objective, constraints),
                               obj_val[row, col].value, solver)
                        # Atoms with Parameter arguments.
                        parameters = []
                        for expr in atom.subexpressions:
                            parameters.append(Parameter(*expr.size))
                            parameters[-1].value = expr.value
                        objective = objective_type(
                            atom_func(*parameters)[row, col])
                        yield (run_atom, atom, Problem(objective),
                               obj_val[row, col].value, solver)
Example #37
0
    def test_value_at_risk(self):
        # Create problem data.
        n = numpy.random.randint(1, 10)
        pbar = numpy.random.randn(n)
        Sigma = numpy.eye(n)
        p = NormalRandomVariable(pbar, Sigma)

        o = numpy.ones((n, 1))
        beta = 0.05
        num_samples = 50

        # Create and solve optimization problem.
        x = Variable(n)
        p1 = Problem(Minimize(-x.T * pbar), [
            prob(-x.T * p >= 0, num_samples) <= beta, x.T * o == 1, x >= -0.1
        ])
        p1.solve()

        # Create and solve analytic form of optimization problem (as a check).
        p2 = Problem(Minimize(-x.T * pbar), [
            x.T * pbar >= scipy.stats.norm.ppf(1 - beta) *
            norm2(sqrtm(Sigma) * x), x.T * o == 1, x >= -0.1
        ])
        p2.solve()

        tol = 0.1
        if numpy.abs(p1.value - p2.value) < tol:
            self.assertAlmostEqual(1, 1)
        else:
            self.assertAlmostEqual(1, 0)
Example #38
0
    def test_add_expression(self):
        # Vectors
        c = Constant([2,2])
        exp = self.x + c
        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(), self.x.name() + " + " + c.name())
        self.assertEqual(exp.size, (2,1))

        z = Variable(2, name='z')
        exp = exp + z + self.x

        with self.assertRaises(Exception) as cm:
            (self.x + self.y)
        self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 1) (3, 1)")

        # Matrices
        exp = self.A + self.B
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(exp.size, (2,2))

        with self.assertRaises(Exception) as cm:
            (self.A + self.C)
        self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 2) (3, 2)")

        with self.assertRaises(Exception) as cm:
            AddExpression([self.A, self.C])
        self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 2) (3, 2)")

        # Test that sum is flattened.
        exp = self.x + c + self.x
        self.assertEqual(len(exp.args), 3)
Example #39
0
    def test_pnorm(self):
        import numpy as np

        x = Variable(3, name='x')

        a = np.array([1.0, 2, 3])

        for p in (1, 1.6, 1.2, 2, 1.99, 3, 3.7, np.inf):
            prob = Problem(Minimize(pnorm(x, p=p)), [x.T * a >= 1])
            prob.solve()

            # formula is true for any a >= 0 with p > 1
            if p == np.inf:
                x_true = np.ones_like(a) / sum(a)
            elif p == 1:
                # only works for the particular a = [1,2,3]
                x_true = np.array([0, 0, 1.0 / 3])
            else:
                x_true = a**(1.0 / (p - 1)) / a.dot(a**(1.0 / (p - 1)))

            x_alg = np.array(x.value).flatten()
            self.assertTrue(np.allclose(x_alg, x_true, 1e-3))
            self.assertTrue(np.allclose(prob.value, np.linalg.norm(x_alg, p)))
            self.assertTrue(
                np.allclose(np.linalg.norm(x_alg, p),
                            pnorm(x_alg, p).value))
Example #40
0
    def test_sub_expression(self):
        # Vectors
        c = Constant([2, 2])
        exp = self.x - c
        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(), self.x.name() + " - " + Constant([2,2]).name())
        self.assertEqual(exp.size, (2, 1))

        z = Variable(2, name='z')
        exp = exp - z - self.x

        with self.assertRaises(Exception) as cm:
            (self.x - self.y)
        self.assertEqual(str(cm.exception),
                         "Incompatible dimensions (2, 1) (3, 1)")

        # Matrices
        exp = self.A - self.B
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(exp.size, (2, 2))

        with self.assertRaises(Exception) as cm:
            (self.A - self.C)
        self.assertEqual(str(cm.exception),
                         "Incompatible dimensions (2, 2) (3, 2)")
Example #41
0
def test_atom():
    for atom_list, objective_type in atoms:
        for atom, obj_val in atom_list:
            for row in xrange(atom.size[0]):
                for col in xrange(atom.size[1]):
                    # Atoms with Constant arguments.
                    yield run_atom, Problem(objective_type(
                        atom[row, col])), obj_val[row, col].value
                    # Atoms with Variable arguments.
                    variables = []
                    constraints = []
                    for expr in atom.subexpressions:
                        variables.append(Variable(*expr.size))
                        constraints.append(variables[-1] == expr)
                    atom_func = atom.__class__
                    objective = objective_type(atom_func(*variables)[row, col])
                    yield run_atom, Problem(objective,
                                            constraints), obj_val[row,
                                                                  col].value
                    # Atoms with Parameter arguments.
                    parameters = []
                    for expr in atom.subexpressions:
                        parameters.append(Parameter(*expr.size))
                        parameters[-1].value = expr.value
                    objective = objective_type(
                        atom_func(*parameters)[row, col])
                    yield run_atom, Problem(objective), obj_val[row, col].value
Example #42
0
    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)
Example #43
0
def test_atom():
    for atom_list, objective_type in atoms:
        for atom, size, args, obj_val in atom_list:
            for row in range(size[0]):
                for col in range(size[1]):
                    for solver in SOLVERS_TO_TRY:
                        # Atoms with Constant arguments.
                        const_args = [Constant(arg) for arg in args]
                        yield (run_atom, atom,
                               Problem(
                                   objective_type(atom(*const_args)[row,
                                                                    col])),
                               obj_val[row, col].value, solver)
                        # Atoms with Variable arguments.
                        variables = []
                        constraints = []
                        for idx, expr in enumerate(args):
                            variables.append(Variable(*intf.size(expr)))
                            constraints.append(variables[-1] == expr)
                        objective = objective_type(atom(*variables)[row, col])
                        yield (run_atom, atom, Problem(objective, constraints),
                               obj_val[row, col].value, solver)
                        # Atoms with Parameter arguments.
                        parameters = []
                        for expr in args:
                            parameters.append(Parameter(*intf.size(expr)))
                            parameters[
                                -1].value = intf.DEFAULT_INTF.const_to_matrix(
                                    expr)
                        objective = objective_type(atom(*parameters)[row, col])
                        yield (run_atom, atom, Problem(objective),
                               obj_val[row, col].value, solver)
Example #44
0
    def test_indexing(self):
        # Vector variables
        p = Problem(Maximize(self.x[0, 0]),
                    [self.x[0, 0] <= 2, self.x[1, 0] == 3])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertItemsAlmostEqual(self.x.value, [2, 3])

        n = 10
        A = matrix(range(n * n), (n, n))
        x = Variable(n, n)
        p = Problem(Minimize(sum_entries(x)), [x == A])
        result = p.solve()
        answer = n * n * (n * n + 1) / 2 - n * n
        self.assertAlmostEqual(result, answer)

        # Matrix variables
        p = Problem(
            Maximize(sum(self.A[i, i] + self.A[i, 1 - i] for i in range(2))),
            [self.A <= [[1, -2], [-3, 4]]])
        result = p.solve()
        self.assertAlmostEqual(result, 0)
        self.assertItemsAlmostEqual(self.A.value, [1, -2, -3, 4])

        # Indexing arithmetic expressions.
        exp = [[1, 2], [3, 4]] * self.z + self.x
        p = Problem(Minimize(exp[1, 0]), [self.x == self.z, self.z == [1, 2]])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertItemsAlmostEqual(self.x.value, self.z.value)
Example #45
0
    def test_hstack(self):
        c = matrix(1, (1, 5))
        p = Problem(Minimize(c * hstack(self.x.T, self.y.T).T),
                    [self.x == [1, 2], self.y == [3, 4, 5]])
        result = p.solve()
        self.assertAlmostEqual(result, 15)

        c = matrix(1, (1, 4))
        p = Problem(Minimize(c * hstack(self.x.T, self.x.T).T),
                    [self.x == [1, 2]])
        result = p.solve()
        self.assertAlmostEqual(result, 6)

        c = matrix(1, (2, 2))
        p = Problem(Minimize(sum_entries(hstack(self.A.T, self.C.T))),
                    [self.A >= 2 * c, self.C == -2])
        result = p.solve()
        self.assertAlmostEqual(result, -4)

        D = Variable(3, 3)
        expr = hstack(self.C, D)
        p = Problem(Minimize(expr[0, 1] + sum_entries(hstack(expr, expr))),
                    [self.C >= 0, D >= 0, D[0, 0] == 2, self.C[0, 1] == 3])
        result = p.solve()
        self.assertAlmostEqual(result, 13)

        c = matrix([1, -1])
        p = Problem(Minimize(c.T * hstack(square(self.a).T,
                                          sqrt(self.b).T).T),
                    [self.a == 2, self.b == 16])
        with self.assertRaises(Exception) as cm:
            p.solve()
        self.assertEqual(str(cm.exception),
                         "Problem does not follow DCP rules.")
Example #46
0
 def test_variable_name_conflict(self):
     var = Variable(name='a')
     p = Problem(Maximize(self.a + var), [var == 2 + self.a, var <= 3])
     result = p.solve()
     self.assertAlmostEqual(result, 4.0)
     self.assertAlmostEqual(self.a.value, 1)
     self.assertAlmostEqual(var.value, 3)
Example #47
0
    def test_neg_indices(self):
        """Test negative indices.
        """
        c = Constant([[1, 2], [3, 4]])
        exp = c[-1, -1]
        self.assertEquals(exp.value, 4)
        self.assertEquals(exp.size, (1, 1))
        self.assertEquals(exp.curvature, u.Curvature.CONSTANT_KEY)

        c = Constant([1, 2, 3, 4])
        exp = c[1:-1]
        self.assertItemsAlmostEqual(exp.value, [2, 3])
        self.assertEquals(exp.size, (2, 1))
        self.assertEquals(exp.curvature, u.Curvature.CONSTANT_KEY)

        c = Constant([1, 2, 3, 4])
        exp = c[::-1]
        self.assertItemsAlmostEqual(exp.value, [4, 3, 2, 1])
        self.assertEquals(exp.size, (4, 1))
        self.assertEquals(exp.curvature, u.Curvature.CONSTANT_KEY)

        x = Variable(4)
        Problem(Minimize(0), [x[::-1] == c]).solve()
        self.assertItemsAlmostEqual(x.value, [4, 3, 2, 1])
        self.assertEquals(x.size, (4, 1))
Example #48
0
 def test_min_entries_sign(self):
     """Test sign for min_entries.
     """
     # One arg.
     self.assertEquals(min_entries(1).sign, u.Sign.POSITIVE_KEY)
     self.assertEquals(min_entries(-2).sign, u.Sign.NEGATIVE_KEY)
     self.assertEquals(min_entries(Variable()).sign, u.Sign.UNKNOWN_KEY)
     self.assertEquals(min_entries(0).sign, u.Sign.ZERO_KEY)
Example #49
0
 def test_min_entries_sign(self):
     """Test sign for min_entries.
     """
     # One arg, test sign.
     self.assertEquals(min_entries(1).sign, s.POSITIVE)
     self.assertEquals(min_entries(-2).sign, s.NEGATIVE)
     self.assertEquals(min_entries(Variable()).sign, s.UNKNOWN)
     self.assertEquals(min_entries(0).sign, s.ZERO)
Example #50
0
 def test_power(self):
     x = Variable()
     prob = Problem(
         Minimize(power(x, 1.7) + power(x, -2.3) - power(x, .45)))
     prob.solve()
     x = x.value
     self.assertTrue(__builtins__['abs'](1.7 * x**.7 - 2.3 * x**-3.3 -
                                         .45 * x**-.55) <= 1e-3)
Example #51
0
 def test_kl_div(self):
     """Test domain for kl_div.
     """
     b = Variable()
     dom = kl_div(self.a, b).domain
     Problem(Minimize(self.a + b), dom).solve()
     self.assertAlmostEqual(self.a.value, 0)
     self.assertAlmostEqual(b.value, 0)
Example #52
0
class TestVstack(unittest.TestCase):
    """ Unit tests for the expressions.affine module. """
    def setUp(self):
        self.x = Variable(2, name='x')
        self.y = Variable(2, name='y')

        self.A = Variable(3,2, name='A')
        self.B = Variable(5,2, name='B')

        self.C = Constant([[1, 2], [1, 2]])
        self.intf = intf.DEFAULT_INTERFACE

    # Test the variables method.
    def test_variables(self):
        exp,constr = vstack(self.x, self.y, self.x+self.y).canonical_form
        self.assertEquals(constr, [])
        self.assertItemsEqual(exp.variables(), [self.x, self.y])
        exp = vstack(self.A, self.B, self.C).canonical_form[0]
        self.assertItemsEqual(exp.variables(), [self.A, self.B])

    # Test coefficients method.
    def test_coefficients(self):
        exp = vstack(self.x).canonical_form[0]
        coeffs = exp.coefficients()
        self.assertEqual(coeffs.keys(), self.x.coefficients().keys())

        exp = vstack(self.x, self.y).canonical_form[0]
        coeffs = exp.coefficients()
        self.assertItemsEqual(coeffs.keys(),
            self.x.coefficients().keys() + \
            self.y.coefficients().keys())
        for k,blocks in coeffs.items():
            self.assertEqual(len(blocks), 1)
            for block in blocks:
                self.assertEqual(intf.size(block), (4,2))

        exp = vstack(self.A, self.B, self.C).canonical_form[0]
        coeffs = exp.coefficients()
        blocks = coeffs[self.A.id]
        self.assertEqual(len(blocks), 2)
        for block in blocks:
            self.assertEqual(intf.size(block), (10,6))
Example #53
0
class TestAffVstack(unittest.TestCase):
    """ Unit tests for the expressions.affine module. """
    def setUp(self):
        self.x = Variable(2, name='x')
        self.y = Variable(2, name='y')

        self.A = Variable(3,2, name='A')
        self.B = Variable(5,2, name='B')

        self.C = Constant([[1, 2], [1, 2]])
        self.intf = intf.DEFAULT_INTERFACE

    # Test the variables method.
    def test_variables(self):
        exp = AffVstack(self.x, self.y, self.x+self.y)
        self.assertItemsEqual(exp.variables(), [self.x, self.y, self.x, self.y])
        exp = AffVstack(self.A, self.B, self.C)
        self.assertItemsEqual(exp.variables(), [self.A, self.B])

    # Test coefficients method.
    def test_coefficients(self):
        exp = AffVstack(self.x)
        coeffs = exp.coefficients(self.intf)
        self.assertEqual(coeffs.keys(), self.x.coefficients(self.intf).keys())

        exp = AffVstack(self.x, self.y)
        coeffs = exp.coefficients(self.intf)
        self.assertItemsEqual(coeffs.keys(), 
            self.x.coefficients(self.intf).keys() + \
            self.y.coefficients(self.intf).keys())
        for k,v in coeffs.items():
            self.assertEqual(intf.size(v), (4,2))

        exp = AffVstack(self.A, self.B, self.C)
        coeffs = exp.coefficients(self.intf)
        v = coeffs[self.A]
        self.assertEqual(intf.size(v), (10,3))
Example #54
0
    def test_variable(self):
        x = Variable(2)
        y = Variable(2)
        assert y.name() != x.name()

        x = Variable(2, name='x')
        y = Variable()
        self.assertEqual(x.name(), 'x')
        self.assertEqual(x.size, (2,1))
        self.assertEqual(y.size, (1,1))
        self.assertEqual(x.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(x.canonical_form[0].size, (2,1))
        self.assertEqual(x.canonical_form[1], [])
Example #55
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].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)
Example #56
0
    def test_variable(self):
        x = Variable(2)
        y = Variable(2)
        assert y.name() != x.name()

        x = Variable(2, name='x')
        y = Variable()
        self.assertEqual(x.name(), 'x')
        self.assertEqual(x.size, (2, 1))
        self.assertEqual(y.size, (1, 1))
        self.assertEqual(x.curvature, s.AFFINE)
        self.assertEqual(x.canonical_form[0].size, (2, 1))
        self.assertEqual(x.canonical_form[1], [])

        self.assertEqual(repr(self.x), "Variable(2, 1)")
        self.assertEqual(repr(self.A), "Variable(2, 2)")
Example #57
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)
Example #58
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].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)
Example #59
0
class TestExpressions(BaseTest):
    """ Unit tests for the expression/expression module. """
    def setUp(self):
        self.a = Variable(name='a')

        self.x = Variable(2, name='x')
        self.y = Variable(3, name='y')
        self.z = Variable(2, name='z')

        self.A = Variable(2,2,name='A')
        self.B = Variable(2,2,name='B')
        self.C = Variable(3,2,name='C')
        self.intf = intf.DEFAULT_INTERFACE

    # Test the Variable class.
    def test_variable(self):
        x = Variable(2)
        y = Variable(2)
        assert y.name() != x.name()

        x = Variable(2, name='x')
        y = Variable()
        self.assertEqual(x.name(), 'x')
        self.assertEqual(x.size, (2,1))
        self.assertEqual(y.size, (1,1))
        self.assertEqual(x.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(x.canonical_form[0].size, (2,1))
        self.assertEqual(x.canonical_form[1], [])

        self.assertEquals(repr(self.x), "Variable(2, 1)")
        self.assertEquals(repr(self.A), "Variable(2, 2)")

        # # Scalar variable
        # coeff = self.a.coefficients()
        # self.assertEqual(coeff[self.a.id], [1])

        # # Vector variable.
        # coeffs = x.coefficients()
        # self.assertItemsEqual(coeffs.keys(), [x.id])
        # vec = coeffs[x.id][0]
        # self.assertEqual(vec.shape, (2,2))
        # self.assertEqual(vec[0,0], 1)

        # # Matrix variable.
        # coeffs = self.A.coefficients()
        # self.assertItemsEqual(coeffs.keys(), [self.A.id])
        # self.assertEqual(len(coeffs[self.A.id]), 2)
        # mat = coeffs[self.A.id][1]
        # self.assertEqual(mat.shape, (2,4))
        # self.assertEqual(mat[0,2], 1)

    # Test tranposing variables.
    def test_transpose_variable(self):
        var = self.a.T
        self.assertEquals(var.name(), "a")
        self.assertEquals(var.size, (1,1))

        self.a.save_value(2)
        self.assertEquals(var.value, 2)

        var = self.x.T
        self.assertEquals(var.name(), "x.T")
        self.assertEquals(var.size, (1,2))

        self.x.save_value( matrix([1,2]) )
        self.assertEquals(var.value[0,0], 1)
        self.assertEquals(var.value[0,1], 2)

        var = self.C.T
        self.assertEquals(var.name(), "C.T")
        self.assertEquals(var.size, (2,3))

        # coeffs = var.canonical_form[0].coefficients()
        # mat = coeffs.values()[0][0]
        # self.assertEqual(mat.size, (2,6))
        # self.assertEqual(mat[1,3], 1)

        index = var[1,0]
        self.assertEquals(index.name(), "C.T[1, 0]")
        self.assertEquals(index.size, (1,1))

        var = self.x.T.T
        self.assertEquals(var.name(), "x.T.T")
        self.assertEquals(var.size, (2,1))

    # Test the Constant class.
    def test_constants(self):
        c = Constant(2)
        self.assertEqual(c.name(), str(2))

        c = Constant(2)
        self.assertEqual(c.value, 2)
        self.assertEqual(c.size, (1,1))
        self.assertEqual(c.curvature, u.Curvature.CONSTANT_KEY)
        self.assertEqual(c.sign, u.Sign.POSITIVE_KEY)
        self.assertEqual(Constant(-2).sign, u.Sign.NEGATIVE_KEY)
        self.assertEqual(Constant(0).sign, u.Sign.ZERO_KEY)
        self.assertEqual(c.canonical_form[0].size, (1,1))
        self.assertEqual(c.canonical_form[1], [])

        # coeffs = c.coefficients()
        # self.assertEqual(coeffs.keys(), [s.CONSTANT])
        # self.assertEqual(coeffs[s.CONSTANT], [2])

        # Test the sign.
        c = Constant([[2], [2]])
        self.assertEqual(c.size, (1, 2))
        self.assertEqual(c.sign, u.Sign.POSITIVE_KEY)
        self.assertEqual((-c).sign, u.Sign.NEGATIVE_KEY)
        self.assertEqual((0*c).sign, u.Sign.ZERO_KEY)
        c = Constant([[2], [-2]])
        self.assertEqual(c.sign, u.Sign.UNKNOWN_KEY)

        # Test sign of a complex expression.
        c = Constant([1, 2])
        A = Constant([[1,1],[1,1]])
        exp = c.T*A*c
        self.assertEqual(exp.sign, u.Sign.POSITIVE_KEY)
        self.assertEqual((c.T*c).sign, u.Sign.POSITIVE_KEY)
        exp = c.T.T
        self.assertEqual(exp.sign, u.Sign.POSITIVE_KEY)
        exp = c.T*self.A
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)

        # Test repr.
        self.assertEqual(repr(c), "Constant(CONSTANT, POSITIVE, (2, 1))")

    # 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.")

    # Test the Parameter class.
    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)

        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")')

    # Test the AddExpresion class.
    def test_add_expression(self):
        # Vectors
        c = Constant([2,2])
        exp = self.x + c
        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(), self.x.name() + " + " + c.name())
        self.assertEqual(exp.size, (2,1))

        z = Variable(2, name='z')
        exp = exp + z + self.x

        with self.assertRaises(Exception) as cm:
            (self.x + self.y)
        self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 1) (3, 1)")

        # Matrices
        exp = self.A + self.B
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(exp.size, (2,2))

        with self.assertRaises(Exception) as cm:
            (self.A + self.C)
        self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 2) (3, 2)")

        with self.assertRaises(Exception) as cm:
            AddExpression([self.A, self.C])
        self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 2) (3, 2)")

        # Test that sum is flattened.
        exp = self.x + c + self.x
        self.assertEqual(len(exp.args), 3)

        # Test repr.
        self.assertEqual(repr(exp), "Expression(AFFINE, UNKNOWN, (2, 1))")

    # Test the SubExpresion class.
    def test_sub_expression(self):
        # Vectors
        c = Constant([2,2])
        exp = self.x - c
        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(), self.x.name() + " - " + Constant([2,2]).name())
        self.assertEqual(exp.size, (2,1))

        z = Variable(2, name='z')
        exp = exp - z - self.x

        with self.assertRaises(Exception) as cm:
            (self.x - self.y)
        self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 1) (3, 1)")

        # Matrices
        exp = self.A - self.B
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(exp.size, (2,2))

        with self.assertRaises(Exception) as cm:
            (self.A - self.C)
        self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 2) (3, 2)")

        # Test repr.
        self.assertEqual(repr(self.x - c), "Expression(AFFINE, UNKNOWN, (2, 1))")

    # Test the MulExpresion class.
    def test_mul_expression(self):
        # Vectors
        c = Constant([[2],[2]])
        exp = c*self.x
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual((c[0]*self.x).sign, u.Sign.UNKNOWN_KEY)
        self.assertEqual(exp.canonical_form[0].size, (1,1))
        self.assertEqual(exp.canonical_form[1], [])
        # self.assertEqual(exp.name(), c.name() + " * " + self.x.name())
        self.assertEqual(exp.size, (1,1))

        with self.assertRaises(Exception) as cm:
            ([2,2,3]*self.x)
        self.assertEqual(str(cm.exception), "Incompatible dimensions (3, 1) (2, 1)")

        # Matrices
        with self.assertRaises(Exception) as cm:
            Constant([[2, 1],[2, 2]]) * self.C
        self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 2) (3, 2)")

        with self.assertRaises(Exception) as cm:
            (self.A * self.B)
        self.assertEqual(str(cm.exception), "Cannot multiply two non-constants.")

        # Constant expressions
        T = Constant([[1,2,3],[3,5,5]])
        exp = (T + T) * self.B
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(exp.size, (3,2))

        # Expression that would break sign multiplication without promotion.
        c = Constant([[2], [2], [-2]])
        exp = [[1], [2]] + c*self.C
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)

        # Scalar constants on the right should be moved left
        # instead of taking the transpose.
        expr = self.C*2
        self.assertEqual(expr.args[0].value, 2)

    # Test the DivExpresion class.
    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)

        rho = Parameter(sign="positive")
        rho.value = 1

        self.assertEquals(rho.sign, u.Sign.POSITIVE_KEY)
        self.assertEquals(Constant(2).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals((Constant(2)/Constant(2)).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals((Constant(2)*rho).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals((rho/2).sign, u.Sign.POSITIVE_KEY)

    # Test the NegExpression class.
    def test_neg_expression(self):
        # Vectors
        exp = -self.x
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        assert exp.is_affine()
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)
        assert not exp.is_positive()
        self.assertEqual(exp.canonical_form[0].size, (2,1))
        self.assertEqual(exp.canonical_form[1], [])
        # self.assertEqual(exp.name(), "-%s" % self.x.name())
        self.assertEqual(exp.size, self.x.size)

        # Matrices
        exp = -self.C
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(exp.size, (3,2))

    # Test promotion of scalar constants.
    def test_scalar_const_promotion(self):
        # Vectors
        exp = self.x + 2
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        assert exp.is_affine()
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)
        assert not exp.is_negative()
        self.assertEqual(exp.canonical_form[0].size, (2,1))
        self.assertEqual(exp.canonical_form[1], [])
        # self.assertEqual(exp.name(), self.x.name() + " + " + Constant(2).name())
        self.assertEqual(exp.size, (2,1))

        self.assertEqual((4 - self.x).size, (2,1))
        self.assertEqual((4 * self.x).size, (2,1))
        self.assertEqual((4 <= self.x).size, (2,1))
        self.assertEqual((4 == self.x).size, (2,1))
        self.assertEqual((self.x >= 4).size, (2,1))

        # Matrices
        exp = (self.A + 2) + 4
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual((3 * self.A).size, (2,2))

        self.assertEqual(exp.size, (2,2))

    # Test indexing expression.
    def test_index_expression(self):
        # Tuple of integers as key.
        exp = self.x[1,0]
        # self.assertEqual(exp.name(), "x[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        assert exp.is_affine()
        self.assertEquals(exp.size, (1,1))
        # coeff = exp.canonical_form[0].coefficients()[self.x][0]
        # self.assertEqual(coeff[0,1], 1)
        self.assertEqual(exp.value, None)

        exp = self.x[1,0].T
        # self.assertEqual(exp.name(), "x[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEquals(exp.size, (1,1))

        with self.assertRaises(Exception) as cm:
            (self.x[2,0])
        self.assertEqual(str(cm.exception), "Index/slice out of bounds.")

        # Slicing
        exp = self.C[0:2,1]
        # self.assertEquals(exp.name(), "C[0:2,1]")
        self.assertEquals(exp.size, (2,1))
        exp = self.C[0:,0:2]
        # self.assertEquals(exp.name(), "C[0:,0:2]")
        self.assertEquals(exp.size, (3,2))
        exp = self.C[0::2,0::2]
        # self.assertEquals(exp.name(), "C[0::2,0::2]")
        self.assertEquals(exp.size, (2,1))
        exp = self.C[:3,:1:2]
        # self.assertEquals(exp.name(), "C[0:3,0]")
        self.assertEquals(exp.size, (3,1))
        exp = self.C[0:,0]
        # self.assertEquals(exp.name(), "C[0:,0]")
        self.assertEquals(exp.size, (3,1))

        c = Constant([[1,-2],[0,4]])
        exp = c[1, 1]
        self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY)
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)
        self.assertEqual(c[0,1].sign, u.Sign.UNKNOWN_KEY)
        self.assertEqual(c[1,0].sign, u.Sign.UNKNOWN_KEY)
        self.assertEquals(exp.size, (1,1))
        self.assertEqual(exp.value, 4)

        c = Constant([[1,-2,3],[0,4,5],[7,8,9]])
        exp = c[0:3,0:4:2]
        self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY)
        assert exp.is_constant()
        self.assertEquals(exp.size, (3,2))
        self.assertEqual(exp[0,1].value, 7)

        # Slice of transpose
        exp = self.C.T[0:2,1]
        self.assertEquals(exp.size, (2,1))

        # Arithmetic expression indexing
        exp = (self.x + self.z)[1,0]
        # self.assertEqual(exp.name(), "x[1,0] + z[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)
        self.assertEquals(exp.size, (1,1))

        exp = (self.x + self.a)[1,0]
        # self.assertEqual(exp.name(), "x[1,0] + a")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEquals(exp.size, (1,1))

        exp = (self.x - self.z)[1,0]
        # self.assertEqual(exp.name(), "x[1,0] - z[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEquals(exp.size, (1,1))

        exp = (self.x - self.a)[1,0]
        # self.assertEqual(exp.name(), "x[1,0] - a")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEquals(exp.size, (1,1))

        exp = (-self.x)[1,0]
        # self.assertEqual(exp.name(), "-x[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEquals(exp.size, (1,1))

        c = Constant([[1,2],[3,4]])
        exp = (c*self.x)[1,0]
        # self.assertEqual(exp.name(), "[[2], [4]] * x[0:,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEquals(exp.size, (1,1))

        c = Constant([[1,2],[3,4]])
        exp = (c*self.a)[1,0]
        # self.assertEqual(exp.name(), "2 * a")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEquals(exp.size, (1,1))

    def test_neg_indices(self):
        """Test negative indices.
        """
        c = Constant([[1,2],[3,4]])
        exp = c[-1, -1]
        self.assertEquals(exp.value, 4)
        self.assertEquals(exp.size, (1, 1))
        self.assertEquals(exp.curvature, u.Curvature.CONSTANT_KEY)

        c = Constant([1,2,3,4])
        exp = c[1:-1]
        self.assertItemsAlmostEqual(exp.value, [2, 3])
        self.assertEquals(exp.size, (2, 1))
        self.assertEquals(exp.curvature, u.Curvature.CONSTANT_KEY)

    def test_logical_indices(self):
        """Test indexing with logical arrays.
        """
        pass
Example #60
0
class TestExpressions(unittest.TestCase):
    """ Unit tests for the expression/expression module. """
    def setUp(self):
        self.a = Variable(name='a')

        self.x = Variable(2, name='x')
        self.y = Variable(3, name='y')
        self.z = Variable(2, name='z')

        self.A = Variable(2,2,name='A')
        self.B = Variable(2,2,name='B')
        self.C = Variable(3,2,name='C')
        self.intf = intf.DEFAULT_INTERFACE

    # Test the Variable class.
    def test_variable(self):
        x = Variable(2)
        y = Variable(2)
        assert y.name() != x.name()

        x = Variable(2, name='x')
        y = Variable()
        self.assertEqual(x.name(), 'x')
        self.assertEqual(x.size, (2,1))
        self.assertEqual(y.size, (1,1))
        self.assertEqual(x.curvature, u.Curvature.AFFINE)
        self.assertEqual(x.canonicalize()[0].size, (2,1))
        self.assertEqual(x.canonicalize()[1], [])

        # Scalar variable
        coeff = self.a.coefficients(self.intf)
        self.assertEqual(coeff[self.a], 1)

        # Vector variable.
        coeffs = x.coefficients(self.intf)
        self.assertItemsEqual(coeffs.keys(), [x])
        vec = coeffs[x]
        self.assertEqual(vec.size, (2,2))
        self.assertEqual(list(vec), [1,0,0,1])

        # Matrix variable.
        coeffs = self.A.coefficients(self.intf)
        self.assertItemsEqual(coeffs.keys(), [self.A])
        mat = coeffs[self.A]
        self.assertEqual(mat.size, (2,2))
        self.assertEqual(list(mat), [1,0,0,1])

    # Test the TransposeVariable class.
    def test_transpose_variable(self):
        var = self.a.T
        self.assertEquals(var.name(), "a")
        self.assertEquals(var.size, (1,1))

        self.a.save_value(2)
        self.assertEquals(var.value, 2)

        var = self.x.T
        self.assertEquals(var.name(), "x.T")
        self.assertEquals(var.size, (1,2))

        self.x.save_value( matrix([1,2]) )
        self.assertEquals(var.value[0,0], 1)
        self.assertEquals(var.value[0,1], 2)

        var = self.C.T
        self.assertEquals(var.name(), "C.T")
        self.assertEquals(var.size, (2,3))

        coeffs = var.coefficients(self.intf)
        self.assertItemsEqual(coeffs.keys(), [var])
        mat = coeffs[var]
        self.assertEqual(mat.size, (2,2))
        self.assertEqual(list(mat), [1,0,0,1])

        index = var[1,0]
        self.assertEquals(index.name(), "C[0,1]")
        self.assertEquals(index.size, (1,1))

        var = self.x.T.T
        self.assertEquals(var.name(), "x")
        self.assertEquals(var.size, (2,1))

    # Test the Constant class.
    def test_constants(self):
        c = Constant(2)
        self.assertEqual(c.name(), str(2))

        c = Constant(2, name="c")
        self.assertEqual(c.name(), "c")
        self.assertEqual(c.value, 2)
        self.assertEqual(c.size, (1,1))
        self.assertEqual(c.curvature, u.Curvature.CONSTANT)
        self.assertEqual(c.sign, u.Sign.POSITIVE)
        self.assertEqual(Constant(-2).sign, u.Sign.NEGATIVE)
        self.assertEqual(Constant(0).sign, u.Sign.ZERO)
        self.assertEqual(c.canonicalize()[0].size, (1,1))
        self.assertEqual(c.canonicalize()[1], [])
        
        coeffs = c.coefficients(self.intf)
        self.assertEqual(coeffs.keys(), [s.CONSTANT])
        self.assertEqual(coeffs[s.CONSTANT], 2)

        # Test the sign.
        c = Constant([[2],[2]])
        self.assertEqual(c.size, (1,2))
        self.assertEqual(c.sign.neg_mat.value.shape, (1,2))

    # Test the Parameter class.
    def test_parameters(self):
        p = Parameter(name='p')
        self.assertEqual(p.name(), "p")
        self.assertEqual(p.size, (1,1))

    # Test the AddExpresion class.
    def test_add_expression(self):
        # Vectors
        c = Constant([2,2])
        exp = self.x + c
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual(exp.sign, u.Sign.UNKNOWN)
        self.assertEqual(exp.canonicalize()[0].size, (2,1))
        self.assertEqual(exp.canonicalize()[1], [])
        self.assertEqual(exp.name(), self.x.name() + " + " + c.name())
        self.assertEqual(exp.size, (2,1))

        z = Variable(2, name='z')
        exp = exp + z + self.x

        with self.assertRaises(Exception) as cm:
            (self.x + self.y)
        self.assertEqual(str(cm.exception), "Incompatible dimensions.")

        # Matrices
        exp = self.A + self.B
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual(exp.size, (2,2))

        with self.assertRaises(Exception) as cm:
            (self.A + self.C)
        self.assertEqual(str(cm.exception), "Incompatible dimensions.")


    # Test the SubExpresion class.
    def test_sub_expression(self):
        # Vectors
        c = Constant([2,2])
        exp = self.x - c
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual(exp.sign, u.Sign.UNKNOWN)
        self.assertEqual(exp.canonicalize()[0].size, (2,1))
        self.assertEqual(exp.canonicalize()[1], [])
        self.assertEqual(exp.name(), self.x.name() + " - " + Constant([2,2]).name())
        self.assertEqual(exp.size, (2,1))

        z = Variable(2, name='z')
        exp = exp - z - self.x

        with self.assertRaises(Exception) as cm:
            (self.x - self.y)
        self.assertEqual(str(cm.exception), "Incompatible dimensions.")

        # Matrices
        exp = self.A - self.B
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual(exp.size, (2,2))

        with self.assertRaises(Exception) as cm:
            (self.A - self.C)
        self.assertEqual(str(cm.exception), "Incompatible dimensions.")

    # Test the MulExpresion class.
    def test_mul_expression(self):
        # Vectors
        c = Constant([[2],[2]])
        exp = c*self.x
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual((c[0]*self.x).sign, u.Sign.UNKNOWN)
        self.assertEqual(exp.canonicalize()[0].size, (1,1))
        self.assertEqual(exp.canonicalize()[1], [])
        self.assertEqual(exp.name(), c.name() + " * " + self.x.name())
        self.assertEqual(exp.size, (1,1))

        with self.assertRaises(Exception) as cm:
            ([2,2,3]*self.x)
        const_name = Constant([2,2,3]).name()
        self.assertEqual(str(cm.exception), 
            "Incompatible dimensions.")

        # Matrices
        with self.assertRaises(Exception) as cm:
            Constant([[2, 1],[2, 2]]) * self.C
        self.assertEqual(str(cm.exception), "Incompatible dimensions.")

        with self.assertRaises(Exception) as cm:
            (self.A * self.B)
        self.assertEqual(str(cm.exception), "Cannot multiply two non-constants.")

        # Constant expressions
        T = Constant([[1,2,3],[3,5,5]])
        exp = (T + T) * self.B
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual(exp.size, (3,2))

        # Expression that would break sign multiplication without promotion.
        c = Constant([[2],[2],[-2]])
        exp = [[1],[2]] + c*self.C
        self.assertEqual(exp.sign.pos_mat.value.shape, (1,2))

    # Test the NegExpression class.
    def test_neg_expression(self):
        # Vectors
        exp = -self.x
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual(exp.sign, u.Sign.UNKNOWN)
        self.assertEqual(exp.canonicalize()[0].size, (2,1))
        self.assertEqual(exp.canonicalize()[1], [])
        self.assertEqual(exp.name(), "-%s" % self.x.name())
        self.assertEqual(exp.size, self.x.size)

        # Matrices
        exp = -self.C
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual(exp.size, (3,2))

    # Test promotion of scalar constants.
    def test_scalar_const_promotion(self):
        # Vectors
        exp = self.x + 2
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual(exp.sign, u.Sign.UNKNOWN)
        self.assertEqual(exp.canonicalize()[0].size, (2,1))
        self.assertEqual(exp.canonicalize()[1], [])
        self.assertEqual(exp.name(), self.x.name() + " + " + Constant(2).name())
        self.assertEqual(exp.size, (2,1))

        self.assertEqual((4 - self.x).size, (2,1))
        self.assertEqual((4 * self.x).size, (2,1))
        self.assertEqual((4 <= self.x).size, (2,1))
        self.assertEqual((4 == self.x).size, (2,1))
        self.assertEqual((self.x >= 4).size, (2,1))

        # Matrices
        exp = (self.A + 2) + 4
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual((3 * self.A).size, (2,2))

        self.assertEqual(exp.size, (2,2))

    # Test indexing expression.
    def test_index_expression(self):
        # Tuple of integers as key.
        exp = self.x[1,0]
        self.assertEqual(exp.name(), "x[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEquals(exp.size, (1,1))
        coeff = exp.coefficients(self.intf)
        self.assertEqual(coeff[exp], 1)
        self.assertEqual(exp.value, None)

        with self.assertRaises(Exception) as cm:
            (self.x[2,0])
        self.assertEqual(str(cm.exception), "Invalid indices 2,0 for 'x'.")

        # Slicing
        exp = self.C[0:2,1]
        self.assertEquals(exp.name(), "C[0:2,1]")
        self.assertEquals(exp.size, (2,1))
        exp = self.C[0:,0:2]
        self.assertEquals(exp.name(), "C[0:,0:2]")
        self.assertEquals(exp.size, (3,2))
        exp = self.C[0::2,0::2]
        self.assertEquals(exp.name(), "C[0::2,0::2]")
        self.assertEquals(exp.size, (2,1))
        exp = self.C[:3,:1:2]
        self.assertEquals(exp.name(), "C[0:3,0]")
        self.assertEquals(exp.size, (3,1))


        c = Constant([[1,-2],[0,4]])
        exp = c[1,1]
        print exp
        self.assertEqual(exp.curvature, u.Curvature.CONSTANT)
        self.assertEqual(exp.sign, u.Sign.POSITIVE)
        self.assertEqual(c[0,1].sign, u.Sign.ZERO)
        self.assertEqual(c[1,0].sign, u.Sign.NEGATIVE)
        self.assertEquals(exp.size, (1,1))
        self.assertEqual(exp.value, 4)

        c = Constant([[1,-2,3],[0,4,5],[7,8,9]])
        exp = c[0:3,0:4:2]
        self.assertEqual(exp.curvature, u.Curvature.CONSTANT)
        self.assertEquals(exp.size, (3,2))
        self.assertEqual(exp[0,1].value, 7)

        # Arithmetic expression indexing
        exp = (self.x + self.z)[1,0]
        self.assertEqual(exp.name(), "x[1,0] + z[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEqual(exp.sign, u.Sign.UNKNOWN)
        self.assertEquals(exp.size, (1,1))

        exp = (self.x + self.a)[1,0]
        self.assertEqual(exp.name(), "x[1,0] + a")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEquals(exp.size, (1,1))

        exp = (self.x - self.z)[1,0]
        self.assertEqual(exp.name(), "x[1,0] - z[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEquals(exp.size, (1,1))

        exp = (self.x - self.a)[1,0]
        self.assertEqual(exp.name(), "x[1,0] - a")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEquals(exp.size, (1,1))

        exp = (-self.x)[1,0]
        self.assertEqual(exp.name(), "-x[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEquals(exp.size, (1,1))

        c = Constant([[1,2],[3,4]])
        exp = (c*self.x)[1,0]
        self.assertEqual(exp.name(), "[[2], [4]] * x[0:,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEquals(exp.size, (1,1))

        c = Constant([[1,2],[3,4]])
        exp = (c*self.a)[1,0]
        self.assertEqual(exp.name(), "2 * a")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE)
        self.assertEquals(exp.size, (1,1))