version 1.3.1.2 (2.66 KB) by
Are Mjaavatten

Fit polynomial p to data, but match exactly at one or more points

**Editor's Note:** This file was selected as MATLAB Central Pick of the Week

Sometimes we want to fit a polynomial to some data, but want to force a perfect match to some known values at one or more points. This function returns such a polynomial.

Are Mjaavatten (2020). polyfix(x,y,n,xfix,yfix,xder,dydx) (https://www.mathworks.com/matlabcentral/fileexchange/54207-polyfix-x-y-n-xfix-yfix-xder-dydx), MATLAB Central File Exchange. Retrieved .

Created with
R2012b

Compatible with any release

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

Start Hunting!Create scripts with code, output, and formatted text in a single executable document.

Francesco CalandroThank u so much!

Jorge SilvaDesiree Ka-ka WongThis is a great update! I was wondering if it was possible to apply this to my 3D data (consisting of x, y and z coordinates), and how I would do that? Thanks!

Xiangyuan ZHENGVehzan RustomjiDylan McCordIncredible. Major time saver, thanks!

Twan WiltingVehzan RustomjiSuperb. Got the job done with least amount of headache. Thanks a ton to the author!

Mykyta IvaniukGuillyTJacob BreslerAre MjaavattenJacob: Thanks for pointing out the errors. I have implemented your corrections (and added scaling of dydx). Obviously, I should have tested more thoroughly.

Jacob BreslerI went through the code, and the only changes you should need to make is the addition of the following lines

xfix = (xfix - mu(1))/mu(2); %this should be added in the new if nargout > 2 loop

also the following lines need to be added in the if nargin > 5 loop

if nargout > 2

xder = (xder(:)-mu(1))/mu(2);

else

xder = xder(:);

end

Jacob Breslerthanks for the update, however the mu function does not appear to be properly applied to the fixed x values

Jacob Breslercould you add a couple lines to deal with the other standard outputs from polyfit such as error and the centering of the x values (mu=[mean(x);std(x)], x_c=(x-mu(1))/mu(2)). Otherwise this is a great script.

Are MjaavattenJesse:

R squared will be negative whenever y = y_mean is a better model than your polynomial fit. This may happen if you fix a point that is not representative for the observed values. Example:

x = linspace(0,1,100)';y = 1 + .1*randn(100,1);

p = polyfix(x,y,2,0,0);f = polyval(p,x);

plot(x,y,'.',x,f);

Rsquared = 1-((y-f)'*(y-f))/((y-mean(y))'*(y-mean(y)))

Jesse KadoshAre,

Many thanks for this useful and efficient code!

Reading about R-squared values, I see that they can be greater than 1 even for linear regression with low-order polynomials in cases where a y-intercept is fixed at 0 (i.e., regression through the origin, which occurs when a constant is not included among the regression functions). I realize that polyfix (which uses polyval) probably always includes a constant term in the regression functions, but I am wondering if the mathematical approach used in polyfix to force the fixed points in the fit has a similar effect to omitting the constant term. That is, if we use polyfix to force the curve to pass through a chosen point, is that equivalent mathematically to "forcing" a y-intercept value of zero (passing through the origin), as far as computing R-squared is concerned? If so, I assume it is then possible for R-squared values to surpass 1 when using polyfix and forcing one or more fixed points.

Some reference posts regarding R-squared surpassing 1 when the y-intercept is omitted (fixed at zero) are:

https://www.mathworks.com/matlabcentral/answers/159369-polyfit-and-r-2-value

https://stats.stackexchange.com/questions/219810/r-squared-and-higher-order-polynomial-regression

https://stats.stackexchange.com/questions/334004/can-r2-be-greater-than-1

Amal MansoorThis is so helpful! I spent hours trying to figure this out. I was just about to give up and use excel (which is horrendous for large data sets) when I found this. Thanks!

Are MjaavattenAvichay: For most of my own use of polyfit or polyfix, visual inspection is more appropriate than formal measures of the goodness of fit. Most of those measures are easily calculated from the inputs and outputs anyway, so I prefer to to leave that to the user.

Here is an example of how to calculate R^2::

x = linspace(0,pi,25);

y = sin(x);

p = polyfix(x,y,2,0,0);

f = polyval(p,x);

Rsquared = 1-((y-f)*(y-f)')/((y-mean(y))*(y-mean(y))');

Avichay EfraimGreat function, thanks!

Is there a way to calculate R^2 of the output fit curve?

Are MjaavattenHeadInTheClouds:

I had a feeling that I might have misunderstood your question. I believe that what you want will require a bounded, non-linear optimization that is best done outside of polyfix.

In the example below, nrm is an in-line function that calculates the norm of the differences between the y values and the corresponding values of the best fit polynomial passing through(x0,0). I use fminbnd from the optimization toolbox to find the value of x0 within the given interval that minimizes nrm(x0). Given the spread of the y values, a straight line seems most appropriate in this case.

x = linspace(0,2,100)';

y = exp(-x)-0.25+ 0.3*randn(100,1);

nrm = @(x0) norm((y-polyval(polyfix(x,y,1,x0,0),x)));

x0 = fminbnd(nrm,1.3,1.6);

disp(x0)

p = polyfix(x,y,1,x0,0);

plot(x,y,'.',x,polyval(p,x),[1.3,1.6],[0,0],'k');

HeadInTheCloudsAre Mjaavatten,

Thank you for the prompt response. My question was poorly worded which resulted in a misunderstanding. It should have been worded, "Is it possible to use this function in order to fit a polynomial through a specified y-value and an x-value within a range of specified x-values?" By this, I mean that I want to force a polynomial to cross the x-axis but do not want to specify a particular x-value in which it crosses the x-axis, I'd like to specify a range of possible x-values in which the polynomial is fit through one point within the specified range.

Hope this helps clear up my question.

Are MjaavattenHeadInTheClouds: If a polynomial is constant throughout an interval it must be constant everywhere, and you do not need polyfix to tell you that. In your case: p(x) = 0. Or did I misunderstand your question?

HeadInTheCloudsHi Are Mjaavatten,

Is it possible to use this function in order to fit a polynomial through a range of values instead of through a discrete point (e.g. if I want to force a function through y=0 between x = x1 and x = x2)?

Thanks in advance!

VogelGreat function!

Does it exist for 3D?

Giuseppina ButtittaAre MjaavattenAnswer to Md. Nahidul Islam:

Sorry I did not see your comment before now. I assume that what you want is to stretch and shift the original curve to pass through the specified points. Let p be the original polynomial and xfix and yfix the coordinates of the specified end points.Then the new polynomial is given by

scale = diff(yfix)/diff(polyval(p,xfix));

pnew = p*scale; % stretch

pnew(4) = pnew(4) + yfix(1)-polyval(pnew,xfix(1)); % shift

Md. Nahidul IslamHi Are Mjaavatten,

Suppose I have an equation

ynew = p1.*xnew.^3 + p2.*xnew.^2 + p3.*xnew + p4; %equation 1

where,

p1 = -4.095e-15;

p2 = 3.3606e-10;

p3 = -1.164e-05;

p4 = 2.9954;

If

xnew=[5:5:22385]; then we have a curve.

I want to get a new curve, which will follow exactly the same trend as equation 1, but will be the start and end point as [5, 22385], [15, 14.7]

How can i do that?

Thank you.

Victoria DukeFantastic code, would be very helpful to have for 3D!

Dana-Adriana BotesteanuburgesThe code works perfectly. How about extending this to 3 dimensions?... Many thanks!

Dominik VítAre MjaavattenAnswer to chef13:

It is certainly A tool, and you have already used it, I see. Whether it is an appropriate tool will depend on the broader context of your task.

chef13Hi I want to solve this problem:

https://www.mathworks.com/matlabcentral/answers/327332-generate-trajectories-with-same-tangent-in-a-specific-point

Do you think that this is the right tool ?

Thanks

Are MjaavattenAnswer to Anelechi Ibekw:

The file has been tested on versions up to R2014b, which is the latest to which have access.

burgesPlease, what version of Matlab has this function? I actually thought it was R2016b, but it isn't.

SEBIN JOSEThank you