用Newton切线法、Newton下山法、割线法求一元非线性方程的近似解-Python

实验内容

分别用Newton切线法、Newton下山法和割线法求方 x 2 − 2 x − e x + 2 = 0 x^2-2x-e^x+2=0 x22xex+2=0的近似根,其对应函数图像如下图所示。
图1  函数f(x) = x**2 - 2*x - exp(x) + 2 和函数f(x) = 0的图像

算法描述

Newton切线法

迭代公式

x k + 1 = x k − f ( x k ) f ( x k ) x_{k+1}=x_k-\frac{f(x_k)}{f (x_k)} xk+1=xkf(xk)f(xk)

算法流程图

在这里插入图片描述

Newton下山法

x k x_k xk x k + 1 x_{k+1} xk+1之间找一个更好的点 x k + 1 ‾ \overline{x_{k+1}} xk+1使得: ∣ f ( x k + 1 ‾ ) ∣ &lt; ∣ f ( x k ) ∣ |f(\overline{x_{k+1}})|&lt;|f(x_k)| f(xk+1)<f(xk)

迭代公式

x k + 1 = x k − r ⋅ f ( x k ) f ( x k ) x_{k+1}=x_k-r\cdot\frac{f(x_k)}{f (x_k)} xk+1=xkrf(xk)f(xk)

算法流程图

在这里插入图片描述

割线法

迭代公式

x k + 1 = x k − x k − x 0 f ( x k ) − f ( x 0 ) f ( x k ) x_{k+1}=x_k-\frac{x_k-x_0}{f(x_k )-f(x_0 ) } f(x_k ) xk+1=xkf(xk)f(x0)xkx0f(xk)

算法流程图

在这里插入图片描述

实验结果

在这里插入图片描述

Python代码求解

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/10/14 19:59
# @Author  : Guojing Li
# @File    : SolveNonlinearEquation.py
# @Software: PyCharm
"""
Methods of solving non-linear equation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This module includes three Methods of solving my non-linear equation and a plot function.
You can choose a Methods to get the solution of  my non-linear equation.
This is my non-linear equation: x**2 - 2*x - exp(x) + 2 = 0
"""
import math
from matplotlib import pyplot as plt
import numpy as np

def plot_nonlinear_equation():
    """
    绘制函数f(x) = x**2 - 2*x - exp(x) + 2 和函数f(x) = 0的图像
    :return: None
    """
    X = np.arange(-3, 3, 0.01)
    Y = [f(x) for x in X]
    plt.plot(X, Y, linewidth='2', linestyle="-" )
    plt.hlines(0, -3, 3, colors='r')
    plt.xlim(-3, 3)
    plt.ylabel("f(x)")
    plt.xlabel("x")
    plt.legend(["f(x) = x**2 - 2*x - exp(x) + 2 ", "f(x) = 0"])
    plt.show()

def f(x):
    """
    :param x:
    :return: f(x)
    """
    return x**2 - 2*x - math.exp(x) + 2

def df(x):
    """
    :param x:
    :return: f(x)的导数
    """
    return 2*x - 2 - math.exp(x)

def tangent_method(x, ep=1e-05, max_iteration=500):
    """
    牛顿切线法求解非线性方程
    :param x: x初始值
    :param ep: 精度
    :param max_iteration: 最大迭代次数
    :return: 迭代次数, 方程的解
    """
    print("牛顿切线法求解方程,精度为", ep, ",最大迭代次数为", max_iteration)
    print("初始值:x =", x)
    for iteration in range(max_iteration):
        if (df(x) == 0):
            exit("导数为0,迭代失败")
        x1 = x - f(x)/df(x)
        print("第", iteration+1, "次迭代,x =", x1)
        if(math.fabs(x1-x) <= ep):
            return iteration+1, x1
        else:
            x = x1
    exit("以迭代到上限值")

def downhill_method(x, ep=1e-05, max_iteration=500):
    """
    牛顿下山法求解非线性方程
    :param x: x初始值
    :param ep: 精度
    :param max_iteration: 最大迭代次数
    :return: 迭代次数, 方程的解
    """
    print("牛顿下山法求解方程,精度为", ep, ",最大迭代次数为", max_iteration)
    print("初始值:x =", x)
    for iteration in range(max_iteration):
        if (df(x) == 0):
            exit("导数为0,迭代失败")
        r = 1
        x1 = x - r*f(x)/df(x)
        while (math.fabs(f(x1)) > math.fabs(f(x))):
            r = r / 2
            x1 = x - r*f(x)/df(x)
            if (math.fabs(f(x1)) < math.fabs(f(x))):
                print("下山调整后,r = ", r)
        x1 = x - r*f(x)/df(x)
        print("第", iteration + 1, "次迭代,x =", x1)
        if(math.fabs(x1-x) <= ep):
            return iteration+1, x1
        else:
            x = x1
    exit("以迭代到上限值")

def secant_method(x0, x1, ep=1e-05, max_iteration=500):
    """
    割线法求解非线性方程
    :param x0: x0初始值
    :param x1: x1初始值
    :param ep: 精度
    :param max_iteration: 最大迭代次数
    :return: 迭代次数, 方程的解
    """
    print("割线法求解方程,精度为", ep, ",最大迭代次数为", max_iteration)
    print("初始值:x0 =", x0, ", x1 = ", x1)
    for iteration in range(max_iteration):
        if(math.fabs(x1-x0) <= ep):
            return iteration, x1
        else:
            x2 = x1 - f(x1)*(x1-x0)/(f(x1)-f(x0))
            x0 = x1
            x1 = x2
            print("第", iteration+1, "次迭代,x0 =", x0, ", x1 =", x1)
    exit("以迭代到上限值")

if __name__ == "__main__":
    #绘制函数f(x) = x**2 - 2*x - exp(x) + 2 和函数f(x) = 0的图像函数的调用
     plot_nonlinear_equation()
    #牛顿切线法函数的调用
    count, result = tangent_method(1)
    print("共迭代%d次, 方程的解为%.17f" % (count, result))
    #牛顿下山法函数的调用
    count, result = downhill_method(1)
    print("共迭代%d次, 方程的解为%.17f" % (count, result))
    # #割线法函数的调用
    count, result = secant_method(0, 1)
    print("共迭代%d次, 方程的解为%.17f" % (count, result))


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值