假设A有边界(1:2,1:2,1:numfoo),你如何对以下几行进行矢量化:
W = zeros( 2, 2, numfoo );
for i = 1:numfoo
temp(1:2,1:2) = inv( A(1:2,1:2,i) );
W(1:2,1:2,i) = ( temp * (temp') );
end
TYIA!
答案 0 :(得分:3)
由于您的矩阵大小仅为2
,因此您可以使用显式表达式来对代码进行矢量化。
https://en.wikipedia.org/wiki/Inverse_of_a_matrix#Inversion_of_2.C3.972_matrices
dets=A(1,1,:).*A(2,2,:)-A(1,2,:).*A(2,1,:);
temp=[A(2,2,:)./dets -A(1,2,:)./dets ; -A(2,1,:)./dets A(1,1,:)./dets];
W=[temp(1,1,:).^2+temp(1,2,:).^2,...
temp(1,1,:).*temp(2,1,:)+temp(1,2,:).*temp(2,2,:);...
temp(2,1,:).*temp(1,1,:)+temp(2,2,:).*temp(1,2,:),...
temp(2,1,:).^2+temp(2,2,:).^2];
我测试了它,它提供了相同的结果,以及加速x100
Elapsed time is 1.070547 seconds.
Elapsed time is 0.012767 seconds.
答案 1 :(得分:2)
我发现很多例子,矢量化代码并不总是更快或更清晰。
如果你想在这里使用矢量化代码是一个使用单元格数组而没有for循环的代码,但它更慢并且不像你的那样清晰。
Acell = mat2cell(A,2,2,ones(1,1,numfoo));
temp = cellfun(@inv,Acell,'UniformOutput',0);
W = cellfun(@(x,y)x*x', temp,'UniformOutput',0);
W = cell2mat(W);
结果与您的代码相同。
答案 2 :(得分:1)
使用mldivide而不是inv可以获得一点速度增益。
clear
clc
tic
numfoo=10000;
W = zeros( 2, 2, numfoo );
A=rand(2,2,numfoo);
for i = 1:numfoo
temp(1:2,1:2) = inv( A(:,:,i) );
W(1:2,1:2,i) = temp *temp';
end
toc
tic
for i = 1:numfoo
temp(1:2,1:2) = A(:,:,i)\[1 0;0 1];
W(1:2,1:2,i) = temp * temp' ;
end
toc
在我的机器上,你得到, 经过的时间是0.182324秒。 经过的时间是0.162933秒。
答案 3 :(得分:0)
首先,这段代码可以大大简化:
W = zeros( 2, 2, numfoo );
for i = 1:numfoo
temp = inv( A(:,:,i) );
W(:,:,i) = temp * temp';
end
其次,你的意思是“矢量化以下几行”?你的目标是什么?你想摆脱FOR循环吗?如果它被“矢量化”,你认为这段代码运行得更快吗?你在寻找什么?