how to vectorize these "for loop"?
1 回表示 (過去 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!