예제 #1
0
 def test_constant_copy(self):
     """Test the copy function for Constants.
     """
     x = Constant(2)
     y = x.copy()
     self.assertEqual(y.size, (1, 1))
     self.assertEqual(y.value, 2)
예제 #2
0
    def test_constants(self):
        c = Constant(2)
        self.assertEqual(c.name(), str(2))

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

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

        # Test the sign.
        c = Constant([[2], [2]])
        self.assertEqual(c.size, (1, 2))
        self.assertEqual(c.sign, u.Sign.UNKNOWN_KEY)

        # Test sign of a complex expression.
        c = Constant([1, 2])
        A = Constant([[1,1],[1,1]])
        exp = c.T*A*c
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)
        self.assertEqual((c.T*c).sign, u.Sign.UNKNOWN_KEY)
        exp = c.T.T
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)
        exp = c.T*self.A
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)
예제 #3
0
    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.")
예제 #4
0
    def setUp(self):
        self.a = Variable()

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

        self.A = Variable(2,2)

        self.c = Constant(3)
        self.C = Constant([[1, 2], [1, 2]])
예제 #5
0
    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(), [Constant])
        self.assertEqual(coeffs[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 sign of a complex expression.
        c = Constant([1, 2])
        A = Constant([[1,1],[1,1]])
        exp = c.T*A*c
        self.assertEqual(exp.sign, u.Sign.POSITIVE)
        self.assertEqual((c.T*c).sign, u.Sign.POSITIVE)
        exp = c.T.T
        self.assertEqual(exp.sign.pos_mat.value.ndim, 2)
        exp = c.T*self.A
        self.assertEqual(exp.sign.pos_mat.value.ndim, 2)
예제 #6
0
    def test_matmul_expression(self):
        """Test matmul function, corresponding to .__matmul__( operator.
        """
        if PY35:
            # Vectors
            c = Constant([[2], [2]])
            exp = c.__matmul__(self.x)
            self.assertEqual(exp.curvature, s.AFFINE)
            self.assertEqual(exp.sign, s.UNKNOWN)
            self.assertEqual(exp.canonical_form[0].size, (1, 1))
            self.assertEqual(exp.canonical_form[1], [])
            # self.assertEqual(exp.name(), c.name() + " .__matmul__( " + self.x.name())
            self.assertEqual(exp.size, (1, 1))

            with self.assertRaises(Exception) as cm:
                self.x.__matmul__(2)
            self.assertEqual(str(cm.exception),
                             "Scalar operands are not allowed, use '*' instead")
            with self.assertRaises(Exception) as cm:
                (self.x.__matmul__(np.array([2, 2, 3])))
            self.assertEqual(str(cm.exception), "Incompatible dimensions (2, 1) (3, 1)")

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

            # Affine times affine is okay
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                q = self.A .__matmul__(self.B)
                self.assertTrue(q.is_quadratic())

            # Nonaffine times nonconstant raises error
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                with self.assertRaises(Exception) as cm:
                    (self.A.__matmul__(self.B).__matmul__(self.A))
                self.assertEqual(str(cm.exception), "Cannot multiply UNKNOWN and AFFINE.")

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

            # Expression that would break sign multiplication without promotion.
            c = Constant([[2], [2], [-2]])
            exp = [[1], [2]] + c.__matmul__(self.C)
            self.assertEqual(exp.sign, s.UNKNOWN)
        else:
            pass
예제 #7
0
def linearize(expr):
    """Returns the tangent approximation to the expression.

    Gives an elementwise lower (upper) bound for convex (concave)
    expressions. No guarantees for non-DCP expressions.

    Returns None if cannot be linearized.

    Args:
        expr: An expression.

    Returns:
        An affine expression or None.
    """
    expr = Constant.cast_to_const(expr)
    if expr.is_affine():
        return expr
    else:
        tangent = expr.value
        if tangent is None:
            raise ValueError(
        "Cannot linearize non-affine expression with missing variable values."
            )
        grad_map = expr.grad
        for var in expr.variables():
            if grad_map[var] is None:
                return None
            elif var.is_matrix():
                flattened = Constant(grad_map[var]).T*vec(var - var.value)
                tangent = tangent + reshape(flattened, *expr.size)
            else:
                tangent = tangent + Constant(grad_map[var]).T*(var - var.value)
        return tangent
예제 #8
0
def quad_form(x, P):
    """ Alias for :math:`x^T P x`.

    """
    x, P = map(Expression.cast_to_const, (x, P))
    # Check dimensions.
    n = P.size[0]
    if P.size[1] != n or x.size != (n, 1):
        raise Exception("Invalid dimensions for arguments.")
    if x.is_constant():
        return x.T * P * x
    elif P.is_constant():
        P = intf.DEFAULT_NP_INTF.const_to_matrix(P.value)
        # Force symmetry
        P = (P + P.T) / 2.0
        scale, M1, M2 = _decomp_quad(P)
        ret = 0
        if M1.size > 0:
            ret += scale * sum_squares(Constant(M1.T) * x)
        if M2.size > 0:
            ret -= scale * sum_squares(Constant(M2.T) * x)
        return ret
    else:
        raise Exception("At least one argument to quad_form must be constant.")
예제 #9
0
def mi_lp_3() -> SolverTestHelper:
    # infeasible (but relaxable) test case
    x = cp.Variable(4, boolean=True)
    from cvxpy.expressions.constants import Constant
    objective = cp.Maximize(Constant(1))
    constraints = [
        x[0] + x[1] + x[2] + x[3] <= 2, x[0] + x[1] + x[2] + x[3] >= 2,
        x[0] + x[1] <= 1, x[0] + x[2] <= 1, x[0] + x[3] <= 1, x[2] + x[3] <= 1,
        x[1] + x[3] <= 1, x[1] + x[2] <= 1
    ]
    obj_pair = (objective, -np.inf)
    con_pairs = [(c, None) for c in constraints]
    var_pairs = [(x, None)]
    sth = SolverTestHelper(obj_pair, var_pairs, con_pairs)
    return sth
예제 #10
0
    def test_div_expression(self):
        # Vectors
        exp = self.x/2
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)
        self.assertEqual(exp.canonical_form[0].size, (2,1))
        self.assertEqual(exp.canonical_form[1], [])
        # self.assertEqual(exp.name(), c.name() + " * " + self.x.name())
        self.assertEqual(exp.size, (2,1))

        with self.assertRaises(Exception) as cm:
            (self.x/[2,2,3])
        print(cm.exception)
        self.assertEqual(str(cm.exception), "Can only divide by a scalar constant.")

        # Constant expressions.
        c = Constant(2)
        exp = c/(3 - 5)
        self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY)
        self.assertEqual(exp.size, (1,1))
        self.assertEqual(exp.sign, u.Sign.NEGATIVE_KEY)

        # Parameters.
        p = Parameter(sign="positive")
        exp = 2/p
        p.value = 2
        self.assertEquals(exp.value, 1)

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

        self.assertEquals(rho.sign, u.Sign.POSITIVE_KEY)
        self.assertEquals(Constant(2).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals((Constant(2)/Constant(2)).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals((Constant(2)*rho).sign, u.Sign.POSITIVE_KEY)
        self.assertEquals((rho/2).sign, u.Sign.POSITIVE_KEY)
예제 #11
0
    def test_none_idx(self):
        """Test None as index.
        """
        expr = self.a[None, None]
        self.assertEqual(expr.shape, (1, 1))

        expr = self.x[:, None]
        self.assertEqual(expr.shape, (2, 1))

        expr = self.x[None, :]
        self.assertEqual(expr.shape, (1, 2))

        expr = Constant([1, 2])[None, :]
        self.assertEqual(expr.shape, (1, 2))
        self.assertItemsAlmostEqual(expr.value, [1, 2])
 def canonicalize_expr(self, expr, args):
     if isinstance(expr, Expression) and not expr.variables():
         # Parameterized expressions are evaluated in a subsequent
         # reduction.
         if expr.parameters():
             rows, cols = expr.shape
             param = CallbackParam(lambda: expr.value, (rows, cols))
             return param, []
         # Non-parameterized expressions are evaluated immediately.
         else:
             return Constant(expr.value), []
     elif type(expr) in self.canon_methods:
         return self.canon_methods[type(expr)](expr, args)
     else:
         return expr.copy(args), []
예제 #13
0
    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))
예제 #14
0
    def _grad(self, values):
        """Gives the (sub/super)gradient of the atom w.r.t. each argument.

        Matrix expressions are vectorized, so the gradient is a matrix.

        Args:
            values: A list of numeric values for the arguments.

        Returns:
            A list of SciPy CSC sparse matrices or None.
        """
        # TODO should be a simple function in cvxcore for this.
        # Make a fake lin op tree for the function.
        fake_args = []
        var_offsets = {}
        offset = 0
        for idx, arg in enumerate(self.args):
            if arg.is_constant():
                fake_args += [Constant(arg.value).canonical_form[0]]
            else:
                fake_args += [lu.create_var(arg.shape, idx)]
                var_offsets[idx] = offset
                offset += arg.size
        fake_expr, _ = self.graph_implementation(fake_args, self.shape,
                                                 self.get_data())
        # Get the matrix representation of the function.
        V, I, J, _ = canonInterface.get_problem_matrix(
            [fake_expr],
            var_offsets,
            None
        )
        shape = (offset, self.size)
        stacked_grad = sp.csc_matrix((V, (J, I)), shape=shape)
        # Break up into per argument matrices.
        grad_list = []
        start = 0
        for arg in self.args:
            if arg.is_constant():
                grad_shape = (arg.size, shape[1])
                if grad_shape == (1, 1):
                    grad_list += [0]
                else:
                    grad_list += [sp.coo_matrix(grad_shape, dtype='float64')]
            else:
                stop = start + arg.size
                grad_list += [stacked_grad[start:stop, :]]
                start = stop
        return grad_list
예제 #15
0
 def test_imag(self) -> None:
     """Test imag.
     """
     A = np.ones((2, 2))
     expr = Constant(A) + 2j*Constant(A)
     expr = cvx.imag(expr)
     assert expr.is_real()
     assert not expr.is_complex()
     assert not expr.is_imag()
     self.assertItemsAlmostEqual(expr.value, 2*A)
예제 #16
0
 def test_conj(self):
     """Test imag.
     """
     A = np.ones((2, 2))
     expr = Constant(A) + 1j*Constant(A)
     expr = cvx.conj(expr)
     assert not expr.is_real()
     assert expr.is_complex()
     assert not expr.is_imag()
     self.assertItemsAlmostEqual(expr.value, A - 1j*A)
예제 #17
0
    def test_real(self):
        """Test real.
        """
        A = np.ones((2, 2))
        expr = Constant(A) + 1j*Constant(A)
        expr = cvx.real(expr)
        assert expr.is_real()
        assert not expr.is_complex()
        assert not expr.is_imag()
        self.assertItemsAlmostEqual(expr.value, A)

        x = Variable(complex=True)
        expr = cvx.imag(x) + cvx.real(x)
        assert expr.is_real()
예제 #18
0
def power_canon(expr, args):
    affine_expr = args[0]
    p = expr.p
    if expr.is_constant():
        return Constant(expr.value), []
    elif p == 0:
        return np.ones(affine_expr.shape), []
    elif p == 1:
        return affine_expr, []
    elif p == 2:
        if isinstance(affine_expr, Variable):
            return SymbolicQuadForm(affine_expr, np.eye(affine_expr.size), expr), []
        else:
            t = Variable(affine_expr.shape)
            return SymbolicQuadForm(t, np.eye(t.size), expr), [affine_expr == t]
    raise ValueError("non-constant quadratic forms can't be raised to a power "
                     "greater than 2.")
예제 #19
0
def quad_form(x, P):
    """ Alias for :math:`x^T P x`.

    """
    x, P = map(Expression.cast_to_const, (x, P))
    # Check dimensions.
    n = P.size[0]
    if P.size[1] != n or x.size != (n, 1):
        raise Exception("Invalid dimensions for arguments.")
    if x.is_constant():
        return x.T * P * x
    elif P.is_constant():
        np_intf = intf.get_matrix_interface(np.ndarray)
        P = np_intf.const_to_matrix(P.value)
        sgn, scale, M = _decomp_quad(P)
        return sgn * scale * square(norm(Constant(M.T) * x))
    else:
        raise Exception("At least one argument to quad_form must be constant.")
예제 #20
0
def pnorm_canon(expr, args):
    x = args[0]
    p = expr.p
    axis = expr.axis
    shape = expr.shape
    t = Variable(shape)

    if p == 2:
        if axis is None:
            assert shape == tuple()
            return t, [SOC(t, vec(x))]
        else:
            return t, [SOC(vec(t), x, axis)]

    # we need an absolute value constraint for the symmetric convex branches
    # (p > 1)
    constraints = []
    if p > 1:
        # TODO(akshayka): Express this more naturally (recursively), in terms
        # of the other atoms
        abs_expr = abs(x)
        abs_x, abs_constraints = abs_canon(abs_expr, abs_expr.args)
        x = abs_x
        constraints += abs_constraints

    # now, we take care of the remaining convex and concave branches
    # to create the rational powers, we need a new variable, r, and
    # the constraint sum(r) == t
    r = Variable(x.shape)
    constraints += [sum(r) == t]

    # todo: no need to run gm_constr to form the tree each time.
    # we only need to form the tree once
    promoted_t = Constant(np.ones(x.shape)) * t
    p = Fraction(p)
    if p < 0:
        constraints += gm_constrs(promoted_t, [x, r],
                                  (-p / (1 - p), 1 / (1 - p)))
    if 0 < p < 1:
        constraints += gm_constrs(r, [x, promoted_t], (p, 1 - p))
    if p > 1:
        constraints += gm_constrs(x, [r, promoted_t], (1 / p, 1 - 1 / p))

    return t, constraints
예제 #21
0
def test_constant_atoms():
    tests = []
    for atom_list, objective_type in atoms:
        for atom, size, args, obj_val in atom_list:
            for indexer in get_indices(size):
                for solver in SOLVERS_TO_TRY:
                    # Atoms with Constant arguments.
                    prob_val = obj_val[indexer].value
                    const_args = [Constant(arg) for arg in args]
                    problem = Problem(
                        objective_type(atom(*const_args)[indexer]))
                    yield (run_atom,
                           atom,
                           problem,
                           prob_val,
                           solver)
                    # Atoms with Variable arguments.
                    variables = []
                    constraints = []
                    for idx, expr in enumerate(args):
                        variables.append(Variable(intf.shape(expr)))
                        constraints.append(variables[-1] == expr)
                    objective = objective_type(atom(*variables)[indexer])
                    new_obj_val = prob_val
                    if objective_type == Maximize:
                        objective = -objective
                        new_obj_val = -new_obj_val
                    problem = Problem(objective, constraints)
                    yield (run_atom,
                           atom,
                           problem,
                           new_obj_val,
                           solver)
                    # Atoms with Parameter arguments.
                    parameters = []
                    for expr in args:
                        parameters.append(Parameter(intf.shape(expr)))
                        parameters[-1].value = intf.DEFAULT_INTF.const_to_matrix(expr)
                    objective = objective_type(atom(*parameters)[indexer])
                    yield (run_atom,
                           atom,
                           Problem(objective),
                           prob_val,
                           solver)
예제 #22
0
파일: atom.py 프로젝트: zxuen/cvxpy
 def canonicalize(self):
     """Represent the atom as an affine objective and conic constraints.
     """
     # Constant atoms are treated as a leaf.
     if self.is_constant() and not self.parameters():
         # Non-parameterized expressions are evaluated immediately.
         return Constant(self.value).canonical_form
     else:
         arg_objs = []
         constraints = []
         for arg in self.args:
             obj, constr = arg.canonical_form
             arg_objs.append(obj)
             constraints += constr
         # Special info required by the graph implementation.
         data = self.get_data()
         graph_obj, graph_constr = self.graph_implementation(
             arg_objs, self.shape, data)
         return graph_obj, constraints + graph_constr
예제 #23
0
    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)
예제 #24
0
def quad_canon(expr, real_args, imag_args, real2imag):
    """Convert quad_form to real.
    """
    if imag_args[0] is None:
        vec = real_args[0]
        matrix = real_args[1]
    elif real_args[0] is None:
        vec = imag_args[0]
        matrix = real_args[1]
    else:
        vec = vstack([at_least_2D(real_args[0]), at_least_2D(imag_args[0])])
        if real_args[1] is None:
            real_args[1] = np.zeros(imag_args[1].shape)
        elif imag_args[1] is None:
            imag_args[1] = np.zeros(real_args[1].shape)
        matrix = bmat([[real_args[1], -imag_args[1]],
                       [imag_args[1], real_args[1]]])
        # HACK TODO
        matrix = Constant(matrix.value)
    return expr.copy([vec, matrix]), None
예제 #25
0
파일: complex2real.py 프로젝트: waxz/cvxpy
 def canonicalize_expr(self, expr, real_args, imag_args, real2imag, leaf_map):
     if isinstance(expr, Expression) and not expr.variables():
         # Parameterized expressions are evaluated in a subsequent
         # reduction.
         if expr.parameters():
             return NotImplemented
         # Non-parameterized expressions are evaluated immediately.
         else:
             return elim_cplx_methods[Constant](Constant(expr.value),
                                                real_args, imag_args, real2imag)
     elif type(expr) in elim_cplx_methods:
         # Only canonicalize a variable/constant/parameter once.
         if len(expr.args) == 0 and expr in leaf_map:
             return leaf_map[expr]
         result = elim_cplx_methods[type(expr)](expr, real_args, imag_args, real2imag)
         if len(expr.args) == 0:
             leaf_map[expr] = result
         return result
     else:
         assert all(v is None for v in imag_args)
         return expr.copy(real_args), None
예제 #26
0
    def test_add_expression(self):
        # Vectors
        c = Constant([2, 2])
        exp = self.x + c
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        self.assertEqual(exp.sign, u.Sign.UNKNOWN_KEY)
        self.assertEqual(exp.canonical_form[0].size, (2, 1))
        self.assertEqual(exp.canonical_form[1], [])
        # self.assertEqual(exp.name(), self.x.name() + " + " + c.name())
        self.assertEqual(exp.size, (2, 1))

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

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

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

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

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

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

        # Test repr.
        self.assertEqual(repr(exp), "Expression(AFFINE, UNKNOWN, (2, 1))")
예제 #27
0
    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))
예제 #28
0
def test_constant_atoms(atom_info, objective_type) -> None:

    atom, size, args, obj_val = atom_info

    for indexer in get_indices(size):
        for solver in SOLVERS_TO_TRY:
            # Atoms with Constant arguments.
            prob_val = obj_val[indexer].value
            const_args = [Constant(arg) for arg in args]
            if len(size) != 0:
                objective = objective_type(atom(*const_args)[indexer])
            else:
                objective = objective_type(atom(*const_args))
            problem = Problem(objective)
            run_atom(atom, problem, prob_val, solver)

            # Atoms with Variable arguments.
            variables = []
            constraints = []
            for idx, expr in enumerate(args):
                variables.append(Variable(intf.shape(expr)))
                constraints.append(variables[-1] == expr)
            if len(size) != 0:
                objective = objective_type(atom(*variables)[indexer])
            else:
                objective = objective_type(atom(*variables))
            problem = Problem(objective, constraints)
            run_atom(atom, problem, prob_val, solver)

            # Atoms with Parameter arguments.
            parameters = []
            for expr in args:
                parameters.append(Parameter(intf.shape(expr)))
                parameters[-1].value = intf.DEFAULT_INTF.const_to_matrix(expr)
            if len(size) != 0:
                objective = objective_type(atom(*parameters)[indexer])
            else:
                objective = objective_type(atom(*parameters))
            run_atom(atom, Problem(objective), prob_val, solver)
예제 #29
0
    def test_div_expression(self):
        # Vectors
        exp = self.x / 2
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.sign, s.UNKNOWN)
        # self.assertEqual(exp.canonical_form[0].shape, (2, 1))
        # self.assertEqual(exp.canonical_form[1], [])
        # self.assertEqual(exp.name(), c.name() + " * " + self.x.name())
        self.assertEqual(exp.shape, (2, ))

        with self.assertRaises(Exception) as cm:
            (self.x / [2, 2, 3])
        print(cm.exception)
        self.assertRegexpMatches(str(cm.exception),
                                 "Incompatible shapes for division.*")

        c = Constant([3.0, 4.0, 12.0])
        self.assertItemsAlmostEqual((c / Constant([1.0, 2.0, 3.0])).value,
                                    np.array([3.0, 2.0, 4.0]))

        # Constant expressions.
        c = Constant(2)
        exp = c / (3 - 5)
        self.assertEqual(exp.curvature, s.CONSTANT)
        self.assertEqual(exp.shape, tuple())
        self.assertEqual(exp.sign, s.NONPOS)

        # Parameters.
        p = Parameter(nonneg=True)
        exp = 2 / p
        p.value = 2
        self.assertEqual(exp.value, 1)

        rho = Parameter(nonneg=True)
        rho.value = 1

        self.assertEqual(rho.sign, s.NONNEG)
        self.assertEqual(Constant(2).sign, s.NONNEG)
        self.assertEqual((Constant(2) / Constant(2)).sign, s.NONNEG)
        self.assertEqual((Constant(2) * rho).sign, s.NONNEG)
        self.assertEqual((rho / 2).sign, s.NONNEG)
예제 #30
0
    def test_add_expression(self):
        # Vectors
        c = Constant([2, 2])
        exp = self.x + c
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.sign, s.UNKNOWN)
        # self.assertEqual(exp.canonical_form[0].shape, (2, 1))
        # self.assertEqual(exp.canonical_form[1], [])
        # self.assertEqual(exp.name(), self.x.name() + " + " + c.name())
        self.assertEqual(exp.shape, (2, ))

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

        # Incompatible dimensions
        with self.assertRaises(ValueError):
            (self.x + self.y)

        # Matrices
        exp = self.A + self.B
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.shape, (2, 2))

        # Incompatible dimensions
        with self.assertRaises(ValueError):
            (self.A + self.C)

        # Incompatible dimensions
        with self.assertRaises(ValueError):
            AddExpression([self.A, self.C])

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

        # Test repr.
        self.assertEqual(repr(exp), "Expression(AFFINE, UNKNOWN, (2,))")
예제 #31
0
def power_canon(expr, args):
    x = args[0]
    p = expr.p
    w = expr.w

    if p == 1:
        return x, []

    shape = expr.shape
    ones = Constant(np.ones(shape))
    if p == 0:
        return ones, []
    else:
        t = Variable(shape)
        # TODO(akshayka): gm_constrs requires each of its inputs to be a Variable;
        # is this something that we want to change?
        if 0 < p < 1:
            return t, gm_constrs(t, [x, ones], w)
        elif p > 1:
            return t, gm_constrs(x, [t, ones], w)
        elif p < 0:
            return t, gm_constrs(ones, [x, t], w)
        else:
            raise NotImplementedError('This power is not yet supported.')
예제 #32
0
def test_atom():
    for atom_list, objective_type in atoms:
        for atom, size, args, obj_val in atom_list:
            for row in range(size[0]):
                for col in range(size[1]):
                    for solver in SOLVERS_TO_TRY:
                        # Atoms with Constant arguments.
                        const_args = [Constant(arg) for arg in args]
                        yield (run_atom,
                               atom,
                               Problem(objective_type(atom(*const_args)[row,col])),
                               obj_val[row,col].value,
                               solver)
                        # Atoms with Variable arguments.
                        variables = []
                        constraints = []
                        for idx, expr in enumerate(args):
                            variables.append( Variable(*intf.size(expr) ))
                            constraints.append( variables[-1] == expr)
                        objective = objective_type(atom(*variables)[row,col])
                        yield (run_atom,
                               atom,
                               Problem(objective, constraints),
                               obj_val[row,col].value,
                               solver)
                        # Atoms with Parameter arguments.
                        parameters = []
                        for expr in args:
                            parameters.append( Parameter(*intf.size(expr)) )
                            parameters[-1].value = intf.DEFAULT_INTF.const_to_matrix(expr)
                        objective = objective_type(atom(*parameters)[row,col])
                        yield (run_atom,
                               atom,
                               Problem(objective),
                               obj_val[row,col].value,
                               solver)
예제 #33
0
    def test_constants(self):
        c = Constant(2)
        self.assertEqual(c.name(), str(2))

        c = Constant(2)
        self.assertEqual(c.value, 2)
        self.assertEqual(c.size, (1, 1))
        self.assertEqual(c.curvature, s.CONSTANT)
        self.assertEqual(c.sign, s.POSITIVE)
        self.assertEqual(Constant(-2).sign, s.NEGATIVE)
        self.assertEqual(Constant(0).sign, s.ZERO)
        self.assertEqual(c.canonical_form[0].size, (1, 1))
        self.assertEqual(c.canonical_form[1], [])

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

        # Test the sign.
        c = Constant([[2], [2]])
        self.assertEqual(c.size, (1, 2))
        self.assertEqual(c.sign, s.POSITIVE)
        self.assertEqual((-c).sign, s.NEGATIVE)
        self.assertEqual((0*c).sign, s.ZERO)
        c = Constant([[2], [-2]])
        self.assertEqual(c.sign, s.UNKNOWN)

        # Test sign of a complex expression.
        c = Constant([1, 2])
        A = Constant([[1, 1], [1, 1]])
        exp = c.T*A*c
        self.assertEqual(exp.sign, s.POSITIVE)
        self.assertEqual((c.T*c).sign, s.POSITIVE)
        exp = c.T.T
        self.assertEqual(exp.sign, s.POSITIVE)
        exp = c.T*self.A
        self.assertEqual(exp.sign, s.UNKNOWN)

        # Test repr.
        self.assertEqual(repr(c), "Constant(CONSTANT, POSITIVE, (2, 1))")
예제 #34
0
    def test_round_attr(self):
        """Test rounding for attributes.
        """
        # Nonpos
        v = Variable(1, nonpos=True)
        self.assertAlmostEqual(v.project(1), 0)
        v = Variable(2, nonpos=True)
        self.assertItemsAlmostEqual(v.project(np.array([1, -1])), [0, -1])

        # Nonneg
        v = Variable(1, nonneg=True)
        self.assertAlmostEqual(v.project(-1), 0)
        v = Variable(2, nonneg=True)
        self.assertItemsAlmostEqual(v.project(np.array([1, -1])), [1, 0])

        # Boolean
        v = Variable((2, 2), boolean=True)
        self.assertItemsAlmostEqual(v.project(np.array([[1, -1], [1, 0]]).T),
                                    [1, 0, 1, 0])

        # Integer
        v = Variable((2, 2), integer=True)
        self.assertItemsAlmostEqual(v.project(np.array([[1, -1.6], [1, 0]]).T),
                                    [1, -2, 1, 0])

        # Symmetric
        v = Variable((2, 2), symmetric=True)
        self.assertItemsAlmostEqual(v.project(np.array([[1, -1], [1, 0]])),
                                    [1, 0, 0, 0])

        # PSD
        v = Variable((2, 2), PSD=True)
        self.assertItemsAlmostEqual(v.project(np.array([[1, -1], [1, -1]])),
                                    [1, 0, 0, 0])

        # NSD
        v = Variable((2, 2), NSD=True)
        self.assertItemsAlmostEqual(v.project(np.array([[1, -1], [1, -1]])),
                                    [0, 0, 0, -1])

        # diag
        v = Variable((2, 2), diag=True)
        self.assertItemsAlmostEqual(
            v.project(np.array([[1, -1], [1, 0]])).todense(), [1, 0, 0, 0])

        # Hermitian
        v = Variable((2, 2), hermitian=True)
        self.assertItemsAlmostEqual(v.project(np.array([[1, -1j], [1, 0]])),
                                    [1, 0.5 + 0.5j, 0.5 - 0.5j, 0])

        A = Constant(np.array([[1.0]]))
        self.assertEqual(A.is_psd(), True)
        self.assertEqual(A.is_nsd(), False)
        A = Constant(np.array([[-1.0]]))
        self.assertEqual(A.is_psd(), False)
        self.assertEqual(A.is_nsd(), True)
        A = Constant(np.array([[0.0]]))
        self.assertEqual(A.is_psd(), True)
        self.assertEqual(A.is_nsd(), True)
예제 #35
0
    def test_matmul_expression(self):
        """Test matmul function, corresponding to .__matmul__( operator.
        """
        # Vectors
        c = Constant([[2], [2]])
        exp = c.__matmul__(self.x)
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.sign, s.UNKNOWN)
        # self.assertEqual(exp.name(), c.name() + " .__matmul__( " + self.x.name())
        self.assertEqual(exp.shape, (1, ))

        with self.assertRaises(Exception) as cm:
            self.x.__matmul__(2)
        self.assertEqual(str(cm.exception),
                         "Scalar operands are not allowed, use '*' instead")

        # Incompatible dimensions
        with self.assertRaises(ValueError) as cm:
            (self.x.__matmul__(np.array([2, 2, 3])))

        # Incompatible dimensions
        with self.assertRaises(Exception) as cm:
            Constant([[2, 1], [2, 2]]).__matmul__(self.C)

        # Affine times affine is okay
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            q = self.A.__matmul__(self.B)
            self.assertTrue(q.is_quadratic())

        # # Nonaffine times nonconstant raises error
        # with warnings.catch_warnings():
        #     warnings.simplefilter("ignore")
        #     with self.assertRaises(Exception) as cm:
        #         (self.A.__matmul__(self.B).__matmul__(self.A))
        #     self.assertEqual(str(cm.exception), "Cannot multiply UNKNOWN and AFFINE.")

        # Constant expressions
        T = Constant([[1, 2, 3], [3, 5, 5]])
        exp = (T + T).__matmul__(self.B)
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.shape, (3, 2))

        # Expression that would break sign multiplication without promotion.
        c = Constant([[2], [2], [-2]])
        exp = [[1], [2]] + c.__matmul__(self.C)
        self.assertEqual(exp.sign, s.UNKNOWN)

        # Testing shape.
        a = Parameter((1, ))
        x = Variable(shape=(1, ))
        expr = a.__matmul__(x)
        self.assertEqual(expr.shape, ())

        # Testing shape.
        a = Parameter((1, ))
        x = Variable(shape=(1, ))
        expr = a.__matmul__(x)
        self.assertEqual(expr.shape, ())

        A = Parameter((4, 4))
        z = Variable((4, 1))
        expr = A.__matmul__(z)
        self.assertEqual(expr.shape, (4, 1))

        v = Variable((1, 1))
        col_scalar = Parameter((1, 1))
        assert v.shape == col_scalar.shape == col_scalar.T.shape
예제 #36
0
class test_coefficients(unittest.TestCase):
    """ Unit tests for the expressions.affine module. """
    def setUp(self):
        self.a = Variable()

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

        self.A = Variable(2,2)

        self.c = Constant(3)
        self.C = Constant([[1, 2], [1, 2]])

    def test_leaf_coeffs(self):
        """Test the coefficients for Variables and Constants.
        """
        # Scalars
        coeffs = self.a.coefficients()
        self.assertItemsEqual(coeffs.keys(), [self.a])
        blocks = coeffs[self.a]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0], 1)

        # Vectors
        coeffs = self.x.coefficients()
        self.assertItemsEqual(coeffs.keys(), [self.x])
        blocks = coeffs[self.x]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (2,2))

        # Matrices
        coeffs = self.A.coefficients()
        self.assertItemsEqual(coeffs.keys(), [self.A])
        blocks = coeffs[self.A]
        self.assertEqual(len(blocks), 2)
        self.assertEqual(blocks[0].size, (2,4))

        # Constants
        coeffs = self.c.coefficients()
        self.assertItemsEqual(coeffs.keys(), [s.CONSTANT])
        blocks = coeffs[s.CONSTANT]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0], 3)

        coeffs = self.C.coefficients()
        self.assertItemsEqual(coeffs.keys(), [s.CONSTANT])
        blocks = coeffs[s.CONSTANT]
        self.assertEqual(len(blocks), 2)
        self.assertEqual(blocks[0].size, (2,1))
        self.assertEqual(blocks[0][0,0], 1)

    def test_add(self):
        """Test adding coefficients.
        """
        coeffs = cu.add(self.x.coefficients(), self.y.coefficients())
        self.assertItemsEqual(coeffs.keys(), [self.x, self.y])
        blocks = coeffs[self.x]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (2,2))

        coeffs = cu.add(coeffs, coeffs)
        self.assertItemsEqual(coeffs.keys(), [self.x, self.y])
        blocks = coeffs[self.x]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (2,2))
        self.assertEqual(blocks[0][0,0], 2)

        coeffs = cu.add(coeffs, self.C.coefficients())
        self.assertItemsEqual(coeffs.keys(), [self.x, self.y, s.CONSTANT])
        blocks = coeffs[s.CONSTANT]
        self.assertEqual(len(blocks), 2)
        self.assertEqual(blocks[0].size, (2,1))
        self.assertEqual(blocks[0][0,0], 1)

    def test_neg(self):
        """Test negating coefficients.
        """
        coeffs = cu.neg(self.a.coefficients())
        self.assertItemsEqual(coeffs.keys(), [self.a])
        blocks = coeffs[self.a]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0], -1)

        coeffs = cu.neg(self.A.coefficients())
        self.assertItemsEqual(coeffs.keys(), [self.A])
        blocks = coeffs[self.A]
        self.assertEqual(len(blocks), 2)
        self.assertEqual(blocks[0].size, (2,4))
        self.assertEqual(blocks[0][0,0], -1)

    def test_sub(self):
        """Test subtracting coefficients.
        """
        coeffs = cu.sub(self.x.coefficients(), self.y.coefficients())
        self.assertItemsEqual(coeffs.keys(), [self.x, self.y])
        blocks = coeffs[self.y]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (2,2))
        self.assertEqual(blocks[0][0,0], -1)

        coeffs = cu.sub(coeffs, self.x.coefficients())
        self.assertItemsEqual(coeffs.keys(), [self.x, self.y])
        blocks = coeffs[self.x]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (2,2))
        self.assertEqual(blocks[0][0,0], 0)

    def test_mul(self):
        """Test multiplying coefficients.
        """
        coeffs = cu.add(self.x.coefficients(), self.y.coefficients())
        coeffs = cu.mul(self.C.coefficients(), coeffs)
        self.assertItemsEqual(coeffs.keys(), [self.x, self.y])
        blocks = coeffs[self.y]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (2,2))
        self.assertEqual(blocks[0][1,0], 2)

        # Scalar by Matrix multiplication.
        coeffs = cu.add(self.x.coefficients(), self.y.coefficients())
        coeffs = cu.mul(self.c.coefficients(), coeffs)
        self.assertItemsEqual(coeffs.keys(), [self.x, self.y])
        blocks = coeffs[self.y]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (2,2))
        self.assertEqual(blocks[0][0,0], 3)

        # Matrix by Scalar multiplication.
        coeffs = self.a.coefficients()
        coeffs = cu.mul(self.C.coefficients(), coeffs)
        self.assertItemsEqual(coeffs.keys(), [self.a])
        blocks = coeffs[self.a]
        self.assertEqual(len(blocks), 2)
        self.assertEqual(blocks[0].size, (2,1))
        self.assertEqual(blocks[0][1,0], 2)
        self.assertEqual(blocks[1].size, (2,1))
        self.assertEqual(blocks[1][1,0], 2)

    def test_index(self):
        """Test indexing/slicing into coefficients.
        """
        # Index.
        sum_coeffs = cu.add(self.x.coefficients(), self.y.coefficients())
        key = ku.validate_key((1, 0), self.x.shape)
        coeffs = cu.index(sum_coeffs, key)
        self.assertItemsEqual(coeffs.keys(), [self.x, self.y])
        blocks = coeffs[self.y]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (1,2))
        self.assertEqual(blocks[0][0,0], 0)

        # Slice.
        sum_coeffs = cu.add(self.A.coefficients(), self.C.coefficients())
        key = ku.validate_key((slice(None, None, None), 1), self.A.shape)
        coeffs = cu.index(sum_coeffs, key)
        self.assertItemsEqual(coeffs.keys(), [self.A, s.CONSTANT])
        # Variable.
        blocks = coeffs[self.A]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (2,4))
        # Constant.
        blocks = coeffs[s.CONSTANT]
        self.assertEqual(len(blocks), 1)
        self.assertEqual(blocks[0].size, (2,1))
예제 #37
0
from cvxpy.problems.objective import *
from cvxpy.problems.problem import Problem
from cvxpy.expressions.variables import Variable
from cvxpy.expressions.constants import Constant, Parameter
import cvxopt
import math
from nose.tools import assert_raises

TOL = 1e-3

v = cvxopt.matrix([-1, 2, -2], tc='d')

atoms = [
    (
        [
            (abs([[-5, 2], [-3, 1]]), Constant([[5, 2], [3, 1]])),
            (exp([[1, 0],
                  [2, -1]]), Constant([[math.e, 1], [math.e**2,
                                                     1.0 / math.e]])),
            #(huber(0.5), 0.25),
            #(huber(-1.5), 2),
            (inv_pos([[1, 2],
                      [3, 4]]), Constant([[1, 1.0 / 2], [1.0 / 3, 1.0 / 4]])),
            (kl_div(math.e, 1), Constant([1])),
            (kl_div(math.e, math.e), Constant([0])),
            (lambda_max([[2, 0], [0, 1]]), Constant([2])),
            (lambda_max([[5, 7], [7, -3]]), Constant([9.06225775])),
            (log_sum_exp([[5, 7], [0, -3]]), Constant([7.1277708268])),
            (max([-5, 2], [-3, 1], 0, [-1, 2]), Constant([0, 2])),
            (max([[-5, 2], [-3, 1]], 0,
                 [[5, 4], [-1, 2]]), Constant([[5, 4], [0, 2]])),
예제 #38
0
    def test_index_expression(self):
        # Tuple of integers as key.
        exp = self.x[1, 0]
        # self.assertEqual(exp.name(), "x[1,0]")
        self.assertEqual(exp.curvature, u.Curvature.AFFINE_KEY)
        assert exp.is_affine()
        self.assertEquals(exp.size, (1, 1))
        # coeff = exp.canonical_form[0].coefficients()[self.x][0]
        # self.assertEqual(coeff[0,1], 1)
        self.assertEqual(exp.value, None)

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

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

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

        c = Constant([[1, -2], [0, 4]])
        exp = c[1, 1]
        self.assertEqual(exp.curvature, u.Curvature.CONSTANT_KEY)
        self.assertEqual(exp.sign, u.Sign.POSITIVE_KEY)
        assert exp.is_positive()
        self.assertEqual(c[0, 1].sign, u.Sign.ZERO_KEY)
        assert c[0, 1].is_zero()
        self.assertEqual(c[1, 0].sign, u.Sign.NEGATIVE_KEY)
        assert c[1, 0].is_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_KEY)
        assert exp.is_constant()
        self.assertEquals(exp.size, (3, 2))
        self.assertEqual(exp[0, 1].value, 7)

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

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

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

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

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

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

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

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

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

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

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

        # Test sign of a complex expression.
        c = Constant([1, 2])
        A = Constant([[1, 1], [1, 1]])
        exp = c.T * A * c
        self.assertEqual(exp.sign, u.Sign.POSITIVE_KEY)
        self.assertEqual((c.T * c).sign, u.Sign.POSITIVE_KEY)
        exp = c.T.T
        self.assertEqual(exp._dcp_attr.sign.pos_mat.shape, (2, 1))
        exp = c.T * self.A
        self.assertEqual(exp._dcp_attr.sign.pos_mat.shape, (1, 2))
예제 #40
0
    def test_index_expression(self):
        # Tuple of integers as key.
        exp = self.x[1]
        # self.assertEqual(exp.name(), "x[1,0]")
        self.assertEqual(exp.curvature, s.AFFINE)
        assert exp.is_affine()
        self.assertEqual(exp.shape, tuple())
        # coeff = exp.canonical_form[0].coefficients()[self.x][0]
        # self.assertEqual(coeff[0,1], 1)
        self.assertEqual(exp.value, None)

        exp = self.x[1].T
        # self.assertEqual(exp.name(), "x[1,0]")
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.shape, tuple())

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

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

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

        c = Constant([[1, -2], [0, 4]])
        exp = c[1, 1]
        self.assertEqual(exp.curvature, s.CONSTANT)
        self.assertEqual(exp.sign, s.UNKNOWN)
        self.assertEqual(c[0, 1].sign, s.UNKNOWN)
        self.assertEqual(c[1, 0].sign, s.UNKNOWN)
        self.assertEqual(exp.shape, tuple())
        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, s.CONSTANT)
        assert exp.is_constant()
        self.assertEqual(exp.shape, (3, 2))
        self.assertEqual(exp[0, 1].value, 7)

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

        # Arithmetic expression indexing
        exp = (self.x + self.z)[1]
        # self.assertEqual(exp.name(), "x[1,0] + z[1,0]")
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.sign, s.UNKNOWN)
        self.assertEqual(exp.shape, tuple())

        exp = (self.x + self.a)[1:2]
        # self.assertEqual(exp.name(), "x[1,0] + a")
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.shape, (1, ))

        exp = (self.x - self.z)[1:2]
        # self.assertEqual(exp.name(), "x[1,0] - z[1,0]")
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.shape, (1, ))

        exp = (self.x - self.a)[1]
        # self.assertEqual(exp.name(), "x[1,0] - a")
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.shape, tuple())

        exp = (-self.x)[1]
        # self.assertEqual(exp.name(), "-x[1,0]")
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.shape, tuple())

        c = Constant([[1, 2], [3, 4]])
        exp = (c * self.x)[1]
        # self.assertEqual(exp.name(), "[[2], [4]] * x[0:,0]")
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.shape, tuple())

        c = Constant([[1, 2], [3, 4]])
        exp = (c * self.a)[1, 0:1]
        # self.assertEqual(exp.name(), "2 * a")
        self.assertEqual(exp.curvature, s.AFFINE)
        self.assertEqual(exp.shape, (1, ))
예제 #41
0
    def test_constants(self):
        c = Constant(2)
        self.assertEqual(c.name(), str(2))

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

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

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

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

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