2016-03-20 49 views
4

三維矩陣的切片我有這些尺寸的三維基質,大約向量化獲得在MATLAB

A = rand(20, 1000, 20); 

,其中第一和第三尺寸總是相同的長度。我想將主要對角切片中的元素歸零。這就是我的意思

for ii = 1:size(A, 1) 
    A(ii, :, ii) = 0; 
end 

是否有矢量化或更快的方式來做到這一點?該代碼運行大約100,000次,具有這些近似大小,但每次都不是完全相同的大小。

+0

它運行10萬次,同樣的矩陣尺寸是多少? – Daniel

+0

不完全。它在每個矩陣上運行〜100次,並且有〜1000個這樣的矩陣,大小略有不同。如果它們總是相同的大小,我會使用一個邏輯索引矩陣。 – buzjwa

回答

1

您可以使用bsxfun構建元件的線性指標將被歸零:

ind = bsxfun(@plus, (0:size(A,2)-1).'*size(A,1), 1:size(A,1)*size(A,2)+1:numel(A)); 
A(ind) = 0; 
+0

這給出比Daniel建議更好的時間,但仍比for循環方法慢2倍以上。有趣的是,即使所有'A'矩陣的大小是恆定的,並且'bsxfun'只被調用一次,情況仍然如此。執行'A(ind)= 0;'100,000次仍然比執行100,000次循環慢。我猜想這是由於使用'A(ii,:,ii)'更快地訪問內存,而使用'A(ind)'訪問「隨機」索引時更快。如果這是真的,這是一個案例_against_矢量化這段代碼。 – buzjwa

+0

但是因爲我確實要求一個矢量化的解決方案,我會接受這個答案作爲最好的矢量化解決方案。 – buzjwa

2

對於多個拖尾維度,您可以使用邏輯索引,而對所有先前維度單獨使用下標索引。通過這種方式,您可以輕鬆地在1000 20 20矩陣上進行操作。若要將此到您的矩陣,置換需要,這可能是緩慢:

n=size(A,3) 
A=permute(A,[2,1,3]); 
A(:,diag(true(n,1)))=0; 
A=permute(A,[2,1,3]); 

如果有可能永久交換A的尺寸在你的代碼,避免置換,這將導致最快的解決方案。

或者您可以使用repmat到索引擴展到的

ix=repmat(reshape(diag(true(n,1)),n,1,n),[1,size(A,2),1]) 
A(ix)=0 

的尺寸,你可以保持IX同樣大小的矩陣。目前無法訪問MATLAB,我不知道哪種解決方案更快。

+0

我現在測試了這些方法。他們慢得多。我想這是矢量化並不優越的地方之一。 – buzjwa