I've been trying to figure out how to code an svd algorithm and I've seen some questions about svd algorithms floating around the Mahout mailing lists. I thought it might be helpful to share what I've found so far.
Really large matrices require using one of the randomizing methods to get done. The methods I've seen reduce one dimension of the problem, but if singular values and/or left/right singular vectors are required, then an svd remains to be done. Here is what I've found as approaches to getting the svd done. Lanczos Algorithm - The Lanczos algorithm is covered pretty well in Chapter 9 of (golub and van loan "Matrix Computations"). The Lanczos algorithm constructs an orthogonal basis set for the Krylov spaces (e.g. the space spanned by (x, Ax, A^x,..)). The basic Lanczos algorithm is only suited to symmetric matrices and has some numerical difficulties maintaining orthonormality. The numerical issues are addressed in "Matrix Computations". That book also described the Arnoldi algorithm, which is a derivative of the Lanczos algorithm. The Arnoldi algorithm works for square non-symmetric matrices. The Arnoldi algorithm also has some numerical issues which are touched upon in "Matrix Computations". Divide and Conquer - A more current favorite is the "divide and conquer" algorithm is also described in "matrix computations". In Section 8.54 (in the third edition - which is current one), golub shows how to apply a perturbation to a tridiagonal matrix in order to break it into a block diagonal matrix with two independent diagonal blocks. This leads to two half-sized problems that can be solved independently (e.g. on different machines). And of course, why stop at halving the system? Why not quarter or keep splitting until the problem is solved or is trivial? The steps with "divide and conquer" would be to apply Householder rotations to the starting matrix to reduce it to tridiagonal and then to split the tridiagonal matrix into smaller pieces to do the actual eigenvalue calculations. Non-square matrices - All of the methods I've found for actually producing singular values or singular vectors are targeted at symmetric matrices or at most square unsymmetric ones (the arnoldi algorithm). I haven't seen anything that attacks the non-square matrix that inevitably arises in latent semantic analysis (for example). One approach that comes to mind is the following. Suppose we have an mxn matrix M that needs svd'ing. It's easy to show that MM^T has the same LHS singular vectors as M. That is, if M = UDV^T is the svd of M, then MM^T = (UDV^T) * ( VDU^T) = U (D^2)U^T. so the eigenvectors of MM^T are the LHS singular vectors of M. And the non-zero eigenvalues of MM^T are the squares of the non-zero singular values of M. Similarly, the eigenvectors of M^TM are the RHS singular vectors and again the non-zero eigenvalues of M^TM are the squares of the non-zero singular values of M. So an obvious way to use existing svd machinery would be to calculate the eigenvectors and eigenvalues of MM^T and of M^TM. Typically one of these is relatively small (on the order of the number of singular values in the final approximation squared (or so) or klog(k) for better randomized methods). The other dimension is relatively large (e.g. the number of words or tokens that are being counted). This is the best I've got so far. If anyone has better, I'd really love to hear about it. Mike