Scipy提供了几个看似等效的函数,用于在给定的时间间隔内查找函数的根:
brentq(f,a,b [,args,xtol,rtol,maxiter,...])在给定的时间间隔内查找函数的根。
brenth(f,a,b [,args,xtol,rtol,maxiter,...])在[a,b]中找到f的根。
ridder(f,a,b [,args,xtol,rtol,maxiter,...])在区间中查找函数的根。
bisect(f,a,b [,args,xtol,rtol,maxiter,...])查找区间内函数的根。
(见this webpage。)
任何人都可以提供一些选择其中一个的指导方针吗?找到适用于我的案例的简单试验和错误的最佳策略是什么?
答案 0 :(得分:2)
brentq
brentq
声称是问题中四个函数中最好的。其文档字符串为
通常认为这里是最好的根寻找例程。
但是,它至少有两个恼人的功能:
1)要求f(a)
的标志与f(b)
不同。
2)如果a
是一个非常小的正数(与1e-3
一样大),它偶尔会返回0.0
作为解决方案 - 即,它会在提交之外返回一个解决方案界限。
brenth
brenth
分享brentq
上面的功能1。
ridder
ridder
分享brentq
上面的功能1。
bisect
bisect
分享brentq
上面的功能1,并且比其他功能慢。
我意识到我可以通过获取函数f
的输出的绝对值来将我的根发现问题转化为最小化问题。 (另一种选择是取f
输出的平方。)Scipy提供了几个函数来限制标量函数的最小化:
fminbound(func,x1,x2 [,args,xtol,...])标量函数的有界最小化。
brent(func [,args,brack,tol,full_output,...])给定一个变量的函数和一个可能的包围间隔,将孤立的函数的最小值返回到tol的小数精度。
brute(func,ranges [,args,Ns,full_output,...])通过暴力将给定范围内的函数最小化。
fminbound
我唯一的抱怨是它很慢。它没有要求f(a)
具有与f(b)
不同的符号的限制。
brent
对于包围间隔[a, b]
,brent
要求f(a)
小于f(b)
。其解决方案不能保证在[a, b]
范围内。
brute
brute
当然非常慢(取决于Ns
参数的值),奇怪的是,可能会返回提交边界之外的解决方案。
所有这一切,我使用this answer中的方法获得了最佳结果 - 即在尚未发布的scipy版本中使用函数least_squares
。此功能没有上述限制。