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.
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
intcoef.a2
ans =
17/25
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.