How can i optimize my code without a for-loop ?

1 visualización (últimos 30 días)
Paul Eluard
Paul Eluard el 12 de Mzo. de 2016
Comentada: Paul Eluard el 12 de Mzo. de 2016
Hello, I've partially written a script which uses a for loop. But the problem is taht it slows too much the program, could you look at it and tell me if it is possible to use only matrix calculus ?
Here is the code:
m = [0 0 m0]; %m0 is a constant
R_rec = repmat(r_rec,size(r_source,1),1); %the dimension is 78000...
R = r_source - R_rec;
for n=1:size(R)
r = R(n,:);
r1 = r/sqrt(r*r');
B0(n,:) = 1/(sqrt(r*r'))^(3/2).*((3*dot(m,r1).*r1) - m);
end
S = sum(B0,1);
Bx = S(1);
By = S(2);
Bz = S(3);
end
The puropose of this script is to calculate the magnetic field of magnet (r_source) at a point (r_sec) r_source is 78000*3 and r_sec = 1*3 that's why I use repmat() to get the position vector r used in the formula. It takes 2-3 minutes to compute the field about +/- 100 points, which is too much...
How can I optimize it ?
Thanks a lot, Paul.
Ps: sorry for my bad English, it's not my mother tongue.

Respuesta aceptada

Ced
Ced el 12 de Mzo. de 2016
Editada: Ced el 12 de Mzo. de 2016
How about this? With 100k rows, I get old version: 0.90 s new version: 0.01 s
m = [0 0 m0]; %m0 is a constant
R_rec = repmat(r_rec,size(r_source,1),1); %the dimension is 78000...
R = r_source - R_rec;
r_norm = sqrt(sum(R.*R,2));
R_norm = R./repmat(r_norm,1,3);
v = 3*m0*R_norm(:,3);
B0 = R_norm.*repmat(v,1,3);
B0(:,3) = B0(:,3)-m0;
B0 = B0./(repmat(r_norm.^(3/2),1,3));
S = sum(B0,1);
Bx = S(1);
By = S(2);
Bz = S(3);
Note that this version will only work if m(1) = m(2) = 0. But I think you won't have any problem in adjusting it if that is not the case.
Cheers
PS: Shouldn't it be sqrt(r*r'))^3 instead of sqrt(r*r'))^(3/2) at the end? But maybe I'm missing something.
  1 comentario
Paul Eluard
Paul Eluard el 12 de Mzo. de 2016
Yes, thanks a lot ! It takes about 0.011 sec on my computer so you're the fastest and yes, it is (r*r')^(3/2) and not with the square root...

Iniciar sesión para comentar.

Más respuestas (1)

Andrei Bobrov
Andrei Bobrov el 12 de Mzo. de 2016
Editada: Andrei Bobrov el 12 de Mzo. de 2016
R = bsxfun(@minus, r_source, r_rec);
sqr1 = 1./sqrt(sum(R.^2,2));
r1 = bsxfun(@times,R,sqr1);
r2 = 3*r1(:,3)*m0;
r3 = bsxfun(@times,r2,r1);
r3(:,3) = r3(:,3) - m0;
S = sum(bsxfun(@times,sqr1.^1.5,r3));
  1 comentario
Paul Eluard
Paul Eluard el 12 de Mzo. de 2016
It also works but i got a faster answer; yours takes about 0.013 but is very clear and easy to understand, thank you

Iniciar sesión para comentar.

Community Treasure Hunt

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

Start Hunting!

Translated by