Asked by Andreas Bovin
on 12 Jan 2017

Hi,

I am trying to curve fit three parameters in a transcendental function to some data, and have searched both Google and MathWorks' fora to find an iterative method. However, so far none have seemed to yield results, or maybe I didn't understand the posted replys..

The function is as follows:

y = B - k1 (x - y/A) - k2 *(1 - exp( -k3(x - y/A)))

I already know the parameters A and B, and want to determine k1, k2 and k3 by fitting to a set of data containing values for x and y.

I have tried to isolate a zero on the left side, and then use the lsqcurvefit function to solve it using the following syntax (taken from one previously mentioned example):

B = 40; %Constants

A = 128e3;

k = [1 1 1]'; %Initial guesses of k1, k2, k3

xdata = epsilon; %x-data of 50 entries

ydata = sigma_matrix(:,5); %y-data of 50 entries

zeroes = zeros(1,length(xdata))'; %array of zeros to find root

predictedzeros = @(k,xdata,ydata) ydata + k1*(xdata-ydata/A) + k2(1-exp(-k3*(xdata-ydata/A))) - B

[ahat,resnorm,residual,exitflag,output,lambda,jacobian] = lsqcurvefit(predictedzeros,k,xdata,zeros(1,length(xdata))')

However, it gives me the following error:

predictedzeros =

@(k,xdata,ydata)ydata+k1*(xdata-ydata/A)+k2(1-exp(-k3*(xdata-ydata/A)))-B

Not enough input arguments.

Error in Fit>@(k,xdata,ydata)ydata+k1*(xdata-ydata/A)+k2(1-exp(-k3*(xdata-ydata/A)))-B

Error in lsqcurvefit (line 202)

initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});

Error in Fit (line 16)

[ahat,resnorm,residual,exitflag,output,lambda,jacobian] = lsqcurvefit(predictedzeros,k,xdata,zeros(1,length(xdata))')

Caused by:

Failure in initial objective function evaluation. LSQCURVEFIT cannot continue.

Does anyone have an idea of how to move forward from this point? I'm not an expert at MATLAB, but you're welcome to throw hardcore work-arounds at me :) I'm pretty frustrated at this point.

Thanks for your help.

Answer by Are Mjaavatten
on 13 Jan 2017

Accepted Answer

Set

k0 = [k1_0;k2_0;k3_0]

to a vector of initial values for your unknown parameters. Write your function as:

predictedzeros = @(k,xdata,ydata) ydata + k(1)*(xdata-ydata/A) + k(2)(1-exp(-k(3)*(xdata-ydata/A))) - B

and write the call to lsqcurvefit as:

k = lsqcurvefit(predictedzeros,k0,xdata,ydata)

You may have to try several initial value vectors.

Are Mjaavatten
on 24 Oct 2017

Dear Uday,

Sorry I did not see your question earlier. Your problem is that your function F does not comply with the requirements for lsqcurvefit. lsqcurvefit tries to fit F(k,xdata) to ydata. Your F is a function of both xdata and ydata and it is unclear what you try to achieve.

Please read the description of lsqcurvefit more thoroughly and try to figure out if it the right tool to solve your problem.

Sankalp Shukla
on 4 May 2018

Hi Are,

I am curious to know as to how the function F posted by Uday is any different from the function predictedzeros posted by Andreas? Doesn't Andreas's predictedzeros function also a function of both xdata and ydata? Thanks.

Are Mjaavatten
on 18 May 2018

Sankalp Shukla: Good point!

It seems my answer to Andreas Bovin was too hasty, and lsqcurvefit is not an appropriate tool for neither his nor Uday Saha's problem. The reason is that their expressions cannot be reformulated on the form y = f(k,x).

Using Uday's formula as an example, I would define function F as a function of k:

F=@(k) F = @(k) k(1)-k(2)*exp((xdata+ydata*k(3))/(0.025887*k(4)))...

-((xdata+ydata*k(3))/k(5));

and find the k that minimizes the sum of squares:

where:

by using use lsqnonlin:

kfit = lsqnonlin(F,k0);

Sign in to comment.

Answer by Andreas Bovin
on 31 Jan 2017

Hi,

Sorry for my slow response! The problem is solved :) Your post helped me understand how the lsqcurvefit function works, and now it yields good results!

Thank you!

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.