python一元函数求根详解

news/2024/11/30 12:25:37/

文章目录

    • root_scalar
    • 参数差异
    • 测试

root_scalar

scipy.optimize提供了统一的一元函数求根方法,其函数定义为

scipy.optimize.root_scalar(f, args=(), method=None, bracket=None, fprime=None, fprime2=None, x0=None, x1=None, xtol=None, rtol=None, maxiter=None, options=None)

其中,f是待求根的函数,args为除了待求的自变量之外的其他函数。bracket为函数的两个异号端点,x0x1为可能用到的根的估计值。

xtol, rtol与精度有关,越小越精,maxiter为最大迭代次数。

其中,method为最关键的参数,用来决定root_scalar采用的求根方法,其中一部分方法在optimize中实现了独立的函数,下表列出了这些方法的对应关系

参数估计参数独立方法备注
'bisect'bracket'bisect'二分求根
'brentq'bracket'brentq'brent方法
'brenth'bracket'brenth'brent方法+双曲外推
'ridder'bracket'ridder'ridder方法
'toms748'bracket'toms748'我也不知道什么方法
'newton'x0'newton'牛顿法
'secant'x0, x1-弦截法
'halley'x0-三阶方法

root_scalar的返回值是一个RootResults对象,里面的.root属性,即为所求的根。

具有独立函数的求根算法,参数与root_scalar大同小异,以bisect为例,其参数为

  • bisect(f, a, b, args=(), xtol=2e-12, rtol=8.881784197001252e-16, maxiter=100, full_output=False, disp=True)

其中,args, xtol, rtol, maxiter, full_output, disp为所有求根算法函数共有的参数,除此之外,求根函数的参数列表如下

  • toms748(f, a, b, k=1)
  • bisect(f, a, b)
  • brentq(f, a, b)
  • brenth(f, a, b)
  • ridder(f, a, b)
  • newton(func, x0, fprime=None, fprime2=None, x1=None)

其中,(a,b)相当于root_scalar中的bracket,其他参数与root_scalar中含义相同。

参数差异

之所以会有(a,b)或是x0这种参数差别,可从二分法和牛顿法的原理来一窥一二。

二分法是最简单的求根算法,如果已知 f ( a ) ⋅ f ( b ) < 0 f(a)\cdot f(b)<0 f(a)f(b)<0,则快速选取 c = a + b 2 c=\frac{a+b}{2} c=2a+b,如果 f ( a ) ⋅ f ( c ) < 0 f(a)\cdot f(c)<0 f(a)f(c)<0,则说明根在 ( a , c ) (a,c) (a,c)之间,否则即说明根在 ( a , b ) (a,b) (a,b)之间,然后不断迭代下去。为了完成二分法,则必须输入一对(a,b)

牛顿法则利用了导数,其迭代公式可表示为

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)

为了执行牛顿法,则必须给一个初始的 x 0 x_0 x0

测试

下面随便写一个函数,来测试这些求根方法

import scipy.optimize as sodef func(x):return x*x - 2so.bisect(func, 0, 2)
# 1.4142135623715149
so.newton(func, 0)
# 1.4142135623715149

这两种方法可以写成等价的root_scalar的形式

so.root_scalar(func, bracket=(0,2), method='bisect')
'''返回值converged: Trueflag: 'converged'function_calls: 42iterations: 40root: 1.4142135623715149
'''

由于root_scalar返回了迭代次数,故而可用这个函数,测试一下不同方法的运算效率。

method=['bisect', 'brentq', 'brenth', 'ridder', 'toms748', 'secant']
bk = (0,2)
x0, x1 = 0, 2res = []
for m in method:print(m)res.append(so.root_scalar(func, method=m, bracket=bk, x0=x0, x1=x1))for r,m in zip(res, method):print(m, r.iterations, r.root**2-2)

最后结果如下

bisect 40 -4.469535852535955e-12
brentq 8 1.1723955140041653e-13
brenth 8 3.9968028886505635e-15
ridder 6 -2.8170799026838722e-12
toms748 5 -4.440892098500626e-16
secant 7 -4.440892098500626e-16

效率最低的是二分法,效率最高的是toms748


http://www.ppmy.cn/news/64351.html

相关文章

Java——二叉搜索树中第k小的元素

题目链接 leetcode在线oj题——二叉搜索树中第k小的元素 题目描述 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 个最小元素&#xff08;从 1 开始计数&#xff09;。 题目示例 示例1 输入&#xff1a;root [3,1…

普罗米修斯统计信息上报结构设计

为了实现高效的监控和警报&#xff0c;普罗米修斯提供了一个强大的统计信息上报机制。通过这个机制&#xff0c;可以将应用程序的各种统计信息发送到普罗米修斯&#xff0c;普罗米修斯会对这些信息进行处理&#xff0c;然后提供丰富的监控和警报功能。下面是基本的统计信息上报…

Mysql索引+事务+存储引擎

索引 索引的概念 索引是一个排序的列表&#xff0c;在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址&#xff08;类似于C语言的链表通过指针指向数据记录的内存地址&#xff09;。 使用索引后可以不用扫描全表来定位某行的数据&#xff0c;而是先通过索引表找…

磁盘空间不足怎么办?释放磁盘空间的4种方法

虽然现在硬盘的空间越来越大&#xff0c;但是在这个数据爆炸的时代中&#xff0c;总是会觉得存储空间不够用&#xff0c;一不注意磁盘就满了&#xff0c;那么除了清空回收站、卸载某些程序外&#xff0c;还能怎么释放磁盘空间呢&#xff1f; 方案一&#xff1a;禁用休眠 休眠是…

文件系统 fdatasync fsync sync 详解

一、Buffer和Cache简介 数据写入内存空间&#xff0c;这段空间就是缓冲区buffer&#xff0c;写入缓冲区 把数据从内存空间读出&#xff0c;这段空间就是缓存器cache&#xff0c;读取缓存区 1、 cache Cache&#xff1a;缓存区&#xff0c;是高速缓存&#xff0c;是位于CPU和主…

InnoDB和MySAM有什么区别?

首先&#xff0c;MySAM和InnoDB都是mysql里面的两个存储引擎&#xff0c;mysql5.5版本之前的存储引擎默认是MySAM&#xff0c;mysql5.5版本以后的存储引擎默认是InnoDB,它们底层数据结构都是基于B树的。 Mylsam存储引擎&#xff1a; Mylsam索引是非聚簇索引&#xff0c;Mylsa…

企业如何利用网络趋势做好线上营销?

随着互联网的不断发展&#xff0c;线上营销越来越成为企业营销的重要组成部分。如何利用网络趋势做好线上营销&#xff0c;已经成为各大企业关注的焦点。本文将为大家介绍如何利用网络趋势做好线上营销的方法和技巧。 一、了解网络趋势 了解网络趋势是做好线上营销的关键。网络…

Cocos Creator 3.7.3 正式上线,渲染管线和算法持续更新

Cocos Creator 3.7.3 正式发布。该版本对近日用户反馈的一系列关键性问题进行了集中修复&#xff0c;也对一部分性能进行了优化&#xff0c;提升了用户体验&#xff0c;建议所有 v3.x 用户升级。 Engine Features Render Graph 自定义渲染管线支持 GLES 后端Deprecate addRast…