MATLAB Answers

Robin L.
0

vectorize calculation of 3 for

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 😉

  0 件のコメント

サインイン to comment.

1 件の回答

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.
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 !

サインイン to comment.



Translated by