How can I use vectorization to speed up the following code
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
I have the following code. x, y and t are variables. M is a big number and I discovered that the double loop will take a longer time. I need help in making it faster, all other example have seen are partially helpful. Thanks a lot.
function f=exact(x,y,t,M,j)
f=0;
for i=1:M
for j=1:M
f=f+(16*(sin(j*pi)*sin(i*pi)*l*i^2*pi^3+4*sin(j*pi)*cos(i*pi)*j*i*pi^2+2*sin(i*pi)*cos(j*pi)*i^2*pi^2+2*sin(j*pi)*j*i*pi^2-2*i^2*pi^2*sin(i*pi)...
-6*sin(j*pi)*sin(i*pi)*j*pi+8*cos(i*pi)*cos(j*pi)*i*pi-8*i*pi*cos(i*pi)+4*cos(j*pi)*i*pi-12*sin(i*pi)*cos(j*pi)-4*i*pi+12*sin(j*pi)))/(i^4*pi^7*j^3)...
*cos(sqrt(i^2+j^2)*pi*t).*sin(i*pi*x).*sin(j*pi*y);
end
end
2 Kommentare
Jan
am 1 Nov. 2015
Bearbeitet: Jan
am 1 Nov. 2015
The expected size of M matters: Completely different approaches are required for M=4 and M=4*1e7 . "Faster" ist not clear enough: Do you have a fixed time limit, such that it is worth to spend an hour to create a C-Mex function? Or doy you want to save some minutes only, such that spending an hour would mean a loss of total time?
The input "j" is not used, because it is overwritten by the FOR loop counter. So perhaps this is a typo: The variable "l" is undefinde. Then accelerating buggy code is fruitless.
Jan
am 1 Nov. 2015
Bearbeitet: Jan
am 1 Nov. 2015
The formula looks very strange: You evaluate a lot of "sin(i*pi)" and "cos(j*pi)", but "i" and "j" are intergers. Then rounding errors dominate the result: Mathematically "sin(i*pi)" is exactly zeros, but the limited precision leads to a value of 1.2246e-016. Nevertheless, you can omit all terms, which contain a "sin(i*pi)" or "sin(j*pi)", while the cos-expressions can be replaced by a multiplication by 1 - which can be omitted.
I have the strong impression, that you did not post the real code. But optimizing pseudo-code is meaningless. Please provide a valid input also.
Antworten (1)
Jan
am 1 Nov. 2015
Bearbeitet: Jan
am 1 Nov. 2015
Although I'm in doubt that the shown code is correct, I've cleaned it up a little bit moving repeated calculations outside the inner loop:
function f=exact(x,y,t,M,l) % "l" instead of "j"?!
pi3 = pi^3;
pi2 = pi^2;
pi7 = pi^7;
f = 0;
for i=1:M
i2 = i^2;
sin_i_pi = sin(i * pi);
cos_i_pi = cos(i * pi);
sin_i_pi_x = sin(i * pi * x);
C1 = sin_i_pi * i2;
C2 = 2 * i2 * pi2 * sin_i_pi;
C3 = 8 * i * pi * cos_i_pi;
C4 = 4 * i * pi;
C5 = i^4 * pi7;
C6 = 4 * cos_i_pi * i * pi2;
C7 = 8 * cos_i_pi * i * pi;
C8 = 6 * sin_i_pi * pi;
for j=1:M
sin_j_pi = sin(j * pi);
cos_j_pi = cos(j * pi);
f = f + (sin_j_pi * C1 * l * pi3 + ...
sin_j_pi * j * C6 + ...
2 * C1 * cos_j_pi * pi2 + ...
2 * sin_j_pi * j * i * pi2 - ...
C2 - ...
sin_j_pi * j * C8 + ...
cos_j_pi * C7 - ...
C3 + ...
4 * cos_j_pi * i * pi - ...
12* sin_i_pi * cos_j_pi - ...
C4 + 12 * sin_j_pi) / ...
(C5 * j^3) * ...
cos(sqrt(i2 + j^2) * pi * t) .* sin_i_pi_x .* sin(j*pi*y);
end
end
f = f * 16;
This takes 1.10 sec instead of 3.15 sec on my old Matlab R2011b/64/Win7/Core2Duo.
But as written in my comment already: All sin terms can be omitted, because they are 0, while the cos expression is 1, such that the formula can be simplified substantially.
3 Kommentare
Jan
am 1 Nov. 2015
The "l" is undefined in the first term:
sin(j*pi) * sin(i*pi) * l * i^2 * pi^3
What about the vanishing value of "sin(i*pi)"?
Siehe auch
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!