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)
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)
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
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
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