矢量化范围设置 - MATLAB

时间:2016-08-09 08:05:44

标签: performance matlab vectorization

我有以下代码。我需要重写它而不需要循环。我该怎么办?

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

4 个答案:

答案 0 :(得分:2)

您可以使用without that -

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)

答案 1 :(得分:1)

再添加一个混合物!这个只是使用一个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

答案 2 :(得分: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)之类的内容。

此外,如果您的矩阵大小真的很大并且内存成为一个问题,您可能仍然希望坚持循环,但对于正常大小'这可能会更快。

答案 3 :(得分:0)

每个矢量化都应该有一些怀疑。如果你实际测量的时间你的循环比给定的答案快,主要是因为你只执行就地写。

这是另一个可能会更快的尺寸,但我还没有测试过:

tic
myind = [];
for i = 1:5
    myind = [myind (5*(i-1))+[l1(i):l2(i)]];
end
A(myind) = 1;
toc
由于线性索引顺序,

给出了转置的A