Избегайте оценки функции с одним и тем же вводом несколько раз

Я пытаюсь использовать scipy.optimise.fsolve для решения функции. Я заметил, что функция оценивается с одним и тем же значением несколько раз в начале и в конце шагов итерации. Например, когда оценивается следующий код:

from scipy.optimize import fsolve

def yy(x):
    print(x)
    return x**2+9*x+20

y = fsolve(yy,22.)

print(y)

Получен следующий вывод:

[ 22.]
[ 22.]
[ 22.]
[ 22.00000033]
[ 8.75471707]
[ 4.34171812]
[ 0.81508685]
[-1.16277103]
[-2.42105811]
[-3.17288066]
[-3.61657372]
[-3.85653348]
[-3.96397335]
[-3.99561793]
[-3.99984826]
[-3.99999934]
[-4.]
[-4.]
[-4.]

Поэтому функция оценивается с 22. три раза, что не нужно.

Это особенно раздражает, когда функция требует значительного времени оценки. Может ли кто-нибудь объяснить это и предложить, как избежать этой проблемы?

2 ответа

Решение

Первая оценка выполняется только для проверки формы и типа данных выходных данных функции. В частности, fsolve звонки _root_hybr который содержит строку

shape, dtype = _check_func('fsolve', 'func', func, x0, args, n, (n,))

Естественно, _check_func вызывает функцию:

res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))

Поскольку из этой оценки сохраняются только форма и тип данных, решатель будет вызывать функцию со значением x0 снова, когда начинается фактический процесс поиска корня.

Вышеуказанный счет для одного постороннего вызова (из двух). Я не отслеживал другой, но вполне возможно, что код FORTRAN выполняет какую-то предварительную проверку самостоятельно. Такого рода вещи случаются, когда алгоритмы, написанные давным-давно, переносятся снова и снова.

Если вы действительно хотите сохранить эти две оценки дорогой функции yy, один из способов - вычислить значение yy(x0) отдельно и сохранить его. Например:

def yy(x):
    if x == x0 and y0 is not None:
       return y0
    print(x)
    return x**2+9*x+20

x0 = 22.
y0 = None
y0 = yy(x0)
y = fsolve(yy, x0)

Я понял, что важной причиной этой проблемы является то, что fsolve не предназначен для такой проблемы: решатели должны выбираться с умом:)

multivariate: fmin, fmin_powell, fmin_cg, fmin_bfgs, fmin_ncg
nonlinear: leastsq
constrained: fmin_l_bfgs_b, fmin_tnc, fmin_cobyla
global: basinhopping, brute, differential_evolution
local: fminbound, brent, golden, bracket
n-dimensional: fsolve
one-dimensional: brenth, ridder, bisect, newton
scalar: fixed_point
Другие вопросы по тегам