In Python / Matlab, if you run a routine for SVD on a significantly non-square matrix, X
, such as X.shape = (2,15000)
you will get significantly longer run time than on a matrix with X.shape = (800,1000)
, even though 2*15000 = 30000
, and 800*1000=800000
.
That is the second matrix clearly has much more terms with which to iterate through than the first matrix yet it is computed faster in standard LAPACK computational routines.
I've tried to look through some big-O complexity analyses, since I believe LAPACK's dgeSVD subroutine is using a series of bi-diagonalization and Househoulder transformations:
But it is confusing to know exactly what it is up to since in their recent paper, they point various small tweaks that have been made over the years which makes me forming a proper conclusion as to why I have my observation as above.
https://www.netlib.org/utk/people/JackDongarra/PAPERS/siam-svd-2018.pdf
I would've thought if matrices were no square, surely they would be placed under the same routine (for example). Then the matrix with fundamentally more parameters to iterate through should take longer than the "smaller" in terms of parameter count, matrix. Or it could be that they are indeed passed through the same subroutines but the difference in matrix size could be making a larger impact than I thought (I'm thinking too naive).
Any help on intuition / links / explanations would be greatly appreciated.
EDIT:
For reference on my PC:
a = time.time()
X = np.random.randn(800,1000)
_,_,_ = np.linalg.svd(X)
b = time.time()
print(b-a)
a = time.time()
X = np.random.randn(1000,800)
_,_,_ = np.linalg.svd(X)
b = time.time()
print(b-a)
a = time.time()
X = np.random.randn(2,15000)
_,_,_ = np.linalg.svd(X)
b = time.time()
print(b-a)
a = time.time()
X = np.random.randn(15000,2)
_,_,_ = np.linalg.svd(X)
b = time.time()
print(b-a)
Has output (seconds):
0.6534378528594971
0.6089930534362793
2.464693069458008
2.5114269256591797