我有以下代码。我需要重写它而不需要循环。我该怎么办?
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
答案 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
。