how to vectorize these "for loop"?

조회 수: 13 (최근 30일)
nelson
nelson 2017년 8월 5일
댓글: nelson 2017년 8월 5일
clear all;
close all;
clc;
i=1;
for k=1:0.5:10;
for a=1:0.5:10;
for b= 1:0.5:10;
num(i,:)=[ k k*a];
den(i,:)=[1 b 0];
i=i+1;
end
end
end
[EDITED, Jan, Code formatted]

채택된 답변

Andrei Bobrov
Andrei Bobrov 2017년 8월 5일
My "ruble".
[b,a,k] = ndgrid(1:.5:10);
n = numel(k);
num1 = [k(:),k(:).*a(:)];
den1 = [ones(n,1), b(:), zeros(n,1)];
  댓글 수: 2
Jan
Jan 2017년 8월 5일
+1: This looks nice and clean. It is just 0.008 sec slower (for 100 iterations!) than the fastest solution I've found, but expanding, debugging and maintaining this nicer code will save at least minutes.
30% faster with explicite pre-allocation:
[b,a,k] = ndgrid(1:.5:10);
n = numel(k);
num = zeros(n, 2);
num(:,1) = k(:);
num(:,2) = k(:) .* a(:);
den = zeros(n, 3);
den(:,1) = 1;
den(:,2) = b(:);
But again: less nice and more prone to typos.
nelson
nelson 2017년 8월 5일
thanks....

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

추가 답변 (1개)

Jan
Jan 2017년 8월 5일
편집: Jan 2017년 8월 5일
The loops are not the main problem here, but the missing pre-allocation.
n = 19^3;
num = zeros(n, 2); % <-- Inserted
den = zeros(n, 3); % <-- Inserted
i = 1;
for k = 1:0.5:10
for a = 1:0.5:10
for b = 1:0.5:10
num(i, :) = [k, k*a];
den(i, :) = [1, b, 0];
i = i + 1;
end
end
end
Now take a look in the data: all den(:, 1) are 1, all den(:, 3) are 0, and the 2nd component is a repeated 1:0.5:10. This can be abbreviated:
v = 1:0.5:10;
n = length(v);
den = zeros(n^3, 3);
den(:, 1) = 1;
den(:, 2) = repmat(v, 1, n^2);
For num:
num = zeros(n^3, 2);
num(:, 1) = repelem(v.', n^2, 1); % REPELEM in >= R2015a
tmp = repelem(v.', n, 1) * v; % Auto-Expand in >= R2016b
num(:, 2) = tmp(:);
For older Matlab versions:
num = zeros(n^3, 2);
num(:, 1) = reshape(repmat(v, n^2, 1), [], 1);
tmp1 = repmat(v, n, 1);
tmp2 = bsxfun(@times, tmp1(:), v);
num(:, 2) = tmp2(:);
Some timings (R2016b/64, Win7, Core2Duo):
tic; for k = 1:100, [d,n] = Untitled; end; toc
Elapsed time is 12.222231 seconds. % Original
Elapsed time is 0.779765 seconds. % Original with pre-allocation !!!
Elapsed time is 0.012142 seconds. % Vectorized >= 2016b
Elapsed time is 0.013797 seconds. % Vectorized <= 2015a
Elapsed time is 0.020055 seconds. % Andrei's solution
Pre-allocation yields a speed gain of factor 16, the vectorization a factor of 1000. Nice!
  댓글 수: 3
Andrei Bobrov
Andrei Bobrov 2017년 8월 5일
+1 Good work.
Jan
Jan 2017년 8월 5일
편집: Jan 2017년 8월 5일
@nelson: Please try it again. I've fixed some typos since the first posting. I get:
v = 1:0.5:10;
n = length(v);
i=1;
for k=v, for a=v, for b=v
num(i,:)=[ k k*a];
i=i+1;
end, end, end
num2 = zeros(n^3, 2);
num2(:, 1) = repelem(v.', n^2, 1); % >= R2015a
tmp = repelem(v.', n, 1) * v; % >= R2016b
num2(:, 2) = tmp(:);
isequal(num, num2) % 1: okay

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

카테고리

Help CenterFile Exchange에서 Startup and Shutdown에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by