2017-04-17 151 views
3

我生成一个三次样条曲线,通过一组给定的数据点的获得三次样条公式:的Python/SciPy的:如何从CubicSpline

import matplotlib.pyplot as plt 
import numpy as np 
import scipy 

x = np.array([1, 2, 4, 5]) # sort data points by increasing x value 
y = np.array([2, 1, 4, 3]) 
arr = np.arange(np.amin(x), np.amax(x), 0.01) 
s = interpolate.CubicSpline(x, y) 
plt.plot(x, y, 'bo', label='Data Point') 
plt.plot(arr, s(arr), 'r-', label='Cubic Spline') 
plt.legend() 
plt.show() 

我怎样才能从CubicSpline样条曲线的方程?我需要以下形式的公式:

我试图通过各种方法来获取系数,但它们都使用通过使用除数据点以外的其他数据获得的数据。

回答

2

the documentation

Ç(ndarray,形状(4,N-1,...))对每个分段多项式的系数。尾部尺寸匹配y, 的轴除外。例如,如果y是1-d,则c[k, i](x-x[i])**(3-k)的 系数,其在x[i]和之间的段上。

在你的例子

因此,对于第一区段的系数[X ,X ]将第0列:

  • ý将是s.c[3, 0]
  • bs.c[2, 0]
  • Çs.c[1, 0]
  • ds.c[0, 0]

然后,对于第二分段[X ,X ]你将不得不s.c[3, 1]s.c[2, 1]s.c[1, 1]s.c[0, 1]ýbcd等,等等。

例如:

x = np.array([1, 2, 4, 5]) # sort data points by increasing x value 
y = np.array([2, 1, 4, 3]) 
arr = np.arange(np.amin(x), np.amax(x), 0.01) 
s = interpolate.CubicSpline(x, y) 

fig, ax = plt.subplots(1, 1) 
ax.hold(True) 
ax.plot(x, y, 'bo', label='Data Point') 
ax.plot(arr, s(arr), 'k-', label='Cubic Spline', lw=1) 

for i in range(x.shape[0] - 1): 
    segment_x = np.linspace(x[i], x[i + 1], 100) 
    # A (4, 100) array, where the rows contain (x-x[i])**3, (x-x[i])**2 etc. 
    exp_x = (segment_x - x[i])[None, :] ** np.arange(4)[::-1, None] 
    # Sum over the rows of exp_x weighted by coefficients in the ith column of s.c 
    segment_y = s.c[:, i].dot(exp_x) 
    ax.plot(segment_x, segment_y, label='Segment {}'.format(i), ls='--', lw=3) 

ax.legend() 
plt.show() 

enter image description here

1

编辑:由于系数可作为属性访问(请参阅@ ali_m的答案),此处显示的方法不必要地间接。如果有人使用一个更加不透明的图书馆,我会在网上离开。

一种方法是在感兴趣的节点来评价:

coeffs = [s(2)] + [s.derivative(i)(2)/misc.factorial(i) for i in range(1,4)] 
s(2.5) 
# -> array(1.59375) 
sum(coeffs[i]*(2.5-2)**i for i in range(4)) 
# -> 1.59375 

严格地说高阶导数的节点不存在,但出现SciPy的返回权片面的衍生物,所以它的工作原理即使它不应该。

+0

我试着用样品及系数的答案运行,这是不正确的。 – jshapy8

+0

@ jshapy8你会友善地分享这个样本吗?在你发布的样本上,它似乎工作得很好。 –

+0

在我发布的样本上,S_1的系数应该如下:[1,2](-13/8),0,(5/8)在[1,2] – jshapy8