필터 지우기
필터 지우기

how to avoid 'two for loop'?

조회 수: 1 (최근 30일)
octopus_love
octopus_love 2017년 3월 14일
편집: Jan 2017년 3월 14일
I don't know how to avoid using for loop, because It takes a lot of time to calculate.
Below is the code to change.
for i = 1 : 26
for j = 1 : 86400
B(86400*(i-1)+j , :) = A(26*(j-1)+i, :);
end
end
I find solutions instead of for loop, like 'repmat' or 'bsxfun', ... but I have no ideas how to shorten the time.
Please give me a hand...

채택된 답변

Akira Agata
Akira Agata 2017년 3월 14일
편집: Akira Agata 2017년 3월 14일
How about using a matrix indexing technique as follows:
for i = 1:26
idx_a = 26*((1:86400)-1) + i;
idx_b = 86400*(i-1)+(1:86400);
B(idx_b,:) = A(idx_a,:);
end
  댓글 수: 2
octopus_love
octopus_love 2017년 3월 14일
편집: octopus_love 2017년 3월 14일
It's very easy but I didn't think about that. Thank you very much ! you are the best!
Jan
Jan 2017년 3월 14일
편집: Jan 2017년 3월 14일
It is interesting and important, that your method is faster than the fully vectorized version:
indexB = bsxfun(@plus, 86400 * (0:25), (1:86400).');
indexA = bsxfun(@plus, 26 * (0:86399).', 1:26);
B(indexB, :) = A(indexA, :);
Creating the large index arrays is expensive.
Your version can be accelerated by using the colon expressions directly for indexing:
for i = 1:26
t = 86400*(i-1);
B((t+1):(t+86400), :) = A(i:26:(86399*26 + i), :);
end
Then Matlab does not check for each element if it is an allowed index (>=0, integer, <=numel(X)). This decreases the runtime from 0.23 to 0.20 seconds.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Jan
Jan 2017년 3월 14일
편집: Jan 2017년 3월 14일
If B is pre-allocated, the computing time is:
A = rand(2246400, 5); % Test data
tic;
B = zeros(size(A));
for i = 1 : 26
for j = 1 : 86400
B(86400*(i-1)+j , :) = A(26*(j-1)+i, :);
end
end
toc
% Elapsed time: 1.37 sec
With the auto-expanding of R2016b:
B(86400 * (0:25) + (1:86400).', :) = A(26 * (0:86399).' + (1:26), :);
Without auto-expanding for R<=2016b:
indexB = bsxfun(@plus, 86400 * (0:25), (1:86400).');
indexA = bsxfun(@plus, 26 * (0:86399).', 1:26);
B(indexB, :) = A(indexA, :);
% Elapsed time: 0.24sec
Akira Agata's code is not completely vectorized and uses 0.23 sec, so it is slightly faster then the complete vectorization. Nice! The creation of the large index matrices wastes a lot of time.
But now take the problem for the viewpoint of permuting the blocks of the array:
AA = reshape(A, 26, 86400, []);
AA = permute(AA, [2,1,3]);
B = reshape(AA, 86400*26, []);
% Elapsed time: 0.16 sec
The internal methods for permuting (a kind of transposing in multi-dim arrays) are faster than the explicit indexing. In addition the programmer has less chances for typos.

카테고리

Help CenterFile Exchange에서 Matrix Indexing에 대해 자세히 알아보기

태그

제품

Community Treasure Hunt

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

Start Hunting!

Translated by