Пример #1
0
def rmul_mat(lin_op):
    """Returns the coefficient matrix for RMUL linear op.

    Parameters
    ----------
    lin_op : LinOp
        The rmul linear op.

    Returns
    -------
    list of SciPy CSC matrix or scalar.
        The matrix for the multiplication on the right operator.
    """
    constant = const_mat(lin_op.data)
    if isinstance(constant, sym.SymMatrix):
        sym_eye = sym.as_sym_matrix(sp.csc_matrix(sp.eye(lin_op.size[0])))
        constant = sym.kron(sym.transpose(constant), sym_eye)
                           
    else:
        # Scalars don't need to be replicated.
        if not intf.is_scalar(constant):
            # Matrix is the kronecker product of constant.T and identity.
            # Each column in the product is a linear combination of the
            # columns of the left hand multiple.
            constant = sp.kron(constant.T, sp.eye(lin_op.size[0])).tocsc()
    return [constant]
Пример #2
0
def mul_by_const(constant, rh_coeffs, size):
    """Multiplies a constant by a list of coefficients.

    Parameters
    ----------
    constant : numeric type
        The constant to multiply by.
    rh_coeffs : list
        The coefficients of the right hand side.
    size : tuple
        (product rows, product columns)

    Returns
    -------
    list
        A list of (id, size, coefficient) tuples.
    """
    new_coeffs = []
    rep_mat = sp.block_diag(size[1] * [constant]).tocsc()
    # Multiply all left-hand constants by right-hand terms.
    for (id_, rh_size, coeff) in rh_coeffs:
        # For scalar left hand constants,
        # if right hand term is constant,
        # or single column, just multiply.
        # Keeps scalars and dense constants as original type.
        if intf.is_scalar(constant) or \
           id_ is lo.CONSTANT_ID or size[1] == 1:
            product = constant * coeff
        # For promoted variables with matrix coefficients,
        # flatten the matrix.
        elif size != (1, 1) and intf.is_scalar(coeff):
            flattened_const = flatten(constant)
            product = flattened_const * coeff
        # Otherwise replicate the matrix.
        else:
            product = rep_mat * coeff
        new_coeffs.append((id_, rh_size, product))
    rh_coeffs = new_coeffs

    return new_coeffs
Пример #3
0
def mul_by_const(constant, rh_coeffs, size):
    """Multiplies a constant by a list of coefficients.

    Parameters
    ----------
    constant : numeric type
        The constant to multiply by.
    rh_coeffs : list
        The coefficients of the right hand side.
    size : tuple
        (product rows, product columns)

    Returns
    -------
    list
        A list of (id, size, coefficient) tuples.
    """
    new_coeffs = []
    # Multiply all left-hand constants by right-hand terms.
    for (id_, rh_size, coeff) in rh_coeffs:
        rep_mat = sp.block_diag(size[1] * [constant]).tocsc()
        # For scalar right hand constants
        # or single column, just multiply.
        if intf.is_scalar(constant) or id_ is lo.CONSTANT_ID or size[1] == 1:
            product = constant * coeff
        # For promoted variables with matrix coefficients,
        # flatten the matrix.
        elif size != (1, 1) and intf.is_scalar(coeff):
            flattened_const = flatten(constant)
            product = flattened_const * coeff
        # Otherwise replicate the matrix.
        else:
            product = rep_mat * coeff
        new_coeffs.append((id_, rh_size, product))
    rh_coeffs = new_coeffs

    return new_coeffs
Пример #4
0
def mul_mat(lin_op):
    """Returns the coefficient matrix for MUL linear op.

    Parameters
    ----------
    lin_op : LinOp
        The mul linear op.

    Returns
    -------
    SciPy CSC matrix or scalar.
        The matrix for the multiplication on the left operator.
    """
    constant = const_mat(lin_op.data)
    # Scalars don't need to be replicated.
    if not intf.is_scalar(constant):
        constant = sp.block_diag(lin_op.size[1] * [constant]).tocsc()
    return constant
Пример #5
0
def mul_mat(lin_op):
    """Returns the coefficient matrix for MUL linear op.

    Parameters
    ----------
    lin_op : LinOp
        The mul linear op.

    Returns
    -------
    list of SciPy CSC matrix or scalar.
        The matrix for the multiplication on the left operator.
    """
    constant = const_mat(lin_op.data)
    # Scalars don't need to be replicated.
    if not intf.is_scalar(constant):
        constant = sp.block_diag(lin_op.size[1]*[constant]).tocsc()
    return [constant]
Пример #6
0
    def _process_constr(self, constr, mat_cache, vert_offset):
        """Extract the coefficients from a constraint.

        Parameters
        ----------
        constr : LinConstr
            The linear constraint to process.
        mat_cache : MatrixCache
            The cached version of the matrix-vector pair.
        vert_offset : int
            The row offset of the constraint.
        """
        V, I, J = mat_cache.coo_tup
        coeffs = op2mat.get_coefficients(constr.expr)
        for id_, block in coeffs:
            vert_start = vert_offset
            vert_end = vert_start + constr.size[0]*constr.size[1]
            if id_ is lo.CONSTANT_ID:
                # Flatten the block.
                block = self.vec_intf.const_to_matrix(block)
                block_size = intf.size(block)
                block = self.vec_intf.reshape(
                    block,
                    (block_size[0]*block_size[1], 1)
                )
                mat_cache.const_vec[vert_start:vert_end, :] += block
            else:
                horiz_offset = self.sym_data.var_offsets[id_]
                if intf.is_scalar(block):
                    block = intf.scalar_value(block)
                    V.append(block)
                    I.append(vert_start)
                    J.append(horiz_offset)
                else:
                    # Block is a numpy matrix or
                    # scipy CSC sparse matrix.
                    if not intf.is_sparse(block):
                        block = intf.DEFAULT_SPARSE_INTF.const_to_matrix(
                            block
                        )
                    block = block.tocoo()
                    V.extend(block.data)
                    I.extend(block.row + vert_start)
                    J.extend(block.col + horiz_offset)
Пример #7
0
    def _process_constr(self, constr, mat_cache, vert_offset):
        """Extract the coefficients from a constraint.

        Parameters
        ----------
        constr : LinConstr
            The linear constraint to process.
        mat_cache : MatrixCache
            The cached version of the matrix-vector pair.
        vert_offset : int
            The row offset of the constraint.
        """
        V, I, J = mat_cache.coo_tup
        coeffs = op2mat.get_coefficients(constr.expr)
        for id_, block in coeffs:
            vert_start = vert_offset
            vert_end = vert_start + constr.size[0] * constr.size[1]
            if id_ is lo.CONSTANT_ID:
                # Flatten the block.
                block = self.vec_intf.const_to_matrix(block)
                block_size = intf.size(block)
                block = self.vec_intf.reshape(
                    block, (block_size[0] * block_size[1], 1))
                mat_cache.const_vec[vert_start:vert_end, :] += block
            else:
                horiz_offset = self.sym_data.var_offsets[id_]
                if intf.is_scalar(block):
                    block = intf.scalar_value(block)
                    V.append(block)
                    I.append(vert_start)
                    J.append(horiz_offset)
                else:
                    # Block is a numpy matrix or
                    # scipy CSC sparse matrix.
                    if not intf.is_sparse(block):
                        block = intf.DEFAULT_SPARSE_INTERFACE.const_to_matrix(
                            block)
                    block = block.tocoo()
                    V.extend(block.data)
                    I.extend(block.row + vert_start)
                    J.extend(block.col + horiz_offset)
Пример #8
0
def rmul_mat(lin_op):
    """Returns the coefficient matrix for RMUL linear op.

    Parameters
    ----------
    lin_op : LinOp
        The rmul linear op.

    Returns
    -------
    list of SciPy CSC matrix or scalar.
        The matrix for the multiplication on the right operator.
    """
    constant = const_mat(lin_op.data)
    # Scalars don't need to be replicated.
    if not intf.is_scalar(constant):
        # Matrix is the kronecker product of constant.T and identity.
        # Each column in the product is a linear combination of the
        # columns of the left hand multiple.
        constant = sp.kron(constant.T, sp.eye(lin_op.size[0])).tocsc()
    return [constant]
Пример #9
0
def mul_mat(lin_op):
    """Returns the coefficient matrix for MUL linear op.

    Parameters
    ----------
    lin_op : LinOp
        The mul linear op.

    Returns
    -------
    list of SciPy CSC matrix or scalar.
        The matrix for the multiplication on the left operator.
    """
    constant = const_mat(lin_op.data)
    #constant = sym.as_sym_matrix(const_mat(lin_op.data))
    if isinstance(constant, sym.SymMatrix):
        if constant.shape != (1,1):
            constant = sym.block_diag(lin_op.size[1]*[constant])
    else:
        # Scalars don't need to be replicated.268
        if not intf.is_scalar(constant):
            constant = sp.block_diag(lin_op.size[1]*[constant]).tocsc()
    return [constant]
Пример #10
0
    def _constr_matrix(self, constraints, var_offsets, x_length,
                       matrix_intf, vec_intf):
        """Returns a matrix and vector representing a list of constraints.

        In the matrix, each constraint is given a block of rows.
        Each variable coefficient is inserted as a block with upper
        left corner at matrix[variable offset, constraint offset].
        The constant term in the constraint is added to the vector.

        Parameters
        ----------
        constraints : list
            A list of constraints.
        var_offsets : dict
            A dict of variable id to horizontal offset.
        x_length : int
            The length of the x vector.
        matrix_intf : interface
            The matrix interface to use for creating the constraints matrix.
        vec_intf : interface
            The matrix interface to use for creating the constant vector.

        Returns
        -------
        tuple
            A (matrix, vector) tuple.
        """

        rows = sum([c.size[0] * c.size[1] for c in constraints])
        cols = x_length
        V, I, J = [], [], []
        const_vec = vec_intf.zeros(rows, 1)
        vert_offset = 0
        for constr in constraints:
            coeffs = op2mat.get_coefficients(constr.expr)
            for id_, block in coeffs:
                vert_start = vert_offset
                vert_end = vert_start + constr.size[0]*constr.size[1]
                if id_ is lo.CONSTANT_ID:
                    # Flatten the block.
                    block = self._DENSE_INTF.const_to_matrix(block)
                    block_size = intf.size(block)
                    block = self._DENSE_INTF.reshape(
                        block,
                        (block_size[0]*block_size[1], 1)
                    )
                    const_vec[vert_start:vert_end, :] += block
                else:
                    horiz_offset = var_offsets[id_]
                    if intf.is_scalar(block):
                        block = intf.scalar_value(block)
                        V.append(block)
                        I.append(vert_start)
                        J.append(horiz_offset)
                    else:
                        # Block is a numpy matrix or
                        # scipy CSC sparse matrix.
                        if not intf.is_sparse(block):
                            block = self._SPARSE_INTF.const_to_matrix(block)
                        block = block.tocoo()
                        V.extend(block.data)
                        I.extend(block.row + vert_start)
                        J.extend(block.col + horiz_offset)
            vert_offset += constr.size[0]*constr.size[1]

        # Create the constraints matrix.
        if len(V) > 0:
            matrix = sp.coo_matrix((V, (I, J)), (rows, cols))
            # Convert the constraints matrix to the correct type.
            matrix = matrix_intf.const_to_matrix(matrix, convert_scalars=True)
        else: # Empty matrix.
            matrix = matrix_intf.zeros(rows, cols)
        return (matrix, -const_vec)
Пример #11
0
    def _constr_matrix(self, constraints, var_offsets, x_length, matrix_intf,
                       vec_intf):
        """Returns a matrix and vector representing a list of constraints.

        In the matrix, each constraint is given a block of rows.
        Each variable coefficient is inserted as a block with upper
        left corner at matrix[variable offset, constraint offset].
        The constant term in the constraint is added to the vector.

        Parameters
        ----------
        constraints : list
            A list of constraints.
        var_offsets : dict
            A dict of variable id to horizontal offset.
        x_length : int
            The length of the x vector.
        matrix_intf : interface
            The matrix interface to use for creating the constraints matrix.
        vec_intf : interface
            The matrix interface to use for creating the constant vector.

        Returns
        -------
        tuple
            A (matrix, vector) tuple.
        """

        rows = sum([c.size[0] * c.size[1] for c in constraints])
        cols = x_length
        V, I, J = [], [], []
        const_vec = vec_intf.zeros(rows, 1)
        vert_offset = 0
        for constr in constraints:
            coeffs = op2mat.get_coefficients(constr.expr)
            for id_, size, block in coeffs:
                vert_start = vert_offset
                vert_end = vert_start + constr.size[0] * constr.size[1]
                if id_ is lo.CONSTANT_ID:
                    # Flatten the block.
                    block = self._DENSE_INTF.const_to_matrix(block)
                    block_size = intf.size(block)
                    block = self._DENSE_INTF.reshape(
                        block, (block_size[0] * block_size[1], 1))
                    const_vec[vert_start:vert_end, :] += block
                else:
                    horiz_offset = var_offsets[id_]
                    if intf.is_scalar(block):
                        block = intf.scalar_value(block)
                        V.append(block)
                        I.append(vert_start)
                        J.append(horiz_offset)
                    else:
                        # Block is a numpy matrix or
                        # scipy CSC sparse matrix.
                        if not intf.is_sparse(block):
                            block = self._SPARSE_INTF.const_to_matrix(block)
                        block = block.tocoo()
                        V.extend(block.data)
                        I.extend(block.row + vert_start)
                        J.extend(block.col + horiz_offset)
            vert_offset += constr.size[0] * constr.size[1]

        # Create the constraints matrix.
        if len(V) > 0:
            matrix = sp.coo_matrix((V, (I, J)), (rows, cols))
            # Convert the constraints matrix to the correct type.
            matrix = matrix_intf.const_to_matrix(matrix, convert_scalars=True)
        else:  # Empty matrix.
            matrix = matrix_intf.zeros(rows, cols)
        return (matrix, -const_vec)