フィルターのクリア

Nested loop problem with the second index

3 ビュー (過去 30 日間)
gianluca
gianluca 2019 年 7 月 2 日
編集済み: Jan 2019 年 7 月 2 日
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.

採用された回答

Jan
Jan 2019 年 7 月 2 日
編集済み: Jan 2019 年 7 月 2 日
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 件のコメント
Jan
Jan 2019 年 7 月 2 日
編集済み: Jan 2019 年 7 月 2 日
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.

サインインしてコメントする。

その他の回答 (2 件)

Torsten
Torsten 2019 年 7 月 2 日
編集済み: Torsten 2019 年 7 月 2 日
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 2019 年 7 月 2 日
編集済み: Stephen23 2019 年 7 月 2 日
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

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

タグ

製品

Community Treasure Hunt

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

Start Hunting!

Translated by