[SOLVED] Determine a linear regression coefficient on a polynomial segment

1 Ansicht (letzte 30 Tage)
Florian
Florian am 23 Mär. 2015
Kommentiert: John D'Errico am 23 Mär. 2015
Hi all,
Thanks in advance for your answer to my question. I have a 3-rd degree polynomial function like : f(x) = 0.1*(x-2).^3 +0.3*x + 0.8 with x=(0:0.2:4) When you draw it, you can see a linear segment from approximately x=1 to x=3. I'd like to know how to determine the regression coefficient on this specific segment ?
Best regards,
Florian

Antworten (1)

John D'Errico
John D'Errico am 23 Mär. 2015
Bearbeitet: John D'Errico am 23 Mär. 2015
I'm sorry. What are you asking? A quadratic or higher order polynomial will not have a linear "segment".
If your goal is to fit a spline perhaps, than you can do that. If you wish to approximate this curve over that region with a linear polynomial, you can do that.
You could for example, find the linear polynomial that best approximates that cubic over the interval [1,3]. Simplest is to simply sample the function, then use polyfit. Or, you could find the function that minimizes the integral of the error over that interval. Either is easy enough, so I'll solve it a couple of ways, and let you choose your preference...
So, first, lets see how a fit would work over the restricted region.
p0 = @(x) 0.1*(x-2).^3 +0.3*x + 0.8;
Golden rule: Always plot EVERYTHING.
ezplot(p0,[0,3])
So over the interval -1,2.5], it is reasonably linear. Not quite so much if you go out to x=3.
Lets sample the function over that interval to create a fit.
x = linspace(1,3,1000);
y = p0(x);
Lots of points here, so the result will be quite close to what we will get using an integral anyway.
xbig = linspace(0,3,1000);
ybig = p0(xbig);
% a simple linear fit over that interval.
plin = polyfit(x,y,1)
plin =
0.36012 0.67976
plot(xbig,ybig,'r-',x,polyval(plin,x),'b-')
grid on
As you can see, there is some lack of fit. Had we restricted the fit to a smaller interval, like [1,2.5], the fit would be better.
Lets solve it symbolically first, using the integral of the squared residual.
syms x a1 a2
psym = 0.1*(x-2).^3 +0.3*x + 0.8;
psymlin = a1*x + a2;
intcoef = solve(gradient(int((psym - psymlin)^2,x,[1,3])))
intcoef =
a1: [1x1 sym]
a2: [1x1 sym]
intcoef.a1
ans =
9/25
% as a decimal: 0.36
intcoef.a2
ans =
17/25
% as a decimal: 0.68
You can see this was quite close to the solution from polyfit. As I said, the two will be close because I used so many points for the fit.
Over a smaller interval...
intcoef = solve(gradient(int((psym - psymlin)^2,x,[1,2.5])))
intcoef =
a1: [1x1 sym]
a2: [1x1 sym]
intcoef.a1
ans =
141/400
intcoef.a2
ans =
277/400
vpa(intcoef.a1)
ans =
0.3525
vpa(intcoef.a2)
ans =
0.6925
Lets see how this fits over the smaller interval.
xsmall = [1,2.5];
plot(xbig,ybig,'r-',xsmall,polyval([141/400 277/400],xsmall),'b-')
grid on
As you see, this is a reasonably decent approximation. But if I try to fit a spline, that has a linear segment on that interval, there will be some distortion around the edges of that interval.
First, lets look to see how constant that slope was over the interval of interest.
ezplot(diff(psym),[0,3])
grid on
In fact, between x=1 and x=2.5, the slope is not constant. Well, perhaps not as much so as you might think.
subs(diff(psym),1)
ans =
3/5
subs(diff(psym),2)
ans =
3/10
So the slope varies from 0.3 to as much as 0.6 over that interval, a factor of 2.
A spline fit is easy enough. I'll use my SLM toolbox, as found for download from the file exchange.
x = linspace(0,3,1000);
y = p0(x);
slm = slmengine(x,y,'knots',[0 1 2.5 3],'c2','off','linearregion',[1.1 2.49],'plot','on')
As you can see, the C1 (one time continuously differentiable) spline fit I used here gives a reasonable fit too.
What are the coefficients of the linear segment?
polys = slmpar(slm,'symabs');
vpa(polys{2,2},15)
ans =
7.40148683083438e-17*x^3 - 3.70074341541719e-16*x^2 + 0.376582405410514*x + 0.641809039858361
See that the cubic and quadratic coefficients are essentially zero, as requested. The slop is just floating point trash. But the linear and constant terms are roughly what we got from the other methods employed.
I know, this all seems to be beating a dead horse, but it can be interesting to see how one might solve a problem in various ways in MATLAB, depending on your goals, needs, available tools, and skills. My guess is with a bit of time, I could have solved it using the chebfun toolbox too.
  5 Kommentare
Florian
Florian am 23 Mär. 2015
Your in-depth answer is really impressive John, I'm really happy to see that this forum has such a kind of professionalism and expertise. Thanks again for your time, this is now very clear in my mind and will be very helpful for my work !

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Spline Postprocessing finden Sie in Help Center und File Exchange

Tags

Noch keine Tags eingegeben.

Community Treasure Hunt

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

Start Hunting!

Translated by