MATLAB Answers

0

lsqcurvefit cannot evaluate initial function, says insufficient input arguments

Asked by Wolfgang Klassen on 4 Jun 2019
Latest activity Edited by Wolfgang Klassen on 4 Jun 2019
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

  0 Comments

Sign in to comment.

1 Answer

Answer by Stephan
on 4 Jun 2019
Edited by Stephan
on 4 Jun 2019
 Accepted Answer

  1 Comment

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.