def weighted_bipartite_matching(A, perm_type='row'): """ Returns an array of row permutations that attempts to maximize the product of the ABS values of the diagonal elements in a nonsingular square CSC sparse matrix. Such a permutation is always possible provided that the matrix is nonsingular. This function looks at both the structure and ABS values of the underlying matrix. Parameters ---------- A : csc_matrix Input matrix perm_type : str {'row', 'column'} Type of permutation to generate. Returns ------- perm : array Array of row or column permutations. Notes ----- This function uses a weighted maximum cardinality bipartite matching algorithm based on breadth-first search (BFS). The columns are weighted according to the element of max ABS value in the associated rows and are traversed in descending order by weight. When performing the BFS traversal, the row associated to a given column is the one with maximum weight. Unlike other techniques[1]_, this algorithm does not guarantee the product of the diagonal is maximized. However, this limitation is offset by the substantially faster runtime of this method. References ---------- .. [1] I. S. Duff and J. Koster, "The design and use of algorithms for permuting large entries to the diagonal of sparse matrices", SIAM J. Matrix Anal. and Applics. 20, no. 4, 889 (1997). """ nrows = A.shape[0] if A.shape[0] != A.shape[1]: raise ValueError('weighted_bfs_matching requires a square matrix.') if sp.isspmatrix_csr(A) or sp.isspmatrix_coo(A): A = A.tocsc() elif not sp.isspmatrix_csc(A): raise TypeError("matrix must be in CSC, CSR, or COO format.") if perm_type == 'column': A = A.transpose().tocsc() perm = _weighted_bipartite_matching( np.asarray(np.abs(A.data), dtype=float), A.indices, A.indptr, nrows) if np.any(perm == -1): raise Exception('Possibly singular input matrix.') return perm
def weighted_bipartite_matching(A, perm_type="row"): """ Returns an array of row permutations that attempts to maximize the product of the ABS values of the diagonal elements in a nonsingular square CSC sparse matrix. Such a permutation is always possible provided that the matrix is nonsingular. This function looks at both the structure and ABS values of the underlying matrix. Parameters ---------- A : csc_matrix Input matrix perm_type : str {'row', 'column'} Type of permutation to generate. Returns ------- perm : array Array of row or column permutations. Notes ----- This function uses a weighted maximum cardinality bipartite matching algorithm based on breadth-first search (BFS). The columns are weighted according to the element of max ABS value in the associated rows and are traversed in descending order by weight. When performing the BFS traversal, the row associated to a given column is the one with maximum weight. Unlike other techniques[1]_, this algorithm does not guarantee the product of the diagonal is maximized. However, this limitation is offset by the substantially faster runtime of this method. References ---------- .. [1] I. S. Duff and J. Koster, "The design and use of algorithms for permuting large entries to the diagonal of sparse matrices", SIAM J. Matrix Anal. and Applics. 20, no. 4, 889 (1997). """ nrows = A.shape[0] if A.shape[0] != A.shape[1]: raise ValueError("weighted_bfs_matching requires a square matrix.") if sp.isspmatrix_csr(A) or sp.isspmatrix_coo(A): A = A.tocsc() elif not sp.isspmatrix_csc(A): raise TypeError("matrix must be in CSC, CSR, or COO format.") if perm_type == "column": A = A.transpose().tocsc() perm = _weighted_bipartite_matching(np.asarray(np.abs(A.data), dtype=float), A.indices, A.indptr, nrows) if np.any(perm == -1): raise Exception("Possibly singular input matrix.") return perm