非线性方程求根法(python实现)

非线性方程求根

import numpy as np


def bisect(f, a, b, tol):
    """

    :param f: 非线性函数
    :param a: 区间左端点
    :param b: 区间右端点
    :param tol: 误差容忍范围
    :return: 非线性函数在[a,b]上的根
    """
    if np.sign(f(a) * f(b)) >= 0:   # wrong input
        print('f(a)f(b) <0 not satisfied')
        return
    fa = f(a)
    fb = f(b)

    while ((b - a) / 2) > tol:
        c = (a + b)/2
        fc = f(c)
        if fc == 0:                 # c is a solution, done
            return c
        if np.sign(fc * fa) < 0:    # new interval [a, c]
            b = c
            fb = fc
        else:                       # new interval [c, b]
            a = c
            fa = fc
    return (a + b)/2                # new midpoint is best estimate


def fixed_demo(g0, x0, n):
    """

    :param g0: 迭代格式
    :param x0: 初始迭代点
    :param n: 迭代次数
    :return: g(x)的不动点,即非线性方程的根
    """
    x = np.zeros(n+1)
    x[0] = x0

    for i in range(n):
        x[i+1] = g0(x[i])

    return x


def newton_demo(f, f_der, x0, n):
    """

    :param f: 非线性函数
    :param f_der: 非线性函数的导数
    :param x0: 初始迭代点
    :param n: 迭代次数
    :return: 非线性方程的根
    """
    x = np.zeros(n+1)
    x[0] = x0

    for i in range(n):
        x[i+1] = x[i] - (f(x[i]) / f_der(x[i]))

    return x


def fun(x):

    return x**3 + 2 * x**2 + 10 * x - 20
    # return x**2 - 3 * x + 2 - np.exp(x)


def fun_der(x):

    return 3 * x**2 + 4 * x + 10
    # return 2 * x - 3 - np.exp(x)


def g(x):

    # return (np.exp(x) - 2) / (x - 3)
    return 20 / (x**2 + 2 * x + 10)


def demo(g0, f_der, f, n):
    """

    :param g0: 不动点迭代法选取的迭代格式g(x)
    :param f_der: 非线性函数的导数
    :param f: 非线性函数
    :param n: 迭代次数
    :return: NONE
    """
    x_newton = newton_demo(f, f_der, 1.5, n)
    x_fixed = fixed_demo(g0, 1.5, n)
    x_ref = bisect(f, 1, 2, 1.e-14)

    print('Reference Solution: ', x_ref)

    print("Newton iteration method")
    print(' no.     solution    error bound    error')

    for i in range(n):
        print("%3d  %14.12f   %7.2e    %7.2e" %
              (i, x_newton[i], np.abs(x_newton[i+1] - x_newton[i]), np.abs(x_ref - x_newton[i])))

    print("")
    print("Fixed point iteration method")
    print(' no.     solution    error bound    error')

    for i in range(n):
        print("%3d  %14.12f   %7.2e    %7.2e" %
              (i, x_fixed[i], np.abs(x_fixed[i+1] - x_fixed[i]), np.abs(x_ref - x_fixed[i])))

if __name__ == '__main__':
    demo(g, fun_der, fun, 11)

运行结果:

reference solution是通过二分法得到的精度较高的解来代替

 

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值