lsqcurvefit cannot evaluate initial function, says insufficient input arguments

3 vues (au cours des 30 derniers jours)
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

Réponse acceptée

Stephan
Stephan le 4 Juin 2019
Modifié(e) : Stephan le 4 Juin 2019
  1 commentaire
Wolfgang Klassen
Wolfgang Klassen le 4 Juin 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.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Interpolation dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by