2012-02-02 144 views
2
以下塊

假定A有一定的限度(1:2,1:2,1:numfoo),你怎麼向量化下面幾行:如何向量化MATLAB

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

考慮在MATLAB發佈這個答案,而不是:HTTP:// WWW .mathworks.com/matlabcentral/answers/ – eternaln00b 2012-02-02 03:15:07

回答

0

首先,這個代碼可以顯著簡化:

W = zeros(2, 2, numfoo); 
for i = 1:numfoo 
    temp = inv(A(:,:,i)); 
    W(:,:,i) = temp * temp'; 
end 

其次,你的意思做「矢量化以下行」?你的目標是什麼?你想擺脫FOR循環嗎?如果它是「矢量化」的,你認爲這段代碼運行得更快嗎?你在找什麼?

+0

是的,就是這樣。 – shuhalo 2012-02-02 03:40:55

+0

對不起,它是什麼?我問了你很多問題,你說什麼是對的?請清楚。 – eternaln00b 2012-02-02 03:42:35

+0

是的,我不想擺脫那個循環。因爲這是我的文件中唯一包含顯式for循環的行。 – shuhalo 2012-02-02 03:45:36

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); 

結果與您的代碼相同。

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秒。

+1

不僅如此,它的數值穩定性 - 與inv – 2012-02-02 10:29:01

3

由於您的矩陣大小隻有2,因此您可以使用顯式表達式來向量化您的代碼。 https://en.wikipedia.org/wiki/Inverse_of_a_matrix#Inversion_of_2.C3.972_matrices enter image description here

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

不同,我同意這是最快的實現方式 – Jorge 2012-02-02 16:10:00