Python 使用scipy.optimize快速查找函数等于0的第一个点

Python 使用scipy.optimize快速查找函数等于0的第一个点,python,scipy,mathematical-optimization,minimization,Python,Scipy,Mathematical Optimization,Minimization,基本上,给定一个函数,该函数为不同的参数生成如下输出: 我想快速找到函数等于0的第一个x。因此,对于产生x上蓝色曲线的参数,我想找到x=134。对于绿色曲线,我想找到x=56,等等 我认为函数总是单调递减直到它达到零,但我不完全确定 函数不一定是单调递减的 我确信它只会击中0一次,然后保持为0 目前,我通过迭代x值直到达到零来强迫它,但我想要的是能够更好地进行有根据的猜测(基于斜率?)和迭代的东西 理想情况下,我想使用已经烘焙过的东西(),比如来自的东西,但似乎所有人都想找到全局最小值或零交叉

基本上,给定一个函数,该函数为不同的参数生成如下输出:

我想快速找到函数等于0的第一个x。因此,对于产生x上蓝色曲线的参数,我想找到x=134。对于绿色曲线,我想找到x=56,等等

我认为函数总是单调递减直到它达到零,但我不完全确定

函数不一定是单调递减的

我确信它只会击中0一次,然后保持为0

目前,我通过迭代x值直到达到零来强迫它,但我想要的是能够更好地进行有根据的猜测(基于斜率?)和迭代的东西

理想情况下,我想使用已经烘焙过的东西(),比如来自的东西,但似乎所有人都想找到全局最小值或零交叉点


(该函数是在Lch颜色空间中给定色度的RGB立方体的墙与墙之间的距离(因此基本上构建“sanely clip to RGB”函数),但由于IRGB和LCh之间的映射可能因库和光源等参数而异。我认为最好只尝试几个值,直到找到正确的值,而不是尝试直接反向计算值?

如果不是因为曲线的右手在任何地方都是0,牛顿方法()会很有用的。但我认为一种变体仍然可以正常工作:

1) 挑一个要点

2) 如果我们在一个斜坡上,取局部斜坡的坡度,从那里画一条线到x截距,并以此作为你的新点(到1)

3) 如果我们在平坦的平面上(x=0,导数=0),那么如果左边的一位是一个斜率(必须对此进行调整,以确定还剩多少可以检查),那么进行局部搜索(可能是带公差的二进制搜索),以找到函数第一个等于零的点。如果不是,则取该点和我们尝试的坡度上的最后一点之间的中间点(使用此新点转到1)


P< >估计导数(以确定你是否在斜坡上),你可以向左和向右采样一个点,只要足够远,你就确信你能得到导数的光滑近似。

:在间隔的中间检查它是否是0;如果是,则从左侧继续,否则从右侧继续。用缩短的间隔递归地做同样的事情,直到足够接近为止。与您的方法相比,此方法的复杂性为O(logn)。

这里有一些代码来充实@ExP的对分/二进制搜索答案:

def find_first_zero(函数、最小值、最大值、tol=1e-3):
最小值,最大值=浮动(最小值),浮动(最大值)
断言(max+tol)>max
当(最大-最小)>tol时:
中间=(最小+最大)/2
如果func(mid)==0:
最大值=中间值
其他:
最小=中等
返回最大值

函数是否为整数范围(或类似离散)?否则,你怎么可能遍历x值呢?另外,如果你有一个全局最小值算法,而你找不到一个过零算法……你可以总是使用
global\u-minimum(lambda x:abs(foo(x)))
。(当然,我并不是说这是正确的解决方案。)我不认为这些方程可以用微积分来求解。换句话说,你必须使用数值方法来近似?同样,如果我理解正确,假设“我确信它只会击中0一次,然后保持为零”,那么正好有一个点是0和拐点。换句话说,如果你解出f(x)==0和Df(x)==0,这就是你的答案。对吗?(你可以假装没有导数,鲍威尔、内尔德·米德等就是这么做的。)现在我想起来了……如果你只是使用一个股票零点搜索算法,然后在0和它找到的任何东西之间进行二进制搜索,直到你找到第一个非零,这可能足够有效。非常简单,牛顿是行不通的:它是基于梯度的(所以你需要从一开始的某个地方得到它),一旦函数的值达到0,它的梯度就是0。这将导致被0除-->失败。您参考的维基文章还显示了牛顿不起作用的其他情况。@ExP这就是我建议修改牛顿方法的原因。阅读我的答案:)“如果我们在斜坡上”和“如果我们在平原上”不是你在选择一个点后知道的东西,但是,它需要作为一个单独的步骤进行计算,否?@endolith您可以通过在足够远的距离上对左侧和右侧的一个点进行采样来确定它,这样您就可以确信图形在该比例上是平滑的。@Patashu:我的意思是您应该更改方向以详细说明这一点。:)只是澄清一下——函数甚至不需要单调递减。“一次归零,永远归零”意味着您基本上已经有了一个“排序”列表,其中所有的零都在一边,您只是在搜索第一个。