def testMatrixPowerh(self): A = numpy.random.rand(10, 10) A = A.T.dot(A) tol = 10**-6 A2 = A.dot(A) lmbda, V = scipy.linalg.eig(A) A12 = Util.matrixPowerh(A, 0.5) self.assertTrue(numpy.linalg.norm(A12.dot(A12) - A) < tol) self.assertTrue(numpy.linalg.norm(numpy.linalg.inv(A) - Util.matrixPowerh(A, -1)) < tol) self.assertTrue(numpy.linalg.norm(A - Util.matrixPowerh(A, 1)) < tol) self.assertTrue(numpy.linalg.norm(A2 - Util.matrixPowerh(A, 2)) < tol) self.assertTrue(numpy.linalg.norm(numpy.linalg.inv(A).dot(numpy.linalg.inv(A)) - Util.matrixPowerh(A, -2)) < tol) #Now lets test on a low rank matrix lmbda[5:] = 0 A = V.dot(numpy.diag(lmbda)).dot(numpy.linalg.inv(V)) A2 = A.dot(A) A12 = Util.matrixPowerh(A, 0.5) Am12 = Util.matrixPowerh(A, -0.5) self.assertTrue(numpy.linalg.norm(numpy.linalg.pinv(A) - Util.matrixPowerh(A, -1)) < tol) self.assertTrue(numpy.linalg.norm(numpy.linalg.pinv(A) - Am12.dot(Am12)) < tol) self.assertTrue(numpy.linalg.norm(A12.dot(A12) - A) < tol) self.assertTrue(numpy.linalg.norm(A - Util.matrixPowerh(A, 1)) < tol) self.assertTrue(numpy.linalg.norm(A2 - Util.matrixPowerh(A, 2)) < tol)
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
def testMatrixPowerh(self): A = numpy.random.rand(10, 10) A = A.T.dot(A) tol = 10**-6 A2 = A.dot(A) lmbda, V = scipy.linalg.eig(A) A12 = Util.matrixPowerh(A, 0.5) self.assertTrue(numpy.linalg.norm(A12.dot(A12) - A) < tol) self.assertTrue( numpy.linalg.norm(numpy.linalg.inv(A) - Util.matrixPowerh(A, -1)) < tol) self.assertTrue(numpy.linalg.norm(A - Util.matrixPowerh(A, 1)) < tol) self.assertTrue(numpy.linalg.norm(A2 - Util.matrixPowerh(A, 2)) < tol) self.assertTrue( numpy.linalg.norm( numpy.linalg.inv(A).dot(numpy.linalg.inv(A)) - Util.matrixPowerh(A, -2)) < tol) #Now lets test on a low rank matrix lmbda[5:] = 0 A = V.dot(numpy.diag(lmbda)).dot(numpy.linalg.inv(V)) A2 = A.dot(A) A12 = Util.matrixPowerh(A, 0.5) Am12 = Util.matrixPowerh(A, -0.5) self.assertTrue( numpy.linalg.norm(numpy.linalg.pinv(A) - Util.matrixPowerh(A, -1)) < tol) self.assertTrue( numpy.linalg.norm(numpy.linalg.pinv(A) - Am12.dot(Am12)) < tol) self.assertTrue(numpy.linalg.norm(A12.dot(A12) - A) < tol) self.assertTrue(numpy.linalg.norm(A - Util.matrixPowerh(A, 1)) < tol) self.assertTrue(numpy.linalg.norm(A2 - Util.matrixPowerh(A, 2)) < tol)