纯Python单变量函数求解器
项目描述
pyroots
摘要
一个Python库,实现了单变量函数的各种根查找方法。
目前实现了以下方法
- 二分法。
- Ridders方法。
- Brent方法。
关于Brent方法,有两种实现,第一个使用逆二次外推(Brentq),而另一个使用双曲外推(Brenth)。
如果您不知道使用哪种方法,您可能应该使用Brentq。但话说回来,Bisect方法安全但速度慢(即迭代次数多)。
示例
# define the function whose root you are searching
def f(x, a):
return x ** 2 - a + 1
# Create the Solver object (instead of Brentq you could also import Brenth/Ridder/Bisect)
from pyroots import Brentq
brent = Brentq(epsilon=1e-5)
# solve the function in `[-3, 0]` while `a` is equal to 2
result = brent(f, -3, 0, a=2)
print(result)
将输出
converged : True
message : Solution converged.
iterations : 6
func calls : 9
x0 : -1.0000000748530762
xtol : 0.0000000000000002
f(x0) : 0.0000001497061579
epsilon : 0.0000100000000000
x_steps : [-3, 0, -0.3333333333333333, -1.6666666666666665, -0.7777777777777779, -1.0686868686868687, -0.9917335278385606, -0.9997244260982788, -1.0000000748530762]
fx_steps : [8, -1, -0.8888888888888888, 1.7777777777777772, -0.3950617283950615, 0.14209162330374459, -0.01646460976088293, -0.0005510718624670563, 1.4970615791476405e-07]
理由
pyroots
的功能已经在scipy
中实现,所以自然会问,为什么还要重新发明轮子?
主要原因在于scipy
是一个庞大的依赖。而Pyroots
只是一个简单的包,可以轻松安装,并且可以轻松地与py2exe
或类似的项目捆绑在一起。甚至不需要安装,只需将pyroots
文件夹放入你的项目,你就可以开始使用了。
除此之外,scipy
函数所使用的API并不是非常用户友好。例如,你不能为你的函数使用关键字参数。此外,在scipy
中,没有可靠的方式来定义你希望获得的根的位数精度。例如,你可能要求6位数字,但scipy可能会计算多达14(或12或更多)位数字。这个“故障”的主要影响是,scipy的方法可能会比实际需要的次数更多地进行函数评估。如果函数计算的是一些简单的东西,比如以下示例中的函数,那么这些额外的函数调用并不是什么大问题,但如果你的函数需要花费大量时间来评估,比如超过几秒钟,那么这可能会很快变得令人烦恼,甚至简单到无法接受,比如函数需要几分钟才能返回一个值。
安装
使用pip
pip install pyroots
使用
所有求解器共享相同的API,因此你可以轻松地在各种方法之间切换。
函数
你正在寻找根的函数必须至少接受一个参数并返回一个单一的数字。这个第一个参数也是依赖变量,除此之外,函数还可以接受任意数量的位置/关键字参数。例如,以下函数是完全有效的
def f(x, a):
return x ** 2 - a + 1
def g(x, a, b, c=3):
return x ** 2 + a ** b - c
求解器对象
首先,你需要为你要使用的方法创建一个Solver
对象
from pyroots import Brentq
brent = Brentq()
当你创建Solver
对象时,你可以指定几个会影响收敛性的参数。其中最重要的是
epsilon
指定了在检查收敛性时要考虑的位数数量。默认值为1e-6
。raise_on_fail
如果收敛失败则会引发异常。默认值为True。
使用上述函数定义,为了找到f
的根,你必须首先定义一个包含根的区间。假设这个区间被定义为[xa, xb]
。在这种情况下,你会这样调用求解器
def f(x, a):
return x ** 2 - a + 1
solver = Brentq()
result = solver(f, xa, xb, a=3)
结果对象
所有方法都返回一个具有以下属性的Result
对象
result.x0 # the root
result.fx0 # the value of ``f(x0)`
result.convergence # True/False
result.iterations # the number of iterations
result.func_calls # the number of function evaluations.
result.msg # a descriptive message regarding the convergence (or the failure of convergence)
result.x_steps # a list containing the x values that have been tried while the solver run
result.fx_steps # a list containing the f(x) values that have been calculated while the solver run
如果由于某种原因无法达到收敛,则会引发一个ConvergenceError
。如果你不希望发生这种情况,那么你必须将False
作为raise_on_fail
参数的值。
def f(x):
return x ** 2 - 1
result = brent(f, xa=-10, xb=-5, raise_on_fail=False)
print(result)
API
每个求解器工厂都有以下签名
SolverFactory(epsilon=1e-6, xtol=EPS, max_iter=500, raise_on_fail=True, debug_precision=10)
其中
epsilon
是所需解的精度,即当|f(x0)|
小于epsilon
时,即达到了解。max_iter
是允许的最大迭代次数。raise_on_fail
是一个布尔标志,表示是否在收敛失败时引发异常。默认值为True。
每个求解器对象都有以下签名
solver_object(f, xa, xb, *args, **kwargs)
其中
f
是我们正在寻找根的函数。xa
是我们正在寻找的解区间的下限。xb
是我们正在寻找的解区间的上限。*args
在评估f
时作为位置参数传递。**kwargs
在评估f
时作为关键字参数传递。
文档
目前,文档尚未准备就绪,但README中的示例应该足以让你入门。
pyroots的源代码仓库可以在以下位置找到:https://github.com/pmav99/pyroots
欢迎反馈和贡献。
pmav99 <gmail>
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。
源分布
构建分布
pyroots-0.5.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 76f3c55c20d8c2a88e1baaef912854206a0dd8fbcc2715ee6ed0a646860c2cf0 |
|
MD5 | 07572db3e61d758af27d4fa6fb54d2cb |
|
BLAKE2b-256 | c6f0b08fb6588d1f39af384910eca3029a10d0df73a6fa81f4106e172e4e9274 |
pyroots-0.5.0-py2.py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 830cf8248ee9d4ded2d2da94137f84ff5112b399d2bcf2a48e824e2213a5769f |
|
MD5 | f746e661bcd4582fb5f5b3eece42e300 |
|
BLAKE2b-256 | bc36887abb4891f67ea0cf458f4af80f7aba29fd7df2d2723373a493a3a7152c |