how to vectorize these "for loop"?
조회 수: 13 (최근 30일)
이전 댓글 표시
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]
댓글 수: 0
채택된 답변
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
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.
추가 답변 (1개)
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
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 Center 및 File Exchange에서 Startup and Shutdown에 대해 자세히 알아보기
제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!