problem description
For a square matrix, one can obtain the SVD
X= USV'
decomposition, by using simply numpy.linalg.svd
u,s,vh = numpy.linalg.svd(X)
routine or numpy.linalg.eigh, to compute the eig decomposition on Hermitian matrix X'X and XX'
Are they using the same algorithm? Calling the same Lapack routine?
Is there any difference in terms of speed? and stability?
Indeed,
numpy.linalg.svdandnumpy.linalg.eighdo not call the same routine of Lapack. On the one hand,numpy.linalg.eighrefers to LAPACK'sdsyevd()whilenumpy.linalg.svdmakes use LAPACK'sdgesdd().The common point between these routines is the use of Cuppen's divide and conquer algorithm, first designed to solve tridiagonal eigenvalue problems. For instance,
dsyevd()only handles Hermitian matrix and performs the following steps, only if eigenvectors are required:Reduce matrix to tridiagonal form using DSYTRD()
Compute the eigenvectors of the tridiagonal matrix using the divide and conquer algorithm, through DSTEDC()
Apply the Householder reflection reported by DSYTRD() using DORMTR().
On the contrary, to compute the SVD,
dgesdd()performs the following steps, in the case job==A (U and VT required):dgebrd()DBDSDC()dgebrd()applyingdormbr()twice, once for U and once for VWhile the actual operations performed by LAPACK are very different, the strategies are globally similar. It may stem from the fact that computing the SVD of a general matrix A is similar to performing the eigendecomposition of the symmetric matrix A^T.A.
Regarding accuracy and performances of lapack divide and conquer SVD, see This survey of SVD methods:
Regarding the symmetric eigenvalue problem, the complexity is 4/3n^3 (but often proves better than that) and the memory footprint is about 2n^2 plus the size of the matrix. Hence, the best choice is likely
numpy.linalg.eighif your matrix is symmetric.The actual complexity can be computed for your particular matrices using the following code:
For such 1D diffusion matrices, eigh outperforms svd, but the actual complexity are similar, slightly lower than n^3, something like n^2.5.
Checking of the accuracy could be performed as well.