在使用bsxfun方面需要帮助

时间:2014-05-31 20:08:01

标签: matlab multidimensional-array vectorization

我在MATLAB中有两个数组:

A; % size(A) = [NX NY NZ 3 3]
b; % size(b) = [NX NY NZ 3 1]

事实上,在三维域中,我为每个(i, j, k)定义了两个数组,它们分别从上面提到的数组Ab获得,它们的大小为{分别为{1}}和[3 3]。让我们举例来说,调用这些数组[3 1]m

n

如何以矢量化方式解决域中每个点的m; % size(m) = [3 3] n; % size(n) = [3 1] ?我使用m\n但我没有成功。

bsxfun

我认为问题在于单例元素的扩展,我不知道如何修复它。

1 个答案:

答案 0 :(得分:2)

我尝试了一些解决方案,似乎for循环在这种情况下实际上是最快的可能性。

天真的方法如下:

%iterate
C=zeros(size(B));
for a=1:size(A,1)
    for b=1:size(A,2)
        for c=1:size(A,3)
            C(a,b,c,:)=squeeze(A(a,b,c,:,:))\squeeze(B(a,b,c,:));
        end
    end
end

挤压在计算时间上很昂贵,因为它需要一些高级索引。相反,更换尺寸更快。

A=permute(A,[4,5,1,2,3]);
B=permute(B,[4,1,2,3]);
C2=zeros(size(B));
for a=1:size(A,3)
    for b=1:size(A,4)
        for c=1:size(A,5)
            C2(:,a,b,c)=(A(:,:,a,b,c))\(B(:,a,b,c));
        end
    end
end
C2=permute(C2,[2,3,4,1]);

第二种解决方案的速度提高了约5倍。

/更新:我发现了一个改进的版本。重塑和仅使用一个大循环会再次提高速度。这个版本也适合与并行计算工具箱一起使用,如果你拥有它,用parfor替换for并启动worker。

A=permute(A,[4,5,1,2,3]);
B=permute(B,[4,1,2,3]);
%linearize A and B to get a better performance
linA=reshape(A,[size(A,1),size(A,2),size(A,3)*size(A,4)*size(A,5)]);
linB=reshape(B,[size(B,1),size(B,2)*size(B,3)*size(B,4)]);
C3=zeros(size(linB));
for a=1:size(linA,3)
    C3(:,a)=(linA(:,:,a))\(linB(:,a));
end
%undo linearization
C3=reshape(C3,size(B));
%undo dimension swap
C3=permute(C3,[2,3,4,1]);