lsqcurvefit cannot evaluate initial function, says insufficient input arguments

2 views (last 30 days)
I have a dataset described by a decaying exponential, I am trying to use lsqcurvefit to fit to this data. I have an anonymous function that plots a decaying exponential just fine, but I get errors like:
Not enough input arguments.
Error in
fitFID>@(amp,tConst,w,phi,offset,x)amp.*exp(-tConst.*x).*cos(w.*x+phi)+offset
(line 33)
FID = @(amp,tConst,w,phi,offset,x) amp.*exp(-tConst.*x).*cos(w.*x + phi)
+ offset;
Error in lsqcurvefit (line 213)
initVals.F =
feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});
Error in fitFID (line 35)%fitFID is the code shown below
par = lsqcurvefit(FID,par0,fitTime,fitData,[],[],opts);
Error in freeInductionDecay (line 75)%this is the code that calls the fitFID code
par = fitFID(data,extPar,1);
Caused by:
Failure in initial objective function evaluation. LSQCURVEFIT cannot
continue.
Here is the code:
%data is a 4x1000000 double
x = data(2,:)';
time = data(4,:)';
%extPar.whatever are all just numbers to help with initial guesses
firstFitPoint = round((extPar.numCycles./extPar.centerFreq).*...
((extPar.endPoint - (extPar.firstPoint - 1))./(extPar.timebase.*10)));
fitData = x(firstFitPoint:end);
fitTime = time(firstFitPoint:end);%trims data to interesting part (i.e the decying part)
%% %%%%%%%%%%%%%%%%%%%Estimate parameters and perform fit%%%%%%%%%%%%%%%%%%
opts = optimset(...
'TolFun',eps,...
'MaxFunEvals',10000,...
'Display','off',...
'TolX',eps);
ampGuess = abs(max(fitData) - min(fitData));%estimate amplitude
tConstGuess = 25;%I don't have a good way to estimate this, so this one is hard-coded
wGuess = 2.*extPar.demodOffset;%estimate frequency
offsetGuess = mean(fitData);%estimate offset
par0 = [ampGuess,tConstGuess,wGuess,0,offsetGuess];%initial parameter set
FID = @(amp,tConst,w,phi,offset,x) amp.*exp(-tConst.*x).*cos(w.*x + phi) + offset;%function
par = lsqcurvefit(FID,par0,fitTime,fitData,[],[],opts);%perform fit
This issue was resolved by Stephan, below. lsqcurvefit assumes the function only has two inputs, one for parameters and one for the variable. The above code would work if the anonymous functino were replaced by:
%par = [amp,tConst,w,phi,offset] to keep track of parameters
FID = @(par,x) par(1).*exp(-par(2).*x).*cos(par(3).*x + par(4)) + par(5);%function

Accepted Answer

Stephan
Stephan on 4 Jun 2019
Edited: Stephan on 4 Jun 2019
  1 Comment
Wolfgang Klassen
Wolfgang Klassen on 4 Jun 2019
Thank you very much! That was indeed the issue. In order to use lsqcurvefit, the anonymous function has to be of the form @(par(:),x), not @(par(1),par(2),par(3),par(4),x), for example.

Sign in to comment.

More Answers (0)

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!