How can I impose a specific point using non linear fitting curve?

3 Ansichten (letzte 30 Tage)
Ezor am 9 Dez. 2016
Bearbeitet: Ezor am 9 Dez. 2016
I'm using a built in function such as lsqcurvefit or nlinfit to solve 3D problem (to find a function with to variables knowing some experimental results).
The output I get are not good enough and I would like to improve it by adding constraint (for instance by imposing the value at x=0). How can I do that with these non linear fitting function?
I know that such option already exists with lsqlin but I can't find thing with the non-linear tools.
Thanks in advance (and sorry for my english)
PS :I'm using matlab 2012a

Antworten (2)

John D'Errico
John D'Errico am 9 Dez. 2016
Bearbeitet: John D'Errico am 9 Dez. 2016
So much to say, so little space.
There are many reasons why you might WANT to do this. Many of them MIGHT be for the wrong reason. Hard to know, since we don't see your data or your model. I'll explain several ways how you might achieve what you are asking. But first...
You might be unsatisfied because the fit has not converged, or diverged to a bad place in parameter space. Usually that means you either have supplied poor starting values, or the model simply cannot fit this data. I cannot know, since I have been given nothing. If the model is imply bad for this data, then you need to get a better model. Trying to force it won't help, and only make things worse then.
For example, suppose you have quadratic data, but have chosen to fit a straight line? The lack of fit will be a problem, but forcing the line to go through one point won't reduce the error. In fact, the overall error will just be worse having done this.
If the starting values are poor, then use better starting values. Of course, sometimes really noisy data is a problem. Nonlinear least squares is sensitive to large residuals, requiring either VERY GOOD starting values, or the use of robust methods or weights.
You might want to force a point because your noise structure is heteroscedastic, thus not all coming from a fixed, well behaved (usually presumed Gaussian) distribution. Very often this happens when you have proportional noise. So lots of noise at one end of the curve, very little at the other. But nonlinear least squares presumes a homoscedastic noise structure.
The answer to proportional data is to either use appropriate weights, or to log your model, or to use maximum likelihood estimation, with an appropriate error structure. (Logging the model is an easy and common fix, since it transforms simple proportional noise into uniform additive noise.)
Lots of things to say, and with a little thought here, I could go on for a long time. But since I don't know your real problem, I'll end by showing you how you might solve the question you did ask (even though I think usually you asked the wrong question, and are trying to solve it using the wrong approach.)
Suppose you want to estimate the coefficients of
y = a + b*x + c*x^2
subject to the constraint it must pass through (x,y)=(2,3). Just eliminate one of the coefficients. We know:
3 = a +b*2 + c*4
a = 3 - 2*b - 4*c
and your model becomes:
y = 3 - 2*b - 4*c + b*x + c*x^2 =
3 + b*(x-2) + c*(x^2 - 4)
Just as easy to estimate. In fact, easier, because this has only 2 unknown coefficients. When you get values for b and c, then recover a from the constraint. Were this a nonlinear model, it would have been as easy to do.
If you really don't want to do the above, then you can formulate the problem using fmincon, in which case the constraint then becomes a nonlinear equality constraint.
As I said above, if you post the data and the model you want to use as an attachment to your question or to a comment, I might be able to help more.

Ezor am 9 Dez. 2016
Bearbeitet: Ezor am 9 Dez. 2016
Thanks for the answer. I'll try to explain a little bit more : I'm looking for a model to fit a '3D -curve' such that f(x,p) = g(x)*h(p). Short story long, I have several curves (x_data,z_data), each one for a given parameter p and I need to find this function f (without g and h of course !).
As you said, starting values have a strong impact on the result. Unfortunately I need that my function works for many differents cases and I have no idea what the coefficients values are. Is their any method to get a "good" guess ?
My function takes as arguments x_data, z_data, p, and 2 models for g and h. Most of the time these models are 2 polynomials. The structure looks like that :
function result = my_function(x,z,p,model_g, model_h)
model_f = @(coef,x,p) model_g(coef,x) .* model_h(coef,p);
start = ??? ; %usually I take ones(1,number_of_curves)/1000
Z = z(:);
coefficients = nlinfit(XY,Z,model,start);
% XY is a matrix arranged such that model(coef,XY,p) = Z
result = @(a,b) model(coefficients,a,b);
(I don't know if it is better or not now...)
I have tried to change the code and remove one coefficient as you said. Unfortunately there are 2 parameters which means I can only fix the point f(0,0) = z0. But at least it's a first step, even if I still have a wrong result when I slightly change the starting values.
What I want to do is fix f(0,p)=z0 for all p (I can estimate that z0), in order to "force" a better fitting.
I took a look at fmincon but I looks very hard to use. (Sadly I still don't understand what I am suppose to enter as argument and where how I put my data )
Hope it will help,
Once again thank you for your time

Community Treasure Hunt

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

Start Hunting!

Translated by