scipy.interpolate.InterpolatedUnivariateSpline.get_coeffs返回什么? [英] What does scipy.interpolate.InterpolatedUnivariateSpline.get_coeffs return?

查看:280
本文介绍了scipy.interpolate.InterpolatedUnivariateSpline.get_coeffs返回什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了以下操作:

spline= interpolate.InterpolatedUnivariateSpline(X, Y, k=3)
coefs= spline.get_coeffs()

XY的每一个中都有五个值,最后我得到了coefs 五个值.假设有五个数据点意味着四个样条曲线部分,并且 三次多项式有四个系数,我本来希望得到 四乘四= 16个系数.有谁知道如何解释get_coeffs方法返回的值?有记录在哪里?

With five values in each of X and Y, I ended up with coefs also having five values. Given that five data points implies four spline sections, and that a cubic polynomial has four coefficients, I would have expected to get four times four= 16 coefficients. Does anyone know how to interpret the values that are returned by the get_coeffs method? Is there any place where this is documented?

推荐答案

这些不是x,x ** 2等的系数:此类单项式不适合表示样条曲线.相反,它们是 B样条的系数,这些系数是针对其上的特定网格计算的插值完成.所涉及的B样条曲线的数量等于数据点的数量,系数的数量也等于.例如,假设我们要对这些数据进行插值:

These are not the coefficients of x, x**2, and so forth: such monomials are ill-suited to representing splines. Rather, they are coefficients of B-splines which are computed for the specific grid on which interpolation is done. The number of B-splines involved is equal to the number of data points, and so is the number of coefficients. As an example, suppose we want to interpolate these data:

xv = [0, 1, 2, 3, 4, 5]
yv = [3, 6, 5, 7, 9, 1]

以k = 1(分段线性样条曲线)的简单情况开始.那么B样条就是这些三角帽"功能:

Begin with the simpler case of degree k=1 (piecewise linear spline). Then the B-splines are these "triangular hat" functions:

其中有6个.它们每个在其"网格点均等于1,在所有其他网格点均等于0.这使得编写插值样条线非常容易:它是y[0]*b[0] + ... + y[5]*b[5].确实,get_coeffs显示系数是y值本身.

There are 6 of them. Each of them is equal to 1 at "its" grid point, and 0 at all other grid points. This makes it really easy to write the interpolating spline: it is y[0]*b[0] + ... + y[5]*b[5]. And indeed, get_coeffs shows the coefficients are the the y-values themselves.

InterpolatedUnivariateSpline(xv, yv, k=1).get_coeffs()  # [ 3.,  6.,  5.,  7.,  9.,  1.]

三次样条线

现在它变得毛茸茸了,因为我们需要光滑的帽子",而不是上面那些尖的帽子.平滑度要求迫使它们更宽,因此每个B样条在几个网格点上都具有非零值. (技术性:三次B样条曲线的最大零结点为非零值,但在下图上的1和4,尽管是网格点,但由于所谓的非结点"情况而并非结点. .这是网格的B样条线:

Cubic splines

Now it gets hairy, because we need "hats" that are smooth, rather than pointy as those above. The smoothness requirement forces them to be wider, so each B-spline has nonzero values on several grid points. (Technicality: a cubic B-spline has nonzero values at up to 3 knots, but on the chart below, 1 and 4, despite being grid points, are not knots due to so-called "not a knot" condition. Never mind this.) Here are the B-splines for our grid:

要得到这些,我使用了scipy.interpolate的旧方法splrepsplev,它们在后台调用了相同的fitpack例程.这里的系数向量是元组tck的第二项;我将其修改为一个1,其余0,从而创建基础样条线(b-spline).

To get these, I used older methods splrep and splev of scipy.interpolate, which call the same fitpack routines under the hood. The coefficient vector here is the second entry of the tuple tck; I modify it to have one 1 and the rest 0, thus creating a basis spline (b-spline).

k = 3
tck = splrep(xv, yv, s=0, k=k)
xx = np.linspace(min(xv), max(xv), 500)
bsplines = []
for j in range(len(xv)):
    tck_mod = (tck[0], np.arange(len(xv)+2*k-2) == j, k)
    bsplines.append(splev(xx, tck_mod))
    plt.plot(xx, bsplines[-1])

现在我们有了列表bsplines,我们可以使用get_coeffs返回的系数将它们自身放在一起作为插值样条线:

Now that we have a list bsplines, we can use the coefficients returned by get_coeffs to put them together ourselves into an interpolating spline:

coeffs = InterpolatedUnivariateSpline(xv, yv, k=3).get_coeffs()
interp_spline = sum([coeff*bspline for coeff, bspline in zip(coeffs, bsplines)])
plt.plot(xx, interp_spline)

如果您想要这些B样条曲线的公式,请在

If you want a formula for the pieces of these B-splines, the Cox-de Boor recursion formula on B-splines can help but these are a chore to compute by hand.

SymPy可以为B样条曲线提供公式,但有一点扭曲.应该通过重复

SymPy can give formulas for B-splines, but there is a little twist. One should pass in a padded set of knots, by repeating the end values like

[0, 0, 0, 0, 2, 3, 5, 5, 5, 5]

这是因为,在0和5时,所有四个系数都改变值,而在1和4时,它们都不改变,因此将它们省略(不是一个结"). (此外,SymPy(1.1.1)的当前版本存在重复打结的问题,但在下一版本中将解决此问题.)

This is because at 0 and 5 all four coefficients change values, while at 1 and 4 none of them do, so they are omitted ("not a knot"). (Also, the current version of SymPy (1.1.1) has an issue with repeated knots, but this will be fixed in the next version.)

from sympy import symbols, bspline_basis_set, plot
x = symbols('x')
xv_padded = [0, 0, 0, 0, 2, 3, 5, 5, 5, 5] 
bs = bspline_basis_set(3, xv_padded, x)

现在bs是一个看起来很可怕的分段公式的数组:

Now bs is an array of scary-looking piecewise formulas:

[Piecewise((-x**3/8 + 3*x**2/4 - 3*x/2 + 1, (x >= 0) & (x <= 2)), (0, True)), 
Piecewise((19*x**3/72 - 5*x**2/4 + 3*x/2, (x >= 0) & (x <= 2)), (-x**3/9 + x**2 - 3*x + 3, (x >= 2) & (x <= 3)), (0, True)), 
Piecewise((-31*x**3/180 + x**2/2, (x >= 0) & (x <= 2)), (11*x**3/45 - 2*x**2 + 5*x - 10/3, (x >= 2) & (x <= 3)), (-x**3/30 + x**2/2 - 5*x/2 + 25/6, (x >= 3) & (x <= 5)), (0, True)), 
Piecewise((x**3/30, (x >= 0) & (x <= 2)), (-11*x**3/45 + 5*x**2/3 - 10*x/3 + 20/9, (x >= 2) & (x <= 3)), (31*x**3/180 - 25*x**2/12 + 95*x/12 - 325/36, (x >= 3) & (x <= 5)), (0, True)), 
Piecewise((x**3/9 - 2*x**2/3 + 4*x/3 - 8/9, (x >= 2) & (x <= 3)), (-19*x**3/72 + 65*x**2/24 - 211*x/24 + 665/72, (x >= 3) & (x <= 5)), (0, True)), 
Piecewise((x**3/8 - 9*x**2/8 + 27*x/8 - 27/8, (x >= 3) & (x <= 5)), (0, True))]

这篇关于scipy.interpolate.InterpolatedUnivariateSpline.get_coeffs返回什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆