vectorial programming instead of for-loops
4 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
xanka bocem
il 25 Lug 2015
Commentato: xanka bocem
il 25 Lug 2015
Hi All,
I have implemented one function that I would like to improve. I used two for loops and instead of at least one of them I would like to use vectorial programming. (The reason is, that my input xMatrix will contain about 100000 columns and the run time will be very large then.) Unfortunately I don´t have an idea how to use the vectorial programming at all. Could you please give me some advices how can I improve the run time of the function below?
That´s my code:
function f = f_n(xMatrix, MatrixX)
n=size(MatrixX,2);
hn=0.5
for i=1:size(xMatrix,2)
xi=xMatrix(:,i);
sume = ones(1, size(xMatrix,2));
sume(i)=0;
for j=1:n;
Xj=MatrixX(:,j);
g=(xi-Xj)./hn;
sume(i) = sume(i) + g;
end
end
f=sume/(n*(hn^3));
Thank you in advance Best Regards Xanka
3 Commenti
Cedric
il 25 Lug 2015
You should explain what you want to achieve, and give an example, because we cannot figure out based on your code.
Risposta accettata
Andrei Bobrov
il 25 Lug 2015
Modificato: Andrei Bobrov
il 25 Lug 2015
hn = .5;
n=size(MatrixX,2);
f = ...
sum(sqrt(sum((bsxfun(@minus,xMatrix,permute(MatrixX,[1,3,2]))/hn).^2)),3)/(n*(hn^3));
Più risposte (1)
Cedric
il 25 Lug 2015
Modificato: Cedric
il 25 Lug 2015
The first thing to consider is that given the size of matrices that you are dealing with (and the fact that elements are of type double, stored on 8 bytes), storing all components of the differences (in the norm) should take around:
>> 1e5 * 2e2 * 3 * 8 / 1e6
ans =
480
(1e5*2e2 differences between vectors, 3 components per vector, 8 bytes per component), so 480MB of RAM, which is not a lot. It may therefore be more efficient to compute everything simultaneously using arrays with all differences/norms/etc, than to loop over a large dimension (even if you were using smaller arrays this way).
Here is some code where I am using a small test setup that will allow you to follow the computations and check by hand (sorry if there are mistakes, I didn't have much contiguous time). In short, what we do is that we build a giant array of components of differences x-Xi that we use to perform further operations. BSXFUN helps us computing these differences, and we loop over the smallest dimension, which is the number of components: 3. Then we divide by hn, compute norms, sum over the dimension that corresponds to X, and divide by the scalar factor.
clear
clc
% - Small test setup.
xs = [5, 7; 5, 7; 5, 7] ;
X = magic( 3 ) ;
hn = 0.5 ;
% - Prealloc 3D array of components; dim 1 associated with vectors of X,
% dim 2 with vectors of xs, and dim 3 are for 3 dims/comps per vector.
n_xs = size( xs, 2 ) ;
n_X = size( X, 2 ) ;
comps = zeros( n_X, n_xs, 3 ) ;
% - Build array of differences, looping over dims (3).
for dimId = 1 : 3
comps(:,:,dimId) = bsxfun( @minus, xs(dimId,:), X(dimId,:)' ) ;
end
% - Divide differences by hn, and compute norms of components
% differences/hn.
norms = sqrt( sum( (comps/hn).^2, 3 )) ;
% - Sum over the dimension that corresponds to the number of columns
% of X and divide by scalar factor.
f_xs = 1 / (n_X * hn^3) * sum( norms, 1 ) ;
Running this, we get:
xs =
5 7
5 7
5 7
X =
8 1 6
3 5 7
4 9 2
comps(:,:,1) =
-3 -1
4 6
-1 1
comps(:,:,2) =
2 4
0 2
-2 0
comps(:,:,3) =
1 3
-4 -2
3 5
norms =
7.4833 10.1980
11.3137 13.2665
7.4833 10.1980
f_xs =
70.0809 89.7669
So you can check manually that it is correct, or use it to find mistakes.
Hope it helps! Cedric
2 Commenti
Cedric
il 25 Lug 2015
Modificato: Cedric
il 25 Lug 2015
PS: I just see Andrei's solution. If you want to understand what happens, I advise you (Xanka) to study my solution with the three 2D singleton expansion (with BSXFUN). But then, Andrei implemented a direct 3D one which makes his solution about 25% faster than mine, so you should implement his solution!
If you understood my simple expansion, Andrei transforms MatrixX with the following:
permute(MatrixX,[1,3,2])
into an array whose singleton dimension is dim 2 (you would see it along axes x and z in a 3D Cartesian system of axes). Then he makes an expansion applying the subtraction operator with matrix xMatrix, whose singleton dimension is implicitly dim 3. This creates an array of differences which is rotated with respect to mine (the 3 components of what you call vectors are along dim 1 in his case, and along dim 3 in mine). Then he divides by hn and squares, and sums implicitly along dim 1, whereas I do it along dim 3. Etc..
Vedere anche
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!