vectorize calculation of 3 for

1 回表示 (過去 30 日間)
Robin L.
Robin L. 2019 年 3 月 8 日
コメント済み: Robin L. 2019 年 3 月 8 日
Hello !
Let us take 3 vectors 1D :
vectors L, M and N
% let us take L, M, N, 3 matrix 1D
for Lidx = 1:length(L)
for Midx = 1:length(M)
for Nidx = 1:length(N)
tab(Lidx, Midx, Nidx) = L(Lidx)*M(Midx)*N(Nidx);
end
end
end
How can I optimize that ?
I found myself a solution :
L_repmat = repmat(L, 1, length(M), length(N));
N_3d = permute(N, [3 1 2]);
N_3d_repmat = repmat(N_3d, length(L), length(M));
vectorized = L_repmat.*N_3d_repmat;
I works nicely, but is there a more optimized way ?
Robin ?

採用された回答

John D'Errico
John D'Errico 2019 年 3 月 8 日
It works, and is already vectorized. Could you have used meshgrid or ndgrid to do the same? Well, yes. Would it be any better? Well, most of the gain was achieved already when you wrote the vectorized code.
A really big problem with the looped code that you wrote was the fact you had not preallocated tab. As cuh, MATLAb is now forced to grow that array dynamically MANY times. If the vectors are long, this will be a big time waster.
The only issue with the repmats is they actually allocate memory that can grow large, if L,M,N have thousands of elements.
Here is a way to write it without the repmats, reshapes, and permutes.
[LL,MM,NN] = ndgrid(L,M,N);
tab = LL.*MM.*NN;
So, as a test, we could do this:
L = 1:3;
M = 1:4;
N = 1:5;
[LL,MM,NN] = ndgrid(L,M,N);
tab = LL.*MM.*NN;
size(tab)
ans =
3 4 5
But, the above call to ndgrid also creates arrays that are fairly large.
If you have a more recent release of MATLAB (thus R2016b or later), then you could have done this without even a call to ndgrid, and with no large intermediate array creation.
tab = L(:) .* M(:).' .* reshape(N,[1 1 numel(N)]);
size(tab)
ans =
3 4 5
Older releases of MATLAB would use bsxfun.
Are any of these expedients truly necessary, unless the vectors are pretty large? Well, it depends on the size of the vectors. Preallocating your array tab for the looped code would have made that code already pretty efficient. Is the final version I wrote the best? Yes, probably so, because MATLAB is able to do all the hard work internally and efficiently.
  1 件のコメント
Robin L.
Robin L. 2019 年 3 月 8 日
Thank you John D'Errico !
I did some performance tests and with big matrix my second solution takes too much time (30 x more than the 3 for), as well as your ndgrid solution.
But with reshape it is perfect, thank to you !

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by