数值分析之牛顿拉夫森迭代(牛顿法)
程序员文章站
2022-06-07 09:47:04
...
@数值分析之非线性方程求解
文章目录
一、牛顿拉夫森迭代
当f(x),f’(x),f’’(x)在根p附近连续,则可将它作为f(x)的特性,用于开发产生收敛到根p的序列{Pk}的算法。该方法相较二分法、试值法,产生序列{Pk}的速度快。
牛顿拉夫森法 依赖于f’(x),f’’(x)的连续性,简称牛顿法,是这类方法中已知最有用和最好用的方法之一。
1.1 牛顿拉夫森法
1.1.1 牛顿-拉夫森定理:
注意:如果不想使用导数,可以使用割线法。割线法采用了试值法中斜率的不同表示来得到c的过程,来代替f’(pk)。
即:f’(pk) = (f(pk) - f(pk-1))/(pk - pk-1)
1.1.2 matlab版算法:
二、题目及实现代码
2.1 题目
在考虑空气阻力情况下,求解投射体撞击地面时经过的时间和水平飞行行程,其中方程为(y为高度):
y=f(t)=9600*(1-e**(-t/15.0)) - 480t;
x=r(t)=2400(1-e**(-t/15.0))。
2.2 输入输出格式
【输入形式】输入3个数,分别表示起始值、前后两次迭代的差的绝对值精度和f(t)函数值的精度。各数间都以一个空格分隔。
【输出形式】第一行输出投射体撞击地面时经过的时间,第二行输出水平飞行行程,精确到小数点后5位。
2.3 样例
输入
8 1 1
输出
9.08955
1090.69211
2.4 思路和要点
思路:先对y函数求出时间t,再带入x函数得水平距离。
2.5 代码
import numpy as np
def f(t):
return 9600*(1-np.e**(-t/15)) - 480*t
def r(t):
return 2400*(1-np.e**(-t/15))
def f_der(t):
return 640*np.e**(-t/15) - 480
def main():
n = np.array(input().split(),dtype = np.float)
p0 = n[0]
delta = 10**(-int(n[1]))
epsilon =10**(-int(n[2]))
while True:
p = p0 - f(p0)/f_der(p0)
err = abs(p - p0)
relerr = 2*err/(abs(p)+delta)
p0 = p
if err<delta or relerr<delta or abs(f(p0))<epsilon:
break
print("%.5f"%p0)
print("%.5f"%r(p0))
if __name__ =='__main__':
main()
2.6 结果
样例: