how to vectorize these "for loop"?
1 Ansicht (letzte 30 Tage)
Ältere Kommentare anzeigen
nelson
am 5 Aug. 2017
Kommentiert: nelson
am 5 Aug. 2017
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 Kommentare
Akzeptierte Antwort
Andrei Bobrov
am 5 Aug. 2017
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 Kommentare
Jan
am 5 Aug. 2017
+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.
Weitere Antworten (1)
Jan
am 5 Aug. 2017
Bearbeitet: Jan
am 5 Aug. 2017
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 Kommentare
Jan
am 5 Aug. 2017
Bearbeitet: Jan
am 5 Aug. 2017
@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
Siehe auch
Kategorien
Mehr zu Startup and Shutdown finden Sie in Help Center und File Exchange
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!