在Python中解决奇异值分解(Singular Value Decomposition,SVD)

3

我正在尝试将一个IDL程序翻译成Python。我需要解决以下方式得到的SVD的结果。

from scipy.linalg import svd
A = [[1,2,3],[4,5,6]]
b = [4,4,5]

u,w,v = svd(A)

这个很好地运行了,并且从IDL翻译得很好。下一步是在IDL中进行操作!
x = svsol(u,w,v,b)

Python和IDL中的u几乎相同(其他矩阵也是如此)。唯一的区别在于尺寸,其中IDL的矩阵更大,但有很多零。从这个意义上说,Python的矩阵更加压缩。
是否有人了解Python类似的情况?
如果有人需要,这里是svsol的手册。

你不能直接使用:scipy.linalg.solve(A,b) 吗? - Andy Hayden
不,我正在寻找类似于IDL中的svsol的东西。我所遵循的方法必须使用这种方式。 - Daniel Thaagaard Andreasen
1个回答

4

使用IDL中的SVDCSVSOL,通过SVD分解解决线性最小二乘问题。在numpy中,可以通过numpy.linalg.lstsq函数完成此操作。(无需先计算SVD分解,然后再反向求解。)

>>> import numpy as np
>>> A = np.array([[1,2,3],[4,5,6]])
>>> b = np.array([4,4])
>>> x, _, _, _ = np.linalg.lstsq(A,b)
>>> x
array([-2.,  0.,  2.])
>>> np.dot(A,x)
array([ 4.,  4.])

请注意,b的长度必须与A的行数相同,因此您的示例是错误的。为了确保我正确解释了IDL语义,这里是在svsol参考手册中的示例:(链接)
>>> A = np.array(
... [[1.0, 2.0, -1.0, 2.5],
...  [1.5, 3.3, -0.5, 2.0],
...  [3.1, 0.7,  2.2, 0.0],
...  [0.0, 0.3, -2.0, 5.3],
...  [2.1, 1.0,  4.3, 2.2],
...  [0.0, 5.5,  3.8, 0.2]])
>>> B = np.array([0.0, 1.0, 5.3, -2.0, 6.3, 3.8])
>>> x, _, _, _ = np.linalg.lstsq(A,B)
>>> print x
[ 1.00095058  0.00881193  0.98417587 -0.01009547]

那看起来非常不错。我想我会使用最小二乘法。只是出于好奇,您能告诉我SVD相对于“lstsq”的优势吗(如果有的话)? 非常感谢您的帮助,我非常感慨! - Daniel Thaagaard Andreasen
1
@DanielThaagaardAndreasen 内部 np.linalg.lstsq 调用 LAPACK dgelsd,而 dgelsd 又是基于 SVD 的,因此在概念上没有区别。尽管如此,通常情况下 dgelsd 比完整的 SVD 和后续的反演求解更快。有关更多信息,请查看 LAPACK 用户指南 - Stefano M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接