在scipy中有根发现

时间:2015-09-28 00:16:25

标签: python optimization scipy minimize

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。)

任何人都可以提供一些选择其中一个的指导方针吗?找到适用于我的案例的简单试验和错误的最佳策略是什么?

1 个答案:

答案 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。此功能没有上述限制。