Polyfit fitting not work on Matlab

13 views (last 30 days)
Hi,
i want to use polyfit in my project and write the following short code.
cooefs = [346.355000, -53.370100, 74.800800, -15.380000];
polyDegree = 5;
cooefs_w_0 = [0, cooefs];
xVals = (0:.01:95)/180*pi;
yVals = polyval(cooefs_w_0(end:-1:1), xVals);
[p,~,mu] = polyfit(yVals, xVals, polyDegree);
p(end) =0;
figure;
hold on;
plot(xVals/pi*180, yVals);
xlabel('Field angle [°]');
ylabel('Radius [px]');
hold all;
plot(polyval(p, yVals/mu(2))/pi*180, yVals,'o');
legend('Original','Fitting');
But the Fitting are not right. Why polyfit not work on Matlab?? Or have I done an misstake in my code?
Right of the Image are my Plot!!
Thanks for all Answer.
  1 Comment
Jan
Jan on 25 Jun 2019
"But the Fitting are not right. Why polyfit not work on Matlab?"
polyfit works exactly as expected. You did not mention, why you assume, that there is a problem. Which result do you expect instead of the one found by Matlab?

Sign in to comment.

Accepted Answer

John D'Errico
John D'Errico on 25 Jun 2019
Edited: John D'Errico on 25 Jun 2019
What is it that you think you are doing? Because this seems a bit strange to me.
cooefs = [346.355000, -53.370100, 74.800800, -15.380000];
polyDegree = 5;
cooefs_w_0 = [0, cooefs];
xVals = (0:.01:95)/180*pi;
yVals = polyval(cooefs_w_0(end:-1:1), xVals);
Ok. So it looks like you have a list of coefficients. You front pad with 0, then you flip the coefficients around to use in polyval. You then evaluate that polynomial at a list of points, going from 0 to 95 degrees, converted to radians. Got it.
[p,~,mu] = polyfit(yVals, xVals, polyDegree);
% p(end) =0; ????????????????????????
Then you did WHAT???????? Is there a reason you expected this to work???? Ok, let me ask, is there a RATIONAL reason you expected it to work? I'm sure you had a reason.
You flipped x and y, and then fit the polynomial as a function x = P(y), where P is a 5th degree polynomial.
Plot your data. What does it look like? Is there any chance you would expect it to work?
plot(xVals/pi*180, yVals);
xlabel('Field angle [°]');
ylabel('Radius [px]');
grid on
So, things are not badly behaved. The curve is pretty smooth. You forced the original polynomial through zero at x==0, by setting the constant coefficient to zero.
The syntax for polyfit, when you do this:
[p,~,mu] = polyfit(yVals, xVals, polyDegree);
does a polynomial fit, where it has centered and scaled the independent variable, that is, it does this:
XHAT = (X-MU(1))/MU(2)
But you need to remember, that you swapped x and y. So it applies that to y. But does what you did make sense? No.
First, you replaced the constant coefficient by zero again, but this time, AFTER the fit. That is NOT how you fit a polynomial with the constant forced to zero. That makes ABSOLUTELY NO SENSE AT ALL. Well, except for nonsense. In fact, as you fit the data, there is no expectation for the fit to have a zero constant term! Your problem is you do not undertand polyfit, or what you did.
[p,~,mu] = polyfit(yVals, xVals, polyDegree)
p =
-0.0010625 0.003935 0.00076123 -0.044631 0.48572 0.86704
mu =
300.23
185.62
So the constant term is VERY different from zero, even though the curve should pass effectively through zero. What does the polynomial predict at y==0? Remember, you swapped x and y, so this poly predicts x(y).
polyval(p,(0 - mu(1))/mu(2))
ans =
0.00011591
polyval(p,0,[],mu)
ans =
0.00011591
See that I did NOT reset the constant term to zero when I did this! If you use polyval correctly, it works.
Ithink what you did, was you think you for some reason, needed to overwrite that constant term. But the constant term in this polynomial is something different.
Let me show what the coefficients of that polynomial are, when I substitute mu into it.
syms Y
vpa(expand(dot(p,((Y - mu(1))/mu(2)).^(5:-1:0))),5)
ans =
- 4.8219e-15*Y^5 + 1.0553e-11*Y^4 - 8.2081e-9*Y^3 + 1.695e-6*Y^2 + 0.0028721*Y + 0.00011591
So that is x(y). At y==0, we should get 0.00011591. Remember that Y has large numbers in it, on the order of 700, so raising those numbers to the 5th power will still be significant, even after we multiply by a coefficient like -4.8e-15. But this is why you had to center and scale the data to fit the polynomial.
Resetting that constant term to 0 does ridiculous things to your polynomial.
Now, let me redo the rest of what you did, without resetting that constant term to zero.
plot(xVals/pi*180, yVals,'r--');
xlabel('Field angle [°]');
ylabel('Radius [px]');
grid on
hold on
plot(polyval(p, (yVals-mu(1))/mu(2))/pi*180, yVals,'g:');
legend('Original','Fitting');
As you should see, the two curves neatly overlay. I used different color and line types there to emphasize that they are so close.
So, yes, polyfit does indeed work properly, but only when you use it properly. When you do something strange, expect strange results.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!