2014-10-08 87 views
2

所以我今天矢量块与overlopping赋值

A_TEST(dest,:)=A_TEST(source,:)+A_TEST(dest,:); 
A_TEST(:,dest)=A_TEST(:,source)+A_TEST(:,dest); 

如果dest是非唯一跑进这个错误,失败(这是有道理的)。所以我的快速解决方案是做一个for循环目标

for (k=1:numel(dest)) 
    A(dest(k),:)=A(source(k),:)+A(dest(k),:); 
    A(:,dest(k))=A(:,source(k))+A(:,dest(k)); 
end 

而matlab是这样的for循环不好。这个呼叫将如何矢量化?

+0

对不起,只是为了确保;你愿意多重吗? – Sheljohn 2014-10-08 22:56:42

+1

我想要多样性。来源是唯一的,但dest不是。 – IdeaHat 2014-10-08 22:57:35

+1

Matlab在循环方面不错,使用JIT编译,尤其是对于简单的循环,它们通常与矢量化代码一样高效。 – David 2014-10-08 23:05:35

回答

3

以下,我将展示如何用行来做到这一点。 要做到这一点,它是一个类似的方法,但不同的代码,我会解释为什么。

总之,你有一个矩阵A,有n行和P列。 您有一个范围为[1,n],src的整数列表,同义词为dst。 我假设他们都具有相同的大小,并可能包含超过n个元素(以便在这两个潜在的重复)。

src s分组 s,很明显您正在讨论的操作等同于行的线性重组。这相当于n x n矩阵的前乘法,其中元素(i,j) = k表示“对应于目标行i的重组i包含具有多重性k的行j”。

这是下面的代码做什么:

function A = madScience(A, src, dst) 

    n = size(A,1); 
    M = eye(n); 

    ix = sub2ind([n,n], dst, src); 

    [ux,~,mlt] = unique(ix); 
    nux = length(ux); 
    mlt = accumarray(mlt(:), 1, [nux,1]); 

    M(ux) = M(ux) + mlt'; 
    A  = M*A; 

end 

注1:两个代码,您在您的文章给有同等学历;您需要两个单独的for循环才能使它们等效。

注2:上的列相同的操作相当于一个柱乘以一个矩阵,其中元素(i,j) = k意思是“对应于第j列的重组包含i相重数k个列”。

注3:如果A是正方形,那么两个操作都可以使用与(M*A) * M'(括号非常重要)相同的矩阵M执行。

+0

非常聪明的做法! +1 – Divakar 2014-10-09 03:56:52

+0

不错......我想这会是某种准马拉松式的疯狂。 – IdeaHat 2014-10-09 16:22:13

+1

我在原帖中没有提到的一点是,矩阵实际上是对角对称(加权邻接矩阵)。我们可以只用行组合来做到这一点......好! – IdeaHat 2014-10-09 16:34:48