Exemplo n.º 1
0
def var_cone_canon(expr, args):
    """Expand implicit constraints on variable.
    """
    # Convert attributes into constraints.
    new_attr = expr.attributes.copy()
    for key in ['nonneg', 'nonpos', 'symmetric', 'PSD', 'NSD']:
        if new_attr[key]:
            new_attr[key] = False

    if expr.is_symmetric():
        n = expr.shape[0]
        shape = (n * (n + 1) // 2, 1)
        upper_tri = Variable(shape, var_id=expr.id, **new_attr)
        fill_coeff = Constant(upper_tri_to_full(n))
        full_mat = fill_coeff * upper_tri
        obj = reshape(full_mat, (n, n))
    else:
        obj = Variable(expr.shape, var_id=expr.id, **new_attr)

    constr = []
    if expr.is_nonneg():
        constr.append(obj >= 0)
    elif expr.is_nonpos():
        constr.append(obj <= 0)
    elif expr.attributes['PSD']:
        constr.append(obj >> 0)
    elif expr.attributes['NSD']:
        constr.append(obj << 0)
    return (obj, constr)
Exemplo n.º 2
0
def scaled_lower_tri(matrix):
    """Returns an expression representing the lower triangular entries

    Scales the strictly lower triangular entries by sqrt(2), as required
    by SCS.

    Parameters
    ----------
    matrix : Expression
        A 2-dimensional CVXPY expression.

    Returns
    -------
    Expression
        An expression representing the (scaled) lower triangular part of
        the supplied matrix expression.
    """
    rows = cols = matrix.shape[0]
    entries = rows * (cols + 1)//2

    row_arr = np.arange(0, entries)

    lower_diag_indices = np.tril_indices(rows)
    col_arr = np.sort(np.ravel_multi_index(lower_diag_indices, (rows, cols), order='F'))

    val_arr = np.zeros((rows, cols))
    val_arr[lower_diag_indices] = np.sqrt(2)
    np.fill_diagonal(val_arr, 1)
    val_arr = np.ravel(val_arr, order='F')
    val_arr = val_arr[np.nonzero(val_arr)]

    shape = (entries, rows*cols)
    coeff = Constant(sp.csc_matrix((val_arr, (row_arr, col_arr)), shape))
    vectorized_matrix = reshape(matrix, (rows*cols, 1))
    return coeff * vectorized_matrix
Exemplo n.º 3
0
def replace_params_with_consts(expr):
    if isinstance(expr, list):
        return [replace_params_with_consts(elem) for elem in expr]
    elif len(expr.parameters()) == 0:
        return expr
    elif isinstance(expr, Parameter):
        if expr.value is None:
            raise ParameterError("Problem contains unspecified parameters.")
        return Constant(expr.value)
    else:
        new_args = []
        for arg in expr.args:
            new_args.append(replace_params_with_consts(arg))
        return expr.copy(new_args)
Exemplo n.º 4
0
    def process_expression(self, expr):

        if isinstance(expr, CallbackParam):
            data_arg = self.process_expression(expr.atom)
            data = CbParamData(expr, [data_arg])
            if expr.id not in self.cbparam_ids: # Check if already there.
                self.callback_params += [data]
                self.cbparam_ids += [expr.id]

        elif isinstance(expr, Parameter):
            data = ParamData(expr)
            if expr.id not in self.param_ids: # Check if already there.
                self.named_params += [data]
                self.param_ids += [expr.id]

        elif isinstance(expr, Constant):
            data = ConstData(expr)
            self.constants += [data]

        elif isinstance(expr, Atom):
            if not expr.parameters(): # expr is just a constant without parameters.
                data = ConstData(Constant(expr.value))
                self.constants += [data]
            else: # Recurse on arguments:
                if id(expr) in self.expr_ids: # Check if already there.
                    idx = self.expr_ids.index(id(expr))
                    self.expressions[idx].force_copy()
                    data = self.expressions[idx]
                else:
                    arg_data = []
                    for arg in expr.args:
                        arg_data += [self.process_expression(arg)]
                    data_list = get_atom_data(expr, arg_data)
                    self.expressions += data_list
                    data = data_list[-1]
                    self.expr_ids += [id(expr)]
                    for d in data_list:
                        if d.macro_name not in self.unique_exprs: # Check if already there.
                            self.unique_exprs += [d.macro_name]
        else:
            raise TypeError('Invalid expression tree type: %s' % type(expr))

        return data
Exemplo n.º 5
0
def scaled_lower_tri(matrix):
    """Returns an expression representing the lower triangular entries

    Scales the strictly lower triangular entries by sqrt(2), as required
    by SCS.

    Parameters
    ----------
    matrix : Expression
        A 2-dimensional CVXPY expression.

    Returns
    -------
    Expression
        An expression representing the (scaled) lower triangular part of
        the supplied matrix expression.
    """
    rows = cols = matrix.shape[0]
    entries = rows * (cols + 1) // 2
    val_arr = []
    row_arr = []
    col_arr = []
    count = 0
    for j in range(cols):
        for i in range(rows):
            if j <= i:
                # Index in the original matrix.
                col_arr.append(j * rows + i)
                # Index in the extracted vector.
                row_arr.append(count)
                if j == i:
                    val_arr.append(1.0)
                else:
                    val_arr.append(np.sqrt(2))
                count += 1
    shape = (entries, rows * cols)
    coeff = Constant(
        sp.coo_matrix((val_arr, (row_arr, col_arr)), shape).tocsc())
    vectorized_matrix = reshape(matrix, (rows * cols, 1))
    return coeff * vectorized_matrix
Exemplo n.º 6
0
def Semidef(n, name=None):
    """An expression representing a positive semidefinite matrix.
    """
    var = SemidefUpperTri(n, name)
    fill_mat = Constant(upper_tri_to_full(n))
    return cvxtypes.reshape()(fill_mat * var, n, n)
Exemplo n.º 7
0
def constant_canon(expr, args):
    del args
    return Constant(np.log(expr.value)), []
Exemplo n.º 8
0
def Symmetric(n, name=None):
    """An expression representing a symmetric matrix.
    """
    var = SymmetricUpperTri(n, name)
    fill_mat = Constant(upper_tri_to_full(n))
    return cvxtypes.reshape()(fill_mat * var, int(n), int(n))