三次样条+线性插值
来源:互联网 发布:facebook程序员面试题 编辑:程序博客网 时间:2024/05/16 00:52
三次样条插值是要解决,在模拟函数的时候,插值节点处不平滑的问题
S(x)是f(x) (x0 .... xn)的三次样条插值函数,则S(x)要在区间(xj,xj+1)上满足S(xj-0) = S(xj+1+0) , S'(xj-0) = S'(xj+1 + 0), s''(xj - 0) = S''(xj+1 +0),
这样在每一个这样的区间建立一个等式条件,同时在两个端点出处得到两个确定值
(S'(x0) = f'(x0),S'(xn) = f'(xn) ,S''(x0) = f''(x0) S''(xn) = f''(xn))
通过上述的等式可以得出S(x)的最终形式
因为S(x)是三次的,导数两次之后就是线性的,在两点之间可以求出两次导数后的S''(x)在往回积分得到下面的式子
S(x) = Mj*(xj+1 - x)^3/(6*hj) + Mj+1(x - xj)^3/(6 * hj) + (yj - Mj*hj^2/6)*(xj+1 - x)/hj+(yj+1 - Mj+1 * hj^2)*(x - xj)/hj j = 0,1,......n-1
hj 就是 xj+1 - xj,现在就是需要求 Mj (Mj是S''(xj)的值)
由求得的S(x)导数一次 + S'(xj-0) = S'(xj+1+0) 可以得到
uj * Mj-1 + 2Mj +lj * Mj+1 = dj
uj = hj-1/(hj-1 + hj) lj = 1 - uj
S(x)是f(x) (x0 .... xn)的三次样条插值函数,则S(x)要在区间(xj,xj+1)上满足S(xj-0) = S(xj+1+0) , S'(xj-0) = S'(xj+1 + 0), s''(xj - 0) = S''(xj+1 +0),
这样在每一个这样的区间建立一个等式条件,同时在两个端点出处得到两个确定值
(S'(x0) = f'(x0),S'(xn) = f'(xn) ,S''(x0) = f''(x0) S''(xn) = f''(xn))
通过上述的等式可以得出S(x)的最终形式
因为S(x)是三次的,导数两次之后就是线性的,在两点之间可以求出两次导数后的S''(x)在往回积分得到下面的式子
S(x) = Mj*(xj+1 - x)^3/(6*hj) + Mj+1(x - xj)^3/(6 * hj) + (yj - Mj*hj^2/6)*(xj+1 - x)/hj+(yj+1 - Mj+1 * hj^2)*(x - xj)/hj j = 0,1,......n-1
hj 就是 xj+1 - xj,现在就是需要求 Mj (Mj是S''(xj)的值)
由求得的S(x)导数一次 + S'(xj-0) = S'(xj+1+0) 可以得到
uj * Mj-1 + 2Mj +lj * Mj+1 = dj
uj = hj-1/(hj-1 + hj) lj = 1 - uj
dj = 6f[xj-1,xj,xj+1]均差
其中 d0 = 6/h0 * (f[x0,x1] - f'(x0)) dn = 6/hn-1 * (f'(xn) - f[xn-1,xn])
可以根据这些写出矩阵
2 l0
u1 2 l1 *M = d[i =0 ....n]
u2 2 l2
.....
un 2
这样可以得到M了,其他需要的也可以计算了.
画图的时候用到了matplotlib
import scipy.interpolate as itpimport matplotlib.pyplot as pltimport numpy as np''''线性插值'''def line_insert(xn,yn): def line(x): for value in range(len(xn)-1): if xn[value] <= x <= xn[value+1]: result1 = ((x-xn[value+1])/(xn[value] - xn[value+1]))*yn[value] result2 = ((x-xn[value])/(xn[value+1] - xn[value]))*yn[value+1] return result1+result2 return line这个是线性插值,返回一个直接计算的函数
接下来是实现的三次样条的茬插值
'''三次样条'''last_trax = []#均差 求d的时候def sub_spl(x,y): if len(x) == 2: return (y[1] -y[0])/(x[1] - x[0]) return (sub_spl(x[1:],y[1:]) - sub_spl(x[:len(x)-1],y[:len(y) - 1]))/(x[len(x) - 1] - x[0])def three_spline_trax(tup_x,tup_y,s0,sn): trax = [] h = [] for i in range(len(tup_x) - 1): h.append(tup_x[i+1] - tup_x[i]) d = [0 for i in range(len(tup_x))] d[0] = 6/h[0] * (sub_spl(tup_x[:2],tup_y[:2]) - s0) d [-1] = 6/h[-1] * (sn - sub_spl(tup_x[-2:],tup_y[-2:])) u = [0 for i in range(len(tup_x)-1)] for j in range(1,len(tup_x) - 1): d[j] = 6 * sub_spl(tup_x[j-1:j+2],tup_y[j-1:j+2]) u[j] = h[j-1]/(h[j-1] + h[j]) l = [1-i for i in u] u.append(1) #un = 1 for i in range(len(tup_x)): trax.append([0 for j in range(len(tup_x))]) trax[i][i] = 2 for i in range(len(tup_x) - 1): trax[i][i+1] = l[i] trax[i+1][i] = u[i+1] trax[i].append(d[i]) trax[-1].append(d[-1]) return trax,h#对得到的矩阵简化上三角def return_trax(trax,m,n,num): if num is 1: last_trax.append(trax[n-1][n-1:]) return else: #寻找主元 Max = abs(trax[0][0]) t1 = 0 for i in range(1,m): if abs(trax[i][0]) > Max: Max = trax[i][0] t1 = i trax[0],trax[t1] = trax[t1],trax[0] tmp2 = [] last_trax.append(trax[0]) for i in range(1,n): #倍数 tmp = -trax[i][0]/trax[0][0] def cal(tup): return tup[0] + tup[1] * tmp tmp2.append(map(cal,zip(trax[i][1:],trax[0][1:]))) trax = tmp2 return return_trax(trax,m-1,n-1,num-1)def s_um(tup): return reduce(lambda x,y:x*y,tup)#这个函数得到M0 - Mndef calculate(trax,m): #倒着循环 l = [0 for i in range(m)] for i in range(m-1,-1,-1): if i == m-1: #直接求出最后一个参数的数值 l[i] = trax[i][m-i]/trax[i][0] else: tmp3 = trax[i][m-i] tmp3 -= sum(map(s_um,zip(l[i:],trax[i][:m-i]))) l[i] = tmp3/trax[i][0] return ldef res(l,tup_x1,tup_y1,h): def outcome(x): for j in range(len(tup_x1) - 1): if tup_x1[j] <= x <= tup_x1[j+1]: sum_func = l[j]*(tup_x1[j+1] - x)**3/(6*h[j]) + l[j+1]*(x - tup_x1[j])**3/(6*h[j])+(tup_y1[j] - l[j]/6*h[j]**2)*(tup_x1[j+1] - x)/h[j] + (tup_y1[j+1]-l[j+1]/6*h[j]**2)*(x - tup_x1[j])/h[j] return sum_func return outcome在计算矩阵的乘法的时候,直接用上次的列主元消去....
最后的res函数就是在构造S(x)
three_line_trax 就是返回上面写的那个带2的矩阵,h就是相邻x的插值
最后再用return_trax返回上三角矩阵,calculate计算就可以
可能中间有些地方说的不准确,如果发现请指正
阅读全文
0 0
- 三次样条+线性插值
- 三次样条曲线
- 三次样条曲线
- 三次样条曲线拟合
- 三次样条差值
- 三次样条曲线
- 三次样条函数插值法
- VBA 三次样条 代码
- 线性插值
- 线性插值
- 线性插值
- 三次样条函数的定积分
- 三次样条函数插值
- 三次样条拟合典型实例
- 三次样条差值-matlab通用程序
- 如何绘制三次B样条曲线
- 三次B样条曲线拟合算法
- 【图像缩放篇之三】三次线性插值和MipMap链
- 趣解什么叫“网关”?
- Java基础
- linux面试常问命令
- VUI参数语义,色彩原色图表,高宽比标示符含义图表
- JS内外部函数调用关系
- 三次样条+线性插值
- 类对象
- Spring面向切面编程AOP
- 14面向对象模型初探
- 【Linux】IPC通信之消息队列
- java获取键盘输入
- jQuery 二级联动(客户端、栏目)
- 2.安装--以及简单使用(二)
- 列车调度(Train)