Beispiel #1
0
    def _save_values(self, result_vec, objects, offset_map):
        """Saves the values of the optimal primal/dual variables.

        Parameters
        ----------
        results_vec : array_like
            A vector containing the variable values.
        objects : list
            The variables or constraints where the values will be stored.
        offset_map : dict
            A map of object id to offset in the results vector.
        """
        if len(result_vec) > 0:
            # Cast to desired matrix type.
            result_vec = self._DENSE_INTF.const_to_matrix(result_vec)
        for obj in objects:
            rows, cols = obj.size
            if obj.id in offset_map:
                offset = offset_map[obj.id]
                # Handle scalars
                if (rows, cols) == (1,1):
                    value = intf.index(result_vec, (offset, 0))
                else:
                    value = self._DENSE_INTF.zeros(rows, cols)
                    self._DENSE_INTF.block_add(value,
                        result_vec[offset:offset + rows*cols],
                        0, 0, rows, cols)
                offset += rows*cols
            else: # The variable was multiplied by zero.
                value = self._DENSE_INTF.zeros(rows, cols)
            obj.save_value(value)
Beispiel #2
0
    def _save_values(self, result_vec, objects, offset_map):
        """Saves the values of the optimal primal/dual variables.

        Parameters
        ----------
        results_vec : array_like
            A vector containing the variable values.
        objects : list
            The variables or constraints where the values will be stored.
        offset_map : dict
            A map of object id to offset in the results vector.
        """
        if len(result_vec) > 0:
            # Cast to desired matrix type.
            result_vec = intf.DEFAULT_INTF.const_to_matrix(result_vec)
        for obj in objects:
            rows, cols = obj.size
            if obj.id in offset_map:
                offset = offset_map[obj.id]
                # Handle scalars
                if (rows, cols) == (1, 1):
                    value = intf.index(result_vec, (offset, 0))
                else:
                    value = intf.DEFAULT_INTF.zeros(rows, cols)
                    intf.DEFAULT_INTF.block_add(value,
                        result_vec[offset:offset + rows*cols],
                        0, 0, rows, cols)
                offset += rows*cols
            else: # The variable was multiplied by zero.
                value = intf.DEFAULT_INTF.zeros(rows, cols)
            obj.save_value(value)
Beispiel #3
0
def index_coeffs(lin_op):
    """Returns the coefficients for INDEX linear op.

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

    Returns
    -------
    list
        A list of (id, size, coefficient) tuples.
    """
    # Special case if variable.
    if lin_op.args[0].type is lo.VARIABLE:
        return index_var(lin_op)
    key = lin_op.data
    coeffs = get_coefficients(lin_op.args[0])
    new_coeffs = []
    for id_, size, block in coeffs:
        # Index/slice constants normally.
        if id_ is lo.CONSTANT_ID:
            size = lin_op.size
            block = intf.index(block, key)
        # Split into column blocks, slice column blocks list,
        # then index each column block and merge.
        else:
            block = get_index_block(block, lin_op.args[0].size, key)
        new_coeffs.append((id_, size, block))

    return new_coeffs
Beispiel #4
0
def index_coeffs(lin_op):
    """Returns the coefficients for INDEX linear op.

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

    Returns
    -------
    list
        A list of (id, size, coefficient) tuples.
    """
    # Special case if variable.
    if lin_op.args[0].type is lo.VARIABLE:
        return index_var(lin_op)
    key = lin_op.data
    coeffs = get_coefficients(lin_op.args[0])
    new_coeffs = []
    for id_, size, block in coeffs:
        # Index/slice constants normally.
        if id_ is lo.CONSTANT_ID:
            size = lin_op.size
            block = intf.index(block, key)
        # Split into column blocks, slice column blocks list,
        # then index each column block and merge.
        else:
            block = get_index_block(block, lin_op.args[0].size, key)
        new_coeffs.append((id_, size, block))

    return new_coeffs
Beispiel #5
0
def get_index_block(block, idx_size, key):
    """Transforms a coefficient into an indexed coefficient.

    Parameters
    ----------
    block : matrix
        The coefficient matrix.
    idx_size : tuple
        The dimensions of the indexed expression.
    key : tuple
        (row slice, column slice)

    Returns
    -------
    The indexed/sliced coefficient matrix.
    """
    rows, cols = idx_size
    # Number of rows in each column block.
    # and number of column blocks.
    col_selection = range(cols)[key[1]]
    # Split into column blocks.
    col_blocks = get_col_blocks(rows, block, col_selection)
    # Select rows from each remaining column block.
    row_key = (key[0], slice(None, None, None))
    # Short circuit for single column.
    if len(col_blocks) == 1:
        block = intf.index(col_blocks[0], row_key)
    else:
        indexed_blocks = []
        for col_block in col_blocks:
            idx_block = intf.index(col_block, row_key)
            # Convert to sparse CSC matrix.
            sp_intf = intf.DEFAULT_SPARSE_INTERFACE
            idx_block = sp_intf.const_to_matrix(idx_block)
            indexed_blocks.append(idx_block)
        block = sp.vstack(indexed_blocks)
    return block
Beispiel #6
0
def get_index_block(block, idx_size, key):
    """Transforms a coefficient into an indexed coefficient.

    Parameters
    ----------
    block : matrix
        The coefficient matrix.
    idx_size : tuple
        The dimensions of the indexed expression.
    key : tuple
        (row slice, column slice)

    Returns
    -------
    The indexed/sliced coefficient matrix.
    """
    rows, cols = idx_size
    # Number of rows in each column block.
    # and number of column blocks.
    col_selection = range(cols)[key[1]]
    # Split into column blocks.
    col_blocks = get_col_blocks(rows, block, col_selection)
    # Select rows from each remaining column block.
    row_key = (key[0], slice(None, None, None))
    # Short circuit for single column.
    if len(col_blocks) == 1:
        block = intf.index(col_blocks[0], row_key)
    else:
        indexed_blocks = []
        for col_block in col_blocks:
            idx_block = intf.index(col_block, row_key)
            # Convert to sparse CSC matrix.
            sp_intf = intf.DEFAULT_SPARSE_INTERFACE
            idx_block = sp_intf.const_to_matrix(idx_block)
            indexed_blocks.append(idx_block)
        block = sp.vstack(indexed_blocks)
    return block
Beispiel #7
0
def get_col_blocks(rows, coeff, col_selection):
    """Selects column blocks from a matrix.

    Parameters
    ----------
    rows : int
        The number of rows in the expression.
    coeff : NumPy matrix or SciPy sparse matrix
        The coefficient matrix to split.
    col_selection : list
        The indices of the columns to select.

    Returns
    -------
    list
        A list of column blocks from the coeff matrix.
    """
    col_blocks = []
    for col in col_selection:
        key = (slice(col * rows, (col + 1) * rows, 1), slice(None, None, None))
        block = intf.index(coeff, key)
        col_blocks.append(block)
    return col_blocks
Beispiel #8
0
def get_col_blocks(rows, coeff, col_selection):
    """Selects column blocks from a matrix.

    Parameters
    ----------
    rows : int
        The number of rows in the expression.
    coeff : NumPy matrix or SciPy sparse matrix
        The coefficient matrix to split.
    col_selection : list
        The indices of the columns to select.

    Returns
    -------
    list
        A list of column blocks from the coeff matrix.
    """
    col_blocks = []
    for col in col_selection:
        key = (slice(col * rows, (col + 1) * rows, 1), slice(None, None, None))
        block = intf.index(coeff, key)
        col_blocks.append(block)
    return col_blocks