# Polynomial equation not giving expected result

2 views (last 30 days)
Chamath Vithanawasam on 18 Mar 2019
Edited: dpb on 19 Mar 2019
I have a set of X axis values that are known moisture content numbers. These values give me the Y axis values in a microcontroller as shown below.
MContent = [1.278096078 22.26039162 31.88752617 40.4470463 45.821662 51.19483315 54.14512732 58.15256688 62.08950419 65.25710918 67.5910596 69.40480782 71.08289411 73.09132161];
BitValue = [1020 960 862 657 440 380 341 193 193 186 179 112 106 85];
When plotting this I will get the following output.
I wanted to obtain a polynomial equation that will fit this line. Therefore I created a 5th order polynomial as shown below.
p5 = polyfit(MContent, BitValue, 5);
format long g
disp(p5)
pp5 = polyval(p5, MContent);
hold on
plot(MContent, pp5, '-p')
Which gives this output.
This line is a satisfactory fit and I intended to use the equation obtained from this to get bit values when I add the moisture content into the 'x' value. To get this polynomial equation I used the following command.
p5 = polyfit(MContent, BitValue, 5);
format long g
disp(p5)
Which gives me
Columns 1 through 4
-1.3759358768261e-05 0.00276912138617569 -0.193482771635317 5.27065703595948
Columns 5 through 6
-53.9134842525771 1080.5582927381
Ignoring the x^5 value, as it is too small, I will use the rest and get the following equation.
yAxis = (0.00276912138617569*(MContent.^4))-(0.193482771635317*(MContent.^3))+(5.27065703595948*(MContent.^2))-(53.9134842525771*(MContent.^1))+(1080.5582927381*(MContent.^0));
But when I try to plot
figure;plot(MContent, yAxis, '-x');
I get the folllowing plot
Which is no where near to the original MContent to BitValue plot. I would like to know why, and how I can get an equation that will fit my original 'MContent' to 'BitValue' plot.
The full code is shown below for reference.
close all
MContent = [1.278096078 22.26039162 31.88752617 40.4470463 45.821662 51.19483315 54.14512732 58.15256688 62.08950419 65.25710918 67.5910596 69.40480782 71.08289411 73.09132161];
BitValue = [1020 960 862 657 440 380 341 193 193 186 179 112 106 85];
plot(MContent, BitValue, ':s', 'MarkerSize', 6, 'MarkerFaceColor', 'b')
title('MContent to bit value from 12th March 2019')
xlabel('Moisture Content (%)')
ylabel('Bit value (bits)')
p5 = polyfit(MContent, BitValue, 5);
format long g
disp(p5)
pp5 = polyval(p5, MContent);
hold on
plot(MContent, pp5, '-p')
legend('M.C. (original)', '5th degree polynomial', 'Location', 'NorthEast')
hold off
yAxis = (0.00276912138617569*(MContent.^4))-(0.193482771635317*(MContent.^3))+(5.27065703595948*(MContent.^2))-(53.9134842525771*(MContent.^1))+(1080.5582927381*(MContent.^0));
figure;plot(MContent, yAxis, '-x');

Pawel Tokarczuk on 18 Mar 2019
What you're seeing is the result of numerical instability.
You should start by centring and scaling your x-variable:
mc = (MContent - 50.0)/50.0;
dpb on 18 Mar 2019
While standardizing would be agoodthing™, numerical issues aren't the problem here; the problem is the OP just ignored one coefficient that once x gets sizable is by far the dominant factor.
The same effect would be true if the coefficients were computed for normalized/standardized variables.

dpb on 18 Mar 2019
Edited: dpb on 19 Mar 2019
Just because the coefficient is small doesn't mean it isn't important...it is, after all the coefficient of x^5 and 75^5 = 2.3730e+09 so a factor of 10E-5 on the coefficent is still a 10E4 contribution so you can't just ignore it.
b=polyfit(MContent, BitValue,5);
plot(MContent,BitValue,'bs','MarkerFaceColor','b')
hold on
xh=0:75;
yh4=polyval(b(2:end),0:75); % evaluate w/o x^5 term
h4=plot(xh,yh4,'b-');
yh5Only=polyval([b(1) zeros(1,5)],xh); % and now just that term...
h5O=plot(xh,yh5Only,'r-');
yHat=polyval(b,xh); % and the real polynomial...
max(abs(yHat-(yh4+yh5Only))) % and that leads to same as adding the x^5 term
ans =
1.5916e-11
plot(xh,(yhat),'g-') % so plot what the real answer is, too...
Above leads to the above plot which clearly illustrates why "you can't DO that!" and expect reasonable results.

Chamath Vithanawasam on 18 Mar 2019
Yep, all I had to do was add the 5th order polynomial and it worked.
dpb on 18 Mar 2019
NB: This also illustrates why it's a very bad idea to extrapolate with any arbitrary fitted function but most particularly with polynomials and why higher-order polynomials are especially bad.
I also intended to note that for numerical stability it would be better to standardize the data before doing the fitting--there's doc/example in the polyfit/polyval do on how to do that.

Chamath Vithanawasam on 18 Mar 2019
So I found out that I am not supposed to ignore any polynomial regardless of how small it may be. Here is the reading with the 5th order.