简体   繁体   English

python scipy fsolve递归函数

[英]python scipy fsolve recursive function

scipy.optimize.fsolve does not appear to work for a function that calls itself. scipy.optimize.fsolve似乎不适用于调用自身的函数。 Here is a MWE 这是MWE

from scipy.optimize import fsolve
def f(x):
    if f.n==0:
        return x
    f.n -= 1
    return 1+f(x)
# Consider n=2 i.e. f(x) = 1 + 1 + x = 2 + x
f.n=2
soln = fsolve(f, -1.5) # Expect [-2]
print(soln) # [0.]

Compare 相比

def g(x):
    return 1 + 1 + x
soln = fsolve(g, -1.5)
print(soln) # [-2.]

Is there a workaround for using fsolve with such a function? 是否有将fsolve与此类功能一起使用的解决方法? My use case is that I have a function defined by a recursive formula that would take very long time to type out by hand for large n . 我的用例是,我有一个由递归公式定义的函数,对于大的n ,需要花费很长时间才能手动输入。

The problem is not that fsolve isn't able to handle recursive functions, but the issue is that your recursive function is polluting the global namespace for recursion. 问题不在于fsolve无法处理递归函数,而是问题在于您的递归函数正在污染全局名称空间以进行递归。 Adding a simple print statement helps make it clearer what is going on. 添加简单的打印语句有助于使事情更清楚。

from scipy.optimize import fsolve
def f(x):
    print(f.n)
    if f.n==0:
        return x
    f.n -= 1
    return 1+f(x)
# Consider n=2 i.e. f(x) = 1 + 1 + x = 2 + x
f.n=2
soln = fsolve(f, -1.5) # Expect [-2]
print(soln) # [0.]

Output: 输出:

2
1
0
0
0
0
0
0
[0.]

A solver essentially has to run the function with different inputs and guess the next "best" value to run for iteratively. 求解器本质上必须使用不同的输入来运行函数,并猜测要迭代运行的下一个“最佳”值。 With a function that relies on global variables, your function "state" itself is unstable and the first time a function is run, the global variables get affected, and your function no longer have the correct global variables to run correctly for the next iteration of the solver. 使用依赖于全局变量的函数,您的函数“状态”本身就不稳定,并且第一次运行该函数时,全局变量会受到影响,并且您的函数不再具有正确的全局变量才能在下一次迭代时正确运行解算器。

You need to modify your recursive function and make it self-contained with explicit argument passing. 您需要修改递归函数,并通过显式参数传递使其独立。

from scipy.optimize import fsolve
def f(x, state):
    print(state)
    if state==0:
        return x
    state -= 1
    return 1+f(x, state)
# Consider n=2 i.e. f(x) = 1 + 1 + x = 2 + x
state=2
soln = fsolve(lambda x: f(x, state), -1.5) #wrapping the 2 arg recursive function with a lambda to mimic a 1 argument function. You may also use functools.partial for this.
print(soln) 

Output: 输出:

2
1
0
2
1
0
2
1
0
2
1
0
2
1
0
2
1
0
[-2.]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM