Python SVD函数返回维数不兼容的矩阵 让我们考虑下面的矩阵< /P> 2 4 1 3 0 0 0 0

Python SVD函数返回维数不兼容的矩阵 让我们考虑下面的矩阵< /P> 2 4 1 3 0 0 0 0,python,linear-algebra,svd,Python,Linear Algebra,Svd,在python中创建此矩阵和相应的奇异值分解可以用一种简单的方式在python中完成 A =np.array([[2,4],[1,3],[0,0],[0,0]]) u,s,v =np.linalg.svd(A) 当我输入相应矩阵的维数时,我得到了如下结果 print(u) print(np.diag(s)) print(v) [-0.57604844 0.81741556 0. 0. ] [ 0. 0. 1.

在python中创建此矩阵和相应的奇异值分解可以用一种简单的方式在python中完成

A =np.array([[2,4],[1,3],[0,0],[0,0]])
u,s,v =np.linalg.svd(A)
当我输入相应矩阵的维数时,我得到了如下结果

print(u)
print(np.diag(s))
print(v)

[-0.57604844  0.81741556  0.          0.        ]
 [ 0.          0.          1.          0.        ]
 [ 0.          0.          0.          1.        ]]
[[5.4649857  0.        ]
 [0.         0.36596619]]
[[-0.40455358 -0.9145143 ]
 [-0.9145143   0.40455358]]
因此,下面重建原始矩阵的代码不起作用

print(u.dot(np.dot(np.diag(s),v)))

我如何解决这个问题?提前感谢

在SVD的正式定义中,
s
的形状应该是
(4,2)
。但是,NumPy的例程返回一个shape
(2,)
的奇异值数组。此外,
np.diag()
不知道完整分解中的
s
“应该”有多大。它只需要一个shape
(n,)
数组,然后返回一个shape
(n,n)
的二维数组。因此,您的内部产品最终会得到形状
(4,4)*(2,2)*(2,2)
,这当然会失败,因为第一个产品的大小没有意义

要解决此问题,只需为
s
构造一个大小正确的数组:

>>> u, s, v = np.linalg.svd(A)
>>> true_s = np.zeros((u.shape[1], v.shape[0]))
>>> true_s[:s.size, :s.size] = np.diag(s)
>>> np.allclose(u.dot(true_s).dot(v), A)
True

s矩阵应为4x2,但较低的2x2部分为空。我们不需要计算它。您可以用两个额外的空行来完成s,或者忽略u的最后两列,这是一种更经济的表示。