user2775698
user2775698

Reputation: 3

How to improve performance in matlab operation with 3 for loops?

I'm trying to improve the speed of the following code calculation:

for i=1:5440
 for j=1:46
  for k= 1:2
    pol(i,j,k)= kr0*exp(0.8*k*0.1)*(abs((I(i)*exp(-0.1*j*2.5))^0.9)+0.0);
   end
  end
end

Where I is a vector with 5440 values.

Is there any way to avoid the three for loops and increase the speed of this operation?. I can't find a right solution.

Thanks

Upvotes: 0

Views: 261

Answers (3)

Kim
Kim

Reputation: 151

MATLAB is column-major, so if you wanted to keep the loops, you should be able to get some speed up by looping your variables in the k, j, i order instead of i, j, k.

Upvotes: 0

Amro
Amro

Reputation: 124563

How about:

[i,j,k] = ndgrid(1:5440,1:46,1:2);
pol = kr0*exp(0.8*k*0.1) .* ( abs((I(i).*exp(-0.1*j*2.5)).^0.9) + 0.0);

Upvotes: 2

Mohsen Nosratinia
Mohsen Nosratinia

Reputation: 9864

Use bsxfunfor vectorization

f1 = @(a,b) (abs((a.*exp(-0.1*b*2.5)).^0.9)+0.0);
f2 = @(c,d) kr0*exp(0.8*c*0.1).*d;
pol = bsxfun(f2, permute(1:2, [3 1 2]), bsxfun(f1, I(:), 1:46));

Note that since array 1:2 is on third dimension we need permute to convert a matrix of size 1x2 to a matrix of size 1x1x2.

Here is a benchmark for comparision

kr0=1;
I=rand(5440,1);
[pol0, pol] = deal(zeros(5440, 46, 2));

tic
for mm = 1:10,
for i=1:5440
 for j=1:46
  for k= 1:2
    pol0(i,j,k)= kr0*exp(0.8*k*0.1)*(abs((I(i)*exp(-0.1*j*2.5))^0.9)+0.0);
   end
  end
end
end
toc

tic
for mm=1:10
f1 = @(a,b) (abs((a.*exp(-0.1*b*2.5)).^0.9)+0.0);
f2 = @(c,d) kr0*exp(0.8*c*0.1).*d;
pol = bsxfun(f2, permute(1:2, [3 1 2]), bsxfun(f1, I(:), 1:46));
end
toc

isequal(pol0,pol)

Which returns

Elapsed time is 1.665443 seconds.
Elapsed time is 0.306089 seconds.

ans =

     1

It is more than 5 times faster and the results are equal.

Upvotes: 3

Related Questions