Fitting polynomial curve

eryksun () eryksun at gmail.com
Fri Mar 18 05:42:05 EDT 2011


On 3/17/2011 1:42 AM, Astan Chee wrote:
>
> I have 2 points in 3D space and a bunch of points in-between them. I'm
> trying to fit a polynomial curve on it. Currently I'm looking through
> numpy but I don't think the function exists to fit a function like this:
> y = ax**4 + bx**3 + cx**2 + dx + e

You can use np.polyfit, which uses np.linalg.lstsq. 

For a degree M-1 polynomial and K samples such that K > M, this is an over-determined least squares problem:

t = [t1, t2, ..., tk]   # K sample times
Y.shape == (K, N)       # data samples Y in R_N

# design matrix X
# you don't have to calculate this since polyfit does it
# for you internally with vander(t, M)
X = [[x**m for m in range(M-1,-1,-1)] for x in t]
X.shape == (K, M)

# unknown coefficient matrix B
B.shape == (M, N)  

Y =~ dot(X, B) 

Use polyfit to form the least squares solution. For example, a 4th order fit:

B = np.polyfit(t, Y, 4)

# or for more information
B, r, rankX, sX, rcond = np.polyfit(t, Y, 4, full=True)

where r is the vector of residuals; rankX and sX are the rank and singular values of the Van der Monde matrix; and rcond was used to threshold the singular values.

Interpolation: 

t2 = np.linspace(t[0], t[-1], len(t)*1000)

Y2 = np.dot(np.vander(t2, M), B)
or 
Y2 = np.polyval(B, t2[:, newaxis])

polyval uses Horner's method, which calculates the following:

t = t2[:, newaxis]
y = zeros_like(t)

for i in range(len(B)):
    y = y * t + B[i]
return y

y is initially a length len(t) column vector of zeros and B[0] is a length N row vector, so the first iteration just tiles B[0] in a len(t) by N matrix. Otherwise it's a normal Horner evaluation.

Other than minimizing the residuals, you can examine the fit visually with a simple matplotlib plot:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(*Y2.T)
ax.plot(*Y.T, marker='.', markerfacecolor='r')

Or you could create three 2D plots of (t2, Y2[:,i]) and (t, Y[:,i]).



More information about the Python-list mailing list