Filter löschen
Filter löschen

Nested loop problem with the second index

3 Ansichten (letzte 30 Tage)
gianluca
gianluca am 2 Jul. 2019
Bearbeitet: Jan am 2 Jul. 2019
Dear all,
the following code does not work well for index j > 1. I have two vectors cpx = 1-by-n and cpy = 1-by-m.
I would a new matrix cp with n-by-m rows and 2 columns with all the possible permutations of the elements in cpx and cpy. Where is the mistake?
for i = 1:length(cpx)
for j = 1:length(cpy)
cp(i.*j,:) = [cpx(i) cpy(j)];
end
end
The results are fine till row 55, so that the first cicle for i = 1:55 and j = 1 works well, then the results are incomprehensible.

Akzeptierte Antwort

Jan
Jan am 2 Jul. 2019
Bearbeitet: Jan am 2 Jul. 2019
The problem of you code was cp(i.*j,:). i*j is not a growing index. In the 1st iteration 1*1 is fine. For i=1 it works for the complete loop over j. But in the next iteration for i=2, j=1 you overwrite the value written by i=1, j=2. Better:
nx = numel(cpx);
ny = numel(cpy);
cp = zeros(nx * ny, 2); % Pre-allocation!!!
for i = 1:nx
for j = 1:ny
cp((i-1) * ny + j,:) = [cpx(i) cpy(j)];
end
end
But this can be written without loops:
cp = [repelem(cpx(:), numel(cpy), 1), repmat(cpy(:), numel(cpx), 1)];
  1 Kommentar
Jan
Jan am 2 Jul. 2019
Bearbeitet: Jan am 2 Jul. 2019
Some timings:
cpx = rand(1000, 1);
cpy = rand(1000, 1);
tic
cp = zeros(length(cpx)*length(cpy),2);
row = 0;
for i = 1:length(cpx)
for j = 1:length(cpy)
row = row + 1;
cp(row,:) = [cpx(i) cpy(j)];
end
end
toc
% 6.8 sec
tic;
[X,Y] = ndgrid(cpx,cpy);
M = [X(:),Y(:)];
toc
% 0.018 sec
tic;
nx = numel(cpx);
ny = numel(cpy);
cp = zeros(nx * ny, 2);
for i = 1:nx
for j = 1:ny
cp((i-1) * ny + j,:) = [cpx(i) cpy(j)];
end
end
toc
% 3.9 sec
tic
cp = [repmat(cpx(:), numel(cpy), 1), repelem(cpy(:), numel(cpx), 1)];
toc
% 0.022 sec
For 100x1 inputs, REPELEM/REPMAT is faster than NDGRID. For arrays > 1000 elements, NDGRID is faster - to my surprise, because it uses REPMAT twice also. In every case, they outperform the loops massively.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

Torsten
Torsten am 2 Jul. 2019
Bearbeitet: Torsten am 2 Jul. 2019
cp = zeros(length(cpx)*length(cpy),2);
row = 0;
for i = 1:length(cpx)
for j = 1:length(cpy)
row = row + 1;
cp(row,:) = [cpx(i) cpy(j)];
end
end

Stephen23
Stephen23 am 2 Jul. 2019
Bearbeitet: Stephen23 am 2 Jul. 2019
The simple MATLAB way:
>> cpx = [1,3,5,7];
>> cpy = [22,44,66];
>> [X,Y] = ndgrid(cpx,cpy);
>> M = [X(:),Y(:)]
M =
1 22
3 22
5 22
7 22
1 44
3 44
5 44
7 44
1 66
3 66
5 66
7 66

Kategorien

Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange

Tags

Produkte

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by