interpret result of scipy.interpolate spline fit

2019-08-05 06:02发布

问题:

I have some data points which I like to approximate with a cubic b-spline fit. In an other program, I like to interpolate some points using only the fitted knots and coefficients. This means that I need to write the code to evaluate a point given the knots and coefficients myself. Using this wiki page, I was already able to evaluate various points correctly with the result of

knots,coeff,n=scipy.interpolate.splrep(x,y)

Strangely, I needed to remove the first and last 3 entries in the arrays to get the code to work (note: the first 4 and last 4 knots entries are the same and will therefore produce a division by 0 error). Does somebody know why there are these duplicated entries? Apart from removing those entries, the equation from the wiki page works. From the result

knots=[   15.,    15.,    15.,    15.,    75.,   105., ...,  2895.,  2925., 2985.,  2985.,  2985.,  2985.]
coeffs=[ 1.87979615,  1.54132042,  1.46751212,  1.31223359,  1.34208367,  1.2181689, ..., 0.99327417,0.5866527,   0.,          0.,          0., 0.        ]

I get a good approximation of the data points.

However, when I want to use weights as well, I noticed that the "knots" and "coeff" arrays look every strange. Who knows how I need to interpret the result of the spline fit function? Currently I get

knots=[15.,15.,15.,15.,2985.,2985.,2985.,2985.] 
coeff=[ 1.48725714,0.3513811,0.71970619,0.66119226,0.,0.,0.,0. ]

Or is this even an error?

Ideally, I like to have some code (C/C++,python) which evaluates various points given the knots and coefficients from the function.

回答1:

I think the reason that you have duplicate knots at the beginning and end is because it is forming a clamped spline. This is an option when creating the spline in other numerical languages (such as Scilab). According to Math.stackexchange repeating the knots is the standard way to get a clamped spline that goes through the endpoints with a spline whose initial and end slope approximate the data to the second and next to last points.

The comment above explains how to evaluate the B-spline. However, you can also use interpolate.PPoly (via interpolate.PPoly.from_spline) to convert from a B-spline to a piece-wise polynomial spline that is easy to evaluate, as is well explained in this answer.