Numpy Polynomial class not printing correct coefficients from fit

Viewed 24

As recommended in the numpy documentation, I am trying to move from the old polyfit and polyval functions to the Polynomial class. Below is a minimal example that demonstrates my confusion with this.

import numpy as np

x = np.array([-2.3, -2.8, -2.9, -3.1])
y = np.array([2.4, 3.1, 3.3, 3.5])

poly = np.polynomial.Polynomial.fit(x, y, 1)
print(poly)
print(poly.coef)
print(poly(0))
print(poly(1) - poly(0))

which gives the output, running numpy 1.23.3,

2.9697841726618703 - 0.5611510791366912·x¹
[ 2.96978417 -0.56115108]
-0.8179856115107942
-1.4028776978417268

Judging from the first two lines, the fitted polynomial is something like 2.969 - 0.561x. But evaluating it at x=0 gives -0.817, and evaluating the slope by f(1) - f(0) gives -1.40. The latter is what I would expect given the points that I am fitting, but what's going on with the first two lines of output?

1 Answers

If you check out the documentation you'll see that the polynomial object has two more fields: poly.domain and poly.window. To get better numerical properties the range independent variable of the input to fit() will get renormalized to [-1, 1] (by default at least, this is the poly.window you can set yourself), so the coefficients you get from poly.coef are valid on that renormalized domain. To get back the "original" coefficients you have to undo that normalization, just as I've done in the following snippet. You can also go in the other direction an normalize the x-values yourself which I also included in this snippet:

import matplotlib.pyplot as plt
plt.plot(t, c[0] + c[1]*t)  # line in the normalized domain
#x_normalized = (x - d[0])/(d[1] - d[0]) * 2 - 1  # points in the normalized domain
a = 2/(d[1]-d[0])
b = - 2*d[0]/(d[1]-d[0]) - 1
x_normalized = a*x + b
print('original coefficients')
print(a*c[1], c[1]*b + c[0])
plt.plot(x_normalized, y, 'o')
plt.show()

Related