def rmul_expr(lh_op, rh_op, size): """Multiply two linear operators, with the constant on the right. Parameters ---------- lh_op : LinOp The left-hand operator in the product. rh_op : LinOp The right-hand operator in the product. size : tuple The size of the product. Returns ------- LinOp A linear operator representing the product. """ return lo.LinOp(lo.RMUL, size, [lh_op], rh_op)
def create_var(size, var_id=None): """Creates a new internal variable. Parameters ---------- size : tuple The (rows, cols) dimensions of the variable. var_id : int The id of the variable. Returns ------- LinOP A LinOp representing the new variable. """ if var_id is None: var_id = get_id() return lo.LinOp(lo.VARIABLE, size, [], var_id)
def conv(lh_op, rh_op, size): """1D discrete convolution of two vectors. Parameters ---------- lh_op : LinOp The left-hand operator in the convolution. rh_op : LinOp The right-hand operator in the convolution. size : tuple The size of the convolution. Returns ------- LinOp A linear operator representing the convolution. """ return lo.LinOp(lo.CONV, size, [rh_op], lh_op)
def index(operator, size, keys): """Indexes/slices an operator. Parameters ---------- operator : LinOp The expression to index. keys : tuple (row slice, column slice) size : tuple The size of the expression after indexing. Returns ------- LinOp An operator representing the indexing. """ return lo.LinOp(lo.INDEX, size, [operator], keys)
def create_param(shape: Tuple[int, ...], param_id=None): """Wraps a parameter. Parameters ---------- value : CVXPY Expression A function of parameters. shape : tuple The (rows, cols) dimensions of the operator. Returns ------- LinOP A LinOp wrapping the parameter. """ if param_id is None: param_id = get_id() return lo.LinOp(lo.PARAM, shape, [], param_id)
def div_expr(lh_op, rh_op): """Divide one linear operator by another. Assumes rh_op is a scalar constant. Parameters ---------- lh_op : LinOp The left-hand operator in the quotient. rh_op : LinOp The right-hand operator in the quotient. size : tuple The size of the quotient. Returns ------- LinOp A linear operator representing the quotient. """ return lo.LinOp(lo.DIV, lh_op.size, [lh_op], rh_op)
def transpose(operator): """Transposes an operator. Parameters ---------- operator : LinOp The operator to transpose. Returns ------- LinOp A linear operator representing the transpose. """ if len(operator.shape) < 2: return operator elif len(operator.shape) > 2: return NotImplemented else: shape = (operator.shape[1], operator.shape[0]) return lo.LinOp(lo.TRANSPOSE, shape, [operator], None)
def replace_new_vars(expr, id_to_new_var): """Replaces the given variables in the expression. Parameters ---------- expr : LinOp The expression to replace variables in. id_to_new_var : dict A map of id to new variable. Returns ------- LinOp An LinOp identical to expr, but with the given variables replaced. """ if expr.type == lo.VARIABLE and expr.data in id_to_new_var: return id_to_new_var[expr.data] else: new_args = [] for arg in expr.args: new_args.append(replace_new_vars(arg, id_to_new_var)) return lo.LinOp(expr.type, expr.shape, new_args, expr.data)
def prune_constants(constraints): """Returns a new list of constraints with constant terms removed. Parameters ---------- constraints : list The constraints that form the matrix. Returns ------- list The pruned constraints. """ pruned_constraints = [] for constr in constraints: constr_type = type(constr) expr = copy.deepcopy(constr.expr) is_constant = prune_expr(expr) # Replace a constant root with a NO_OP. if is_constant: expr = lo.LinOp(lo.NO_OP, expr.shape, [], None) pruned = constr_type(expr, constr.constr_id, constr.shape) pruned_constraints.append(pruned) return pruned_constraints