Выполнение одного шага ODE

Можно ли сделать один шаг с интегратором scipy ODE? Мне известен аргумент step для scipy.integrate.ode.integrate, но я не могу понять, как установить аргумент t таким образом, чтобы он гарантированно выполнял ровно один полный шаг. Очевидный выбор — t=inf, но это приводит к ошибке ODE::

from scipy.integrate import ode
obj = ode(lambda t, y: -y)
obj.set_initial_value(1)
y_new = obj.integrate(inf, step=True)

-

 DVODE--  At T (=R1) and step size H (=R2), the    
       corrector convergence failed repeatedly     
       or with abs(H) = HMIN   
      In above,  R1 =  0.0000000000000D+00   R2 =             Infinity
C:\Anaconda3\lib\site-packages\scipy\integrate\_ode.py:869: UserWarning: 
vode: Repeated convergence failures. (Perhaps bad Jacobian supplied or 
wrong choice of MF or tolerances.)
  'Unexpected istate=%s' % istate))

Если я использую t=0, то ОДУ вообще не продвигается. Я могу выбрать конечное положительное число, но гарантируется ли это полным шагом и перешагиванием t, если t меньше полного шага? Я пишу общую библиотеку и не знаю, какой будет типичный размер шага.


person drhagen    schedule 24.04.2016    source источник


Ответы (2)


Я провел несколько тестов и убедился, что установка step=True и t, равная любому положительному конечному числу, займет ровно один шаг. Он перейдет через t, если t меньше следующего шага.

from scipy.integrate import ode
obj = ode(lambda t, y: -y)
obj.set_initial_value(1)
while obj.t < 1:
    y_new = obj.integrate(1, step=True)
print(obj.t) # prints 1.037070648009345

Следует отметить, что адаптивный размер шага угадывает начальный размер шага на основе определенной доли t. Выбор меньшего t приводит к меньшему первому шагу. Вот почему inf терпит неудачу и почему нет значения t, которое заставит интегратор перешагнуть через t на первом шаге.

person drhagen    schedule 26.04.2016

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

Функция (объект callable), которую вы передаете в качестве аргумента set_solout(), будет вызываться на каждом шаге интегрирования.

person Cyb3rFly3r    schedule 24.04.2016
comment
Я не ищу фиксированный шаг. Но даже у решателей с переменным шагом есть шаги (функция, переданная set_selout, вызывается каждый раз после каждого). Я попытаюсь вернуть -1 из функции seout, чтобы сделать то, что я хочу. - person drhagen; 25.04.2016
comment
Да, это был смысл моего ответа: set_selout это то, что вы, вероятно, хотели, но ваш вопрос был о выполнении одного шага с интегратором. - person Cyb3rFly3r; 25.04.2016
comment
Численные интеграторы на самом деле не рассчитаны на фиксированные шаги — это зависит от метода. Явный Runge-Kutta, например, использует фиксированный размер шага . - person dkv; 19.04.2017