Как использовать события в scipy.integrate.solve_ivp - PullRequest
0 голосов
/ 05 сентября 2018

Я не уверен, что обработка событий в scipy.integrate.solve_ivp работает правильно. В приведенном ниже примере я интегрировал производную, которая должна привести к кубическому полиному с тремя корнями в точках x = -6, x = -2 и x = 2. Я установил функцию события, которая возвращает y, которая будет равна нулю при этих значениях x. Я ожидал увидеть три записи в атрибуте t_events решения, но вижу только одну, хотя ясно, что решение пересекает ось X три раза.

Я что-то здесь не так делаю?

Пример кода воспроизведения:

def fprime(x, y):
    return 3 * x**2 + 12 * x - 4

def event(x, y):
    return y

import numpy as np
from scipy.integrate import solve_ivp
sol = solve_ivp(fprime, (-8, 4), np.array([-120]), t_eval=np.linspace(-8, 4, 10), events=[event])

Приведенный выше код приводит к:

message: 'The solver successfully reached the interval end.'
      nfev: 26
      njev: 0
       nlu: 0
       sol: None
    status: 0
   success: True
         t: array([-8.        , -6.66666667, -5.33333333, -4.        , -2.66666667,
        -1.33333333,  0.        ,  1.33333333,  2.66666667,  4.        ])
  t_events: [array([-6.])]
         y: array([[-120.        ,  -26.96296296,   16.2962963 ,   24.        ,
           10.37037037,  -10.37037037,  -24.        ,  -16.2962963 ,
           26.96296296,  120.        ]])

`` `

Проблема в том, что из массива sol.y видно, что должно быть три нуля (есть три изменения знака), но записывается только одно событие.

Информация о версии Scipy / Numpy / Python:

1.0.0 1.13.3 sys.version_info(major=3, minor=6, micro=0, releaselevel='final', serial=0)

[ОБНОВЛЕНИЕ]: если я использую необязательный аргумент max_step для solve_ivp и сделаю его достаточно маленьким, тогда я вижу все три корня. Кажется, что функции событий вызываются не на шагах t_eval, а скорее только на внутренних шагах решателя, которые намного меньше шагов t_eval и которые в конечном итоге пропускают некоторые корни. Это не кажется очень полезным, так как вы должны знать, как установить max_steps, чтобы избежать пропущенных корней.

1 Ответ

0 голосов
/ 05 сентября 2018

функции событий вызываются не на шагах t_eval, а только на внутренних шагах решателя

Это правильно. После того, как новая (t, y) пара найдена , из них вычисляются события и передаются в find_active_events, которые будут сравнивать знаки событий-функций с предыдущим шагом.

t_eval вообще не используется при вычислении события, оно рассматривается позже . Таким образом, изменения знака, которые видят события, это те, которые вы видите в выходных данных с t_eval=None, из которых только один.

y: array([[-120.        , -110.49687882,  -35.93785936,   94.46893375,
     120.        ]]) 

Кажется, стоит поднять проблему на трекере SciPy; есть несколько открытых вопросов относительно solve_ivp, который все еще довольно новый.

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