Fitting of a data set with interpolation condition

Hi everyone, I'm trying to fit a data set on the plane whose trend is concave.
Doing that with "Curve Fitting Toolbox" is quite easy, but I have to add another condition: I need that a assigned point A belong to the fitting curve.
Someone can help me?
Thank you very much

3 commentaires

Im not sure what you mean, but with the curve fitting toolbox you can generate a script. In this script you can change whatever you want.
I am attaching below a first plot of the fitting curve made with the toolbox. I want to impose the passage through the circled point. Do you know if it is possible adding this condition in the toolbox with no other calculations?
dpb
dpb le 15 Mar 2020
Not an implemented constraint. You could try a weighted fit and give the specific point a very high weight and see what happens...otherwise, would have to solve a specific model.

Connectez-vous pour commenter.

 Réponse acceptée

Ameer Hamza
Ameer Hamza le 15 Mar 2020
Modifié(e) : Ameer Hamza le 17 Mar 2020
As pointed out by dpb, you can specify the weights of each data point to the fit() function. Following code shows an example
rng(0);
x = linspace(-1, 1, 20);
y = 2 - x.^2 + 0.25*rand(size(x));
w = ones(size(x));
w(11) = 200;
fitCurve1 = fit(x', y', 'poly2');
y_fit1 = fitCurve1(x');
fitCurve2 = fit(x', y', 'poly2', 'Weights', w);
y_fit2 = fitCurve2(x');
plot(x, y_fit1, 'b', x, y_fit2, 'k', x, y, 'r+', 'LineWidth', 2)
hold on
plot(x(11), y(11), 'r+', 'LineWidth', 4, 'MarkerSize', 15);
legend({'Equal Weights', 'Unequal Weights'})
This code gives high weight to the 11th data point (indicated with a big marker below) in the input. The following figure shows both responses (with and without high weight).

2 commentaires

thank you so much!
Glad to be of help.

Connectez-vous pour commenter.

Plus de réponses (1)

Simone Guadagni
Simone Guadagni le 21 Mai 2020

0 votes

I have an additional question: is it also possible to impose a condition on the derivative in the marked point? (in particular i need a maximum in this point).
thanks a lot

8 commentaires

Try this example
rng(0);
x = linspace(-1, 1, 20);
y = 2 - x.^2 + 0.25*rand(size(x));
w = ones(size(x));
w(11) = 200;
fun = @(a, b, c) a.*x.^2 + b.*x + c;
fun_ = @(p) fun(p(1),p(2),p(3));
p_sol = fmincon(@(p) norm((fun_(p)-y).*w), rand(1,3), [], [], [], [], [], [], @(p) nonlcon(p, x(11)));
plot(x, fun_(p_sol), 'b', x, y, 'r+', 'LineWidth', 2)
hold on
plot(x(11), y(11), 'r+', 'LineWidth', 4, 'MarkerSize', 15);
legend({'Equal Weights', 'Unequal Weights'})
function [c, ceq] = nonlcon(p, peak_x)
ceq = -p(2)/(2*p(1)) - peak_x;
c = [];
end
It uses the fact that the peak of a quadratic equation lies at .
Thank you for your answer, but unfortunately my data have no a a quadratic trend.
In the plot below there is a previous simulation.
The most important thing is that the fitting function passes through the point (1,0) and there the derivative is 0 at the cost of losing precision in the other points
If it is not quadratic, then what is the equation of the line?
John D'Errico
John D'Errico le 25 Mai 2020
Modifié(e) : John D'Errico le 25 Mai 2020
Please don't add an answer just to ask another question. However, since this answer has gotten multiple comments on it, I have no choice.
I don't have your data, so I cannot give a direct example. Yes, you could use tools like fmincon to solve the problem.
Easier however, is my SLM toolbox, which does offer the ability to do pretty much anything you want.
x = rand(1,100);
y = sin(pi*x) + randn(size(x))/10;
slm = slmengine(x,y,'plot','on','xyp',[.5 0],'concavedown','on');
hold on
fplot(@(x) sin(x*pi),[0,1])
So I required the second derivative must be everywhere negative, AND that the yfirst derivative of the function at x==0.5 must be zero. As you can see, these two pieces of information provide a huge regularizing influence on the fit.
This is the entire concept of SLM (Shape Language Modeling) - that you have information about the shape of the result that you know to be true. The problem lies in how to encode that information in a usable form.
SLM is free, download it from the file exchange:
Thank you very much, and i'm sorry for adding question to an old question.
This is an example of a data set that I have
x=[0.1 0.15 0.2 0.3 0.35 0.4 0.42324455 0.441392221 0.457042596 0.47224307 0.488541432 0.507038465 0.52844053 0.553112155 0.581128629 0.61232859 0.646366615 0.682765809 0.720970398 0.760398315 0.800493793 0.840779953 0.880911396 0.920726792 0.960301467 1 1.083766622 1.149812621 1.202289818 1.24464108 1.279664388 1.309576915 1.336079098 1.360418715 1.383454958 1.405722507 1.427495604 1.448852127 1.469737665 1.490029595 1.509601149 1.528385495 1.54643981 1.564009351 1.581591532 1.6 1.65 1.8 2 2.2 2.3];
y=[-74.6934 -63.81115 -54.1096 -38.2486 -32.08915 -26.35931599 -25.09719768 -23.9895761 -22.94958061 -21.90901407 -20.81693952 -19.63826686 -18.3523396 -16.95152151 -15.43978333 -13.83128947 -12.14898471 -10.42318089 -8.69014361 -6.990678932 -5.368720067 -3.869914079 -2.54020858 -1.424438428 -0.564912421 0 -0.177963743 -0.523479932 -0.999732753 -1.572846112 -2.21203549 -2.8897598 -3.581873251 -4.267777196 -4.930572001 -5.557208896 -6.138641835 -6.669979354 -7.150636429 -7.584486337 -7.980012509 -8.35046039 -8.7139893 -9.093824289 -9.518407993 -10.0215525 -11.67973 -18.98872 -34.252 -55.82152 -68.97112];
could you do a test on them?
Simone, you can download John's package (link in his comment), use the code in his comment and try it yourself. If there is an issue, then you can ask here.
John D'Errico
John D'Errico le 26 Mai 2020
Modifié(e) : John D'Errico le 26 Mai 2020
You need to consider if forcing the curve to have a zero slope at exactly x==1 makes sense in terms of that data. For example, if we zoom into your data
I see you have one point at x==1, perhaps it was even artificially inserted. That is, your data has the exact point (x,y) = (1,0), whereas most of the other data has many decimals in it.
However, if we look at the shape of the curve near there, it seem there is a natural maximum around x==1.05, a location that lies between that point and the next. The shape is fairly complex, but if you force the curve to have a zero slope exactly at x==1, this forces what is essentially a second derivative discontinuity into the curve at x==0.
In this plot, the vertical line in black is where the maximum wants to live, in order to be consistent with the data we see. In fact, this is relative nice, smooth data. In fact, the model fits very well, even though there is some interesting behavior around x=1.5 where the curve dips down, and there is one strange point at x=0.4, that seems to be almost another derivative discontinuity. (I wonder how the data was generated.) In the model as created, the data naturally wants the maximum to be around x=1.05. I get 1.0517 from the curve, where that peak lies.
But, now consider the fit when I artifically force the maximum to live exactly at x=1.
Do you see what happens? This is inconsistent with the data itself. In turn, that introduces oscillations into the curve away from that point. I had to force the fit to do something inconsistent with the data.
In order to get the result you want I might as well break the problem into two separate problems, where I model the left and right halves of the curve separately. If I do that, splitting the curve into two halves, but forcing each half to pass through the point at (x,y) = (1,0), then things do fit reasonably well. This implicitly creates a point at x=1 where the curve is continuous but not differentiable.
Simone Guadagni
Simone Guadagni le 29 Mai 2020
Modifié(e) : Simone Guadagni le 17 Juil 2020
thank you very much John you have been very kind.
I will do some tests these days and if I have problems I will contact you.
Thanks a lot

Connectez-vous pour commenter.

Catégories

En savoir plus sur Get Started with Curve Fitting Toolbox dans Centre d'aide et File Exchange

Produits

Version

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by