Incorrect curve fitting with lsqcurvefit

12 views (last 30 days)
Hello everybody,
I think I'm having a problem with lsqcurvefit. Maybe it's from me, I don't know.
So, I have a set of data [x_data,y_data] that I want to fit with a function F(A,x) where A contains six free parameters. I define the anonymous function F=@(A,x) A(3)+A(4)*(x-A(5))+(1-int_sinc(A(6)*abs(A(5)-x))).*(A(1)*sign(x-A(5))-(1-A(2))*int_sinc(A(6)*abs(A(5)-x))) where int_sinc(x) is a function that calculate the integral of sin(t)/t from 0 to x. I also define lb and ub as the lower and upper bound for my parameters and A0 the initial values of my free parameters.
I run A=lsqcurvefit(F,A0,x_data,y_data,lb,ub) and once it's done, I plot F(A,x) and y_data on the same graph. And that's where I see that my fit and my datas do not correspond ... I can see a slight likeness but that's all. Furthermore, I remarked that the fit was really "initial condition sensitive" and the first two parameters seems to stay as they are in A0 ...
So I wanted to know where the "error", if there is one, can come from or if I just didn't understand the principle of lsqcurvefit.
I wish my english is comprehensible, and I thank you if reach that point ;)
Pierre

Accepted Answer

Steven
Steven on 28 Jan 2015
There are several things I thought I would mention of 'tricks' I've used to get fitting functions to work by estimating or eliminating free parameters. First off: Lsqcurvefit is not magic, it is going to match your model to the data by varying the parameters until it can find a good combination such that the data-model = 0 ( but not really zero because we are working with finite numbers so it will keep on finding a lower minimum until you run out of iterations (MaxIter, MaxFunEvals) or until you get close enough to zero (TolFun, TolX ) )
1) Eliminate scaling parameters In this example the function already has an y = x + c you already know how far it is from center so subtract c off to center it around 0 and then fit it, if you have to add c back. This goes for y also, you can subtract an average out and then fit it, then add it back to your fitted model after your done.
2) Rescale or estimate the amplitude Something like y = A*sin(x) is easy to find A with a max function (or in the case of y = A*(sin(x+c0)+c1) combination of max min and/or mean). Use this information to your advantage! Either use it to normalize the function and eliminate a scaling parameter or use it to help lsqcurvefit. You can do this by setting the initial parameter estimate or setting upper and lower bounds to help lsqcurvefit find a local minimum.
3) Use good initial guesses and set a upper and lower bound if necessary (kind of already said it)
4) Set parameters that you know and won't change, if there is a frequency parameter and its easy to find then estimate it yourself and then set it in the model and don't allow it to change
5) Don't use data that is bad or you don't want to model You can include only the data that you want to fit, sometimes portions of the function are easier to find or data that looks more like the model. I've done this with two dimensional functions with great results.
In this case I would start with by centering and scaling the data and remove the A(5) and A(3) parameters out of the data by centering it and try and fit the rest of the function which may or may not work with all of the sign(x) functions but since it is symmetrical, only fit one half of it (the negative half could go away, then you could throw away all of the abs and sinc functions that have a potential to create problems since the minimum would be flipping when it moved across this point)
F=@(A,x) A(4)*(x)+(1-int_sinc(A(6)*abs(x))).*(A(1)*sign(x)-(1-A(2))*int_sinc(A(6)*abs(x)))
F=@(A,x) A(4)*(x)+(1-int_sinc(A(6)*(x))).*(A(1)*(x)-(1-A(2))*int_sinc(A(6)*(x)))
Of course these are only suggestions and things that I've done that may help you or anyone else trying to get a good model fit.
  2 Comments
Pierre
Pierre on 28 Jan 2015
Thank you Steven for your clear answer ;) Actually I arrived to the same conclusions (I posted my question 10 months ago so I've had time to think about it ^^). I fixed some parameters manually and also constrained the length of the signal I wanted to fit and it worked well ! Sometimes the solution doesn't converge, but I think it's inner to all minimisation processes unfortunately ...
Matt J
Matt J on 28 Jan 2015
Edited: Matt J on 28 Jan 2015
then you could throw away all of the abs and sinc functions that have a potential to create problems since the minimum would be flipping when it moved across this point
This part is especially important since lsqcurvefit uses the Jacobian of F to drive its iteration updates. However, your function doesn't have a Jacobian with all the non-differentiable functions like sign() and abs() in there.

Sign in to comment.

More Answers (2)

Matt J
Matt J on 28 Jan 2015
Edited: Matt J on 28 Jan 2015
You could try fminspleas ( Download ) which should work well for your problem since your F has a linear dependence on four out of the six A(i) parameters. Also, fminspleas doesn't strictly care if F is differentiable, see also my Comment here, although I would have more peace of mind regardless if the fit were restricted to a portion of the curve which is differentiable in "A".

shariq khan
shariq khan on 18 Nov 2018
Edited: shariq khan on 18 Nov 2018
First and foremost
  • Make sure your scale of x and y axis is same for example if your x axis is x10^-3 and y axis is x10-1, there are high possibilities that your curve does not fit
  • secondly, if your curve pattern is recurring after certain time, try taking only one part of it for example in case of exponential - take either positive edge or negative edge and compute curve fit
But I think I am quite early on this discussion :P

Community Treasure Hunt

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

Start Hunting!