簡體   English   中英

矢量化范圍設置 - MATLAB

[英]Vectorizing range setting - MATLAB

我有以下代碼。 我需要重寫它而不需要循環。 我該怎么辦?

l1 = [1 2 3 2 1];
l2 = [3 4 4 5 4];
A = zeros(5,5);
for i=1:5
    A(i, l1(i):l2(i)) = 1;
end

A

你可以用bsxfun -

I = 1:5 % Array corresponding to iterator : "for i=1:5"
out = bsxfun(@le,l1(:),I) & bsxfun(@ge,l2(:),I)

如果你需要一個雙數據類型數組,轉換為double,就像這樣 -

out_double = double(out)

再添加一個混合物! 這個只是使用一個cumsum來生成所有1 - 所以它根本不使用:運算符 - 它也完全平行:D

l1 = [1 2 3 2 1];
l2 = [3 4 4 5 4];
A = zeros(5,5);

L1 = l1+(1:5)*5-5; %Convert to matrix location index
L2 = l2+(1:5)*5-5; %Convert to matrix location index
A(L1) = 1;         %Place 1 in that location
A(L2) = 1;         %Place 1 in that location

B = cumsum(A,1) ==1 ;   %So fast
Answer = (A|B)';        %Lightning fast

Answer =

 1     1     1     0     0
 0     1     1     1     0
 0     0     1     1     0
 0     1     1     1     1
 1     1     1     1     0

以下是如何在不使用循環的情況下構建矩陣。

% Our starting values
l1 = [1 2 3 2 1];
l2 = [3 4 4 5 4];

% Coordinate grid of the right size (we don't need r, but I keep it there for illustration)
[r,c] = ndgrid(1:5);

% Build the logical index based on our lower and upper bounds on the column indices
idx_l1=bsxfun(@ge,c,l1');
idx_l2=bsxfun(@le,c,l2');

% The result
A = zeros(size(idx_l1));
A(idx_l1&idx_l2)=1

你可能需要像[r,c] = ndgrid(1:numel(l1),1:10)

此外,如果您的矩陣大小真的很大並且內存成為一個問題,您可能仍然希望堅持循環,但對於“正常大小”,這可能會更快。

每個矢量化都應該有一些懷疑。 如果你實際測量的時間你的循環比給定的答案快,主要是因為你只執行就地寫。

這是另一個可能會更大的尺寸,但我還沒有測試:

tic
myind = [];
for i = 1:5
    myind = [myind (5*(i-1))+[l1(i):l2(i)]];
end
A(myind) = 1;
toc

由於線性索引順序,給出轉置的A

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM