How can I efficiently perform a curve fitting a large number of times without a constant 'for loop'?

22 views (last 30 days)
I currently am using the function 'fit' where it outputs an exponential curve fitting function to the equation
S(TE)=A*exp(-TE/T2)
The code works perfectly fine except it is extremely slow. I need to do this on matrices approximately [240,240,30] so basically it goes through the curve fitting function 240*240 times. This is obviously not ideal but I can't figure out how to do by input matrices. Any help would be greatly appreciated! Attached is my code:
for j = 1:240
for k = 1:240
if IM(j,k,1) > 0
for ii = 1:length(TE)
s(ii)=IM(j,k,ii);
end
s=s/max(s);
fo_ = fitoptions('method','NonlinearLeastSquares','Lower',[1 0 0],'Upper',[Inf 10 1],'MaxFunEvals',1e10,'MaxIter',1e10);
ft_ = fittype('a*exp(-x./T2)+c',...
'dependent',{'y'},'independent',{'x'},...
'coefficients',{'T2', 'a', 'c'});
[cf_] = fit(TE',s',ft_,fo_);
T2=cf_.T2;
MAP(j,k)=T2;
end
end

Answers (4)

Image Analyst
Image Analyst on 11 Jun 2014
Use the "Run and time" to see where the time is being used up. The for loops are not eating up the time. I can do 100 million iterations in 0.2 seconds on my computer. Your 57 thousand (240*240) iterations took only 118 microseconds on my computer. I'm sure the time is being taken up in the other operations.
  2 Comments
José-Luis
José-Luis on 11 Jun 2014
You could start by moving as much as you can out of your loop: fo_ and ft_ can be safely declared outside. Also, you should pre-allocate MAP.
But as Image Analyst said, I would be very surprised if most of the time was not spent within the optimisation itself. There are ways you can speed up an optimization, but you could start with what I suggested.
Laura
Laura on 12 Jun 2014
Edited: Laura on 12 Jun 2014
Your right the main issue isn't the for loop, but needing to do the curve fitting individually for each pixel. That's where all the time is being spent. I will take out fo_ and ft_ but that won't be changing much either. MAP is actually already pre-allocated as well.

Sign in to comment.


Sara
Sara on 11 Jun 2014
The first thing you can try is to do this outside the loop:
[j,k] = find(IM(:,:,1) > 0);
and then replace the loops with:
for m = 1:numel(j)
and use j(m) and k(m) inside the loops. So, if IM has a lot of zeros, this will save you time. Then replace:
for ii = 1:length(TE)
s(ii)=IM(j,k,ii);
end
with:
s=IM(j(m),k(m),1:numel(TE));
Use tic toc to see if you get any speed improvement. For more help, post the inputs to your code so we can try them.

Sean de Wolski
Sean de Wolski on 11 Jun 2014
If you have the Optimization Toolbox, use lsqcurvefit rather than fit. It will be faster.

Szu-Yu Lee
Szu-Yu Lee on 8 Apr 2021
Hi, I guess you are trying to fit a large number of independent equations? MATLAB "fit" function do not support multiple independent curves fitting. I have created a function that takes in a 2D matrix, where each row is a curve to be fitted to some polynomial expression. The function does not use for-loop, so can work on large number of rows in a very short time.
https://www.mathworks.com/matlabcentral/fileexchange/90017-matrix-row-wise-polynomial-fit

Categories

Find more on Interpolation in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!