Python/SciPy: 如何从 CubicSpline 得到三次样条方程
Python/SciPy: How to get cubic spline equations from CubicSpline
我正在通过一组给定的数据点生成三次样条曲线图:
import matplotlib.pyplot as plt
import numpy as np
from scipy import interpolate
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
得到样条方程?我需要以下形式的方程式:
我尝试了各种方法来获取系数,但它们都使用了使用不同数据获得的数据,而不仅仅是数据点。
编辑:由于系数可作为属性访问(请参阅@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 似乎是 return 右单边导数,所以即使它不应该也有效。
c (ndarray, shape (4, n-1, ...)) Coefficients of the polynomials on each segment. The trailing dimensions match the dimensions of y
,
excluding axis. For example, if y
is 1-d, then c[k, i]
is a
coefficient for (x-x[i])**(3-k)
on the segment between x[i]
and
x[i+1]
.
所以在你的例子中,第一段的系数 [x1, x2] 将在第 0 列中:
- y1 将是
s.c[3, 0]
- b1 将是
s.c[2, 0]
- c1 将是
s.c[1, 0]
- d1 将是
s.c[0, 0]
.
然后对于第二段 [x2, x3] 你会s.c[3, 1]
、s.c[2, 1]
、s.c[1, 1]
和 s.c[0, 1]
for y2、b2,c2,d2,依此类推。
例如:
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()
我正在通过一组给定的数据点生成三次样条曲线图:
import matplotlib.pyplot as plt
import numpy as np
from scipy import interpolate
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
得到样条方程?我需要以下形式的方程式:
我尝试了各种方法来获取系数,但它们都使用了使用不同数据获得的数据,而不仅仅是数据点。
编辑:由于系数可作为属性访问(请参阅@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 似乎是 return 右单边导数,所以即使它不应该也有效。
c (ndarray, shape (4, n-1, ...)) Coefficients of the polynomials on each segment. The trailing dimensions match the dimensions of
y
, excluding axis. For example, ify
is 1-d, thenc[k, i]
is a coefficient for(x-x[i])**(3-k)
on the segment betweenx[i]
andx[i+1]
.
所以在你的例子中,第一段的系数 [x1, x2] 将在第 0 列中:
- y1 将是
s.c[3, 0]
- b1 将是
s.c[2, 0]
- c1 将是
s.c[1, 0]
- d1 将是
s.c[0, 0]
.
然后对于第二段 [x2, x3] 你会s.c[3, 1]
、s.c[2, 1]
、s.c[1, 1]
和 s.c[0, 1]
for y2、b2,c2,d2,依此类推。
例如:
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()