如何将SVD输出重排为与输入对角块对应的形式
研究背景
我需要对M个规模可能不同的独立问题执行SVD(奇异值分解)。待分解的数据集(矩阵)规模为N_M⨯2,其中每个问题的N_M各不相同,且∀M, N_M > 2。
可行方案
- 一种直观方法是通过可并行化的循环,将每个数据集单独输入SVD并分别处理结果。
- 另一种方案是将不同数据集排列为可能稀疏的对角块矩阵,仅调用一次SVD,实现计算向量化并仅处理一组输出。本文重点关注该方案。
问题描述
常见的SVD实现(如MATLAB和Numpy中的版本)会根据奇异值S的大小对U和V矩阵的列/行进行排序。这种自动排序对对角块矩阵场景不利,会导致奇异值/向量与生成它们的块之间的关联丢失。例如:
%% 定义待分解矩阵: A = [1, 1, 2; 2, 1, 3]; B = [1, 2; 2, 1]; M = blkdiag(A,B); %{ M = 1 1 2 0 0 2 1 3 0 0 0 0 0 1 2 0 0 0 2 1 %} %% 执行SVD [Ua, Sa, Va] = svd(A, 'econ'); [Ub, Sb, Vb] = svd(B, 'econ'); [Um, Sm, Vm] = svd(M, 'econ'); %{ Ua = # Ub = # Um = -0.5449 -0.8385 # -0.7071 -0.7071 # -0.5449 0 0 -0.8385 -0.8385 0.5449 # -0.7071 0.7071 # -0.8385 0 0 0.5449 # # 0 -0.7071 0.7071 0 # # 0 -0.7071 -0.7071 0 # # Sa = # Sb = # Sm = 4.4552 0 # 3.0000 0 # 4.4552 0 0 0 0 0.3888 # 0 1.0000 # 0 3.0000 0 0 # # 0 0 1.0000 0 # # 0 0 0 0.3888 # # Va = # Vb = # Vm = -0.4987 0.6465 # -0.7071 0.7071 # -0.4987 0 0 0.6465 -0.3105 -0.7551 # -0.7071 -0.7071 # -0.3105 0 0 -0.7551 -0.8092 -0.1087 # # -0.8092 0 0 -0.1087 # # 0 -0.7071 -0.7071 0 # # 0 -0.7071 0.7071 0 %}
可以看到Um、Sm和Vm的值分别与{Ua, Ub}、{Sa, Sb}和{Va, Vb}一致,但来自A的值在M的分解结果中并未被分组在一起。
那么,**如何重排(“还原排序”)Um、Sm和Vm使其与输入块对应?**重排后的预期结果为:
% 若M = blkdiag(A, B),我们期望(符号不确定性除外): Um == blkdiag(Ua, Ub); Sm == blkdiag(Sa, Sb); Vm == blkdiag(Va, Vb);
内容的提问来源于stack exchange,提问作者Dev-iL
相关产品推荐
相关产品推荐

