二次插值法的python实现
二次插值法的基本思想:用插值函数 p ( x ) p(x) p(x)的极值点 x p ∗ x_p^* xp∗作为单峰区间 [ x 1 , x 3 ] [x_1,x_3] [x1,x3]中的一个新点,通过比较 f ( x p ∗ ) f(x_p^*) f(xp∗)与 f ( x 2 ) f(x_2) f(x2)的大小,确定取舍区间,再反复插值,逐渐缩小区间逼近极值点。
例题
算法流程图
注:图片来源于《优化设计》- 杨挺
import sympy as sp
from sympy import *
# 构造函数表达式并绘图
def get_function_expression(show=True):
x = sp.symbols('x')
f = sp.E**(x+1)-5*(x+1)
figure = plot(f,line_color='red',show=show)
return x,f,figure
x,f,figure = get_function_expression()
def quadratic_interpolaion_method(f,x,a,b,epsilon):
x1 = a
x3 = b
x2 = 0.5*(x1+x3)
f1 = f.subs(x,x1)
f2 = f.subs(x,x2)
f3 = f.subs(x,x3)
C1 = (f3-f1)/(x3-x1)
C2 = ((f2-f1)/(x2-x1)-C1)/(x2-x3)
if C2 == 0: # 说明三个插值节点在一条直线上,输出任意一点即可作为极值点
x_min = x2
f_min = f2
return x_min,f_min
else:
x_min = 0.5*(x1+x3-C1/C2) # 极值点
x4 = x_min
if (x4-x1)*(x3-x4)>0: # 说明x4在x1和x3之间
f4 = f.subs(x,x4)
if abs(x4-x2) <= epsilon: # 说明极值点和插值点之间的距离满足精度要求,可以输出极值点
if f4 < f2:
x_min = x4
f_min = f4
return x_min,f_min
else:
x_min = x2
f_min = f2
return x_min,f_min
else:# 当极值点和插值点之间的距离不满足精度要求时,需要继续迭代
if x4 < x2:
if f2 > f4: # 说明极值点在x1和x2之间
# 把x4作为新的插值点,继续迭代
x3 = x2
f3 = f2
x2 = x4
f2 = f4
# 递归调用
return quadratic_interpolaion_method(f,x,x1,x2,epsilon)
else: # 说明极值点在x4和x3之间
# 让然把x2作为插值点,继续迭代
x1 = x4
f1 = f4
return quadratic_interpolaion_method(f,x,x1,x3,epsilon)
else: # 当x2<x4时,说明极值点在x2和x3之间
if f2 > f4:
x1 = x2
f1 = f2
x2 = x4
f2 = f4
return quadratic_interpolaion_method(f,x,x2,x3,epsilon)
else:
x3 = x4
f3 = f4
return quadratic_interpolaion_method(f,x,x1,x3,epsilon)
else:
x_min = x2
f_min = f2
return x_min,f_min
# 求解例题
x,f,_ = get_function_expression(show=False)
x_min,f_min = quadratic_interpolaion_method(f,x,a=-0.5,b=2.5,epsilon=0.005)
print('极值点为:',x_min)
print('极值点对应的函数值为:',f_min)
极值点为: -0.0589665341387181
极值点对应的函数值为: -2.14253889000847