为给定的公差截断2D数组[Python]

问题描述 投票:0回答:1

关于奇异值分解的一个老问题使我问这个问题:如何将二维数组截断为一定公差所决定的许多列?

特别是,请考虑以下代码段,该代码段定义了可接受的公差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);

谢谢。我希望我的帖子不会太混乱以至于无法理解。

python truncate svd truncation
1个回答
1
投票

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

以下代码从数组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)
© www.soinside.com 2019 - 2024. All rights reserved.