数值分析python实现(改进的Euler公式,二分法,牛顿法)

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

持续更新中!望大家支持,你们的支持是我前进的动力!

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值