Scipy提供了几个看似等效的函数,用于在给定的时间间隔内查找函数的根:
brentq(f, a, b[, args, xtol, rtol, maxiter, …]) Find a root of a function in given interval.
brenth(f, a, b[, args, xtol, rtol, maxiter, …]) Find root of f in [a,b].
ridder(f, a, b[, args, xtol, rtol, maxiter, …]) Find a root of a function in an interval.
bisect(f, a, b[, args, xtol, rtol, maxiter, …]) Find root of a function within an interval.
(见this webpage.)
任何人都可以提供一些指导方针来选择其中一个吗?找到适用于我案例的简单试验和错误的最佳策略是什么?
解决方法:
brentq
brentq声称是问题中四个函数中最好的.它的文档读取
Generally considered the best of the rootfinding routines here.
但是,它有(至少)两个恼人的功能:
1)它要求f(a)具有与f(b)不同的符号.
2)如果a是一个非常小的正数(大到1e-3),它偶尔返回0.0作为解决方案 – 即,它返回提交边界之外的解.
brenth
brenth分享brentq的特色1,上面.
里德
ridder分享brentq的功能1,上面.
对分
bisect分享brentq上面的功能1,并且比其他功能慢.
最小化方法
我意识到我可以通过获取函数f输出的绝对值将我的根发现问题转化为最小化问题. (另一种选择是取f的输出的平方.)Scipy提供了几个函数来限制标量函数的最小化:
fminbound(func, x1, x2[, args, xtol, …]) Bounded minimization for scalar functions.
brent(func[, args, brack, tol, full_output, …]) Given a function of one-variable and a possible bracketing interval, return the minimum of the function isolated to a fractional precision of tol.
brute(func, ranges[, args, Ns, full_output, …]) Minimize a function over a given range by brute force.
fminbound
我唯一的抱怨是它很慢.它没有要求f(a)具有与f(b)不同的符号的限制.
黑雁
对于包围间隔[a,b],布伦特要求f(a)小于f(b).其解决方案不能保证在[a,b]范围内.
畜生
brute当然非常慢(取决于Ns参数的值),奇怪的是,可能会返回提交边界之外的解决方案.
结论
总而言之,我使用this answer中的方法获得了最好的结果 – 即,在尚未发布的scipy版本中使用函数least_squares.该功能没有上述限制.