从节点和系数创建 BSpline [英] Create BSpline from knots and coefficients

查看:47
本文介绍了从节点和系数创建 BSpline的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果只知道点和系数,如何创建样条?我在这里使用 scipy.interpolate.BSpline,但我也对其他标准包开放.所以基本上我希望能够为某人提供那些简短的系数数组,以便他们能够重新创建对数据的拟合.请参阅下面的失败红虚线.

将 numpy 导入为 np导入 matplotlib.pyplot 作为 plt从 scipy.interpolate 导入 BSpline,LSQUnivariateSplinex = np.linspace(0, 10, 50) # x 数据y = np.exp(-(x-5)**2/4) # y 数据# 定义节点位置t = [1, 2, 4, 5, 6, 8, 9]# 获得样条拟合s1 = LSQUnivariateSpline(x, y, t)x2 = np.linspace(0, 10, 200) # 新的 x-gridy2 = s1(x2) # 在新网格上评估样条# 失败:尝试使用节点和系数构建 BSplinek = s1.get_knots()c = s1.get_coeffs()s2 = BSpline(t,c,2)# 绘图plt.plot(x, y, label='original')plt.plot(t, s1(t),'o', label='knots')plt.plot(x2, y2, '--', label='spline 1')plt.plot(x2, s2(x2), 'r:', label='spline 2')plt.legend()

解决方案

等效地,kn = 4*[x[0]] + t + 4*[x[-1]] 会起作用:您的 t 列表仅包含内部结,所以 x[0]x[-1] 相加,然后每个重复 k 次.

重复的数学原因是 B 样条需要一些空间来构建,因为它们的 归纳定义,它要求 (k-1) 度样条存在于我们定义 k<的每个区间周围/code>th 度样条.

How can a spline be created if only the points and the coefficients are known? I'm using scipy.interpolate.BSpline here, but am open to other standard packages as well. So basically I want to be able to give someone just those short arrays of coefficients for them to be able to recreate the fit to the data. See the failed red-dashed curve below.

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import BSpline, LSQUnivariateSpline

x = np.linspace(0, 10, 50) # x-data
y = np.exp(-(x-5)**2/4)    # y-data

# define the knot positions

t = [1, 2, 4, 5, 6, 8, 9]

# get spline fit

s1 = LSQUnivariateSpline(x, y, t)

x2 = np.linspace(0, 10, 200) # new x-grid
y2 = s1(x2) # evaluate spline on that new grid

# FAILED: try to construct BSpline using the knots and coefficients

k = s1.get_knots()
c = s1.get_coeffs()
s2 = BSpline(t,c,2)

# plotting

plt.plot(x, y, label='original')
plt.plot(t, s1(t),'o', label='knots')
plt.plot(x2, y2, '--', label='spline 1')
plt.plot(x2, s2(x2), 'r:', label='spline 2') 
plt.legend()

解决方案

The fine print under get_knots says:

Internally, the knot vector contains 2*k additional boundary knots.

That means, to get a usable knot array from get_knots, one should add k copies of the left boundary knot at the beginning of array, and k copies of the right boundary knot at the end. Here k is the degree of the spline, which is usually 3 (you asked for LSQUnivariateSpline of default degree, so that's 3). So:

kn = s1.get_knots()
kn = 3*[kn[0]] + list(kn) + 3*[kn[-1]]
c = s1.get_coeffs()
s2 = BSpline(kn, c, 3)    # not "2" as in your sample; we are working with a cubic spline 

Now, the spline s2 is the same as s1:

Equivalently, kn = 4*[x[0]] + t + 4*[x[-1]] would work: your t list contains only interior knots, so x[0] and x[-1] are added, and then each repeated k times more.

The mathematical reason for the repetition is that B-splines need some room to get built, due to their inductive definition which requires (k-1)-degree splines to exist around every interval in which we define the kth degree spline.

这篇关于从节点和系数创建 BSpline的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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