def rsvd(A, k, p=10, q=2, omega=None): """ Compute the randomised SVD using the algorithm on page 9 of Halko et al., Finding Structure with randomness: stochastic algorithms for constructing approximate matrix decompositions, 2009. Finds the partial SVD of a sparse or dense matrix A, resolving the largest k singular vectors/values, using exponent q and k+p projections. Returns the left and right singular vectors, and the singular values. The resulting matrix can be approximated using A ~ U s V.T. To improve the approximation quality for a fixed k, increase p or q. :param A: A sparse or dense matrix or GeneralLinearOperator :param k: The number of singular values and random projections :param p: The oversampling parameter :param q: The exponent for the projections. :param omega: An initial matrix to perform random projections onto with at least k columns :return U: The left singular vectors :return s: The singular values :return V: The right singular vectors """ Parameter.checkInt(k, 1, float("inf")) Parameter.checkInt(p, 0, float("inf")) Parameter.checkInt(q, 0, float("inf")) if isinstance(A, GeneralLinearOperator): L = A else: L = GeneralLinearOperator.asLinearOperator(A) n = L.shape[1] if omega is None: omega = numpy.random.randn(n, k + p) else: omega = numpy.c_[omega, numpy.random.randn(n, p + k - omega.shape[1])] Y = L.matmat(omega) Q, R = numpy.linalg.qr(Y) del omega for i in range(q): Y = L.rmatmat(Q) Q, R = numpy.linalg.qr(Y) gc.collect() Y = L.matmat(Q) Q, R = numpy.linalg.qr(Y) gc.collect() del Y del R gc.collect() B = L.rmatmat(Q).T U, s, V = numpy.linalg.svd(B, full_matrices=False) del B V = V.T U = Q.dot(U) U = U[:, 0:k] s = s[0:k] V = V[:, 0:k] return U, s, V
def testCheckInt(self): min = 0 max = 5 i = 2 Parameter.checkInt(i, min, max) Parameter.checkInt(min, min, max) Parameter.checkInt(max, min, max) Parameter.checkInt(i, i, i) self.assertRaises(ValueError, Parameter.checkInt, i, max, min) self.assertRaises(ValueError, Parameter.checkInt, i, float(min), max) self.assertRaises(ValueError, Parameter.checkInt, i, min, float(max)) #self.assertRaises(ValueError, Parameter.checkInt, 2.0, min, max) self.assertRaises(ValueError, Parameter.checkInt, -1, min, max) self.assertRaises(ValueError, Parameter.checkInt, 6, min, max) #Check half ranges such as [0, inf] Parameter.checkInt(i, min, float("inf")) Parameter.checkInt(i, float("-inf"), max) #Check use of numpy int32 min = numpy.int32(0) max = numpy.int32(5) i = numpy.int32(2) Parameter.checkInt(i, min, max) Parameter.checkInt(min, min, max) Parameter.checkInt(max, min, max) Parameter.checkInt(i, i, i) #Test using an array with 1 int i = numpy.array([1], numpy.int) logging.debug((type(i))) self.assertRaises(ValueError, Parameter.checkInt, i, min, max)