def eigpsd(X, n): """ Find the eigenvalues and eigenvectors of a positive semi-definite symmetric matrix. The input matrix X can be a numpy array or a scipy sparse matrix. In the case that n==X.shape[0] we convert to an ndarray. :param X: The matrix to find the eigenvalues of. :type X: :class:`ndarray` :param n: If n is an int, then it is the number of columns to sample otherwise n is an array of column indices. :return lmbda: The set of eigenvalues :return V: The matrix of eigenvectors as a ndarray """ if type(n) == int: n = min(n, X.shape[0]) inds = numpy.sort(numpy.random.permutation(X.shape[0])[0:n]) elif type(n) == numpy.ndarray: inds = numpy.sort(n) else: raise ValueError("Invalid n value: " + str(n)) invInds = numpy.setdiff1d(numpy.arange(X.shape[0]), inds) if inds.shape[0] == X.shape[0] and (inds == numpy.arange( X.shape[0])).all(): if scipy.sparse.issparse(X): X = numpy.array(X.todense()) lmbda, V = Util.safeEigh(X) return lmbda, V tmp = X[inds, :] A = tmp[:, inds] B = tmp[:, invInds] if scipy.sparse.issparse(X): A = numpy.array(A.todense()) BB = numpy.array((B.dot(B.T)).todense()) else: BB = B.dot(B.T) #Following line is very slow #Am12 = scipy.linalg.sqrtm(numpy.linalg.pinv(A)) Am12 = Util.matrixPowerh(A, -0.5) S = A + Am12.dot(BB).dot(Am12) S = (S.T + S) / 2 lmbda, U = Util.safeEigh(S) tol = 10**-10 lmbdaN = lmbda.copy() lmbdaN[numpy.abs(lmbda) < tol] = 0 lmbdaN[numpy.abs(lmbda) > tol] = lmbdaN[numpy.abs(lmbda) > tol]**-0.5 V = X[:, inds].dot(Am12.dot(U) * lmbdaN) return lmbda, V
def eigpsd(X, n): """ Find the eigenvalues and eigenvectors of a positive semi-definite symmetric matrix. The input matrix X can be a numpy array or a scipy sparse matrix. In the case that n==X.shape[0] we convert to an ndarray. :param X: The matrix to find the eigenvalues of. :type X: :class:`ndarray` :param n: If n is an int, then it is the number of columns to sample otherwise n is an array of column indices. :return lmbda: The set of eigenvalues :return V: The matrix of eigenvectors as a ndarray """ if type(n) == int: n = min(n, X.shape[0]) inds = numpy.sort(numpy.random.permutation(X.shape[0])[0:n]) elif type(n) == numpy.ndarray: inds = numpy.sort(n) else: raise ValueError("Invalid n value: " + str(n)) invInds = numpy.setdiff1d(numpy.arange(X.shape[0]), inds) if inds.shape[0] == X.shape[0] and (inds == numpy.arange(X.shape[0])).all(): if scipy.sparse.issparse(X): X = numpy.array(X.todense()) lmbda, V = Util.safeEigh(X) return lmbda, V tmp = X[inds, :] A = tmp[:, inds] B = tmp[:, invInds] if scipy.sparse.issparse(X): A = numpy.array(A.todense()) BB = numpy.array((B.dot(B.T)).todense()) else: BB = B.dot(B.T) # Following line is very slow # Am12 = scipy.linalg.sqrtm(numpy.linalg.pinv(A)) Am12 = Util.matrixPowerh(A, -0.5) S = A + Am12.dot(BB).dot(Am12) S = (S.T + S) / 2 lmbda, U = Util.safeEigh(S) tol = 10 ** -10 lmbdaN = lmbda.copy() lmbdaN[numpy.abs(lmbda) < tol] = 0 lmbdaN[numpy.abs(lmbda) > tol] = lmbdaN[numpy.abs(lmbda) > tol] ** -0.5 V = X[:, inds].dot(Am12.dot(U) * lmbdaN) return lmbda, V