`scipy.optimize.root` ускоряет поиск корня

Я использую scipy.optimize.root с hybr метод (лучший?), чтобы найти корень числовой функции

Я печатаю остаток на каждой итерации

delta d 117.960112417 delta d 117.960112417 delta d 117.960112417 delta d 117.960048733 delta d 117.960112427 delta d 117.960112121 delta d 1.46141491664 delta d 0.0322651167588 delta d 0.000363688881595 delta d 4.05494689256e-08

Как я могу ускорить поиск корня, увеличив размер шага, особенно между первыми итерациями? Я не знаю, как именно работает алгоритм, но выглядит странно, что 3 первых результата одинаковы, и 3 nexts также совершенно идентичны.

Читая документ, я попытался изменить eps фактор, без успеха

РЕДАКТИРОВАТЬ: @sasha, вот очень простая функция, чтобы проиллюстрировать проблему

def f(X1,X2):
    print ' X1 , diff , norm ' , X1 , X2 - X1 , np.linalg.norm(X2 - X1)
    return X2 - X1

Xa = np.array([1000,1000,1000,1000])
Xb = np.array([2000,2000,2000,2000])

SOL = scipy.optimize.root(f,Xa,(Xb,))

В результате мы получим 3 одинаковых итерации в начале, независимо от длины X

 X1 , diff , norm  [1000 1000 1000 1000] [1000 1000 1000 1000] 2000.0
 X1 , diff , norm  [ 1000.  1000.  1000.  1000.] [ 1000.  1000.  1000.  1000.] 2000.0
 X1 , diff , norm  [ 1000.  1000.  1000.  1000.] [ 1000.  1000.  1000.  1000.] 2000.0
 X1 , diff , norm  [ 1000.0000149  1000.         1000.         1000.       ] [  999.9999851  1000.         1000.         1000.       ] 1999.99999255
 X1 , diff , norm  [ 1000.         1000.0000149  1000.         1000.       ] [ 1000.          999.9999851  1000.         1000.       ] 1999.99999255
 X1 , diff , norm  [ 1000.         1000.         1000.0000149  1000.       ] [ 1000.         1000.          999.9999851  1000.       ] 1999.99999255
 X1 , diff , norm  [ 1000.         1000.         1000.         1000.0000149] [ 1000.         1000.         1000.          999.9999851] 1999.99999255
 X1 , diff , norm  [ 2000.  2000.  2000.  2000.] [-0. -0. -0. -0.] 4.36239133705e-09
 X1 , diff , norm  [ 2000.  2000.  2000.  2000.] [ 0.  0.  0.  0.] 0.0  

1 ответ

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

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

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

Конечно, вы можете избежать всей этой работы, предоставив решателю функцию Якобе, которую он может вызвать для оценки якобиана в некоторой точке. Если вы сделаете это, ему не нужно будет делать несколько звонков, чтобы оценить это.

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

http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.optimize.root.html

Другие вопросы по тегам