我有一个稀疏矩阵A(使用scipy.sparse)和一个向量b,想要解决Ax = b for x。 A的行数多于列数,因此它似乎超定;然而,A的行是线性相关的,因此实际上A的行级等于列的数量。例如,A可能是
A = np.array([[1., 1.], [-1., -1.], [1., 0.]])
而b是
b = np.array([0., 0., 1.])
然后解决方案是x = [1.,-1。]。我想知道如何使用scipy.sparse.linalg中提供的函数在Python中解决这个系统。谢谢!
答案 0 :(得分:4)
您的系统可能欠定吗?如果不是,并且实际上有解决方案,则最小二乘解决方案将是该解决方案,因此您可以尝试
from scipy.sparse.linalg import lsqr
return_values = lsqr(A, b)
x = return_values[0]
如果您的系统实际上是欠定的,那么应该找到最小的L2规范解决方案。如果它不起作用,请将参数damp
设置为非常小的值(例如1e-5
)。
如果您的系统完全确定(即A
是满级的)并且有一个解决方案,并且您的矩阵A
很高,正如您所描述的那样,那么你可以在正规方程中找到一个等价的系统:
A.T.dot(A).dot(x) == A.T.dot(b)
在x
中有一个独特的解决方案。这是一个方形线性系统,因此可以使用scipy.sparse.linalg.spsolve
答案 1 :(得分:2)
解决问题的正式方法是使用SVD。你有一个表格
的系统A [MxN] * x [Nx1] = b [Mx1]
SVD将矩阵A
分解为另外三个,所以你得到:
U [MxM] * S[MxN] * V[N*N] * x[Nx1] = b[Mx1]
矩阵U
和V
都是正交的(它们的倒数是它们的转置),S
是对角矩阵。如果我们改写上面的内容,我们得到:
S[MxN] * V [N * N] * x[Nx1] = U.T [MxM] * b [Mx1]
如果M > N
,则矩阵S
的最后M - N
行将为零,如果您的系统确实存在,那么U.T b
也应该具有最后一行M - N
行为零。这意味着您可以将您的系统解决为:
>>> a = np.array([[1., 1.], [-1., -1.], [1., 0.]])
>>> b = np.array([0., 0., 1.])
>>> u, s, v = np.linalg.svd(a)
>>> np.allclose(u.T.dot(b)[-m+n:], 0) #check system is not overdetermined
True
>>> np.linalg.solve(s[:, None] * v, u.T.dot(b)[:n])
array([ 1., -1.])