def svd(matrix, k=50): """ Calculate the truncated singular value decomposition :math:`A = U * Sigma * V^T` using SVDLIBC. Returns a triple of: - U as a dense labeled matrix - S, a dense vector representing the diagonal of Sigma - V as a dense labeled matrix This matrix must not contain any empty rows or columns. If it does, use the .squish() method first. """ assert matrix.ndim == 2 if isinstance(matrix, DenseMatrix): # FIXME: we can probably feed this into SVDLIBC directly. matrix = matrix.to_sparse() if matrix.shape[1] >= matrix.shape[0] * 1.2: # transpose the matrix for speed V, S, U = matrix.T.svd(k) return U, S, V Ut, S, Vt = svd_llmat(matrix.llmatrix, k) U = DenseMatrix(Ut.T, matrix.row_labels, None) V = DenseMatrix(Vt.T, matrix.col_labels, None) return (U, S, V)
def svd(matrix, k=50): """ Calculate the truncated singular value decomposition :math:`A = U * Sigma * V^T` using SVDLIBC. Returns a triple of: - U as a dense labeled matrix - S, a dense vector representing the diagonal of Sigma - V as a dense labeled matrix This matrix must not contain any empty rows or columns. If it does, use the .squish() method first. """ assert matrix.ndim == 2 if isinstance(matrix, DenseMatrix): Ut, S, Vt = svd_ndarray(matrix, k) elif isinstance(matrix, SparseMatrix): if matrix.nnz == 0: # don't let svdlib touch a matrix of all zeros. It explodes and # corrupts its state. Just return a zero result instead. U = DenseMatrix((matrix.shape[0], k)) S = np.zeros((k,)) V = DenseMatrix((matrix.shape[1], k)) return U, S, V if matrix.shape[1] >= matrix.shape[0] * 1.2: # transpose the matrix for speed V, S, U = matrix.T.svd(k) return U, S, V Ut, S, Vt = svd_llmat(matrix.llmatrix, k) else: raise TypeError("Don't know how to SVD a %r", type(matrix)) U = DenseMatrix(Ut.T, matrix.row_labels, None) V = DenseMatrix(Vt.T, matrix.col_labels, None) return U, S, V
def svd(matrix, k=50): """ Calculate the truncated singular value decomposition :math:`A = U * Sigma * V^T` using SVDLIBC. Returns a triple of: - U as a dense labeled matrix - S, a dense vector representing the diagonal of Sigma - V as a dense labeled matrix This matrix must not contain any empty rows or columns. If it does, use the .squish() method first. """ assert matrix.ndim == 2 if isinstance(matrix, DenseMatrix): Ut, S, Vt = svd_ndarray(matrix, k) elif isinstance(matrix, SparseMatrix): if matrix.nnz == 0: # don't let svdlib touch a matrix of all zeros. It explodes and # corrupts its state. Just return a zero result instead. U = DenseMatrix((matrix.shape[0], k)) S = np.zeros((k, )) V = DenseMatrix((matrix.shape[1], k)) return U, S, V if matrix.shape[1] >= matrix.shape[0] * 1.2: # transpose the matrix for speed V, S, U = matrix.T.svd(k) return U, S, V Ut, S, Vt = svd_llmat(matrix.llmatrix, k) else: raise TypeError("Don't know how to SVD a %r", type(matrix)) U = DenseMatrix(Ut.T, matrix.row_labels, None) V = DenseMatrix(Vt.T, matrix.col_labels, None) return U, S, V