对如下函数表建立三次样条插值函数 x 1 2 3 f(x) 2 4 2 f’(x) 1 -1,并提供完整的python代码
时间: 2024-02-13 16:05:44 浏览: 120
三次样条插值代码.rar
以下是Python代码实现:
```python
import numpy as np
from scipy.linalg import solve_banded
# 确定已知数据点
x = np.array([1, 2, 3])
f = np.array([2, 4, 2])
fd = np.array([1, -1])
# 计算每个小区间的长度
h = np.diff(x)
# 计算每个小区间的一次导数值
A = np.zeros((3, 3))
A[0, 0] = 1
A[1, 0] = h[0]
A[1, 1] = 2 * (h[0] + h[1])
A[1, 2] = h[1]
A[2, 1] = 1
b = np.zeros(3)
b[1] = 3 * ((f[2] - f[1]) / h[1] - (f[1] - f[0]) / h[0])
fd = solve_banded((1, 1), A, b)
# 计算每个小区间的系数
a = f[:-1]
b = fd[:-1]
c = (3 * (f[1:] - f[:-1]) / h - 2 * fd[:-1] - fd[1:]) / h
d = (fd[:-1] + fd[1:] - 2 * (f[1:] - f[:-1]) / h) / h ** 2
# 构造三次样条插值函数
def S(x):
i = np.searchsorted(x, x[:-1])
i = np.concatenate(([0], i, [len(x) - 1]))
return np.piecewise(x, [x < x[i[1]], x >= x[i[-2]]],
[lambda x: a[0] + b[0] * (x - x[0]) + c[0] * (x - x[0]) ** 2 + d[0] * (x - x[0]) ** 3,
lambda x: a[-1] + b[-1] * (x - x[-2]) + c[-1] * (x - x[-2]) ** 2 + d[-1] * (x - x[-2]) ** 3,
lambda x, i=i: a[i[1:-1]] + b[i[1:-1]] * (x - x[i[1:-1]]) + c[i[1:-1]] * (x - x[i[1:-1]]) ** 2 + d[i[1:-1]] * (x - x[i[1:-1]]) ** 3])
# 测试
import matplotlib.pyplot as plt
xx = np.linspace(1, 3, 100)
yy = S(xx)
plt.plot(xx, yy)
plt.scatter(x, f)
plt.show()
```
其中,使用了 `numpy` 和 `scipy.linalg` 库来完成计算。
最终的三次样条插值函数 `S(x)` 可以接受一个数组 `x` 作为输入,并返回对应的插值结果。在测试部分,我们使用 `matplotlib` 库将插值结果可视化出来,以便直观地观察插值效果。
阅读全文