Python 尝试建立反函数
*如果你在胡吉做介绍,要小心。。。 我知道你为什么来这里* 我试图构建一个函数,它以一个函数(假设单调的连续性)作为参数,并返回它的反函数。 从数学上我知道我需要将函数反映到Python 尝试建立反函数,python,algorithm,math,Python,Algorithm,Math,*如果你在胡吉做介绍,要小心。。。 我知道你为什么来这里* 我试图构建一个函数,它以一个函数(假设单调的连续性)作为参数,并返回它的反函数。 从数学上我知道我需要将函数反映到y=x。 但这并不顺利 我写了一些东西,它将给我x0,使f(x0)=0 def solve(f, x0=-10000, x1=10000, epsilon=EPSILON): """return the solution to f in the range between x0 and x1""" while x1-x0&
y=x
。
但这并不顺利
我写了一些东西,它将给我x0
,使f(x0)=0
def solve(f, x0=-10000, x1=10000, epsilon=EPSILON):
"""return the solution to f in the range between x0 and x1"""
while x1-x0>EPSILON:
if (f(x0)*f((x1+x0)/2))<0:
x1=((x1+x0)/2)
elif (f(x0)*f((x1+x0)/2))>0:
x0=((x1+x0)/2)
elif (f(x0)*f(x1))==0:
if f(x0)==0:
return x0
else:
return x1
if f(x0)*f(x1)<0:
return (x1+x0)/2
else:
return None
我建议先进行小范围的研究,而不是指数级的扩展。如果使用[-1,1]、-2,2]、-4,4]等范围,即使在最坏的情况下,开销也会保持不变。没有代数表达式
y=f(x)
dx=0.0001 // or dx=function(|f(x0),f(x0+0.0001)|)
if (|f(x0-dx)-y|<|f(x0+dx)-y|) dx=-dx;
无法知道实际的x
或y
间隔
如您所述,您只需要连续和单调的间隔
因此,如果你不知道,你可以尝试寻找极值点(一阶导数与零交叉的地方),通过一些搜索,动态步长取决于导数值(线性或对数),但总有丢失一些小凸起的风险。如果创建这些点的列表,则它们之间的间隔应该是单调的。在此之后,如果x=g(y)
是函数,则可以使用二进制搜索。如果存在小凸起,则更好
对于无约束单调函数y=f(x)
dx=0.0001 // or dx=function(|f(x0),f(x0+0.0001)|)
if (|f(x0-dx)-y|<|f(x0+dx)-y|) dx=-dx;
您可以将近似搜索从上面的链接更改为以下内容:
x0=0
如果没有更多关于g,f
的信息,我们将无能为力。如果x0=0
不是选项,请使用任何其他安全值dx
dx=0.0001 // or dx=function(|f(x0),f(x0+0.0001)|)
if (|f(x0-dx)-y|<|f(x0+dx)-y|) dx=-dx;
在最近的比赛中停下来。如果需要动态步骤,则还需添加dx=函数(| f(x0),f(x0+0.0001)|)
内部循环
dx=0.0001 // or dx=function(|f(x0),f(x0+0.0001)|)
if (|f(x0-dx)-y|<|f(x0+dx)-y|) dx=-dx;
所以你们可以按原样从上面的链接使用二进制近似搜索x0
常数我刚刚发布了一个python包,它正好做到了这一点,并且必须经历许多警告。您可能想从中借用一些想法: 它基本上遵循这一战略:
- 在有限间隔的情况下,点参考点为间隔的1/4和3/4
- 在无限的时间间隔内,任何两个值都能起作用
- 如果f(ref1)
- 如果提供了值,则使用这些值
- 在闭合区间中,只需计算f(a)和f(b),其中a和b是区间的端点
- 在开放区间中,尝试计算f(a)和f(b),如果这有效,则使用它们,否则将假定为(-Inf,Inf)
- 有界f(x):
- 如果x低于间隔,且f增加,则返回-Inf
- 如果x低于间隔,且f减小,则返回+Inf
- 如果x大于间隔,且f增加,则返回+Inf
- 如果x大于间隔,且f减小,则返回-Inf
- 否则返回f(x)
Brent
方法最小化(有界的_f(x)-y0)**2,找到有界的_f(x)-y0的根,通过将ref1、ref2设置为括号,确保最小化算法从原始间隔内的一个点开始。一旦if超出允许的区间,bounded_f返回无穷大,迫使算法返回到区间内搜索多次执行相同的函数调用是低效的;Python不会为您优化这些。你可以从维基百科上的文章中获得一些改进代码的想法。FWIW,要进行函数反演,你可以使用牛顿法,或是与之密切相关的方法。对于括号内的更快的方法,使用regula-falsi-假位置法,并进行伊利诺伊州反失速修正。它比二分法快得多,只比相关的割线法慢一点。嗨,Spektre!我按照你的要求做了,把它写下来,并更新成问题。谢谢。