예제 #1
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])
예제 #2
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.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)
예제 #3
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)
예제 #4
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], [])
예제 #5
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()))
예제 #6
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)")
예제 #7
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()))
예제 #8
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))
예제 #9
0
class TestProblem(BaseTest):
    """ Unit tests for the expression/expression module. """
    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')

    def test_to_str(self):
        """Test string representations.
        """
        obj = Minimize(self.a)
        prob = Problem(obj)
        self.assertEqual(repr(prob), "Problem(%s, %s)" % (repr(obj), repr([])))
        constraints = [self.x * 2 == self.x, self.x == 0]
        prob = Problem(obj, constraints)
        self.assertEqual(repr(prob),
                         "Problem(%s, %s)" % (repr(obj), repr(constraints)))

        # Test str.
        result = "minimize %(name)s\nsubject to %(name)s == 0\n           0 <= %(name)s" % {
            "name": self.a.name()
        }
        prob = Problem(Minimize(self.a), [self.a == 0, self.a >= 0])
        self.assertEqual(str(prob), result)

    def test_variables(self):
        """Test the variables method.
        """
        p = Problem(Minimize(self.a), [self.a <= self.x, self.b <= self.A + 2])
        vars_ = p.variables()
        ref = [self.a, self.x, self.b, self.A]
        if PY2:
            self.assertItemsEqual(vars_, ref)
        else:
            self.assertCountEqual(vars_, ref)

    def test_parameters(self):
        """Test the parameters method.
        """
        p1 = Parameter()
        p2 = Parameter(3, sign="negative")
        p3 = Parameter(4, 4, sign="positive")
        p = Problem(Minimize(p1), [self.a + p1 <= p2, self.b <= p3 + p3 + 2])
        params = p.parameters()
        ref = [p1, p2, p3]
        if PY2:
            self.assertItemsEqual(params, ref)
        else:
            self.assertCountEqual(params, ref)

    def test_get_problem_data(self):
        """Test get_problem_data method.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Maximize(exp(self.a))).get_problem_data(s.ECOS)
        self.assertEqual(str(cm.exception),
                         "The solver ECOS cannot solve the problem.")

        data = Problem(Maximize(exp(self.a) + 2)).get_problem_data(s.SCS)
        dims = data["dims"]
        self.assertEqual(dims['ep'], 1)
        self.assertEqual(data["c"].shape, (2, ))
        self.assertEqual(data["A"].shape, (3, 2))

        data = Problem(Minimize(norm(self.x) + 3)).get_problem_data(s.ECOS)
        dims = data["dims"]
        self.assertEqual(dims["q"], [3])
        self.assertEqual(data["c"].shape, (3, ))
        self.assertEqual(data["A"].shape, (0, 3))
        self.assertEqual(data["G"].shape, (3, 3))

        data = Problem(Minimize(norm(self.x) + 3)).get_problem_data(s.CVXOPT)
        dims = data["dims"]
        self.assertEqual(dims["q"], [3])
        self.assertEqual(data["c"].size, (3, 1))
        self.assertEqual(data["A"].size, (0, 3))
        self.assertEqual(data["G"].size, (3, 3))

    def test_unpack_results(self):
        """Test unpack results method.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(exp(self.a))).unpack_results("blah", None)
        self.assertEqual(str(cm.exception), "Unknown solver.")

        prob = Problem(Minimize(exp(self.a)), [self.a == 0])
        args = prob.get_problem_data(s.SCS)
        data = {"c": args["c"], "A": args["A"], "b": args["b"]}
        results_dict = scs.solve(data, args["dims"])
        prob = Problem(Minimize(exp(self.a)), [self.a == 0])
        prob.unpack_results(s.SCS, results_dict)
        self.assertAlmostEqual(self.a.value, 0, places=4)
        self.assertAlmostEqual(prob.value, 1, places=3)
        self.assertAlmostEqual(prob.status, s.OPTIMAL)

        prob = Problem(Minimize(norm(self.x)), [self.x == 0])
        args = prob.get_problem_data(s.ECOS)
        results_dict = ecos.solve(args["c"], args["G"], args["h"],
                                  args["dims"], args["A"], args["b"])
        prob = Problem(Minimize(norm(self.x)), [self.x == 0])
        prob.unpack_results(s.ECOS, results_dict)
        self.assertItemsAlmostEqual(self.x.value, [0, 0])
        self.assertAlmostEqual(prob.value, 0)
        self.assertAlmostEqual(prob.status, s.OPTIMAL)

        prob = Problem(Minimize(norm(self.x)), [self.x == 0])
        args = prob.get_problem_data(s.CVXOPT)
        results_dict = cvxopt.solvers.conelp(args["c"], args["G"], args["h"],
                                             args["dims"], args["A"],
                                             args["b"])
        prob = Problem(Minimize(norm(self.x)), [self.x == 0])
        prob.unpack_results(s.CVXOPT, results_dict)
        self.assertItemsAlmostEqual(self.x.value, [0, 0])
        self.assertAlmostEqual(prob.value, 0)
        self.assertAlmostEqual(prob.status, s.OPTIMAL)

    # Test silencing and enabling solver messages.
    def test_verbose(self):
        import sys
        # From http://stackoverflow.com/questions/5136611/capture-stdout-from-a-script-in-python
        # setup the environment
        outputs = {True: [], False: []}
        backup = sys.stdout
        # ####
        for verbose in [True, False]:
            for solver in installed_solvers():
                # Don't test GLPK because there's a race
                # condition in setting CVXOPT solver options.
                if solver in ["GLPK", "GLPK_MI"]:
                    continue
                # if solver == "GLPK":
                #     # GLPK's stdout is separate from python,
                #     # so we have to do this.
                #     # Note: This probably breaks (badly) on Windows.
                #     import os
                #     import tempfile

                #     stdout_fd = 1
                #     tmp_handle = tempfile.TemporaryFile(bufsize = 0)
                #     os.dup2(tmp_handle.fileno(), stdout_fd)
                # else:
                sys.stdout = StringIO()  # capture output

                p = Problem(Minimize(self.a + self.x[0]),
                            [self.a >= 2, self.x >= 2])
                if SOLVERS[solver].MIP_CAPABLE:
                    p.constraints.append(Bool() == 0)
                p.solve(verbose=verbose, solver=solver)
                if SOLVERS[solver].EXP_CAPABLE:
                    p = Problem(Minimize(self.a), [log(self.a) >= 2])
                    p.solve(verbose=verbose, solver=solver)

                # if solver == "GLPK":
                #     # GLPK's stdout is separate from python,
                #     # so we have to do this.
                #     tmp_handle.seek(0)
                #     out = tmp_handle.read()
                #     tmp_handle.close()
                # else:
                out = sys.stdout.getvalue()  # release output

                outputs[verbose].append((out, solver))
        # ####
        sys.stdout.close()  # close the stream
        sys.stdout = backup  # restore original stdout
        for output, solver in outputs[True]:
            print(solver)
            assert len(output) > 0
        for output, solver in outputs[False]:
            print(solver)
            assert len(output) == 0

    # Test registering other solve methods.
    def test_register_solve(self):
        Problem.register_solve("test", lambda self: 1)
        p = Problem(Minimize(1))
        result = p.solve(method="test")
        self.assertEqual(result, 1)

        def test(self, a, b=2):
            return (a, b)

        Problem.register_solve("test", test)
        p = Problem(Minimize(0))
        result = p.solve(1, b=3, method="test")
        self.assertEqual(result, (1, 3))
        result = p.solve(1, method="test")
        self.assertEqual(result, (1, 2))
        result = p.solve(1, method="test", b=4)
        self.assertEqual(result, (1, 4))

    def test_consistency(self):
        """Test that variables and constraints keep a consistent order.
        """
        import itertools
        num_solves = 4
        vars_lists = []
        ineqs_lists = []
        var_ids_order_created = []
        for k in range(num_solves):
            sum = 0
            constraints = []
            var_ids = []
            for i in range(100):
                var = Variable(name=str(i))
                var_ids.append(var.id)
                sum += var
                constraints.append(var >= i)
            var_ids_order_created.append(var_ids)
            obj = Minimize(sum)
            p = Problem(obj, constraints)
            objective, constraints = p.canonicalize()
            sym_data = SymData(objective, constraints, SOLVERS[s.ECOS])
            # Sort by offset.
            vars_ = sorted(sym_data.var_offsets.items(),
                           key=lambda key_val: key_val[1])
            vars_ = [var_id for (var_id, offset) in vars_]
            vars_lists.append(vars_)
            ineqs_lists.append(sym_data.constr_map[s.LEQ])

        # Verify order of variables is consistent.
        for i in range(num_solves):
            self.assertEqual(var_ids_order_created[i], vars_lists[i])
        for i in range(num_solves):
            for idx, constr in enumerate(ineqs_lists[i]):
                var_id, _ = lu.get_expr_vars(constr.expr)[0]
                self.assertEqual(var_ids_order_created[i][idx], var_id)

    # Test removing duplicate constraint objects.
    def test_duplicate_constraints(self):
        eq = (self.x == 2)
        le = (self.x <= 2)
        obj = 0

        def test(self):
            objective, constraints = self.canonicalize()
            sym_data = SymData(objective, constraints, SOLVERS[s.ECOS])
            return (len(sym_data.constr_map[s.EQ]),
                    len(sym_data.constr_map[s.LEQ]))

        Problem.register_solve("test", test)
        p = Problem(Minimize(obj), [eq, eq, le, le])
        result = p.solve(method="test")
        self.assertEqual(result, (1, 1))

        # Internal constraints.
        X = Semidef(2)
        obj = sum_entries(X + X)
        p = Problem(Minimize(obj))
        result = p.solve(method="test")
        self.assertEqual(result, (0, 1))

        # Duplicates from non-linear constraints.
        exp = norm(self.x, 2)
        prob = Problem(Minimize(0), [exp <= 1, exp <= 2])
        result = prob.solve(method="test")
        self.assertEqual(result, (0, 4))

    # Test the is_dcp method.
    def test_is_dcp(self):
        p = Problem(Minimize(normInf(self.a)))
        self.assertEqual(p.is_dcp(), True)

        p = Problem(Maximize(normInf(self.a)))
        self.assertEqual(p.is_dcp(), False)
        with self.assertRaises(Exception) as cm:
            p.solve()
        self.assertEqual(str(cm.exception),
                         "Problem does not follow DCP rules.")
        p.solve(ignore_dcp=True)

    # Test problems involving variables with the same name.
    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)

    # Test scalar LP problems.
    def test_scalar_lp(self):
        p = Problem(Minimize(3 * self.a), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 6)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Maximize(3 * self.a - self.b),
                    [self.a <= 2, self.b == self.a, self.b <= 5])
        result = p.solve()
        self.assertAlmostEqual(result, 4.0)
        self.assertAlmostEqual(self.a.value, 2)
        self.assertAlmostEqual(self.b.value, 2)

        # With a constant in the objective.
        p = Problem(Minimize(3 * self.a - self.b + 100), [
            self.a >= 2, self.b + 5 * self.c - 2 == self.a,
            self.b <= 5 + self.c
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 101 + 1.0 / 6)
        self.assertAlmostEqual(self.a.value, 2)
        self.assertAlmostEqual(self.b.value, 5 - 1.0 / 6)
        self.assertAlmostEqual(self.c.value, -1.0 / 6)

        # Test status and value.
        exp = Maximize(self.a)
        p = Problem(exp, [self.a <= 2])
        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.OPTIMAL)
        assert self.a.value is not None
        assert p.constraints[0].dual_value is not None

        # Unbounded problems.
        p = Problem(Maximize(self.a), [self.a >= 2])
        p.solve(solver=s.ECOS)
        self.assertEqual(p.status, s.UNBOUNDED)
        assert numpy.isinf(p.value)
        assert p.value > 0
        assert self.a.value is None
        assert p.constraints[0].dual_value is None

        p = Problem(Minimize(-self.a), [self.a >= 2])
        result = p.solve(solver=s.CVXOPT)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.UNBOUNDED)
        assert numpy.isinf(p.value)
        assert p.value < 0

        # Infeasible problems.
        p = Problem(Maximize(self.a), [self.a >= 2, self.a <= 1])
        self.a.save_value(2)
        p.constraints[0].save_value(2)

        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.INFEASIBLE)
        assert numpy.isinf(p.value)
        assert p.value < 0
        assert self.a.value is None
        assert p.constraints[0].dual_value is None

        p = Problem(Minimize(-self.a), [self.a >= 2, self.a <= 1])
        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.INFEASIBLE)
        assert numpy.isinf(p.value)
        assert p.value > 0

    # Test vector LP problems.
    def test_vector_lp(self):
        c = matrix([1, 2])
        p = Problem(Minimize(c.T * self.x), [self.x >= c])
        result = p.solve()
        self.assertAlmostEqual(result, 5)
        self.assertItemsAlmostEqual(self.x.value, [1, 2])

        A = matrix([[3, 5], [1, 2]])
        I = Constant([[1, 0], [0, 1]])
        p = Problem(Minimize(c.T * self.x + self.a), [
            A * self.x >= [-1, 1], 4 * I * self.z == self.x, self.z >= [2, 2],
            self.a >= 2
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 26, places=3)
        obj = c.T * self.x.value + self.a.value
        self.assertAlmostEqual(obj[0, 0], result)
        self.assertItemsAlmostEqual(self.x.value, [8, 8], places=3)
        self.assertItemsAlmostEqual(self.z.value, [2, 2], places=3)

    def test_ecos_noineq(self):
        """Test ECOS with no inequality constraints.
        """
        T = matrix(1, (2, 2))
        p = Problem(Minimize(1), [self.A == T])
        result = p.solve(solver=s.ECOS)
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, T)

    # Test matrix LP problems.
    def test_matrix_lp(self):
        T = matrix(1, (2, 2))
        p = Problem(Minimize(1), [self.A == T])
        result = p.solve()
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, T)

        T = matrix(2, (2, 3))
        c = matrix([3, 4])
        p = Problem(Minimize(1),
                    [self.A >= T * self.C, self.A == self.B, self.C == T.T])
        result = p.solve()
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, self.B.value)
        self.assertItemsAlmostEqual(self.C.value, T)
        assert (self.A.value >= T * self.C.value).all()

        # Test variables are dense.
        self.assertEqual(type(self.A.value),
                         intf.DEFAULT_INTERFACE.TARGET_MATRIX)

    # Test variable promotion.
    def test_variable_promotion(self):
        p = Problem(Minimize(self.a), [self.x <= self.a, self.x == [1, 2]])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Minimize(self.a),
                    [self.A <= self.a, self.A == [[1, 2], [3, 4]]])
        result = p.solve()
        self.assertAlmostEqual(result, 4)
        self.assertAlmostEqual(self.a.value, 4)

        # Promotion must happen before the multiplication.
        p = Problem(Minimize([[1], [1]] * (self.x + self.a + 1)),
                    [self.a + self.x >= [1, 2]])
        result = p.solve()
        self.assertAlmostEqual(result, 5)

    # Test parameter promotion.
    def test_parameter_promotion(self):
        a = Parameter()
        exp = [[1, 2], [3, 4]] * a
        a.value = 2
        assert not (exp.value - 2 * numpy.array([[1, 2], [3, 4]]).T).any()

    def test_parameter_problems(self):
        """Test problems with parameters.
        """
        p1 = Parameter()
        p2 = Parameter(3, sign="negative")
        p3 = Parameter(4, 4, sign="positive")
        p = Problem(Maximize(p1 * self.a),
                    [self.a + p1 <= p2, self.b <= p3 + p3 + 2])
        p1.value = 2
        p2.value = -numpy.ones((3, 1))
        p3.value = numpy.ones((4, 4))
        result = p.solve()
        self.assertAlmostEqual(result, -6)

    # Test problems with normInf
    def test_normInf(self):
        # Constant argument.
        p = Problem(Minimize(normInf(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(normInf(self.a)), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Minimize(3 * normInf(self.a + 2 * self.b) + self.c),
                    [self.a >= 2, self.b <= -1, self.c == 3])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertAlmostEqual(self.a.value + 2 * self.b.value, 0)
        self.assertAlmostEqual(self.c.value, 3)

        # Maximize
        p = Problem(Maximize(-normInf(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(normInf(self.x - self.z) + 5),
                    [self.x >= [2, 3], self.z <= [-1, -4]])
        result = p.solve()
        self.assertAlmostEqual(float(result), 12)
        self.assertAlmostEqual(
            float(list(self.x.value)[1] - list(self.z.value)[1]), 7)

    # Test problems with norm1
    def test_norm1(self):
        # Constant argument.
        p = Problem(Minimize(norm1(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(norm1(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, -2)

        # Maximize
        p = Problem(Maximize(-norm1(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(norm1(self.x - self.z) + 5),
                    [self.x >= [2, 3], self.z <= [-1, -4]])
        result = p.solve()
        self.assertAlmostEqual(float(result), 15)
        self.assertAlmostEqual(
            float(list(self.x.value)[1] - list(self.z.value)[1]), 7)

    # Test problems with norm2
    def test_norm2(self):
        # Constant argument.
        p = Problem(Minimize(norm2(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(norm2(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, -2)

        # Maximize
        p = Problem(Maximize(-norm2(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(norm2(self.x - self.z) + 5),
                    [self.x >= [2, 3], self.z <= [-1, -4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12.61577)
        self.assertItemsAlmostEqual(self.x.value, [2, 3])
        self.assertItemsAlmostEqual(self.z.value, [-1, -4])

        # Row  arguments.
        p = Problem(Minimize(norm2((self.x - self.z).T) + 5),
                    [self.x >= [2, 3], self.z <= [-1, -4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12.61577)
        self.assertItemsAlmostEqual(self.x.value, [2, 3])
        self.assertItemsAlmostEqual(self.z.value, [-1, -4])

    # Test problems with abs
    def test_abs(self):
        p = Problem(Minimize(sum_entries(abs(self.A))), [-2 >= self.A])
        result = p.solve()
        self.assertAlmostEqual(result, 8)
        self.assertItemsAlmostEqual(self.A.value, [-2, -2, -2, -2])

    # Test problems with quad_form.
    def test_quad_form(self):
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(self.x, self.A))).solve()
        self.assertEqual(
            str(cm.exception),
            "At least one argument to quad_form must be constant.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(1, self.A))).solve()
        self.assertEqual(str(cm.exception),
                         "Invalid dimensions for arguments.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(self.x, [[-1, 0], [0, 9]]))).solve()
        self.assertEqual(str(cm.exception),
                         "P has both positive and negative eigenvalues.")

        P = [[4, 0], [0, 9]]
        p = Problem(Minimize(quad_form(self.x, P)), [self.x >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 13, places=3)

        c = [1, 2]
        p = Problem(Minimize(quad_form(c, self.A)), [self.A >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 9)

        c = [1, 2]
        P = [[4, 0], [0, 9]]
        p = Problem(Minimize(quad_form(c, P)))
        result = p.solve()
        self.assertAlmostEqual(result, 40)

    # Test combining atoms
    def test_mixed_atoms(self):
        p = Problem(
            Minimize(
                norm2(5 + norm1(self.z) + norm1(self.x) +
                      normInf(self.x - self.z))), [
                          self.x >= [2, 3], self.z <= [-1, -4],
                          norm2(self.x + self.z) <= 2
                      ])
        result = p.solve()
        self.assertAlmostEqual(result, 22)
        self.assertItemsAlmostEqual(self.x.value, [2, 3])
        self.assertItemsAlmostEqual(self.z.value, [-1, -4])

    # Test multiplying by constant atoms.
    def test_mult_constant_atoms(self):
        p = Problem(Minimize(norm2([3, 4]) * self.a), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertAlmostEqual(self.a.value, 2)

    # Test recovery of dual variables.
    def test_dual_variables(self):
        p = Problem(Minimize(norm1(self.x + self.z)), [
            self.x >= [2, 3], [[1, 2], [3, 4]] * self.z == [-1, -4],
            norm2(self.x + self.z) <= 100
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 4)
        self.assertItemsAlmostEqual(self.x.value, [4, 3])
        self.assertItemsAlmostEqual(self.z.value, [-4, 1])
        # Dual values
        self.assertItemsAlmostEqual(p.constraints[0].dual_value, [0, 1])
        self.assertItemsAlmostEqual(p.constraints[1].dual_value, [-1, 0.5])
        self.assertAlmostEqual(p.constraints[2].dual_value, 0)

        T = matrix(2, (2, 3))
        c = matrix([3, 4])
        p = Problem(Minimize(1),
                    [self.A >= T * self.C, self.A == self.B, self.C == T.T])
        result = p.solve()
        # Dual values
        self.assertItemsAlmostEqual(p.constraints[0].dual_value, 4 * [0])
        self.assertItemsAlmostEqual(p.constraints[1].dual_value, 4 * [0])
        self.assertItemsAlmostEqual(p.constraints[2].dual_value, 6 * [0])

    # Test problems with indexing.
    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)

    # Test problems with slicing.
    def test_slicing(self):
        p = Problem(Maximize(sum_entries(self.C)),
                    [self.C[1:3, :] <= 2, self.C[0, :] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2 * [1, 2, 2])

        p = Problem(Maximize(sum_entries(self.C[0:3:2, 1])),
                    [self.C[1:3, :] <= 2, self.C[0, :] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.C.value[0:3:2, 1], [1, 2])

        p = Problem(Maximize(sum_entries((self.C[0:2, :] + self.A)[:, 0:2])),
                    [
                        self.C[1:3, :] <= 2, self.C[0, :] == 1,
                        (self.A + self.B)[:, 0] == 3,
                        (self.A + self.B)[:, 1] == 2, self.B == 1
                    ])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertItemsAlmostEqual(self.C.value[0:2, :], [1, 2, 1, 2])
        self.assertItemsAlmostEqual(self.A.value, [2, 2, 1, 1])

        p = Problem(Maximize([[3], [4]] * (self.C[0:2, :] + self.A)[:, 0]), [
            self.C[1:3, :] <= 2, self.C[0, :] == 1, [[1], [2]] *
            (self.A + self.B)[:, 0] == 3,
            (self.A + self.B)[:, 1] == 2, self.B == 1, 3 * self.A[:, 0] <= 3
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertItemsAlmostEqual(self.C.value[0:2, 0], [1, 2])
        self.assertItemsAlmostEqual(self.A.value, [1, -.5, 1, 1])

        p = Problem(Minimize(norm2((self.C[0:2, :] + self.A)[:, 0])),
                    [
                        self.C[1:3, :] <= 2, self.C[0, :] == 1,
                        (self.A + self.B)[:, 0] == 3,
                        (self.A + self.B)[:, 1] == 2, self.B == 1
                    ])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.C.value[0:2, 0], [1, -2])
        self.assertItemsAlmostEqual(self.A.value, [2, 2, 1, 1])

        # Transpose of slice.
        p = Problem(Maximize(sum_entries(self.C)),
                    [self.C[1:3, :].T <= 2, self.C[0, :].T == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2 * [1, 2, 2])

    # Test the vstack atom.
    def test_vstack(self):
        c = matrix(1, (1, 5))
        p = Problem(Minimize(c * vstack(self.x, self.y)),
                    [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 * vstack(self.x, self.x)), [self.x == [1, 2]])
        result = p.solve()
        self.assertAlmostEqual(result, 6)

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

        c = matrix(1, (1, 2))
        p = Problem(Minimize(sum_entries(vstack(c * self.A, c * self.B))),
                    [self.A >= 2, self.B == -2])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

        c = matrix([1, -1])
        p = Problem(Minimize(c.T * vstack(square(self.a), sqrt(self.b))),
                    [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.")

    # Test the hstack atom.
    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.")

    def test_bad_objective(self):
        """Test using a cvxpy expression as an objective.
        """
        with self.assertRaises(Exception) as cm:
            Problem(self.x + 2)
        self.assertEqual(str(cm.exception),
                         "Problem objective must be Minimize or Maximize.")

    # Test variable transpose.
    def test_transpose(self):
        p = Problem(Minimize(sum_entries(self.x)),
                    [self.x.T >= matrix([1, 2]).T])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.x.value, [1, 2])

        p = Problem(Minimize(sum_entries(self.C)),
                    [matrix([1, 1]).T * self.C.T >= matrix([0, 1, 2]).T])
        result = p.solve()
        value = self.C.value

        constraints = [
            1 * self.C[i, 0] + 1 * self.C[i, 1] >= i for i in range(3)
        ]
        p = Problem(Minimize(sum_entries(self.C)), constraints)
        result2 = p.solve()
        self.assertAlmostEqual(result, result2)
        self.assertItemsAlmostEqual(self.C.value, value)

        p = Problem(Minimize(self.A[0, 1] - self.A.T[1, 0]),
                    [self.A == [[1, 2], [3, 4]]])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

        exp = (-self.x).T
        p = Problem(Minimize(sum_entries(self.x)), [(-self.x).T <= 1])
        result = p.solve()
        self.assertAlmostEqual(result, -2)

        c = matrix([1, -1])
        p = Problem(Minimize(max_elemwise(c.T, 2, 2 + c.T)[1]))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        c = matrix([[1, -1, 2], [1, -1, 2]])
        p = Problem(Minimize(sum_entries(max_elemwise(c, 2, 2 + c).T[:, 0])))
        result = p.solve()
        self.assertAlmostEqual(result, 6)

        c = matrix([[1, -1, 2], [1, -1, 2]])
        p = Problem(Minimize(sum_entries(square(c.T).T[:, 0])))
        result = p.solve()
        self.assertAlmostEqual(result, 6)

        # Slice of transpose.
        p = Problem(Maximize(sum_entries(self.C)),
                    [self.C.T[:, 1:3] <= 2, self.C.T[:, 0] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2 * [1, 2, 2])

    # Test multiplication on the left by a non-constant.
    def test_multiplication_on_left(self):
        c = matrix([1, 2])
        p = Problem(Minimize(c.T * self.A * c), [self.A >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 18)

        p = Problem(Minimize(self.a * 2), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 4)

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

        p = Problem(Minimize((self.x.T + self.z.T) * c),
                    [self.x >= 2, self.z >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 9)

    # Test redundant constraints in cvxopt.
    def test_redundant_constraints(self):
        obj = Minimize(sum_entries(self.x))
        constraints = [self.x == 2, self.x == 2, self.x.T == 2, self.x[0] == 2]
        p = Problem(obj, constraints)
        result = p.solve(solver=s.CVXOPT)
        self.assertAlmostEqual(result, 4)

        obj = Minimize(sum_entries(square(self.x)))
        constraints = [self.x == self.x]
        p = Problem(obj, constraints)
        result = p.solve(solver=s.CVXOPT)
        self.assertAlmostEqual(result, 0)

    # Test that symmetry is enforced.
    def test_sdp_symmetry(self):
        # TODO should these raise exceptions?
        # with self.assertRaises(Exception) as cm:
        #     lambda_max([[1,2],[3,4]])
        # self.assertEqual(str(cm.exception), "lambda_max called on non-symmetric matrix.")

        # with self.assertRaises(Exception) as cm:
        #     lambda_min([[1,2],[3,4]])
        # self.assertEqual(str(cm.exception), "lambda_min called on non-symmetric matrix.")

        p = Problem(Minimize(lambda_max(self.A)), [self.A >= 2])
        result = p.solve()
        self.assertItemsAlmostEqual(self.A.value, self.A.value.T)

        p = Problem(Minimize(lambda_max(self.A)), [self.A == [[1, 2], [3, 4]]])
        result = p.solve()
        self.assertEqual(p.status, s.INFEASIBLE)

    # Test SDP
    def test_sdp(self):
        # Ensure sdp constraints enforce transpose.
        obj = Maximize(self.A[1, 0] - self.A[0, 1])
        p = Problem(obj, [
            lambda_max(self.A) <= 100, self.A[0, 0] == 2, self.A[1, 1] == 2,
            self.A[1, 0] == 2
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

    # Test getting values for expressions.
    def test_expression_values(self):
        diff_exp = self.x - self.z
        inf_exp = normInf(diff_exp)
        sum_entries_exp = 5 + norm1(self.z) + norm1(self.x) + inf_exp
        constr_exp = norm2(self.x + self.z)
        obj = norm2(sum_entries_exp)
        p = Problem(Minimize(obj),
                    [self.x >= [2, 3], self.z <= [-1, -4], constr_exp <= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 22)
        self.assertItemsAlmostEqual(self.x.value, [2, 3])
        self.assertItemsAlmostEqual(self.z.value, [-1, -4])
        # Expression values.
        self.assertItemsAlmostEqual(diff_exp.value,
                                    self.x.value - self.z.value)
        self.assertAlmostEqual(inf_exp.value,
                               LA.norm(self.x.value - self.z.value, numpy.inf))
        self.assertAlmostEqual(sum_entries_exp.value,
            5 + LA.norm(self.z.value, 1) + LA.norm(self.x.value, 1) + \
            LA.norm(self.x.value - self.z.value, numpy.inf))
        self.assertAlmostEqual(constr_exp.value,
                               LA.norm(self.x.value + self.z.value, 2))
        self.assertAlmostEqual(obj.value, result)

    def test_mult_by_zero(self):
        """Test multiplication by zero.
        """
        exp = 0 * self.a
        self.assertEqual(exp.value, 0)
        obj = Minimize(exp)
        p = Problem(obj)
        result = p.solve()
        self.assertAlmostEqual(result, 0)
        assert self.a.value is not None

    def test_div(self):
        """Tests a problem with division.
        """
        obj = Minimize(normInf(self.A / 5))
        p = Problem(obj, [self.A >= 5])
        result = p.solve()
        self.assertAlmostEqual(result, 1)

    def test_mul_elemwise(self):
        """Tests problems with mul_elemwise.
        """
        c = [[1, -1], [2, -2]]
        expr = mul_elemwise(c, self.A)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.A == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, -5] + [10, -10])

        # Test with a sparse matrix.
        import cvxopt
        interface = intf.get_matrix_interface(cvxopt.spmatrix)
        c = interface.const_to_matrix([1, 2])
        expr = mul_elemwise(c, self.x)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.x == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, 10])

        # Test promotion.
        c = [[1, -1], [2, -2]]
        expr = mul_elemwise(c, self.a)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.a == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, -5] + [10, -10])

    def test_invalid_solvers(self):
        """Tests that errors occur when you use an invalid solver.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(-log(self.a))).solve(solver=s.ECOS)
        self.assertEqual(str(cm.exception),
                         "The solver ECOS cannot solve the problem.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(lambda_max(self.a))).solve(solver=s.ECOS)
        self.assertEqual(str(cm.exception),
                         "The solver ECOS cannot solve the problem.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(self.a)).solve(solver=s.SCS)
        self.assertEqual(str(cm.exception),
                         "The solver SCS cannot solve the problem.")

    def test_reshape(self):
        """Tests problems with reshape.
        """
        # Test on scalars.
        self.assertEqual(reshape(1, 1, 1).value, 1)

        # Test vector to matrix.
        x = Variable(4)
        mat = matrix([[1, -1], [2, -2]])
        vec = matrix([1, 2, 3, 4])
        vec_mat = matrix([[1, 2], [3, 4]])
        expr = reshape(x, 2, 2)
        obj = Minimize(sum_entries(mat * expr))
        prob = Problem(obj, [x == vec])
        result = prob.solve()
        self.assertAlmostEqual(result, sum(mat * vec_mat))

        # Test on matrix to vector.
        c = [1, 2, 3, 4]
        expr = reshape(self.A, 4, 1)
        obj = Minimize(expr.T * c)
        constraints = [self.A == [[-1, -2], [3, 4]]]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 20)
        self.assertItemsAlmostEqual(expr.value, [-1, -2, 3, 4])
        self.assertItemsAlmostEqual(reshape(expr, 2, 2).value, [-1, -2, 3, 4])

        # Test matrix to matrix.
        expr = reshape(self.C, 2, 3)
        mat = numpy.matrix([[1, -1], [2, -2]])
        C_mat = numpy.matrix([[1, 4], [2, 5], [3, 6]])
        obj = Minimize(sum_entries(mat * expr))
        prob = Problem(obj, [self.C == C_mat])
        result = prob.solve()
        reshaped = numpy.reshape(C_mat, (2, 3), 'F')
        self.assertAlmostEqual(result, (mat.dot(reshaped)).sum())
        self.assertItemsAlmostEqual(expr.value, C_mat)

        # Test promoted expressions.
        c = matrix([[1, -1], [2, -2]])
        expr = reshape(c * self.a, 1, 4)
        obj = Minimize(expr * [1, 2, 3, 4])
        prob = Problem(obj, [self.a == 2])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(expr.value, 2 * c)

        expr = reshape(c * self.a, 4, 1)
        obj = Minimize(expr.T * [1, 2, 3, 4])
        prob = Problem(obj, [self.a == 2])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(expr.value, 2 * c)

    def test_vec(self):
        """Tests problems with vec.
        """
        c = [1, 2, 3, 4]
        expr = vec(self.A)
        obj = Minimize(expr.T * c)
        constraints = [self.A == [[-1, -2], [3, 4]]]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 20)
        self.assertItemsAlmostEqual(expr.value, [-1, -2, 3, 4])

    def test_diag_prob(self):
        """Test a problem with diag.
        """
        C = Variable(3, 3)
        obj = Maximize(C[0, 2])
        constraints = [
            diag(C) == 1, C[0, 1] == 0.6, C[1, 2] == -0.3, C == Semidef(3)
        ]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 0.583151)

    def test_presolve_constant_constraints(self):
        """Test that the presolver removes constraints with no variables.
        """
        x = Variable()
        obj = Maximize(sqrt(x))
        prob = Problem(obj)
        data = prob.get_problem_data(s.ECOS)
        A = data["A"]
        G = data["G"]
        for row in range(A.shape[0]):
            assert A[row, :].nnz > 0
        for row in range(G.shape[0]):
            assert G[row, :].nnz > 0

    def test_presolve_parameters(self):
        """Test presolve with parameters.
        """
        # Test with parameters.
        gamma = Parameter(sign="positive")
        x = Variable()
        obj = Minimize(x)
        prob = Problem(obj, [gamma == 1, x >= 0])
        gamma.value = 0
        prob.solve(solver=s.SCS)
        self.assertEqual(prob.status, s.INFEASIBLE)

        gamma.value = 1
        prob.solve(solver=s.CVXOPT)
        self.assertEqual(prob.status, s.OPTIMAL)

    def test_parameter_expressions(self):
        """Test that expressions with parameters are updated properly.
        """
        x = Variable()
        y = Variable()
        x0 = Parameter()
        xSquared = x0 * x0 + 2 * x0 * (x - x0)

        # initial guess for x
        x0.value = 2

        # make the constraint x**2 - y == 0
        g = xSquared - y

        # set up the problem
        obj = abs(x - 1)
        prob = Problem(Minimize(obj), [g == 0])
        prob.solve()
        x0.value = 1
        prob.solve()
        self.assertAlmostEqual(g.value, 0)

        # Test multiplication.
        prob = Problem(Minimize(x0 * x), [x == 1])
        x0.value = 2
        prob.solve()
        x0.value = 1
        prob.solve()
        self.assertAlmostEqual(prob.value, 1)

    def test_geo_mean(self):
        import numpy as np

        x = Variable(2)
        cost = geo_mean(x)
        prob = Problem(Maximize(cost), [x <= 1])
        prob.solve()
        self.assertAlmostEqual(prob.value, 1)

        prob = Problem(Maximize(cost), [sum(x) <= 1])
        prob.solve()
        self.assertItemsAlmostEqual(x.value, [.5, .5])

        x = Variable(3, 3)
        self.assertRaises(ValueError, geo_mean, x)

        x = Variable(3, 1)
        g = geo_mean(x)
        self.assertSequenceEqual(g.w, [Fraction(1, 3)] * 3)

        x = Variable(1, 5)
        g = geo_mean(x)
        self.assertSequenceEqual(g.w, [Fraction(1, 5)] * 5)

        # check that we get the right answer for
        # max geo_mean(x) s.t. sum(x) <= 1
        p = np.array([.07, .12, .23, .19, .39])

        def short_geo_mean(x, p):
            p = np.array(p) / sum(p)
            x = np.array(x)
            return np.prod(x**p)

        x = Variable(5)
        prob = Problem(Maximize(geo_mean(x, p)), [sum(x) <= 1])
        prob.solve()
        x = np.array(x.value).flatten()
        x_true = p / sum(p)

        self.assertTrue(np.allclose(prob.value, geo_mean(list(x), p).value))
        self.assertTrue(np.allclose(prob.value, short_geo_mean(x, p)))
        self.assertTrue(np.allclose(x, x_true, 1e-3))

        # check that we get the right answer for
        # max geo_mean(x) s.t. norm(x) <= 1
        x = Variable(5)
        prob = Problem(Maximize(geo_mean(x, p)), [norm(x) <= 1])
        prob.solve()
        x = np.array(x.value).flatten()
        x_true = np.sqrt(p / sum(p))

        self.assertTrue(np.allclose(prob.value, geo_mean(list(x), p).value))
        self.assertTrue(np.allclose(prob.value, short_geo_mean(x, p)))
        self.assertTrue(np.allclose(x, x_true, 1e-3))

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

    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)
예제 #10
0
class TestProblem(BaseTest):
    """ Unit tests for the expression/expression module. """
    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')

    def test_to_str(self):
        """Test string representations.
        """
        obj = Minimize(self.a)
        prob = Problem(obj)
        self.assertEqual(repr(prob), "Problem(%s, %s)" % (repr(obj), repr([])))
        constraints = [self.x*2 == self.x, self.x == 0]
        prob = Problem(obj, constraints)
        self.assertEqual(repr(prob), "Problem(%s, %s)" % (repr(obj), repr(constraints)))

        # Test str.
        result = "minimize %(name)s\nsubject to %(name)s == 0\n           0 <= %(name)s" % {"name": self.a.name()}
        prob = Problem(Minimize(self.a), [self.a == 0, self.a >= 0])
        self.assertEqual(str(prob), result)

    def test_variables(self):
        """Test the variables method.
        """
        p = Problem(Minimize(self.a), [self.a <= self.x, self.b <= self.A + 2])
        vars_ = p.variables()
        self.assertItemsEqual(vars_, [self.a, self.x, self.b, self.A])

    def test_parameters(self):
        """Test the parameters method.
        """
        p1 = Parameter()
        p2 = Parameter(3, sign="negative")
        p3 = Parameter(4, 4, sign="positive")
        p = Problem(Minimize(p1), [self.a + p1 <= p2, self.b <= p3 + p3 + 2])
        params = p.parameters()
        self.assertItemsEqual(params, [p1, p2, p3])

    def test_get_problem_data(self):
        """Test get_problem_data method.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Maximize(exp(self.a))).get_problem_data(s.ECOS)
        self.assertEqual(str(cm.exception), "The solver ECOS cannot solve the problem.")

        with self.assertRaises(Exception) as cm:
            Problem(Maximize(exp(self.a))).get_problem_data(s.CVXOPT)
        self.assertEqual(str(cm.exception), "Cannot return problem data for the solver CVXOPT.")

        args = Problem(Maximize(exp(self.a) + 2)).get_problem_data(s.SCS)
        data, dims = args
        self.assertEqual(dims['ep'], 1)
        self.assertEqual(data["c"].shape, (2,))
        self.assertEqual(data["A"].shape, (3, 2))

        args = Problem(Minimize(norm(self.x) + 3)).get_problem_data(s.ECOS)
        c, G, h, dims, A, b = args
        self.assertEqual(dims["q"], [3])
        self.assertEqual(c.shape, (3,))
        self.assertEqual(A.shape, (0, 3))
        self.assertEqual(G.shape, (3, 3))

        args = Problem(Minimize(norm(self.x) + 3)).get_problem_data(s.CVXOPT)
        c, G, h, dims, A, b = args
        self.assertEqual(dims["q"], [3])
        self.assertEqual(c.size, (3, 1))
        self.assertEqual(A.size, (0, 3))
        self.assertEqual(G.size, (3, 3))

    # Test silencing and enabling solver messages.
    def test_verbose(self):
        # From http://stackoverflow.com/questions/5136611/capture-stdout-from-a-script-in-python
        # setup the environment
        outputs = {True: [], False: []}
        backup = sys.stdout

        # ####
        for verbose in [True, False]:
            for solver in [s.ECOS, s.CVXOPT, s.SCS]:
                sys.stdout = StringIO()     # capture output
                p = Problem(Minimize(self.a + self.x[0]), [self.a >= 2, self.x >= 2])
                p.solve(verbose=verbose, solver=solver)
                if solver != s.ECOS:
                    p = Problem(Minimize(self.a), [log(self.a) >= 2])
                    p.solve(verbose=verbose, solver=solver)
                out = sys.stdout.getvalue() # release output
                outputs[verbose].append(out.upper())
        # ####

        sys.stdout.close()  # close the stream
        sys.stdout = backup # restore original stdout

        for output in outputs[True]:
            assert len(output) > 0
        for output in outputs[False]:
            assert len(output) == 0

    # Test registering other solve methods.
    def test_register_solve(self):
        Problem.register_solve("test",lambda self: 1)
        p = Problem(Minimize(1))
        result = p.solve(method="test")
        self.assertEqual(result, 1)

        def test(self, a, b=2):
            return (a,b)
        Problem.register_solve("test", test)
        p = Problem(Minimize(0))
        result = p.solve(1,b=3,method="test")
        self.assertEqual(result, (1,3))
        result = p.solve(1,method="test")
        self.assertEqual(result, (1,2))
        result = p.solve(1,method="test",b=4)
        self.assertEqual(result, (1,4))

    def test_consistency(self):
        """Test that variables and constraints keep a consistent order.
        """
        import itertools
        num_solves = 4
        vars_lists = []
        ineqs_lists = []
        var_ids_order_created = []
        for k in range(num_solves):
            sum = 0
            constraints = []
            var_ids = []
            for i in range(100):
                var = Variable(name=str(i))
                var_ids.append(var.id)
                sum += var
                constraints.append(var >= i)
            var_ids_order_created.append(var_ids)
            obj = Minimize(sum)
            p = Problem(obj, constraints)
            objective, constr_map = p.canonicalize()
            all_ineq = itertools.chain(constr_map[s.EQ], constr_map[s.LEQ])
            var_offsets, var_sizes, x_length = p._get_var_offsets(objective, all_ineq)
            # Sort by offset.
            vars_ = sorted(var_offsets.items(), key=lambda (var_id, offset): offset)
            vars_ = [var_id for (var_id, offset) in vars_]
            vars_lists.append(vars_)
            ineqs_lists.append(constr_map[s.LEQ])

        # Verify order of variables is consistent.
        for i in range(num_solves):
            self.assertEqual(var_ids_order_created[i],
                vars_lists[i])
        for i in range(num_solves):
            for idx, constr in enumerate(ineqs_lists[i]):
                var_id, _ = lu.get_expr_vars(constr.expr)[0]
                self.assertEqual(var_ids_order_created[i][idx],
                    var_id)

    # Test removing duplicate constraint objects.
    def test_duplicate_constraints(self):
        eq = (self.x == 2)
        le = (self.x <= 2)
        obj = 0
        def test(self):
            objective, constr_map  = self.canonicalize()
            self._presolve(objective, constr_map)
            print len(constr_map[s.SOC])
            dims = self._format_for_solver(constr_map, s.ECOS)
            return (len(constr_map[s.EQ]),len(constr_map[s.LEQ]))
        Problem.register_solve("test", test)
        p = Problem(Minimize(obj),[eq,eq,le,le])
        result = p.solve(method="test")
        self.assertEqual(result, (1, 1))

        # Internal constraints.
        X = Semidef(2)
        obj = sum_entries(X + X)
        p = Problem(Minimize(obj))
        result = p.solve(method="test")
        self.assertEqual(result, (1, 1))

        # Duplicates from non-linear constraints.
        exp = norm(self.x, 2)
        prob = Problem(Minimize(0), [exp <= 1, exp <= 2])
        result = prob.solve(method="test")
        self.assertEqual(result, (0, 4))

    # Test the is_dcp method.
    def test_is_dcp(self):
        p = Problem(Minimize(normInf(self.a)))
        self.assertEqual(p.is_dcp(), True)

        p = Problem(Maximize(normInf(self.a)))
        self.assertEqual(p.is_dcp(), False)
        with self.assertRaises(Exception) as cm:
            p.solve()
        self.assertEqual(str(cm.exception), "Problem does not follow DCP rules.")
        p.solve(ignore_dcp=True)

    # Test problems involving variables with the same name.
    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)

    # Test scalar LP problems.
    def test_scalar_lp(self):
        p = Problem(Minimize(3*self.a), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 6)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Maximize(3*self.a - self.b),
            [self.a <= 2, self.b == self.a, self.b <= 5])
        result = p.solve()
        self.assertAlmostEqual(result, 4.0)
        self.assertAlmostEqual(self.a.value, 2)
        self.assertAlmostEqual(self.b.value, 2)

        # With a constant in the objective.
        p = Problem(Minimize(3*self.a - self.b + 100),
            [self.a >= 2,
             self.b + 5*self.c - 2 == self.a,
             self.b <= 5 + self.c])
        result = p.solve()
        self.assertAlmostEqual(result, 101 + 1.0/6)
        self.assertAlmostEqual(self.a.value, 2)
        self.assertAlmostEqual(self.b.value, 5-1.0/6)
        self.assertAlmostEqual(self.c.value, -1.0/6)

        # Test status and value.
        exp = Maximize(self.a)
        p = Problem(exp, [self.a <= 2])
        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.OPTIMAL)
        assert self.a.value is not None
        assert p.constraints[0].dual_value is not None

        # Unbounded problems.
        p = Problem(Maximize(self.a), [self.a >= 2])
        p.solve(solver=s.ECOS)
        self.assertEqual(p.status, s.UNBOUNDED)
        assert numpy.isinf(p.value)
        assert p.value > 0
        assert self.a.value is None
        assert p.constraints[0].dual_value is None

        p = Problem(Minimize(-self.a), [self.a >= 2])
        result = p.solve(solver=s.CVXOPT)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.UNBOUNDED)
        assert numpy.isinf(p.value)
        assert p.value < 0

        # Infeasible problems.
        p = Problem(Maximize(self.a), [self.a >= 2, self.a <= 1])
        self.a.save_value(2)
        p.constraints[0].save_value(2)

        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.INFEASIBLE)
        assert numpy.isinf(p.value)
        assert p.value < 0
        assert self.a.value is None
        assert p.constraints[0].dual_value is None

        p = Problem(Minimize(-self.a), [self.a >= 2, self.a <= 1])
        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.INFEASIBLE)
        assert numpy.isinf(p.value)
        assert p.value > 0

    # Test vector LP problems.
    def test_vector_lp(self):
        c = matrix([1,2])
        p = Problem(Minimize(c.T*self.x), [self.x >= c])
        result = p.solve()
        self.assertAlmostEqual(result, 5)
        self.assertItemsAlmostEqual(self.x.value, [1,2])

        A = matrix([[3,5],[1,2]])
        I = Constant([[1,0],[0,1]])
        p = Problem(Minimize(c.T*self.x + self.a),
            [A*self.x >= [-1,1],
             4*I*self.z == self.x,
             self.z >= [2,2],
             self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 26, places=3)
        obj = c.T*self.x.value + self.a.value
        self.assertAlmostEqual(obj[0], result)
        self.assertItemsAlmostEqual(self.x.value, [8,8], places=3)
        self.assertItemsAlmostEqual(self.z.value, [2,2], places=3)

    def test_ecos_noineq(self):
        """Test ECOS with no inequality constraints.
        """
        T = matrix(1, (2, 2))
        p = Problem(Minimize(1), [self.A == T])
        result = p.solve(solver=s.ECOS)
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, T)

    # Test matrix LP problems.
    def test_matrix_lp(self):
        T = matrix(1, (2, 2))
        p = Problem(Minimize(1), [self.A == T])
        result = p.solve()
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, T)

        T = matrix(2,(2,3))
        c = matrix([3,4])
        p = Problem(Minimize(1), [self.A >= T*self.C,
            self.A == self.B, self.C == T.T])
        result = p.solve()
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, self.B.value)
        self.assertItemsAlmostEqual(self.C.value, T)
        assert (self.A.value >= T*self.C.value).all()

        # Test variables are dense.
        self.assertEqual(type(self.A.value), p._DENSE_INTF.TARGET_MATRIX)

    # Test variable promotion.
    def test_variable_promotion(self):
        p = Problem(Minimize(self.a), [self.x <= self.a, self.x == [1,2]])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Minimize(self.a),
            [self.A <= self.a,
             self.A == [[1,2],[3,4]]
             ])
        result = p.solve()
        self.assertAlmostEqual(result, 4)
        self.assertAlmostEqual(self.a.value, 4)

        # Promotion must happen before the multiplication.
        p = Problem(Minimize([[1],[1]]*(self.x + self.a + 1)),
            [self.a + self.x >= [1,2]])
        result = p.solve()
        self.assertAlmostEqual(result, 5)

    # Test parameter promotion.
    def test_parameter_promotion(self):
        a = Parameter()
        exp = [[1,2],[3,4]]*a
        a.value = 2
        assert not (exp.value - 2*numpy.array([[1,2],[3,4]]).T).any()

    def test_parameter_problems(self):
        """Test problems with parameters.
        """
        p1 = Parameter()
        p2 = Parameter(3, sign="negative")
        p3 = Parameter(4, 4, sign="positive")
        p = Problem(Maximize(p1*self.a), [self.a + p1 <= p2, self.b <= p3 + p3 + 2])
        p1.value = 2
        p2.value = -numpy.ones((3,1))
        p3.value = numpy.ones((4, 4))
        result = p.solve()
        self.assertAlmostEqual(result, -6)

    # Test problems with normInf
    def test_normInf(self):
        # Constant argument.
        p = Problem(Minimize(normInf(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(normInf(self.a)), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Minimize(3*normInf(self.a + 2*self.b) + self.c),
            [self.a >= 2, self.b <= -1, self.c == 3])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertAlmostEqual(self.a.value + 2*self.b.value, 0)
        self.assertAlmostEqual(self.c.value, 3)

        # Maximize
        p = Problem(Maximize(-normInf(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(normInf(self.x - self.z) + 5),
            [self.x >= [2,3], self.z <= [-1,-4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertAlmostEqual(list(self.x.value)[1] - list(self.z.value)[1], 7)

    # Test problems with norm1
    def test_norm1(self):
        # Constant argument.
        p = Problem(Minimize(norm1(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(norm1(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, -2)

        # Maximize
        p = Problem(Maximize(-norm1(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(norm1(self.x - self.z) + 5),
            [self.x >= [2,3], self.z <= [-1,-4]])
        result = p.solve()
        self.assertAlmostEqual(result, 15)
        self.assertAlmostEqual(list(self.x.value)[1] - list(self.z.value)[1], 7)

    # Test problems with norm2
    def test_norm2(self):
        # Constant argument.
        p = Problem(Minimize(norm2(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(norm2(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, -2)

        # Maximize
        p = Problem(Maximize(-norm2(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(norm2(self.x - self.z) + 5),
            [self.x >= [2,3], self.z <= [-1,-4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12.61577)
        self.assertItemsAlmostEqual(self.x.value, [2,3])
        self.assertItemsAlmostEqual(self.z.value, [-1,-4])

        # Row  arguments.
        p = Problem(Minimize(norm2((self.x - self.z).T) + 5),
            [self.x >= [2,3], self.z <= [-1,-4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12.61577)
        self.assertItemsAlmostEqual(self.x.value, [2,3])
        self.assertItemsAlmostEqual(self.z.value, [-1,-4])

    # Test problems with abs
    def test_abs(self):
        p = Problem(Minimize(sum_entries(abs(self.A))), [-2 >= self.A])
        result = p.solve()
        self.assertAlmostEqual(result, 8)
        self.assertItemsAlmostEqual(self.A.value, [-2,-2,-2,-2])

    # Test problems with quad_form.
    def test_quad_form(self):
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(self.x, self.A))).solve()
        self.assertEqual(str(cm.exception), "At least one argument to quad_form must be constant.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(1, self.A))).solve()
        self.assertEqual(str(cm.exception), "Invalid dimensions for arguments.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(self.x, [[-1, 0], [0, 9]]))).solve()
        self.assertEqual(str(cm.exception), "P has both positive and negative eigenvalues.")

        P = [[4, 0], [0, 9]]
        p = Problem(Minimize(quad_form(self.x, P)), [self.x >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 13, places=3)

        c = [1,2]
        p = Problem(Minimize(quad_form(c, self.A)), [self.A >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 9)

        c = [1,2]
        P = [[4, 0], [0, 9]]
        p = Problem(Minimize(quad_form(c, P)))
        result = p.solve()
        self.assertAlmostEqual(result, 40)

    # Test combining atoms
    def test_mixed_atoms(self):
        p = Problem(Minimize(norm2(5 + norm1(self.z)
                                  + norm1(self.x) +
                                  normInf(self.x - self.z) ) ),
            [self.x >= [2,3], self.z <= [-1,-4], norm2(self.x + self.z) <= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 22)
        self.assertItemsAlmostEqual(self.x.value, [2,3])
        self.assertItemsAlmostEqual(self.z.value, [-1,-4])

    # Test multiplying by constant atoms.
    def test_mult_constant_atoms(self):
        p = Problem(Minimize(norm2([3,4])*self.a), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertAlmostEqual(self.a.value, 2)

    # Test recovery of dual variables.
    def test_dual_variables(self):
        p = Problem(Minimize( norm1(self.x + self.z) ),
            [self.x >= [2,3],
             [[1,2],[3,4]]*self.z == [-1,-4],
             norm2(self.x + self.z) <= 100])
        result = p.solve()
        self.assertAlmostEqual(result, 4)
        self.assertItemsAlmostEqual(self.x.value, [4,3])
        self.assertItemsAlmostEqual(self.z.value, [-4,1])
        # Dual values
        self.assertItemsAlmostEqual(p.constraints[0].dual_value, [0, 1])
        self.assertItemsAlmostEqual(p.constraints[1].dual_value, [-1, 0.5])
        self.assertAlmostEqual(p.constraints[2].dual_value, 0)

        T = matrix(2, (2, 3))
        c = matrix([3,4])
        p = Problem(Minimize(1),
            [self.A >= T*self.C,
             self.A == self.B,
             self.C == T.T])
        result = p.solve()
        # Dual values
        self.assertItemsAlmostEqual(p.constraints[0].dual_value, 4*[0])
        self.assertItemsAlmostEqual(p.constraints[1].dual_value, 4*[0])
        self.assertItemsAlmostEqual(p.constraints[2].dual_value, 6*[0])

    # Test problems with indexing.
    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)

    # Test problems with slicing.
    def test_slicing(self):
        p = Problem(Maximize(sum_entries(self.C)), [self.C[1:3,:] <= 2, self.C[0,:] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2*[1,2,2])

        p = Problem(Maximize(sum_entries(self.C[0:3:2,1])),
            [self.C[1:3,:] <= 2, self.C[0,:] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.C.value[0:3:2,1], [1,2])

        p = Problem(Maximize(sum_entries( (self.C[0:2,:] + self.A)[:,0:2] )),
            [self.C[1:3,:] <= 2, self.C[0,:] == 1,
             (self.A + self.B)[:,0] == 3, (self.A + self.B)[:,1] == 2,
             self.B == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertItemsAlmostEqual(self.C.value[0:2,:], [1,2,1,2])
        self.assertItemsAlmostEqual(self.A.value, [2,2,1,1])

        p = Problem(Maximize( [[3],[4]]*(self.C[0:2,:] + self.A)[:,0] ),
            [self.C[1:3,:] <= 2, self.C[0,:] == 1,
             [[1],[2]]*(self.A + self.B)[:,0] == 3, (self.A + self.B)[:,1] == 2,
             self.B == 1, 3*self.A[:,0] <= 3])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertItemsAlmostEqual(self.C.value[0:2,0], [1,2])
        self.assertItemsAlmostEqual(self.A.value, [1,-.5,1,1])

        p = Problem(Minimize(norm2((self.C[0:2,:] + self.A)[:,0] )),
            [self.C[1:3,:] <= 2, self.C[0,:] == 1,
             (self.A + self.B)[:,0] == 3, (self.A + self.B)[:,1] == 2,
             self.B == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.C.value[0:2,0], [1,-2])
        self.assertItemsAlmostEqual(self.A.value, [2,2,1,1])

        # Transpose of slice.
        p = Problem(Maximize(sum_entries(self.C)), [self.C[1:3,:].T <= 2, self.C[0,:].T == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2*[1,2,2])

    # Test the vstack atom.
    def test_vstack(self):
        c = matrix(1, (1,5))
        p = Problem(Minimize(c * vstack(self.x, self.y)),
            [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 * vstack(self.x, self.x)),
            [self.x == [1,2]])
        result = p.solve()
        self.assertAlmostEqual(result, 6)


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

        c = matrix(1, (1,2))
        p = Problem( Minimize( sum_entries(vstack(c*self.A, c*self.B)) ),
            [self.A >= 2,
            self.B == -2])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

        c = matrix([1,-1])
        p = Problem( Minimize( c.T * vstack(square(self.a), sqrt(self.b))),
            [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.")

    # Test the hstack atom.
    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.")

    def test_bad_objective(self):
        """Test using a cvxpy expression as an objective.
        """
        with self.assertRaises(Exception) as cm:
            Problem(self.x+2)
        self.assertEqual(str(cm.exception), "Problem objective must be Minimize or Maximize.")

    # Test variable transpose.
    def test_transpose(self):
        p = Problem(Minimize(sum_entries(self.x)), [self.x.T >= matrix([1,2]).T])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.x.value, [1,2])

        p = Problem(Minimize(sum_entries(self.C)), [matrix([1,1]).T*self.C.T >= matrix([0,1,2]).T])
        result = p.solve()
        value = self.C.value

        constraints = [1*self.C[i,0] + 1*self.C[i,1] >= i for i in range(3)]
        p = Problem(Minimize(sum_entries(self.C)), constraints)
        result2 = p.solve()
        self.assertAlmostEqual(result, result2)
        self.assertItemsAlmostEqual(self.C.value, value)

        p = Problem(Minimize(self.A[0,1] - self.A.T[1,0]),
                    [self.A == [[1,2],[3,4]]])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

        exp = (-self.x).T
        p = Problem(Minimize(sum_entries(self.x)), [(-self.x).T <= 1])
        result = p.solve()
        self.assertAlmostEqual(result, -2)

        c = matrix([1,-1])
        p = Problem(Minimize(max_elemwise(c.T, 2, 2 + c.T)[1]))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        c = matrix([[1,-1,2],[1,-1,2]])
        p = Problem(Minimize(sum_entries(max_elemwise(c, 2, 2 + c).T[:,0])))
        result = p.solve()
        self.assertAlmostEqual(result, 6)

        c = matrix([[1,-1,2],[1,-1,2]])
        p = Problem(Minimize(sum_entries(square(c.T).T[:,0])))
        result = p.solve()
        self.assertAlmostEqual(result, 6)

        # Slice of transpose.
        p = Problem(Maximize(sum_entries(self.C)), [self.C.T[:,1:3] <= 2, self.C.T[:,0] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2*[1,2,2])

    # Test multiplication on the left by a non-constant.
    def test_multiplication_on_left(self):
        c = matrix([1,2])
        p = Problem(Minimize(c.T*self.A*c), [self.A >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 18)

        p = Problem(Minimize(self.a*2), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 4)

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

        p = Problem(Minimize((self.x.T + self.z.T)*c),
            [self.x >= 2, self.z >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 9)

    # Test redundant constraints in cvxopt.
    def test_redundant_constraints(self):
        obj = Minimize(sum_entries(self.x))
        constraints = [self.x == 2, self.x == 2, self.x.T == 2, self.x[0] == 2]
        p = Problem(obj, constraints)
        result = p.solve(solver=s.CVXOPT)
        self.assertAlmostEqual(result, 4)

        obj = Minimize(sum_entries(square(self.x)))
        constraints = [self.x == self.x]
        p = Problem(obj, constraints)
        result = p.solve(solver=s.CVXOPT)
        self.assertAlmostEqual(result, 0)

    # Test that symmetry is enforced.
    def test_sdp_symmetry(self):
        # TODO should these raise exceptions?
        # with self.assertRaises(Exception) as cm:
        #     lambda_max([[1,2],[3,4]])
        # self.assertEqual(str(cm.exception), "lambda_max called on non-symmetric matrix.")

        # with self.assertRaises(Exception) as cm:
        #     lambda_min([[1,2],[3,4]])
        # self.assertEqual(str(cm.exception), "lambda_min called on non-symmetric matrix.")

        p = Problem(Minimize(lambda_max(self.A)), [self.A >= 2])
        result = p.solve()
        self.assertItemsAlmostEqual(self.A.value, self.A.value.T)

        p = Problem(Minimize(lambda_max(self.A)), [self.A == [[1,2],[3,4]]])
        result = p.solve()
        self.assertEqual(p.status, s.INFEASIBLE)

    # Test SDP
    def test_sdp(self):
        # Ensure sdp constraints enforce transpose.
        obj = Maximize(self.A[1,0] - self.A[0,1])
        p = Problem(obj, [lambda_max(self.A) <= 100,
                          self.A[0,0] == 2,
                          self.A[1,1] == 2,
                          self.A[1,0] == 2])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

    # Test getting values for expressions.
    def test_expression_values(self):
        diff_exp = self.x - self.z
        inf_exp = normInf(diff_exp)
        sum_entries_exp = 5 + norm1(self.z) + norm1(self.x) + inf_exp
        constr_exp = norm2(self.x + self.z)
        obj = norm2(sum_entries_exp)
        p = Problem(Minimize(obj),
            [self.x >= [2,3], self.z <= [-1,-4], constr_exp <= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 22)
        self.assertItemsAlmostEqual(self.x.value, [2,3])
        self.assertItemsAlmostEqual(self.z.value, [-1,-4])
        # Expression values.
        self.assertItemsAlmostEqual(diff_exp.value, self.x.value - self.z.value)
        self.assertAlmostEqual(inf_exp.value,
            LA.norm(self.x.value - self.z.value, numpy.inf))
        self.assertAlmostEqual(sum_entries_exp.value,
            5 + LA.norm(self.z.value, 1) + LA.norm(self.x.value, 1) + \
            LA.norm(self.x.value - self.z.value, numpy.inf))
        self.assertAlmostEqual(constr_exp.value,
            LA.norm(self.x.value + self.z.value, 2))
        self.assertAlmostEqual(obj.value, result)

    def test_mult_by_zero(self):
        """Test multiplication by zero.
        """
        exp = 0*self.a
        self.assertEqual(exp.value, 0)
        obj = Minimize(exp)
        p = Problem(obj)
        result = p.solve()
        self.assertAlmostEqual(result, 0)
        assert self.a.value is not None

    def test_div(self):
        """Tests a problem with division.
        """
        obj = Minimize(normInf(self.A/5))
        p = Problem(obj, [self.A >= 5])
        result = p.solve()
        self.assertAlmostEqual(result, 1)

    def test_mul_elemwise(self):
        """Tests problems with mul_elemwise.
        """
        c = [[1, -1], [2, -2]]
        expr = mul_elemwise(c, self.A)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.A == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, -5] + [10, -10])

        # Test with a sparse matrix.
        import cvxopt
        interface = intf.get_matrix_interface(cvxopt.spmatrix)
        c = interface.const_to_matrix([1,2])
        expr = mul_elemwise(c, self.x)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.x == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, 10])

        # Test promotion.
        c = [[1, -1], [2, -2]]
        expr = mul_elemwise(c, self.a)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.a == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, -5] + [10, -10])

    def test_invalid_solvers(self):
        """Tests that errors occur when you use an invalid solver.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(-log(self.a))).solve(solver=s.ECOS)
        self.assertEqual(str(cm.exception),
            "The solver ECOS cannot solve the problem.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(lambda_max(self.a))).solve(solver=s.ECOS)
        self.assertEqual(str(cm.exception),
            "The solver ECOS cannot solve the problem.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(self.a)).solve(solver=s.SCS)
        self.assertEqual(str(cm.exception),
            "The solver SCS cannot solve the problem.")

    def test_reshape(self):
        """Tests problems with reshape.
        """
        # Test on scalars.
        self.assertEqual(reshape(1, 1, 1).value, 1)

        # Test vector to matrix.
        x = Variable(4)
        mat = matrix([[1,-1], [2, -2]])
        vec = matrix([1, 2, 3, 4])
        vec_mat = matrix([[1, 2], [3, 4]])
        expr = reshape(x, 2, 2)
        obj = Minimize(sum_entries(mat*expr))
        prob = Problem(obj, [x == vec])
        result = prob.solve()
        self.assertAlmostEqual(result, sum(mat*vec_mat))

        # Test on matrix to vector.
        c = [1, 2, 3, 4]
        expr = reshape(self.A, 4, 1)
        obj = Minimize(expr.T*c)
        constraints = [self.A == [[-1, -2], [3, 4]]]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 20)
        self.assertItemsAlmostEqual(expr.value, [-1, -2, 3, 4])
        self.assertItemsAlmostEqual(reshape(expr, 2, 2).value, [-1, -2, 3, 4])

        # Test matrix to matrix.
        expr = reshape(self.C, 2, 3)
        mat = numpy.matrix([[1,-1], [2, -2]])
        C_mat = numpy.matrix([[1, 4], [2, 5], [3, 6]])
        obj = Minimize(sum_entries(mat*expr))
        prob = Problem(obj, [self.C == C_mat])
        result = prob.solve()
        reshaped = numpy.reshape(C_mat, (2, 3), 'F')
        self.assertAlmostEqual(result, (mat.dot(reshaped)).sum())
        self.assertItemsAlmostEqual(expr.value, C_mat)

        # Test promoted expressions.
        c = matrix([[1,-1], [2, -2]])
        expr = reshape(c*self.a, 1, 4)
        obj = Minimize(expr*[1, 2, 3, 4])
        prob = Problem(obj, [self.a == 2])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(expr.value, 2*c)

        expr = reshape(c*self.a, 4, 1)
        obj = Minimize(expr.T*[1, 2, 3, 4])
        prob = Problem(obj, [self.a == 2])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(expr.value, 2*c)

    def test_vec(self):
        """Tests problems with vec.
        """
        c = [1, 2, 3, 4]
        expr = vec(self.A)
        obj = Minimize(expr.T*c)
        constraints = [self.A == [[-1, -2], [3, 4]]]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 20)
        self.assertItemsAlmostEqual(expr.value, [-1, -2, 3, 4])

    def test_diag_prob(self):
        """Test a problem with diag.
        """
        C = Variable(3, 3)
        obj = Maximize(C[0, 2])
        constraints = [diag(C) == 1,
                       C[0, 1] == 0.6,
                       C[1, 2] == -0.3,
                       C == Semidef(3)]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 0.583151)

    def test_presolve_constant_constraints(self):
        """Test that the presolver removes constraints with no variables.
        """
        x = Variable()
        obj = Maximize(sqrt(x))
        prob = Problem(obj)
        c, G, h, dims, A, b = prob.get_problem_data(s.ECOS)
        for row in range(A.shape[0]):
            assert A[row, :].nnz > 0
        for row in range(G.shape[0]):
            assert G[row, :].nnz > 0
예제 #11
0
class TestProblem(BaseTest):
    """ Unit tests for the expression/expression module. """
    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')

    def test_to_str(self):
        """Test string representations.
        """
        obj = Minimize(self.a)
        prob = Problem(obj)
        self.assertEqual(repr(prob), "Problem(%s, %s)" % (repr(obj), repr([])))
        constraints = [self.x * 2 == self.x, self.x == 0]
        prob = Problem(obj, constraints)
        self.assertEqual(repr(prob),
                         "Problem(%s, %s)" % (repr(obj), repr(constraints)))

        # Test str.
        result = "minimize %(name)s\nsubject to %(name)s == 0\n           0 <= %(name)s" % {
            "name": self.a.name()
        }
        prob = Problem(Minimize(self.a), [self.a == 0, self.a >= 0])
        self.assertEqual(str(prob), result)

    def test_variables(self):
        """Test the variables method.
        """
        p = Problem(Minimize(self.a), [self.a <= self.x, self.b <= self.A + 2])
        vars_ = p.variables()
        self.assertItemsEqual(vars_, [self.a, self.x, self.b, self.A])

    def test_parameters(self):
        """Test the parameters method.
        """
        p1 = Parameter()
        p2 = Parameter(3, sign="negative")
        p3 = Parameter(4, 4, sign="positive")
        p = Problem(Minimize(p1), [self.a + p1 <= p2, self.b <= p3 + p3 + 2])
        params = p.parameters()
        self.assertItemsEqual(params, [p1, p2, p3])

    def test_get_problem_data(self):
        """Test get_problem_data method.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Maximize(exp(self.a))).get_problem_data(s.ECOS)
        self.assertEqual(str(cm.exception),
                         "The solver ECOS cannot solve the problem.")

        args = Problem(Maximize(exp(self.a) + 2)).get_problem_data(s.SCS)
        data, dims = args
        self.assertEqual(dims['ep'], 1)
        self.assertEqual(data["c"].shape, (2, ))
        self.assertEqual(data["A"].shape, (3, 2))

        args = Problem(Minimize(norm(self.x) + 3)).get_problem_data(s.ECOS)
        c, G, h, dims, A, b = args
        self.assertEqual(dims["q"], [3])
        self.assertEqual(c.shape, (3, ))
        self.assertEqual(A.shape, (0, 3))
        self.assertEqual(G.shape, (3, 3))

        args = Problem(Minimize(norm(self.x) + 3)).get_problem_data(s.CVXOPT)
        c, G, h, dims, A, b = args
        self.assertEqual(dims["q"], [3])
        self.assertEqual(c.size, (3, 1))
        self.assertEqual(A.size, (0, 3))
        self.assertEqual(G.size, (3, 3))

    # Test silencing and enabling solver messages.
    def test_verbose(self):
        # From http://stackoverflow.com/questions/5136611/capture-stdout-from-a-script-in-python
        # setup the environment
        outputs = {True: [], False: []}
        backup = sys.stdout

        # ####
        for verbose in [True, False]:
            for solver in [s.ECOS, s.CVXOPT, s.SCS]:
                sys.stdout = StringIO()  # capture output
                p = Problem(Minimize(self.a + self.x[0]),
                            [self.a >= 2, self.x >= 2])
                p.solve(verbose=verbose, solver=solver)
                if solver != s.ECOS:
                    p = Problem(Minimize(self.a), [log(self.a) >= 2])
                    p.solve(verbose=verbose, solver=solver)
                out = sys.stdout.getvalue()  # release output
                outputs[verbose].append(out.upper())
        # ####

        sys.stdout.close()  # close the stream
        sys.stdout = backup  # restore original stdout

        for output in outputs[True]:
            assert len(output) > 0
        for output in outputs[False]:
            assert len(output) == 0

    # Test registering other solve methods.
    def test_register_solve(self):
        Problem.register_solve("test", lambda self: 1)
        p = Problem(Minimize(1))
        result = p.solve(method="test")
        self.assertEqual(result, 1)

        def test(self, a, b=2):
            return (a, b)

        Problem.register_solve("test", test)
        p = Problem(Minimize(0))
        result = p.solve(1, b=3, method="test")
        self.assertEqual(result, (1, 3))
        result = p.solve(1, method="test")
        self.assertEqual(result, (1, 2))
        result = p.solve(1, method="test", b=4)
        self.assertEqual(result, (1, 4))

    def test_consistency(self):
        """Test that variables and constraints keep a consistent order.
        """
        import itertools
        num_solves = 4
        vars_lists = []
        ineqs_lists = []
        var_ids_order_created = []
        for k in range(num_solves):
            sum = 0
            constraints = []
            var_ids = []
            for i in range(100):
                var = Variable(name=str(i))
                var_ids.append(var.id)
                sum += var
                constraints.append(var >= i)
            var_ids_order_created.append(var_ids)
            obj = Minimize(sum)
            p = Problem(obj, constraints)
            objective, constraints = p.canonicalize()
            sym_data = SymData(objective, constraints, SOLVERS[s.ECOS])
            # Sort by offset.
            vars_ = sorted(sym_data.var_offsets.items(),
                           key=lambda (var_id, offset): offset)
            vars_ = [var_id for (var_id, offset) in vars_]
            vars_lists.append(vars_)
            ineqs_lists.append(sym_data.constr_map[s.LEQ])

        # Verify order of variables is consistent.
        for i in range(num_solves):
            self.assertEqual(var_ids_order_created[i], vars_lists[i])
        for i in range(num_solves):
            for idx, constr in enumerate(ineqs_lists[i]):
                var_id, _ = lu.get_expr_vars(constr.expr)[0]
                self.assertEqual(var_ids_order_created[i][idx], var_id)

    # Test removing duplicate constraint objects.
    def test_duplicate_constraints(self):
        eq = (self.x == 2)
        le = (self.x <= 2)
        obj = 0

        def test(self):
            objective, constraints = self.canonicalize()
            sym_data = SymData(objective, constraints, SOLVERS[s.ECOS])
            return (len(sym_data.constr_map[s.EQ]),
                    len(sym_data.constr_map[s.LEQ]))

        Problem.register_solve("test", test)
        p = Problem(Minimize(obj), [eq, eq, le, le])
        result = p.solve(method="test")
        self.assertEqual(result, (1, 1))

        # Internal constraints.
        X = Semidef(2)
        obj = sum_entries(X + X)
        p = Problem(Minimize(obj))
        result = p.solve(method="test")
        self.assertEqual(result, (1, 1))

        # Duplicates from non-linear constraints.
        exp = norm(self.x, 2)
        prob = Problem(Minimize(0), [exp <= 1, exp <= 2])
        result = prob.solve(method="test")
        self.assertEqual(result, (0, 4))

    # Test the is_dcp method.
    def test_is_dcp(self):
        p = Problem(Minimize(normInf(self.a)))
        self.assertEqual(p.is_dcp(), True)

        p = Problem(Maximize(normInf(self.a)))
        self.assertEqual(p.is_dcp(), False)
        with self.assertRaises(Exception) as cm:
            p.solve()
        self.assertEqual(str(cm.exception),
                         "Problem does not follow DCP rules.")
        p.solve(ignore_dcp=True)

    # Test problems involving variables with the same name.
    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)

    # Test scalar LP problems.
    def test_scalar_lp(self):
        p = Problem(Minimize(3 * self.a), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 6)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Maximize(3 * self.a - self.b),
                    [self.a <= 2, self.b == self.a, self.b <= 5])
        result = p.solve()
        self.assertAlmostEqual(result, 4.0)
        self.assertAlmostEqual(self.a.value, 2)
        self.assertAlmostEqual(self.b.value, 2)

        # With a constant in the objective.
        p = Problem(Minimize(3 * self.a - self.b + 100), [
            self.a >= 2, self.b + 5 * self.c - 2 == self.a,
            self.b <= 5 + self.c
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 101 + 1.0 / 6)
        self.assertAlmostEqual(self.a.value, 2)
        self.assertAlmostEqual(self.b.value, 5 - 1.0 / 6)
        self.assertAlmostEqual(self.c.value, -1.0 / 6)

        # Test status and value.
        exp = Maximize(self.a)
        p = Problem(exp, [self.a <= 2])
        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.OPTIMAL)
        assert self.a.value is not None
        assert p.constraints[0].dual_value is not None

        # Unbounded problems.
        p = Problem(Maximize(self.a), [self.a >= 2])
        p.solve(solver=s.ECOS)
        self.assertEqual(p.status, s.UNBOUNDED)
        assert numpy.isinf(p.value)
        assert p.value > 0
        assert self.a.value is None
        assert p.constraints[0].dual_value is None

        p = Problem(Minimize(-self.a), [self.a >= 2])
        result = p.solve(solver=s.CVXOPT)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.UNBOUNDED)
        assert numpy.isinf(p.value)
        assert p.value < 0

        # Infeasible problems.
        p = Problem(Maximize(self.a), [self.a >= 2, self.a <= 1])
        self.a.save_value(2)
        p.constraints[0].save_value(2)

        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.INFEASIBLE)
        assert numpy.isinf(p.value)
        assert p.value < 0
        assert self.a.value is None
        assert p.constraints[0].dual_value is None

        p = Problem(Minimize(-self.a), [self.a >= 2, self.a <= 1])
        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.INFEASIBLE)
        assert numpy.isinf(p.value)
        assert p.value > 0

    # Test vector LP problems.
    def test_vector_lp(self):
        c = matrix([1, 2])
        p = Problem(Minimize(c.T * self.x), [self.x >= c])
        result = p.solve()
        self.assertAlmostEqual(result, 5)
        self.assertItemsAlmostEqual(self.x.value, [1, 2])

        A = matrix([[3, 5], [1, 2]])
        I = Constant([[1, 0], [0, 1]])
        p = Problem(Minimize(c.T * self.x + self.a), [
            A * self.x >= [-1, 1], 4 * I * self.z == self.x, self.z >= [2, 2],
            self.a >= 2
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 26, places=3)
        obj = c.T * self.x.value + self.a.value
        self.assertAlmostEqual(obj[0], result)
        self.assertItemsAlmostEqual(self.x.value, [8, 8], places=3)
        self.assertItemsAlmostEqual(self.z.value, [2, 2], places=3)

    def test_ecos_noineq(self):
        """Test ECOS with no inequality constraints.
        """
        T = matrix(1, (2, 2))
        p = Problem(Minimize(1), [self.A == T])
        result = p.solve(solver=s.ECOS)
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, T)

    # Test matrix LP problems.
    def test_matrix_lp(self):
        T = matrix(1, (2, 2))
        p = Problem(Minimize(1), [self.A == T])
        result = p.solve()
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, T)

        T = matrix(2, (2, 3))
        c = matrix([3, 4])
        p = Problem(Minimize(1),
                    [self.A >= T * self.C, self.A == self.B, self.C == T.T])
        result = p.solve()
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, self.B.value)
        self.assertItemsAlmostEqual(self.C.value, T)
        assert (self.A.value >= T * self.C.value).all()

        # Test variables are dense.
        self.assertEqual(type(self.A.value),
                         intf.DEFAULT_INTERFACE.TARGET_MATRIX)

    # Test variable promotion.
    def test_variable_promotion(self):
        p = Problem(Minimize(self.a), [self.x <= self.a, self.x == [1, 2]])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Minimize(self.a),
                    [self.A <= self.a, self.A == [[1, 2], [3, 4]]])
        result = p.solve()
        self.assertAlmostEqual(result, 4)
        self.assertAlmostEqual(self.a.value, 4)

        # Promotion must happen before the multiplication.
        p = Problem(Minimize([[1], [1]] * (self.x + self.a + 1)),
                    [self.a + self.x >= [1, 2]])
        result = p.solve()
        self.assertAlmostEqual(result, 5)

    # Test parameter promotion.
    def test_parameter_promotion(self):
        a = Parameter()
        exp = [[1, 2], [3, 4]] * a
        a.value = 2
        assert not (exp.value - 2 * numpy.array([[1, 2], [3, 4]]).T).any()

    def test_parameter_problems(self):
        """Test problems with parameters.
        """
        p1 = Parameter()
        p2 = Parameter(3, sign="negative")
        p3 = Parameter(4, 4, sign="positive")
        p = Problem(Maximize(p1 * self.a),
                    [self.a + p1 <= p2, self.b <= p3 + p3 + 2])
        p1.value = 2
        p2.value = -numpy.ones((3, 1))
        p3.value = numpy.ones((4, 4))
        result = p.solve()
        self.assertAlmostEqual(result, -6)

    # Test problems with normInf
    def test_normInf(self):
        # Constant argument.
        p = Problem(Minimize(normInf(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(normInf(self.a)), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Minimize(3 * normInf(self.a + 2 * self.b) + self.c),
                    [self.a >= 2, self.b <= -1, self.c == 3])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertAlmostEqual(self.a.value + 2 * self.b.value, 0)
        self.assertAlmostEqual(self.c.value, 3)

        # Maximize
        p = Problem(Maximize(-normInf(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(normInf(self.x - self.z) + 5),
                    [self.x >= [2, 3], self.z <= [-1, -4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertAlmostEqual(
            list(self.x.value)[1] - list(self.z.value)[1], 7)

    # Test problems with norm1
    def test_norm1(self):
        # Constant argument.
        p = Problem(Minimize(norm1(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(norm1(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, -2)

        # Maximize
        p = Problem(Maximize(-norm1(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(norm1(self.x - self.z) + 5),
                    [self.x >= [2, 3], self.z <= [-1, -4]])
        result = p.solve()
        self.assertAlmostEqual(result, 15)
        self.assertAlmostEqual(
            list(self.x.value)[1] - list(self.z.value)[1], 7)

    # Test problems with norm2
    def test_norm2(self):
        # Constant argument.
        p = Problem(Minimize(norm2(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(norm2(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, -2)

        # Maximize
        p = Problem(Maximize(-norm2(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(norm2(self.x - self.z) + 5),
                    [self.x >= [2, 3], self.z <= [-1, -4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12.61577)
        self.assertItemsAlmostEqual(self.x.value, [2, 3])
        self.assertItemsAlmostEqual(self.z.value, [-1, -4])

        # Row  arguments.
        p = Problem(Minimize(norm2((self.x - self.z).T) + 5),
                    [self.x >= [2, 3], self.z <= [-1, -4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12.61577)
        self.assertItemsAlmostEqual(self.x.value, [2, 3])
        self.assertItemsAlmostEqual(self.z.value, [-1, -4])

    # Test problems with abs
    def test_abs(self):
        p = Problem(Minimize(sum_entries(abs(self.A))), [-2 >= self.A])
        result = p.solve()
        self.assertAlmostEqual(result, 8)
        self.assertItemsAlmostEqual(self.A.value, [-2, -2, -2, -2])

    # Test problems with quad_form.
    def test_quad_form(self):
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(self.x, self.A))).solve()
        self.assertEqual(
            str(cm.exception),
            "At least one argument to quad_form must be constant.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(1, self.A))).solve()
        self.assertEqual(str(cm.exception),
                         "Invalid dimensions for arguments.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(self.x, [[-1, 0], [0, 9]]))).solve()
        self.assertEqual(str(cm.exception),
                         "P has both positive and negative eigenvalues.")

        P = [[4, 0], [0, 9]]
        p = Problem(Minimize(quad_form(self.x, P)), [self.x >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 13, places=3)

        c = [1, 2]
        p = Problem(Minimize(quad_form(c, self.A)), [self.A >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 9)

        c = [1, 2]
        P = [[4, 0], [0, 9]]
        p = Problem(Minimize(quad_form(c, P)))
        result = p.solve()
        self.assertAlmostEqual(result, 40)

    # Test combining atoms
    def test_mixed_atoms(self):
        p = Problem(
            Minimize(
                norm2(5 + norm1(self.z) + norm1(self.x) +
                      normInf(self.x - self.z))), [
                          self.x >= [2, 3], self.z <= [-1, -4],
                          norm2(self.x + self.z) <= 2
                      ])
        result = p.solve()
        self.assertAlmostEqual(result, 22)
        self.assertItemsAlmostEqual(self.x.value, [2, 3])
        self.assertItemsAlmostEqual(self.z.value, [-1, -4])

    # Test multiplying by constant atoms.
    def test_mult_constant_atoms(self):
        p = Problem(Minimize(norm2([3, 4]) * self.a), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertAlmostEqual(self.a.value, 2)

    # Test recovery of dual variables.
    def test_dual_variables(self):
        p = Problem(Minimize(norm1(self.x + self.z)), [
            self.x >= [2, 3], [[1, 2], [3, 4]] * self.z == [-1, -4],
            norm2(self.x + self.z) <= 100
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 4)
        self.assertItemsAlmostEqual(self.x.value, [4, 3])
        self.assertItemsAlmostEqual(self.z.value, [-4, 1])
        # Dual values
        self.assertItemsAlmostEqual(p.constraints[0].dual_value, [0, 1])
        self.assertItemsAlmostEqual(p.constraints[1].dual_value, [-1, 0.5])
        self.assertAlmostEqual(p.constraints[2].dual_value, 0)

        T = matrix(2, (2, 3))
        c = matrix([3, 4])
        p = Problem(Minimize(1),
                    [self.A >= T * self.C, self.A == self.B, self.C == T.T])
        result = p.solve()
        # Dual values
        self.assertItemsAlmostEqual(p.constraints[0].dual_value, 4 * [0])
        self.assertItemsAlmostEqual(p.constraints[1].dual_value, 4 * [0])
        self.assertItemsAlmostEqual(p.constraints[2].dual_value, 6 * [0])

    # Test problems with indexing.
    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)

    # Test problems with slicing.
    def test_slicing(self):
        p = Problem(Maximize(sum_entries(self.C)),
                    [self.C[1:3, :] <= 2, self.C[0, :] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2 * [1, 2, 2])

        p = Problem(Maximize(sum_entries(self.C[0:3:2, 1])),
                    [self.C[1:3, :] <= 2, self.C[0, :] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.C.value[0:3:2, 1], [1, 2])

        p = Problem(Maximize(sum_entries((self.C[0:2, :] + self.A)[:, 0:2])),
                    [
                        self.C[1:3, :] <= 2, self.C[0, :] == 1,
                        (self.A + self.B)[:, 0] == 3,
                        (self.A + self.B)[:, 1] == 2, self.B == 1
                    ])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertItemsAlmostEqual(self.C.value[0:2, :], [1, 2, 1, 2])
        self.assertItemsAlmostEqual(self.A.value, [2, 2, 1, 1])

        p = Problem(Maximize([[3], [4]] * (self.C[0:2, :] + self.A)[:, 0]), [
            self.C[1:3, :] <= 2, self.C[0, :] == 1, [[1], [2]] *
            (self.A + self.B)[:, 0] == 3,
            (self.A + self.B)[:, 1] == 2, self.B == 1, 3 * self.A[:, 0] <= 3
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertItemsAlmostEqual(self.C.value[0:2, 0], [1, 2])
        self.assertItemsAlmostEqual(self.A.value, [1, -.5, 1, 1])

        p = Problem(Minimize(norm2((self.C[0:2, :] + self.A)[:, 0])),
                    [
                        self.C[1:3, :] <= 2, self.C[0, :] == 1,
                        (self.A + self.B)[:, 0] == 3,
                        (self.A + self.B)[:, 1] == 2, self.B == 1
                    ])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.C.value[0:2, 0], [1, -2])
        self.assertItemsAlmostEqual(self.A.value, [2, 2, 1, 1])

        # Transpose of slice.
        p = Problem(Maximize(sum_entries(self.C)),
                    [self.C[1:3, :].T <= 2, self.C[0, :].T == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2 * [1, 2, 2])

    # Test the vstack atom.
    def test_vstack(self):
        c = matrix(1, (1, 5))
        p = Problem(Minimize(c * vstack(self.x, self.y)),
                    [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 * vstack(self.x, self.x)), [self.x == [1, 2]])
        result = p.solve()
        self.assertAlmostEqual(result, 6)

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

        c = matrix(1, (1, 2))
        p = Problem(Minimize(sum_entries(vstack(c * self.A, c * self.B))),
                    [self.A >= 2, self.B == -2])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

        c = matrix([1, -1])
        p = Problem(Minimize(c.T * vstack(square(self.a), sqrt(self.b))),
                    [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.")

    # Test the hstack atom.
    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.")

    def test_bad_objective(self):
        """Test using a cvxpy expression as an objective.
        """
        with self.assertRaises(Exception) as cm:
            Problem(self.x + 2)
        self.assertEqual(str(cm.exception),
                         "Problem objective must be Minimize or Maximize.")

    # Test variable transpose.
    def test_transpose(self):
        p = Problem(Minimize(sum_entries(self.x)),
                    [self.x.T >= matrix([1, 2]).T])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.x.value, [1, 2])

        p = Problem(Minimize(sum_entries(self.C)),
                    [matrix([1, 1]).T * self.C.T >= matrix([0, 1, 2]).T])
        result = p.solve()
        value = self.C.value

        constraints = [
            1 * self.C[i, 0] + 1 * self.C[i, 1] >= i for i in range(3)
        ]
        p = Problem(Minimize(sum_entries(self.C)), constraints)
        result2 = p.solve()
        self.assertAlmostEqual(result, result2)
        self.assertItemsAlmostEqual(self.C.value, value)

        p = Problem(Minimize(self.A[0, 1] - self.A.T[1, 0]),
                    [self.A == [[1, 2], [3, 4]]])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

        exp = (-self.x).T
        p = Problem(Minimize(sum_entries(self.x)), [(-self.x).T <= 1])
        result = p.solve()
        self.assertAlmostEqual(result, -2)

        c = matrix([1, -1])
        p = Problem(Minimize(max_elemwise(c.T, 2, 2 + c.T)[1]))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        c = matrix([[1, -1, 2], [1, -1, 2]])
        p = Problem(Minimize(sum_entries(max_elemwise(c, 2, 2 + c).T[:, 0])))
        result = p.solve()
        self.assertAlmostEqual(result, 6)

        c = matrix([[1, -1, 2], [1, -1, 2]])
        p = Problem(Minimize(sum_entries(square(c.T).T[:, 0])))
        result = p.solve()
        self.assertAlmostEqual(result, 6)

        # Slice of transpose.
        p = Problem(Maximize(sum_entries(self.C)),
                    [self.C.T[:, 1:3] <= 2, self.C.T[:, 0] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2 * [1, 2, 2])

    # Test multiplication on the left by a non-constant.
    def test_multiplication_on_left(self):
        c = matrix([1, 2])
        p = Problem(Minimize(c.T * self.A * c), [self.A >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 18)

        p = Problem(Minimize(self.a * 2), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 4)

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

        p = Problem(Minimize((self.x.T + self.z.T) * c),
                    [self.x >= 2, self.z >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 9)

    # Test redundant constraints in cvxopt.
    def test_redundant_constraints(self):
        obj = Minimize(sum_entries(self.x))
        constraints = [self.x == 2, self.x == 2, self.x.T == 2, self.x[0] == 2]
        p = Problem(obj, constraints)
        result = p.solve(solver=s.CVXOPT)
        self.assertAlmostEqual(result, 4)

        obj = Minimize(sum_entries(square(self.x)))
        constraints = [self.x == self.x]
        p = Problem(obj, constraints)
        result = p.solve(solver=s.CVXOPT)
        self.assertAlmostEqual(result, 0)

    # Test that symmetry is enforced.
    def test_sdp_symmetry(self):
        # TODO should these raise exceptions?
        # with self.assertRaises(Exception) as cm:
        #     lambda_max([[1,2],[3,4]])
        # self.assertEqual(str(cm.exception), "lambda_max called on non-symmetric matrix.")

        # with self.assertRaises(Exception) as cm:
        #     lambda_min([[1,2],[3,4]])
        # self.assertEqual(str(cm.exception), "lambda_min called on non-symmetric matrix.")

        p = Problem(Minimize(lambda_max(self.A)), [self.A >= 2])
        result = p.solve()
        self.assertItemsAlmostEqual(self.A.value, self.A.value.T)

        p = Problem(Minimize(lambda_max(self.A)), [self.A == [[1, 2], [3, 4]]])
        result = p.solve()
        self.assertEqual(p.status, s.INFEASIBLE)

    # Test SDP
    def test_sdp(self):
        # Ensure sdp constraints enforce transpose.
        obj = Maximize(self.A[1, 0] - self.A[0, 1])
        p = Problem(obj, [
            lambda_max(self.A) <= 100, self.A[0, 0] == 2, self.A[1, 1] == 2,
            self.A[1, 0] == 2
        ])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

    # Test getting values for expressions.
    def test_expression_values(self):
        diff_exp = self.x - self.z
        inf_exp = normInf(diff_exp)
        sum_entries_exp = 5 + norm1(self.z) + norm1(self.x) + inf_exp
        constr_exp = norm2(self.x + self.z)
        obj = norm2(sum_entries_exp)
        p = Problem(Minimize(obj),
                    [self.x >= [2, 3], self.z <= [-1, -4], constr_exp <= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 22)
        self.assertItemsAlmostEqual(self.x.value, [2, 3])
        self.assertItemsAlmostEqual(self.z.value, [-1, -4])
        # Expression values.
        self.assertItemsAlmostEqual(diff_exp.value,
                                    self.x.value - self.z.value)
        self.assertAlmostEqual(inf_exp.value,
                               LA.norm(self.x.value - self.z.value, numpy.inf))
        self.assertAlmostEqual(sum_entries_exp.value,
            5 + LA.norm(self.z.value, 1) + LA.norm(self.x.value, 1) + \
            LA.norm(self.x.value - self.z.value, numpy.inf))
        self.assertAlmostEqual(constr_exp.value,
                               LA.norm(self.x.value + self.z.value, 2))
        self.assertAlmostEqual(obj.value, result)

    def test_mult_by_zero(self):
        """Test multiplication by zero.
        """
        exp = 0 * self.a
        self.assertEqual(exp.value, 0)
        obj = Minimize(exp)
        p = Problem(obj)
        result = p.solve()
        self.assertAlmostEqual(result, 0)
        assert self.a.value is not None

    def test_div(self):
        """Tests a problem with division.
        """
        obj = Minimize(normInf(self.A / 5))
        p = Problem(obj, [self.A >= 5])
        result = p.solve()
        self.assertAlmostEqual(result, 1)

    def test_mul_elemwise(self):
        """Tests problems with mul_elemwise.
        """
        c = [[1, -1], [2, -2]]
        expr = mul_elemwise(c, self.A)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.A == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, -5] + [10, -10])

        # Test with a sparse matrix.
        import cvxopt
        interface = intf.get_matrix_interface(cvxopt.spmatrix)
        c = interface.const_to_matrix([1, 2])
        expr = mul_elemwise(c, self.x)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.x == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, 10])

        # Test promotion.
        c = [[1, -1], [2, -2]]
        expr = mul_elemwise(c, self.a)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.a == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, -5] + [10, -10])

    def test_invalid_solvers(self):
        """Tests that errors occur when you use an invalid solver.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(-log(self.a))).solve(solver=s.ECOS)
        self.assertEqual(str(cm.exception),
                         "The solver ECOS cannot solve the problem.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(lambda_max(self.a))).solve(solver=s.ECOS)
        self.assertEqual(str(cm.exception),
                         "The solver ECOS cannot solve the problem.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(self.a)).solve(solver=s.SCS)
        self.assertEqual(str(cm.exception),
                         "The solver SCS cannot solve the problem.")

    def test_reshape(self):
        """Tests problems with reshape.
        """
        # Test on scalars.
        self.assertEqual(reshape(1, 1, 1).value, 1)

        # Test vector to matrix.
        x = Variable(4)
        mat = matrix([[1, -1], [2, -2]])
        vec = matrix([1, 2, 3, 4])
        vec_mat = matrix([[1, 2], [3, 4]])
        expr = reshape(x, 2, 2)
        obj = Minimize(sum_entries(mat * expr))
        prob = Problem(obj, [x == vec])
        result = prob.solve()
        self.assertAlmostEqual(result, sum(mat * vec_mat))

        # Test on matrix to vector.
        c = [1, 2, 3, 4]
        expr = reshape(self.A, 4, 1)
        obj = Minimize(expr.T * c)
        constraints = [self.A == [[-1, -2], [3, 4]]]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 20)
        self.assertItemsAlmostEqual(expr.value, [-1, -2, 3, 4])
        self.assertItemsAlmostEqual(reshape(expr, 2, 2).value, [-1, -2, 3, 4])

        # Test matrix to matrix.
        expr = reshape(self.C, 2, 3)
        mat = numpy.matrix([[1, -1], [2, -2]])
        C_mat = numpy.matrix([[1, 4], [2, 5], [3, 6]])
        obj = Minimize(sum_entries(mat * expr))
        prob = Problem(obj, [self.C == C_mat])
        result = prob.solve()
        reshaped = numpy.reshape(C_mat, (2, 3), 'F')
        self.assertAlmostEqual(result, (mat.dot(reshaped)).sum())
        self.assertItemsAlmostEqual(expr.value, C_mat)

        # Test promoted expressions.
        c = matrix([[1, -1], [2, -2]])
        expr = reshape(c * self.a, 1, 4)
        obj = Minimize(expr * [1, 2, 3, 4])
        prob = Problem(obj, [self.a == 2])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(expr.value, 2 * c)

        expr = reshape(c * self.a, 4, 1)
        obj = Minimize(expr.T * [1, 2, 3, 4])
        prob = Problem(obj, [self.a == 2])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(expr.value, 2 * c)

    def test_vec(self):
        """Tests problems with vec.
        """
        c = [1, 2, 3, 4]
        expr = vec(self.A)
        obj = Minimize(expr.T * c)
        constraints = [self.A == [[-1, -2], [3, 4]]]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 20)
        self.assertItemsAlmostEqual(expr.value, [-1, -2, 3, 4])

    def test_diag_prob(self):
        """Test a problem with diag.
        """
        C = Variable(3, 3)
        obj = Maximize(C[0, 2])
        constraints = [
            diag(C) == 1, C[0, 1] == 0.6, C[1, 2] == -0.3, C == Semidef(3)
        ]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 0.583151)

    def test_presolve_constant_constraints(self):
        """Test that the presolver removes constraints with no variables.
        """
        x = Variable()
        obj = Maximize(sqrt(x))
        prob = Problem(obj)
        c, G, h, dims, A, b = prob.get_problem_data(s.ECOS)
        for row in range(A.shape[0]):
            assert A[row, :].nnz > 0
        for row in range(G.shape[0]):
            assert G[row, :].nnz > 0

    def test_presolve_parameters(self):
        """Test presolve with parameters.
        """
        # Test with parameters.
        gamma = Parameter(sign="positive")
        x = Variable()
        obj = Minimize(x)
        prob = Problem(obj, [gamma == 1, x >= 0])
        gamma.value = 0
        prob.solve(solver=s.SCS)
        self.assertEqual(prob.status, s.INFEASIBLE)

        gamma.value = 1
        prob.solve(solver=s.CVXOPT)
        self.assertEqual(prob.status, s.OPTIMAL)
예제 #12
0
class TestProblem(BaseTest):
    """ Unit tests for the expression/expression module. """
    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')

    def test_to_str(self):
        """Test string representations.
        """
        obj = Minimize(self.a)
        prob = Problem(obj)
        self.assertEqual(repr(prob), "Problem(%s, %s)" % (repr(obj), repr([])))
        constraints = [self.x*2 == self.x, self.x == 0]
        prob = Problem(obj, constraints)
        self.assertEqual(repr(prob), "Problem(%s, %s)" % (repr(obj), repr(constraints)))

        # Test str.
        result = "minimize %(name)s\nsubject to %(name)s == 0\n           0 <= %(name)s" % {"name": self.a.name()}
        prob = Problem(Minimize(self.a), [self.a == 0, self.a >= 0])
        self.assertEqual(str(prob), result)

    def test_variables(self):
        """Test the variables method.
        """
        p = Problem(Minimize(self.a), [self.a <= self.x, self.b <= self.A + 2])
        vars_ = p.variables()
        ref = [self.a, self.x, self.b, self.A]
        if PY2:
            self.assertItemsEqual(vars_, ref)
        else:
            self.assertCountEqual(vars_, ref)

    def test_parameters(self):
        """Test the parameters method.
        """
        p1 = Parameter()
        p2 = Parameter(3, sign="negative")
        p3 = Parameter(4, 4, sign="positive")
        p = Problem(Minimize(p1), [self.a + p1 <= p2, self.b <= p3 + p3 + 2])
        params = p.parameters()
        ref = [p1, p2, p3]
        if PY2:
            self.assertItemsEqual(params, ref)
        else:
            self.assertCountEqual(params, ref)

    def test_get_problem_data(self):
        """Test get_problem_data method.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Maximize(exp(self.a))).get_problem_data(s.ECOS)
        self.assertEqual(str(cm.exception), "The solver ECOS cannot solve the problem.")

        data = Problem(Maximize(exp(self.a) + 2)).get_problem_data(s.SCS)
        dims = data["dims"]
        self.assertEqual(dims['ep'], 1)
        self.assertEqual(data["c"].shape, (2,))
        self.assertEqual(data["A"].shape, (3, 2))

        data = Problem(Minimize(norm(self.x) + 3)).get_problem_data(s.ECOS)
        dims = data["dims"]
        self.assertEqual(dims["q"], [3])
        self.assertEqual(data["c"].shape, (3,))
        self.assertEqual(data["A"].shape, (0, 3))
        self.assertEqual(data["G"].shape, (3, 3))

        data = Problem(Minimize(norm(self.x) + 3)).get_problem_data(s.CVXOPT)
        dims = data["dims"]
        self.assertEqual(dims["q"], [3])
        self.assertEqual(data["c"].size, (3, 1))
        self.assertEqual(data["A"].size, (0, 3))
        self.assertEqual(data["G"].size, (3, 3))

    def test_unpack_results(self):
        """Test unpack results method.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(exp(self.a))).unpack_results("blah", None)
        self.assertEqual(str(cm.exception), "Unknown solver.")

        prob = Problem(Minimize(exp(self.a)), [self.a == 0])
        args = prob.get_problem_data(s.SCS)
        data = {"c": args["c"], "A": args["A"], "b": args["b"]}
        results_dict = scs.solve(data, args["dims"])
        prob = Problem(Minimize(exp(self.a)), [self.a == 0])
        prob.unpack_results(s.SCS, results_dict)
        self.assertAlmostEqual(self.a.value, 0, places=3)
        self.assertAlmostEqual(prob.value, 1, places=3)
        self.assertAlmostEqual(prob.status, s.OPTIMAL)

        prob = Problem(Minimize(norm(self.x)), [self.x == 0])
        args = prob.get_problem_data(s.ECOS)
        results_dict = ecos.solve(args["c"], args["G"], args["h"],
                                  args["dims"], args["A"], args["b"])
        prob = Problem(Minimize(norm(self.x)), [self.x == 0])
        prob.unpack_results(s.ECOS, results_dict)
        self.assertItemsAlmostEqual(self.x.value, [0,0])
        self.assertAlmostEqual(prob.value, 0)
        self.assertAlmostEqual(prob.status, s.OPTIMAL)

        prob = Problem(Minimize(norm(self.x)), [self.x == 0])
        args = prob.get_problem_data(s.CVXOPT)
        results_dict = cvxopt.solvers.conelp(args["c"], args["G"], args["h"],
                                             args["dims"], args["A"], args["b"])
        prob = Problem(Minimize(norm(self.x)), [self.x == 0])
        prob.unpack_results(s.CVXOPT, results_dict)
        self.assertItemsAlmostEqual(self.x.value, [0,0])
        self.assertAlmostEqual(prob.value, 0)
        self.assertAlmostEqual(prob.status, s.OPTIMAL)

    # Test silencing and enabling solver messages.
    def test_verbose(self):
        import sys
        # From http://stackoverflow.com/questions/5136611/capture-stdout-from-a-script-in-python
        # setup the environment
        outputs = {True: [], False: []}
        backup = sys.stdout
        # ####
        for verbose in [True, False]:
            for solver in installed_solvers():
                # Don't test GLPK because there's a race
                # condition in setting CVXOPT solver options.
                if solver in ["GLPK", "GLPK_MI"]:
                    continue
                # if solver == "GLPK":
                #     # GLPK's stdout is separate from python,
                #     # so we have to do this.
                #     # Note: This probably breaks (badly) on Windows.
                #     import os
                #     import tempfile

                #     stdout_fd = 1
                #     tmp_handle = tempfile.TemporaryFile(bufsize = 0)
                #     os.dup2(tmp_handle.fileno(), stdout_fd)
                # else:
                sys.stdout = StringIO() # capture output

                p = Problem(Minimize(self.a + self.x[0]),
                                     [self.a >= 2, self.x >= 2])
                if SOLVERS[solver].MIP_CAPABLE:
                    p.constraints.append(Bool() == 0)
                p.solve(verbose=verbose, solver=solver)
                if SOLVERS[solver].EXP_CAPABLE:
                    p = Problem(Minimize(self.a), [log(self.a) >= 2])
                    p.solve(verbose=verbose, solver=solver)

                # if solver == "GLPK":
                #     # GLPK's stdout is separate from python,
                #     # so we have to do this.
                #     tmp_handle.seek(0)
                #     out = tmp_handle.read()
                #     tmp_handle.close()
                # else:
                out = sys.stdout.getvalue() # release output

                outputs[verbose].append((out, solver))
        # ####
        sys.stdout.close()  # close the stream
        sys.stdout = backup # restore original stdout
        for output, solver in outputs[True]:
            print(solver)
            assert len(output) > 0
        for output, solver in outputs[False]:
            print(solver)
            assert len(output) == 0

    # Test registering other solve methods.
    def test_register_solve(self):
        Problem.register_solve("test",lambda self: 1)
        p = Problem(Minimize(1))
        result = p.solve(method="test")
        self.assertEqual(result, 1)

        def test(self, a, b=2):
            return (a,b)
        Problem.register_solve("test", test)
        p = Problem(Minimize(0))
        result = p.solve(1,b=3,method="test")
        self.assertEqual(result, (1,3))
        result = p.solve(1,method="test")
        self.assertEqual(result, (1,2))
        result = p.solve(1,method="test",b=4)
        self.assertEqual(result, (1,4))

    def test_consistency(self):
        """Test that variables and constraints keep a consistent order.
        """
        import itertools
        num_solves = 4
        vars_lists = []
        ineqs_lists = []
        var_ids_order_created = []
        for k in range(num_solves):
            sum = 0
            constraints = []
            var_ids = []
            for i in range(100):
                var = Variable(name=str(i))
                var_ids.append(var.id)
                sum += var
                constraints.append(var >= i)
            var_ids_order_created.append(var_ids)
            obj = Minimize(sum)
            p = Problem(obj, constraints)
            objective, constraints = p.canonicalize()
            sym_data = SymData(objective, constraints, SOLVERS[s.ECOS])
            # Sort by offset.
            vars_ = sorted(sym_data.var_offsets.items(),
                key=lambda key_val: key_val[1])
            vars_ = [var_id for (var_id, offset) in vars_]
            vars_lists.append(vars_)
            ineqs_lists.append(sym_data.constr_map[s.LEQ])

        # Verify order of variables is consistent.
        for i in range(num_solves):
            self.assertEqual(var_ids_order_created[i],
                vars_lists[i])
        for i in range(num_solves):
            for idx, constr in enumerate(ineqs_lists[i]):
                var_id, _ = lu.get_expr_vars(constr.expr)[0]
                self.assertEqual(var_ids_order_created[i][idx],
                    var_id)

    # Test removing duplicate constraint objects.
    def test_duplicate_constraints(self):
        eq = (self.x == 2)
        le = (self.x <= 2)
        obj = 0
        def test(self):
            objective, constraints = self.canonicalize()
            sym_data = SymData(objective, constraints, SOLVERS[s.CVXOPT])
            return (len(sym_data.constr_map[s.EQ]),
                    len(sym_data.constr_map[s.LEQ]))
        Problem.register_solve("test", test)
        p = Problem(Minimize(obj),[eq,eq,le,le])
        result = p.solve(method="test")
        self.assertEqual(result, (1, 1))

        # Internal constraints.
        X = Semidef(2)
        obj = sum_entries(X + X)
        p = Problem(Minimize(obj))
        result = p.solve(method="test")
        self.assertEqual(result, (0, 1))

        # Duplicates from non-linear constraints.
        exp = norm(self.x, 2)
        prob = Problem(Minimize(0), [exp <= 1, exp <= 2])
        result = prob.solve(method="test")
        self.assertEqual(result, (0, 4))

    # Test the is_dcp method.
    def test_is_dcp(self):
        p = Problem(Minimize(normInf(self.a)))
        self.assertEqual(p.is_dcp(), True)

        p = Problem(Maximize(normInf(self.a)))
        self.assertEqual(p.is_dcp(), False)
        with self.assertRaises(Exception) as cm:
            p.solve()
        self.assertEqual(str(cm.exception), "Problem does not follow DCP rules.")
        p.solve(ignore_dcp=True)

    # Test problems involving variables with the same name.
    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)

    # Test scalar LP problems.
    def test_scalar_lp(self):
        p = Problem(Minimize(3*self.a), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 6)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Maximize(3*self.a - self.b),
            [self.a <= 2, self.b == self.a, self.b <= 5])
        result = p.solve()
        self.assertAlmostEqual(result, 4.0)
        self.assertAlmostEqual(self.a.value, 2)
        self.assertAlmostEqual(self.b.value, 2)

        # With a constant in the objective.
        p = Problem(Minimize(3*self.a - self.b + 100),
            [self.a >= 2,
             self.b + 5*self.c - 2 == self.a,
             self.b <= 5 + self.c])
        result = p.solve()
        self.assertAlmostEqual(result, 101 + 1.0/6)
        self.assertAlmostEqual(self.a.value, 2)
        self.assertAlmostEqual(self.b.value, 5-1.0/6)
        self.assertAlmostEqual(self.c.value, -1.0/6)

        # Test status and value.
        exp = Maximize(self.a)
        p = Problem(exp, [self.a <= 2])
        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.OPTIMAL)
        assert self.a.value is not None
        assert p.constraints[0].dual_value is not None

        # Unbounded problems.
        p = Problem(Maximize(self.a), [self.a >= 2])
        p.solve(solver=s.ECOS)
        self.assertEqual(p.status, s.UNBOUNDED)
        assert numpy.isinf(p.value)
        assert p.value > 0
        assert self.a.value is None
        assert p.constraints[0].dual_value is None

        p = Problem(Minimize(-self.a), [self.a >= 2])
        result = p.solve(solver=s.CVXOPT)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.UNBOUNDED)
        assert numpy.isinf(p.value)
        assert p.value < 0

        # Infeasible problems.
        p = Problem(Maximize(self.a), [self.a >= 2, self.a <= 1])
        self.a.save_value(2)
        p.constraints[0].save_value(2)

        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.INFEASIBLE)
        assert numpy.isinf(p.value)
        assert p.value < 0
        assert self.a.value is None
        assert p.constraints[0].dual_value is None

        p = Problem(Minimize(-self.a), [self.a >= 2, self.a <= 1])
        result = p.solve(solver=s.ECOS)
        self.assertEqual(result, p.value)
        self.assertEqual(p.status, s.INFEASIBLE)
        assert numpy.isinf(p.value)
        assert p.value > 0

    # Test vector LP problems.
    def test_vector_lp(self):
        c = matrix([1,2])
        p = Problem(Minimize(c.T*self.x), [self.x >= c])
        result = p.solve()
        self.assertAlmostEqual(result, 5)
        self.assertItemsAlmostEqual(self.x.value, [1,2])

        A = matrix([[3,5],[1,2]])
        I = Constant([[1,0],[0,1]])
        p = Problem(Minimize(c.T*self.x + self.a),
            [A*self.x >= [-1,1],
             4*I*self.z == self.x,
             self.z >= [2,2],
             self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 26, places=3)
        obj = c.T*self.x.value + self.a.value
        self.assertAlmostEqual(obj[0,0], result)
        self.assertItemsAlmostEqual(self.x.value, [8,8], places=3)
        self.assertItemsAlmostEqual(self.z.value, [2,2], places=3)

    def test_ecos_noineq(self):
        """Test ECOS with no inequality constraints.
        """
        T = matrix(1, (2, 2))
        p = Problem(Minimize(1), [self.A == T])
        result = p.solve(solver=s.ECOS)
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, T)

    # Test matrix LP problems.
    def test_matrix_lp(self):
        T = matrix(1, (2, 2))
        p = Problem(Minimize(1), [self.A == T])
        result = p.solve()
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, T)

        T = matrix(2,(2,3))
        c = matrix([3,4])
        p = Problem(Minimize(1), [self.A >= T*self.C,
            self.A == self.B, self.C == T.T])
        result = p.solve()
        self.assertAlmostEqual(result, 1)
        self.assertItemsAlmostEqual(self.A.value, self.B.value)
        self.assertItemsAlmostEqual(self.C.value, T)
        assert (self.A.value >= T*self.C.value).all()

        # Test variables are dense.
        self.assertEqual(type(self.A.value), intf.DEFAULT_INTERFACE.TARGET_MATRIX)

    # Test variable promotion.
    def test_variable_promotion(self):
        p = Problem(Minimize(self.a), [self.x <= self.a, self.x == [1,2]])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Minimize(self.a),
            [self.A <= self.a,
             self.A == [[1,2],[3,4]]
             ])
        result = p.solve()
        self.assertAlmostEqual(result, 4)
        self.assertAlmostEqual(self.a.value, 4)

        # Promotion must happen before the multiplication.
        p = Problem(Minimize([[1],[1]]*(self.x + self.a + 1)),
            [self.a + self.x >= [1,2]])
        result = p.solve()
        self.assertAlmostEqual(result, 5)

    # Test parameter promotion.
    def test_parameter_promotion(self):
        a = Parameter()
        exp = [[1,2],[3,4]]*a
        a.value = 2
        assert not (exp.value - 2*numpy.array([[1,2],[3,4]]).T).any()

    def test_parameter_problems(self):
        """Test problems with parameters.
        """
        p1 = Parameter()
        p2 = Parameter(3, sign="negative")
        p3 = Parameter(4, 4, sign="positive")
        p = Problem(Maximize(p1*self.a), [self.a + p1 <= p2, self.b <= p3 + p3 + 2])
        p1.value = 2
        p2.value = -numpy.ones((3,1))
        p3.value = numpy.ones((4, 4))
        result = p.solve()
        self.assertAlmostEqual(result, -6)

    # Test problems with normInf
    def test_normInf(self):
        # Constant argument.
        p = Problem(Minimize(normInf(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(normInf(self.a)), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, 2)

        p = Problem(Minimize(3*normInf(self.a + 2*self.b) + self.c),
            [self.a >= 2, self.b <= -1, self.c == 3])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertAlmostEqual(self.a.value + 2*self.b.value, 0)
        self.assertAlmostEqual(self.c.value, 3)

        # Maximize
        p = Problem(Maximize(-normInf(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(normInf(self.x - self.z) + 5),
            [self.x >= [2,3], self.z <= [-1,-4]])
        result = p.solve()
        self.assertAlmostEqual(float(result), 12)
        self.assertAlmostEqual(float(list(self.x.value)[1] - list(self.z.value)[1]), 7)

    # Test problems with norm1
    def test_norm1(self):
        # Constant argument.
        p = Problem(Minimize(norm1(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(norm1(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, -2)

        # Maximize
        p = Problem(Maximize(-norm1(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(norm1(self.x - self.z) + 5),
            [self.x >= [2,3], self.z <= [-1,-4]])
        result = p.solve()
        self.assertAlmostEqual(float(result), 15)
        self.assertAlmostEqual(float(list(self.x.value)[1] - list(self.z.value)[1]), 7)

    # Test problems with norm2
    def test_norm2(self):
        # Constant argument.
        p = Problem(Minimize(norm2(-2)))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        # Scalar arguments.
        p = Problem(Minimize(norm2(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, 2)
        self.assertAlmostEqual(self.a.value, -2)

        # Maximize
        p = Problem(Maximize(-norm2(self.a)), [self.a <= -2])
        result = p.solve()
        self.assertAlmostEqual(result, -2)
        self.assertAlmostEqual(self.a.value, -2)

        # Vector arguments.
        p = Problem(Minimize(norm2(self.x - self.z) + 5),
            [self.x >= [2,3], self.z <= [-1,-4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12.61577)
        self.assertItemsAlmostEqual(self.x.value, [2,3])
        self.assertItemsAlmostEqual(self.z.value, [-1,-4])

        # Row  arguments.
        p = Problem(Minimize(norm2((self.x - self.z).T) + 5),
            [self.x >= [2,3], self.z <= [-1,-4]])
        result = p.solve()
        self.assertAlmostEqual(result, 12.61577)
        self.assertItemsAlmostEqual(self.x.value, [2,3])
        self.assertItemsAlmostEqual(self.z.value, [-1,-4])

    # Test problems with abs
    def test_abs(self):
        p = Problem(Minimize(sum_entries(abs(self.A))), [-2 >= self.A])
        result = p.solve()
        self.assertAlmostEqual(result, 8)
        self.assertItemsAlmostEqual(self.A.value, [-2,-2,-2,-2])

    # Test problems with quad_form.
    def test_quad_form(self):
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(self.x, self.A))).solve()
        self.assertEqual(str(cm.exception), "At least one argument to quad_form must be constant.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(1, self.A))).solve()
        self.assertEqual(str(cm.exception), "Invalid dimensions for arguments.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(quad_form(self.x, [[-1, 0], [0, 9]]))).solve()
        self.assertEqual(str(cm.exception), "P has both positive and negative eigenvalues.")

        P = [[4, 0], [0, 9]]
        p = Problem(Minimize(quad_form(self.x, P)), [self.x >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 13, places=3)

        c = [1,2]
        p = Problem(Minimize(quad_form(c, self.A)), [self.A >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 9)

        c = [1,2]
        P = [[4, 0], [0, 9]]
        p = Problem(Minimize(quad_form(c, P)))
        result = p.solve()
        self.assertAlmostEqual(result, 40)

    # Test combining atoms
    def test_mixed_atoms(self):
        p = Problem(Minimize(norm2(5 + norm1(self.z)
                                  + norm1(self.x) +
                                  normInf(self.x - self.z) ) ),
            [self.x >= [2,3], self.z <= [-1,-4], norm2(self.x + self.z) <= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 22)
        self.assertItemsAlmostEqual(self.x.value, [2,3])
        self.assertItemsAlmostEqual(self.z.value, [-1,-4])

    # Test multiplying by constant atoms.
    def test_mult_constant_atoms(self):
        p = Problem(Minimize(norm2([3,4])*self.a), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertAlmostEqual(self.a.value, 2)

    # Test recovery of dual variables.
    def test_dual_variables(self):
        p = Problem(Minimize( norm1(self.x + self.z) ),
            [self.x >= [2,3],
             [[1,2],[3,4]]*self.z == [-1,-4],
             norm2(self.x + self.z) <= 100])
        result = p.solve()
        self.assertAlmostEqual(result, 4)
        self.assertItemsAlmostEqual(self.x.value, [4,3])
        self.assertItemsAlmostEqual(self.z.value, [-4,1])
        # Dual values
        self.assertItemsAlmostEqual(p.constraints[0].dual_value, [0, 1])
        self.assertItemsAlmostEqual(p.constraints[1].dual_value, [-1, 0.5])
        self.assertAlmostEqual(p.constraints[2].dual_value, 0)

        T = matrix(2, (2, 3))
        c = matrix([3,4])
        p = Problem(Minimize(1),
            [self.A >= T*self.C,
             self.A == self.B,
             self.C == T.T])
        result = p.solve()
        # Dual values
        self.assertItemsAlmostEqual(p.constraints[0].dual_value, 4*[0])
        self.assertItemsAlmostEqual(p.constraints[1].dual_value, 4*[0])
        self.assertItemsAlmostEqual(p.constraints[2].dual_value, 6*[0])

    # Test problems with indexing.
    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)

    # Test problems with slicing.
    def test_slicing(self):
        p = Problem(Maximize(sum_entries(self.C)), [self.C[1:3,:] <= 2, self.C[0,:] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2*[1,2,2])

        p = Problem(Maximize(sum_entries(self.C[0:3:2,1])),
            [self.C[1:3,:] <= 2, self.C[0,:] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.C.value[0:3:2,1], [1,2])

        p = Problem(Maximize(sum_entries( (self.C[0:2,:] + self.A)[:,0:2] )),
            [self.C[1:3,:] <= 2, self.C[0,:] == 1,
             (self.A + self.B)[:,0] == 3, (self.A + self.B)[:,1] == 2,
             self.B == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertItemsAlmostEqual(self.C.value[0:2,:], [1,2,1,2])
        self.assertItemsAlmostEqual(self.A.value, [2,2,1,1])

        p = Problem(Maximize( [[3],[4]]*(self.C[0:2,:] + self.A)[:,0] ),
            [self.C[1:3,:] <= 2, self.C[0,:] == 1,
             [[1],[2]]*(self.A + self.B)[:,0] == 3, (self.A + self.B)[:,1] == 2,
             self.B == 1, 3*self.A[:,0] <= 3])
        result = p.solve()
        self.assertAlmostEqual(result, 12)
        self.assertItemsAlmostEqual(self.C.value[0:2,0], [1,2])
        self.assertItemsAlmostEqual(self.A.value, [1,-.5,1,1])

        p = Problem(Minimize(norm2((self.C[0:2,:] + self.A)[:,0] )),
            [self.C[1:3,:] <= 2, self.C[0,:] == 1,
             (self.A + self.B)[:,0] == 3, (self.A + self.B)[:,1] == 2,
             self.B == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.C.value[0:2,0], [1,-2])
        self.assertItemsAlmostEqual(self.A.value, [2,2,1,1])

        # Transpose of slice.
        p = Problem(Maximize(sum_entries(self.C)), [self.C[1:3,:].T <= 2, self.C[0,:].T == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2*[1,2,2])

    # Test the vstack atom.
    def test_vstack(self):
        c = matrix(1, (1,5))
        p = Problem(Minimize(c * vstack(self.x, self.y)),
            [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 * vstack(self.x, self.x)),
            [self.x == [1,2]])
        result = p.solve()
        self.assertAlmostEqual(result, 6)


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

        c = matrix(1, (1,2))
        p = Problem( Minimize( sum_entries(vstack(c*self.A, c*self.B)) ),
            [self.A >= 2,
            self.B == -2])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

        c = matrix([1,-1])
        p = Problem( Minimize( c.T * vstack(square(self.a), sqrt(self.b))),
            [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.")

    # Test the hstack atom.
    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.")

    def test_bad_objective(self):
        """Test using a cvxpy expression as an objective.
        """
        with self.assertRaises(Exception) as cm:
            Problem(self.x+2)
        self.assertEqual(str(cm.exception), "Problem objective must be Minimize or Maximize.")

    # Test variable transpose.
    def test_transpose(self):
        p = Problem(Minimize(sum_entries(self.x)), [self.x.T >= matrix([1,2]).T])
        result = p.solve()
        self.assertAlmostEqual(result, 3)
        self.assertItemsAlmostEqual(self.x.value, [1,2])

        p = Problem(Minimize(sum_entries(self.C)), [matrix([1,1]).T*self.C.T >= matrix([0,1,2]).T])
        result = p.solve()
        value = self.C.value

        constraints = [1*self.C[i,0] + 1*self.C[i,1] >= i for i in range(3)]
        p = Problem(Minimize(sum_entries(self.C)), constraints)
        result2 = p.solve()
        self.assertAlmostEqual(result, result2)
        self.assertItemsAlmostEqual(self.C.value, value)

        p = Problem(Minimize(self.A[0,1] - self.A.T[1,0]),
                    [self.A == [[1,2],[3,4]]])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

        exp = (-self.x).T
        p = Problem(Minimize(sum_entries(self.x)), [(-self.x).T <= 1])
        result = p.solve()
        self.assertAlmostEqual(result, -2)

        c = matrix([1,-1])
        p = Problem(Minimize(max_elemwise(c.T, 2, 2 + c.T)[1]))
        result = p.solve()
        self.assertAlmostEqual(result, 2)

        c = matrix([[1,-1,2],[1,-1,2]])
        p = Problem(Minimize(sum_entries(max_elemwise(c, 2, 2 + c).T[:,0])))
        result = p.solve()
        self.assertAlmostEqual(result, 6)

        c = matrix([[1,-1,2],[1,-1,2]])
        p = Problem(Minimize(sum_entries(square(c.T).T[:,0])))
        result = p.solve()
        self.assertAlmostEqual(result, 6)

        # Slice of transpose.
        p = Problem(Maximize(sum_entries(self.C)), [self.C.T[:,1:3] <= 2, self.C.T[:,0] == 1])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(self.C.value, 2*[1,2,2])

    # Test multiplication on the left by a non-constant.
    def test_multiplication_on_left(self):
        c = matrix([1,2])
        p = Problem(Minimize(c.T*self.A*c), [self.A >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 18)

        p = Problem(Minimize(self.a*2), [self.a >= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 4)

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

        p = Problem(Minimize((self.x.T + self.z.T)*c),
            [self.x >= 2, self.z >= 1])
        result = p.solve()
        self.assertAlmostEqual(result, 9)

    # Test redundant constraints in cvxopt.
    def test_redundant_constraints(self):
        obj = Minimize(sum_entries(self.x))
        constraints = [self.x == 2, self.x == 2, self.x.T == 2, self.x[0] == 2]
        p = Problem(obj, constraints)
        result = p.solve(solver=s.CVXOPT)
        self.assertAlmostEqual(result, 4)

        obj = Minimize(sum_entries(square(self.x)))
        constraints = [self.x == self.x]
        p = Problem(obj, constraints)
        result = p.solve(solver=s.CVXOPT)
        self.assertAlmostEqual(result, 0)

    # Test that symmetry is enforced.
    def test_sdp_symmetry(self):
        # TODO should these raise exceptions?
        # with self.assertRaises(Exception) as cm:
        #     lambda_max([[1,2],[3,4]])
        # self.assertEqual(str(cm.exception), "lambda_max called on non-symmetric matrix.")

        # with self.assertRaises(Exception) as cm:
        #     lambda_min([[1,2],[3,4]])
        # self.assertEqual(str(cm.exception), "lambda_min called on non-symmetric matrix.")

        p = Problem(Minimize(lambda_max(self.A)), [self.A >= 2])
        result = p.solve()
        self.assertItemsAlmostEqual(self.A.value, self.A.value.T)

        p = Problem(Minimize(lambda_max(self.A)), [self.A == [[1,2],[3,4]]])
        result = p.solve()
        self.assertEqual(p.status, s.INFEASIBLE)

    # Test SDP
    def test_sdp(self):
        # Ensure sdp constraints enforce transpose.
        obj = Maximize(self.A[1,0] - self.A[0,1])
        p = Problem(obj, [lambda_max(self.A) <= 100,
                          self.A[0,0] == 2,
                          self.A[1,1] == 2,
                          self.A[1,0] == 2])
        result = p.solve()
        self.assertAlmostEqual(result, 0)

    # Test getting values for expressions.
    def test_expression_values(self):
        diff_exp = self.x - self.z
        inf_exp = normInf(diff_exp)
        sum_entries_exp = 5 + norm1(self.z) + norm1(self.x) + inf_exp
        constr_exp = norm2(self.x + self.z)
        obj = norm2(sum_entries_exp)
        p = Problem(Minimize(obj),
            [self.x >= [2,3], self.z <= [-1,-4], constr_exp <= 2])
        result = p.solve()
        self.assertAlmostEqual(result, 22)
        self.assertItemsAlmostEqual(self.x.value, [2,3])
        self.assertItemsAlmostEqual(self.z.value, [-1,-4])
        # Expression values.
        self.assertItemsAlmostEqual(diff_exp.value, self.x.value - self.z.value)
        self.assertAlmostEqual(inf_exp.value,
            LA.norm(self.x.value - self.z.value, numpy.inf))
        self.assertAlmostEqual(sum_entries_exp.value,
            5 + LA.norm(self.z.value, 1) + LA.norm(self.x.value, 1) + \
            LA.norm(self.x.value - self.z.value, numpy.inf))
        self.assertAlmostEqual(constr_exp.value,
            LA.norm(self.x.value + self.z.value, 2))
        self.assertAlmostEqual(obj.value, result)

    def test_mult_by_zero(self):
        """Test multiplication by zero.
        """
        exp = 0*self.a
        self.assertEqual(exp.value, 0)
        obj = Minimize(exp)
        p = Problem(obj)
        result = p.solve()
        self.assertAlmostEqual(result, 0)
        assert self.a.value is not None

    def test_div(self):
        """Tests a problem with division.
        """
        obj = Minimize(normInf(self.A/5))
        p = Problem(obj, [self.A >= 5])
        result = p.solve()
        self.assertAlmostEqual(result, 1)

    def test_mul_elemwise(self):
        """Tests problems with mul_elemwise.
        """
        c = [[1, -1], [2, -2]]
        expr = mul_elemwise(c, self.A)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.A == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, -5] + [10, -10])

        # Test with a sparse matrix.
        import cvxopt
        interface = intf.get_matrix_interface(cvxopt.spmatrix)
        c = interface.const_to_matrix([1,2])
        expr = mul_elemwise(c, self.x)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.x == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, 10])

        # Test promotion.
        c = [[1, -1], [2, -2]]
        expr = mul_elemwise(c, self.a)
        obj = Minimize(normInf(expr))
        p = Problem(obj, [self.a == 5])
        result = p.solve()
        self.assertAlmostEqual(result, 10)
        self.assertItemsAlmostEqual(expr.value, [5, -5] + [10, -10])

    def test_invalid_solvers(self):
        """Tests that errors occur when you use an invalid solver.
        """
        with self.assertRaises(Exception) as cm:
            Problem(Minimize(-log(self.a))).solve(solver=s.ECOS)
        self.assertEqual(str(cm.exception),
            "The solver ECOS cannot solve the problem.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(lambda_max(self.a))).solve(solver=s.ECOS)
        self.assertEqual(str(cm.exception),
            "The solver ECOS cannot solve the problem.")

        with self.assertRaises(Exception) as cm:
            Problem(Minimize(self.a)).solve(solver=s.SCS)
        self.assertEqual(str(cm.exception),
            "The solver SCS cannot solve the problem.")

    def test_reshape(self):
        """Tests problems with reshape.
        """
        # Test on scalars.
        self.assertEqual(reshape(1, 1, 1).value, 1)

        # Test vector to matrix.
        x = Variable(4)
        mat = matrix([[1,-1], [2, -2]])
        vec = matrix([1, 2, 3, 4])
        vec_mat = matrix([[1, 2], [3, 4]])
        expr = reshape(x, 2, 2)
        obj = Minimize(sum_entries(mat*expr))
        prob = Problem(obj, [x == vec])
        result = prob.solve()
        self.assertAlmostEqual(result, sum(mat*vec_mat))

        # Test on matrix to vector.
        c = [1, 2, 3, 4]
        expr = reshape(self.A, 4, 1)
        obj = Minimize(expr.T*c)
        constraints = [self.A == [[-1, -2], [3, 4]]]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 20)
        self.assertItemsAlmostEqual(expr.value, [-1, -2, 3, 4])
        self.assertItemsAlmostEqual(reshape(expr, 2, 2).value, [-1, -2, 3, 4])

        # Test matrix to matrix.
        expr = reshape(self.C, 2, 3)
        mat = numpy.matrix([[1,-1], [2, -2]])
        C_mat = numpy.matrix([[1, 4], [2, 5], [3, 6]])
        obj = Minimize(sum_entries(mat*expr))
        prob = Problem(obj, [self.C == C_mat])
        result = prob.solve()
        reshaped = numpy.reshape(C_mat, (2, 3), 'F')
        self.assertAlmostEqual(result, (mat.dot(reshaped)).sum())
        self.assertItemsAlmostEqual(expr.value, C_mat)

        # Test promoted expressions.
        c = matrix([[1,-1], [2, -2]])
        expr = reshape(c*self.a, 1, 4)
        obj = Minimize(expr*[1, 2, 3, 4])
        prob = Problem(obj, [self.a == 2])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(expr.value, 2*c)

        expr = reshape(c*self.a, 4, 1)
        obj = Minimize(expr.T*[1, 2, 3, 4])
        prob = Problem(obj, [self.a == 2])
        result = prob.solve()
        self.assertAlmostEqual(result, -6)
        self.assertItemsAlmostEqual(expr.value, 2*c)

    def test_vec(self):
        """Tests problems with vec.
        """
        c = [1, 2, 3, 4]
        expr = vec(self.A)
        obj = Minimize(expr.T*c)
        constraints = [self.A == [[-1, -2], [3, 4]]]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 20)
        self.assertItemsAlmostEqual(expr.value, [-1, -2, 3, 4])

    def test_diag_prob(self):
        """Test a problem with diag.
        """
        C = Variable(3, 3)
        obj = Maximize(C[0, 2])
        constraints = [diag(C) == 1,
                       C[0, 1] == 0.6,
                       C[1, 2] == -0.3,
                       C == Semidef(3)]
        prob = Problem(obj, constraints)
        result = prob.solve()
        self.assertAlmostEqual(result, 0.583151)

    def test_presolve_constant_constraints(self):
        """Test that the presolver removes constraints with no variables.
        """
        x = Variable()
        obj = Maximize(sqrt(x))
        prob = Problem(obj)
        data = prob.get_problem_data(s.ECOS)
        A = data["A"]
        G = data["G"]
        for row in range(A.shape[0]):
            assert A[row, :].nnz > 0
        for row in range(G.shape[0]):
            assert G[row, :].nnz > 0

    def test_presolve_parameters(self):
        """Test presolve with parameters.
        """
        # Test with parameters.
        gamma = Parameter(sign="positive")
        x = Variable()
        obj = Minimize(x)
        prob = Problem(obj, [gamma == 1, x >= 0])
        gamma.value = 0
        prob.solve(solver=s.SCS)
        self.assertEqual(prob.status, s.INFEASIBLE)

        gamma.value = 1
        prob.solve(solver=s.CVXOPT)
        self.assertEqual(prob.status, s.OPTIMAL)

    def test_parameter_expressions(self):
        """Test that expressions with parameters are updated properly.
        """
        x = Variable()
        y = Variable()
        x0 = Parameter()
        xSquared = x0*x0 + 2*x0*(x - x0)

        # initial guess for x
        x0.value = 2

        # make the constraint x**2 - y == 0
        g = xSquared - y

        # set up the problem
        obj = abs(x - 1)
        prob = Problem( Minimize( obj ), [ g == 0 ] )
        prob.solve()
        x0.value = 1
        prob.solve()
        self.assertAlmostEqual(g.value, 0)

        # Test multiplication.
        prob = Problem( Minimize( x0*x ), [ x == 1 ] )
        x0.value = 2
        prob.solve()
        x0.value = 1
        prob.solve()
        self.assertAlmostEqual(prob.value, 1)

    def test_geo_mean(self):
        import numpy as np

        x = Variable(2)
        cost = geo_mean(x)
        prob = Problem(Maximize(cost), [x <= 1])
        prob.solve()
        self.assertAlmostEqual(prob.value, 1)

        prob = Problem(Maximize(cost), [sum(x) <= 1])
        prob.solve()
        self.assertItemsAlmostEqual(x.value, [.5, .5])

        x = Variable(3, 3)
        self.assertRaises(ValueError, geo_mean, x)

        x = Variable(3, 1)
        g = geo_mean(x)
        self.assertSequenceEqual(g.w, [Fraction(1, 3)]*3)

        x = Variable(1, 5)
        g = geo_mean(x)
        self.assertSequenceEqual(g.w, [Fraction(1, 5)]*5)

        # check that we get the right answer for
        # max geo_mean(x) s.t. sum(x) <= 1
        p = np.array([.07, .12, .23, .19, .39])

        def short_geo_mean(x, p):
            p = np.array(p)/sum(p)
            x = np.array(x)
            return np.prod(x**p)

        x = Variable(5)
        prob = Problem(Maximize(geo_mean(x, p)), [sum(x) <= 1])
        prob.solve()
        x = np.array(x.value).flatten()
        x_true = p/sum(p)

        self.assertTrue(np.allclose(prob.value, geo_mean(list(x), p).value))
        self.assertTrue(np.allclose(prob.value, short_geo_mean(x, p)))
        self.assertTrue(np.allclose(x, x_true, 1e-3))

        # check that we get the right answer for
        # max geo_mean(x) s.t. norm(x) <= 1
        x = Variable(5)
        prob = Problem(Maximize(geo_mean(x, p)), [norm(x) <= 1])
        prob.solve()
        x = np.array(x.value).flatten()
        x_true = np.sqrt(p/sum(p))

        self.assertTrue(np.allclose(prob.value, geo_mean(list(x), p).value))
        self.assertTrue(np.allclose(prob.value, short_geo_mean(x, p)))
        self.assertTrue(np.allclose(x, x_true, 1e-3))

    def test_pnorm(self):
        import numpy as np

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

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

        # todo: add -1, .5, .3, -2.3 and testing positivity constraints

        for p in (1, 1.6, 1.3, 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), 'p = {}'.format(p))
            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))

    def test_pnorm_concave(self):
        import numpy as np

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

        # test positivity constraints
        a = np.array([-1.0, 2, 3])
        for p in (-1, .5, .3, -2.3):
            prob = Problem(Minimize(sum_entries(abs(x-a))), [pnorm(x, p) >= 0])
            prob.solve()

            self.assertTrue(np.allclose(prob.value, 1))

        a = np.array([1.0, 2, 3])
        for p in (-1, .5, .3, -2.3):
            prob = Problem(Minimize(sum_entries(abs(x-a))), [pnorm(x, p) >= 0])
            prob.solve()

            self.assertTrue(np.allclose(prob.value, 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)