MATLAB - 使用其他(稀疏)矩阵中的信息填充矩阵的有效方法?

时间:2011-11-29 18:27:08

标签: matlab

为尴尬的标题道歉,这里是对问题的更具体的描述。我有一个大的(例如10 ^ 6×10 ^ 6)稀疏对称矩阵,它定义了节点之间的连接。

e.g。矩阵A = [0 1 0 0 0; 1 0 0 2 3; 0 0 0 4 0; 0 2 4 0 5; 0 3 0 5 0]将描述5节点系统,使得节点1和2通过键号A(1,2) = 1连接,节点3和4通过键号A(3,4) = 4连接,等等。 / p>

我想形成两个新的矩阵。第一个,B,将列出连接到每个节点的节点(即,B的每一行i都有find(A(i,:))给出的元素,并在必要时用末尾填充零),第二个C将列出债券连接到该节点(即C的每一行i都有nonzeros(A(i,:))给出的元素,必要时再填充。)

e.g。对于上面的矩阵A,我想形成B = [2 0 0; 1 4 5; 4 0 0; 2 3 5; 2 4 0]C = [1 0 0; 1 2 3; 4 0 0; 2 4 5; 3 5 0]

目前的代码是:

B=zeros(length(A), max(sum(spones(A))))
C=zeros(length(A), max(sum(spones(A))))
for i=1:length(A)
    B(i,1:length(find(A(i,:)))) = find(A(i,:));
    C(i,1:length(nonzeros(A(i,:)))) = nonzeros(A(i,:));
end

有效,但长度很长(A)。我尝试了其他配方,但它们都包含for循环,并没有给出太多改进。

如何在不循环遍历行的情况下执行此操作?

2 个答案:

答案 0 :(得分:0)

嗯。不确定如何向量化(find在给定矩阵时返回线性索引,这不是你想要的),但是你试过这个:

B=zeros(length(A), 0);
C=zeros(length(A), 0);
for i=1:length(A)
    Bi = find(A(i,:));
    B(i,1:length(Bi)) = Bi;
    Ci = nonzeros(A(i,:));
    C(i,1:length(Ci)) = Ci;
end

我做了两处修改:

  • 删除了对spones的调用(似乎没有必要;扩展B和C中的#列所需的性能影响可能很小)
  • 缓存了find()和nonzeros()的结果,因此它们不会被调用两次

答案 1 :(得分:0)

我知道它很难阅读,但该代码是代码的矢量化版本:

[ i j k ] = find(A);
A2=(A~=0);
j2=nonzeros(cumsum(A2,2).*A2);
C2=accumarray([i,j2],k)
k2=nonzeros(bsxfun(@times,1:size(A,2),A2));
B2=accumarray([i,j2],k2);

试试并告诉我它是否适合你。

相关问题