关于奇异值分解的一个老问题使我问这个问题:如何将二维数组截断为一定公差所决定的许多列?
特别是,请考虑以下代码段,该代码段定义了可接受的公差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);
谢谢。我希望我的帖子不会太混乱以至于无法理解。
我不确定我是否正确理解你。如果我的解决方案不是您要的,请考虑为您的问题添加示例。
以下代码从数组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)