Python Scipy FSOLVE рекурсивная функция - PullRequest
0 голосов
/ 01 февраля 2019

scipy.optimize.fsolve не работает для функции, которая вызывает себя.Вот 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.]

Сравнить

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

Есть ли обходной путь для использования fsolve с такой функцией?Мой вариант использования состоит в том, что у меня есть функция, определенная рекурсивной формулой, для ввода которой вручную потребовалось бы очень много времени n.

1 Ответ

0 голосов
/ 01 февраля 2019

Проблема не в том, что fsolve не может обрабатывать рекурсивные функции, а в том, что ваша рекурсивная функция загрязняет глобальное пространство имен для рекурсии.Добавление простого оператора печати помогает прояснить происходящее.

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.]

Вывод:

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

По сути, решатель должен запустить функцию с разными входами и угадать следующее "лучшее "значение для запуска итеративноС функцией, которая опирается на глобальные переменные, сама ваша функция «состояние» нестабильна, и при первом запуске функции глобальные переменные оказываются затронутыми, и у вашей функции больше нет правильных глобальных переменных для правильного запуска для следующей итерациирешатель.

Вам нужно изменить рекурсивную функцию и сделать ее автономной с явной передачей аргументов.

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) 

Вывод:

2
1
0
2
1
0
2
1
0
2
1
0
2
1
0
2
1
0
[-2.]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...