我今天注意到了一些奇怪的事情。我有一个X
非常瘦的矩阵(20800 x 200
),双精度实数,不稀疏,我想要它的 SVD 快速。Matlab 做得相当快:
> tic; [U,S,V] = svd(X,'econ'); toc
Elapsed time is 0.280848 seconds.
但是如果我要求它的转置的 SVD,这是一个非常胖的矩阵,它要慢得多。
> Xt = X';
> tic; [UU,SS,VV] = svd(Xt,'econ'); toc
Elapsed time is 0.722308 seconds.
任何想法为什么会这样?这看起来很奇怪,因为如果我想要一个胖矩阵的 SVD,这意味着我可以通过转置来更快地做到这一点,找到这个瘦矩阵的 SVD,然后交换“U”和“V”。
我的猜测是,这是因为 Matlab 使用列主顺序,所以在瘦的情况下,“U”矩阵是大的,并且在它上面运行的任何例程都使用 1 的步幅长度,而在相反的情况下, Matlab 实现调用具有非单位步长的东西,这在内存调用方面效率较低。
但即使有充分的理由,它也引出了一个问题,为什么 Matlab 不检查脂肪矩阵而只取转置的 SVD?转置运算符的速度非常快。例如,
> tic; [VV,SS,UU] = svd(Xt','econ'); toc
Elapsed time is 0.293725 seconds.
给了我VV,UU,SS
和上面一样的东西,但要快得多。