1、用改进的EULER方法求解初值问题
# 用改进的EULER方法求解初值问题
import numpy as np
def f(x,y): # 原题目
return x**2 + x - y
def f_1(x): # 准确值方程
return x**2 - x + 1 - np.exp(-x)
def Euler(x_0, y_0, h, f, f_1): # 构造Euler公式
yn = y_0
xn = x_0
for n in range(1, 11):
x = xn + h*n
yp = yn + h*f(xn, yn)
yc = yn + h*f(x, yp)
y = (yp + yc)/2
yn = f_1(x) # 计算准确值
eps = abs(yn - y)
print('迭代次数:', "{0:.0f}".format(n),
'迭代后x值:', "{0:.4f}".format(x),
'迭代后y值:', "{0:.4f}".format(y),
'y的精确值:', "{0:.4f}".format(yn),
'误差:', "{0:.4f}".format(eps))
if x == 0.5:
print('y(0.5)=', "{0:.4f}".format(y))
x_0 = 0
y_0 = 0
h = 0.1
Euler(x_0, y_0, h, f, f_1)
迭代次数: 1 迭代后x值: 0.1000 迭代后y值: 0.0055 y的精确值: 0.0052 误差: 0.0003
迭代次数: 2 迭代后x值: 0.2000 迭代后y值: 0.0167 y的精确值: 0.0213 误差: 0.0046
迭代次数: 3 迭代后x值: 0.3000 迭代后y值: 0.0387 y的精确值: 0.0492 误差: 0.0104
迭代次数: 4 迭代后x值: 0.4000 迭代后y值: 0.0725 y的精确值: 0.0897 误差: 0.0172
迭代次数: 5 迭代后x值: 0.5000 迭代后y值: 0.1187 y的精确值: 0.1435 误差: 0.0248
y(0.5)= 0.1187
迭代次数: 6 迭代后x值: 0.6000 迭代后y值: 0.1778 y的精确值: 0.2112 误差: 0.0333
迭代次数: 7 迭代后x值: 0.7000 迭代后y值: 0.2506 y的精确值: 0.2934 误差: 0.0428
迭代次数: 8 迭代后x值: 0.8000 迭代后y值: 0.3375 y的精确值: 0.3907 误差: 0.0531
迭代次数: 9 迭代后x值: 0.9000 迭代后y值: 0.4391 y的精确值: 0.5034 误差: 0.0644
迭代次数: 10 迭代后x值: 1.0000 迭代后y值: 0.5556 y的精确值: 0.6321 误差: 0.0765
2.用二分法求方程的根
# 1.用二分法求方程x**2-x-1=0的正根,要求误差小于0.05
# 做迭代二分法函数
def devide_two_way(f, a, b, eps):
n = 1
fa = f(a)
fb = f(b)
while True:
if fa*fb > 0:
print("不能用二分法求解!")
break
c=(a+b)/2
fc=f(c)
l=abs(b-a) # 计算区间(a,b)长度
print('二分次数:', "{0:.0f}".format(n),
'c:', "{0:.3f}".format(c),
'a:', "{0:.3f}".format(a),
'b:', "{0:.3f}".format(b),
'区间(a,b)长度:', "{0:.3f}".format(l))
n=n+1
if f(c) == 0:
print('方程的根:', c)
break
elif fa*fc <0:
b=c
fb=fc
else:
a=c
fa=fc
if b-a<eps:
print('最终区间长度:', abs(b-a))
break
return c
# 定义函数f(x)
def f(x):
return x**2-x-1
eps = 0.05 #确定误差范围
# 在(0,2)区间上求根
a=0 # a为左端点
b=2 # b为右端点
x = devide_two_way(f, a, b, eps)
print('方程的根为x=',"{0:.5f}".format(x))
二分次数: 1 c: 1.000 a: 0.000 b: 2.000 区间(a,b)长度: 2.000
二分次数: 2 c: 1.500 a: 1.000 b: 2.000 区间(a,b)长度: 1.000
二分次数: 3 c: 1.750 a: 1.500 b: 2.000 区间(a,b)长度: 0.500
二分次数: 4 c: 1.625 a: 1.500 b: 1.750 区间(a,b)长度: 0.250
二分次数: 5 c: 1.562 a: 1.500 b: 1.625 区间(a,b)长度: 0.125
二分次数: 6 c: 1.594 a: 1.562 b: 1.625 区间(a,b)长度: 0.062
最终区间长度: 0.03125
方程的根为x= 1.59375
3.用newton法求解方程的根
# 用Newton法求x - tanx = 0的最小正根
from sympy import *
# 1.定义原方程
def f(x):
return x - tan(x)
# 2.定义函数求导公式
def sympy_derivative():
x = symbols('x') # 定义符号变量
# 定义表达式内容
Y = f(x)
# 计算 x的导数
return diff(Y, x)
# 3.定义迭代公式
def f_1(x0):
f_1 = sympy_derivative().evalf(subs={'x': x0})
x1 = x0 - f(x0) / f_1
return float(x1)
# 4.控制、修改
def Newton(x0, eps, f_1):
n = 0
while True:
if n < 20:
n = n + 1
x1 = f_1(x0)
if abs(f(x1)) > abs(f(x0)):
print('因为不满足单调性,需要另选初值x0计算')
break
x0 = x1
print('迭代次数:', "{0:.0f}".format(n),
'迭代后的值:', " {0:.4f}".format(x1))
if x1 < eps:
print('迭代最终次数:', "{0:.0f}".format(n),
'牛顿法求得方程的根:', " {0:.4f}".format(x1))
break
x0 = x1
print('迭代次数:', "{0:.0f}".format(n),
'迭代后的值:', " {0:.4f}".format(x1))
else:
break
# 5.调用迭代函数
eps = 0.005 # 设定误差限
x0 = pi/6 # 设定初值
Newton(x0, eps, f_1) # 调用函数进行迭代
迭代次数: 1 迭代后的值: 0.3623
迭代次数: 1 迭代后的值: 0.3623
迭代次数: 2 迭代后的值: 0.2459
迭代次数: 2 迭代后的值: 0.2459
迭代次数: 3 迭代后的值: 0.1652
迭代次数: 3 迭代后的值: 0.1652
迭代次数: 4 迭代后的值: 0.1106
迭代次数: 4 迭代后的值: 0.1106
迭代次数: 5 迭代后的值: 0.0738
迭代次数: 5 迭代后的值: 0.0738
迭代次数: 6 迭代后的值: 0.0493
迭代次数: 6 迭代后的值: 0.0493
迭代次数: 7 迭代后的值: 0.0328
迭代次数: 7 迭代后的值: 0.0328
迭代次数: 8 迭代后的值: 0.0219
迭代次数: 8 迭代后的值: 0.0219
迭代次数: 9 迭代后的值: 0.0146
迭代次数: 9 迭代后的值: 0.0146
迭代次数: 10 迭代后的值: 0.0097
迭代次数: 10 迭代后的值: 0.0097
迭代次数: 11 迭代后的值: 0.0065
迭代次数: 11 迭代后的值: 0.0065
迭代次数: 12 迭代后的值: 0.0043
迭代最终次数: 12 牛顿法求得方程的根: 0.0043
持续更新中!望大家支持,你们的支持是我前进的动力!