Polyfit coeffs weird output

%Importing Data
x1= csvread('C:\Users\User\Desktop\spdctrl.csv',450,0,[450,0,2050,0]);
y= csvread('C:\Users\User\Desktop\spdctrl.csv',450,1,[450,1,2050,1]);
%Curve Fitting and finding R^2
[p,s] = polyfit(x1,y,15);
R2 = 1 - (s.normr/norm(y - mean(y)))^2;
m = polyval(p,x1);
% Plotting Original vs Curve Fit
figure(1)
subplot(2,1,1)
plot(x1,y)
xlabel('X')
ylabel('Original')
subplot(2,1,2)
plot(x1,m)
xlabel('X')
ylabel('Fitted')
%Extracting the Equation of the Curve-Fit
syms x;
sympref('FloatingPointOutput',true);
i=1;
Throttle = 0;
while i<=length(p) %p is 1x16 double
Throttle = Throttle + p(i)*x^(16-i); % (Coeff)*(input)^(16-i) , 16-i because Coeffs are in decreasing order.
i=i+1;
end
disp(['R-squared = ', num2str(R2)])
disp('Model Eq : Throttle = ')
Throttle
%%
Throttle = - 2.3673e-20*x^15 + 2.5403e-17*x^14 - 1.2612e-14*x^13 + 3.8441e-12*x^12 - 8.0455e-10*x^11 + 1.2250e-07*x^10 - 1.4019e-05*x^9 + 0.0012*x^8 - 0.0830*x^7 + 4.3320*x^6 - 173.0548*x^5 + 5.1978e+03*x^4 - 1.1363e+05*x^3 + 1.7069e+06*x^2 - 1.5755e+07*x + 6.7369e+07 (This is the output in the terminal, Notice how Coeffs have very high " 10^ ")
%%
%%converting x from sym to double and plotting the above equation versus the original imported data "x1". This is bsically the same as subplot(2,1,2) above.%%
figure(2)
thr = double(subs(Throttle,x,x1));
plot(x1,thr)
%Testing
%----------------------------
y1 = -2.3673e-20*x1.^15 + 2.5403e-17*x1.^14 - 1.2612e-14*x1.^13 + 3.8441e-12*x1.^12 - 8.0455e-10*x1.^11 + 1.2250e-07*x1.^10 - 1.4019e-05*x1.^9 + 0.0012*x1.^8 - 0.0830*x1.^7 + 4.3320*x1.^6 - 173.0548*x1.^5 + 5.1978e+03*x1.^4 - 1.1363e+05*x1.^3 + 1.7069e+06*x1.^2 - 1.5755e+07*x1 + 6.7369e+07;
figure(3)
plot(x1,y1)
%% I literally just copy pasted the Equation from the terminal output and changed ^ to .^ so i can compute it. then i plotted it versus the same original data x1. This time however i got a very weird result. What is wrong?? if i try to use the equation in other applications, i get the results in figure 3. I need the results in Figure 2 though. Are the coeffs wrong? and if so then why Fig2 and subplot(2,1,2) gave a correct output??
%%
Workspace

2 Comments

You forgot to attach your data. I can't run your code to try to fix it until you do.
If you have any more questions, then attach your data and code to read it in with the paperclip icon after you read this:
Code and data are attached now

Sign in to comment.

 Accepted Answer

John D'Errico
John D'Errico on 3 Dec 2022
Edited: John D'Errico on 3 Dec 2022
You don't really need to show anything more than this:
[p,s] = polyfit(x1,y,15);
A degree 15 polynomial. That means the equations will be terribly near to singular. It also means the coefficients will probably vary over many orders of magnitude. Finally, it means that even the TINIEST variation in the value of those coefficients will cause the polynomial to generate complete crap for results. Honestly, I don't even need to see more than the number 15 to know essentially all of that. You CANNOT do this:
y1 = -2.3673e-20*x1.^15 + 2.5403e-17*x1.^14 - 1.2612e-14*x1.^13 + 3.8441e-12*x1.^12 - 8.0455e-10*x1.^11 + 1.2250e-07*x1.^10 - 1.4019e-05*x1.^9 + 0.0012*x1.^8 - 0.0830*x1.^7 + 4.3320*x1.^6 - 173.0548*x1.^5 + 5.1978e+03*x1.^4 - 1.1363e+05*x1.^3 + 1.7069e+06*x1.^2 - 1.5755e+07*x1 + 6.7369e+07;
PERIOD. CRAP will result. You used only 5 significant digits there in each coefficient. GARBAGE. Complete, utter garbage can and probably will result.
Was it an absurdly risky thing, to even try to fit a degree 15 polynomial? Probably, yes. In my opinon, polyfit should have been written to return a warning that the result of such a high degree polynomial should rarely be trusted no matter what. But the problem is, how high a degree will result in crap can vary. I can easily give examples where even cubic polynomials start to show numerical problems. I've seen that happen. Since I don't think you have attached your original data, I can't really go into more depth to show the difference.

6 Comments

You mean 💩💩💩💩💩 🗑️🗑️🗑️🗑️?
Code and data are attached now.
degree of 15 was the only one that showed a close enough fit. I totally understand that the higher the degree of a polynomial, the less accurate the result, but i still don't understand why Figure 2 showed a correct plot. Isn't using the same coeffs to evaluate the function??
@Chaos: The coefficients used to generate the plot in figure 2 (i.e., in the symbolic expression) have higher precision than the 5 significant digits shown on the command line. When you copy and paste those numbers from the command line, you lose that precision and get a totally different result.
The result is so different because of the sensitivity of such a high-degree polynomial, as @John D'Errico states: "even the TINIEST variation in the value of those coefficients will cause the polynomial to generate complete crap for results".
If you were to copy the symbolic expression for Throttle, and use that as its definition (i.e., define and plot Throttle using the coefficients from the command line), you would get a plot that reproduces the plot in figure 3, not figure 2. So the problem is not because of symbolic-to-double conversion; it is because of copying-and-pasting numbers, and losing precision as a result.
The coefficients in the fit object are stored in double precision.
p = pi
p = 3.1416
Even though the coefficient is displayed with only 4 decimal places it is stored with more as you can see if you change the display format.
format longg
p = pi
p =
3.14159265358979
Is p exactly 3.1416 as it was shown in the first code snippet? No.
difference = p - 3.1416
difference =
-7.34641020683213e-06
You may say that the difference between p and 3.1416 is small and negligible. In many circumstances, you'd be right. But when you're raising values to the 15th power and multiplying them by that coefficient, that difference isn't so small or negligible.
f1 = 4^15 * p
f1 =
3373259426.1305
f2 = 4^15 * 3.1416
f2 =
3373267314.2784
difference = f1-f2
difference =
-7888.14789533615
And that's just for x = 4. You were using x values between 40 and 90.
To paraphrase a Jeff Goldblum meme, just because you can fit a 15th degree polynomial to your data doesn't mean you should fit a 15th degree polynomial to your data.
I love the comment by Steve, relayed from Jeff Goldblum.
But let me try to give an example. Suppose we decide to fit a 15th degree polynomial to your data, now that we actually have the data.
x1 = csvread('spdctrl.csv',450,0,[450,0,2050,0]);
y = csvread('spdctrl.csv',450,1,[450,1,2050,1]);
format long g
p15 = polyfit(x1,y,15);
Warning: Polynomial is badly conditioned. Add points with distinct X values, reduce the degree of the polynomial, or try centering and scaling as described in HELP POLYFIT.
p15'
ans = 16×1
-1.45065221676765e-20 1.63006524140676e-17 -8.41439800948396e-15 2.65147978332848e-12 -5.71128765031008e-10 8.91630366587979e-08 -1.0430160584222e-05 0.000931488004816832 -0.0640629065584983 3.39424777162443
Now, look carefully at the warning message. Then look carefully at the coefficients produced. Do you see how many orders of magnitude they vary by? As well, the warning message itself tells you that you should seriously NOT trust this polynomial.
Consider that when x is on the order of 50, what is 50^15?
50^15
ans =
3.0517578125e+25
So even a TINY error in the value of the coefficient of x^15 is then multiplied by a number on the order of 3e25. Now you are adding and subtracting a whole slew of those numbers, each of which is in error. So when you decided to use only 5 digit version of those coefficients, you get GARBAGE as a result.
Honestly, even if you use the actual coefficients, I would not trust that polynomial to compute anything.
Got it know! Thank you for everyone who explained it to me!

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2019a

Asked:

on 3 Dec 2022

Commented:

on 4 Dec 2022

Community Treasure Hunt

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

Start Hunting!