针对给定的公差截断二维数组 [Python]

Truncating a 2D array for a given tolerance [Python]

一个关于奇异值分解的老问题让我问这个问题: 我如何将二维数组截断为由特定容差决定的列数?

具体来说,请考虑以下代码片段,它定义了 1e-4 的可接受容差并将奇异值分解应用于矩阵 'A'。

#Python
tol=1e-4
U,Sa,V=np.linalg.svd(A)
S=np.diag(Sa)

生成的奇异值对角矩阵 'S' 包含数量级递减的非负奇异值。

我想要获得的是一个截断的 'S' 矩阵,在这种情况下,矩阵中奇异值低于 1e-4 的列将被删除。然后,将此截断应用于矩阵 'U'.

有没有简单的方法可以做到这一点?我一直在四处寻找,找到了一些解决 Matlab 问题的方法,但没有找到与 Python 类似的方法。 对于 Matlab,代码类似于:

%Matlab
tol=1e-4
mask=any(Sigma>=tol,2);
sigRB=Sigma(:,mask);
mask2=any(U>=tol,2);
B=U(:,mask);

提前致谢。我希望我的 post 不会太乱,看不懂。

我不确定我是否理解正确。如果我的解决方案不是您所要求的,请考虑为您的问题添加示例。

以下代码删除数组 s 中仅包含小于 tol.

的值的所有列
s = np.array([
    [1, 0, 0, 0, 0, 0],
    [0, .9, 0, 0, 0, 0],
    [0, 0, .5, 0, 0, 0],
    [0, 0, 0, .4, 0, 0],
    [0, 0, 0, 0, .3, 0],
    [0, 0, 0, 0, 0, .2]
])

print(s)

tol = .4
ind = np.argwhere(s.max(axis=1) < tol)

s = np.delete(s, ind, 1)

print(s)

输出:

[[1.  0.  0.  0.  0.  0. ]
 [0.  0.9 0.  0.  0.  0. ]
 [0.  0.  0.5 0.  0.  0. ]
 [0.  0.  0.  0.4 0.  0. ]
 [0.  0.  0.  0.  0.3 0. ]
 [0.  0.  0.  0.  0.  0.2]]


[[1.  0.  0.  0. ]
 [0.  0.9 0.  0. ]
 [0.  0.  0.5 0. ]
 [0.  0.  0.  0.4]
 [0.  0.  0.  0. ]
 [0.  0.  0.  0. ]]

我将 max 应用于轴 1,然后使用 np.argwhere 获取最大值小于 tol 的列的索引。

编辑:为了截断矩阵 'U' 的列,使其大小与缩小后的矩阵 'S' 一致,以下代码有效:

k = len(S[0])
Ured = U[:,0:k]
Uredsize = np.shape(Ured) # To check it has worked
print(Uredsize)