Интегрируйте жесткие ODE с Python
Я ищу хорошую библиотеку, которая будет интегрировать жесткие ODE в Python. Проблема в том, что scipy odeint иногда дает мне хорошие решения, но малейшее изменение начальных условий заставляет его упасть и сдаться. Эта же проблема решается довольно успешно с помощью жестких решателей MATLAB (ode15s и ode23s), но я не могу ее использовать (даже из Python, потому что ни одно из связок Python для API MATLAB C не реализует обратные вызовы, и мне нужно передать функцию к решателю ODE). Я пытаюсь PyGSL, но это ужасно сложно. Любые предложения были бы с благодарностью.
EDIT: Конкретная проблема, с которой я столкнулась с PyGSL, заключается в выборе функции правого шага. Есть несколько из них, но нет прямых аналогов ode15s или ode23s (формула bdf и модифицированный Rosenbrock, если это имеет смысл). Итак, что такое хорошая функция для выбора жесткой системы? Я должен решить эту систему в течение очень долгого времени, чтобы убедиться, что она достигает стационарного состояния, а решатели GSL либо выбирают минимальный временной шаг, либо слишком большой.
Ответы
Ответ 1
Python может называть C. Промышленный стандарт LSODE в ODEPACK. Это общедоступный. Вы можете скачать версию C. Эти решатели чрезвычайно сложны, поэтому лучше всего использовать некоторые проверенные коды.
Добавлено: убедитесь, что у вас действительно жесткая система, т.е. если скорости (собственные значения) отличаются более чем на 2 или 3 порядка. Кроме того, если система жесткая, но вы ищете только стационарное решение, эти решатели дают вам возможность решать некоторые уравнения алгебраически. В противном случае хороший рейндж Runge-Kutta, такой как DVERK, будет хорошим и гораздо более простым решением.
Добавлен здесь, потому что он не вписывается в комментарий: это из документа DLSODE doc:
C T :INOUT Value of the independent variable. On return it
C will be the current value of t (normally TOUT).
C
C TOUT :IN Next point where output is desired (.NE. T).
Кроме того, да, кинетика Михаэлиса-Ментена нелинейна. Однако ускорение Aitken работает с ним. (Если вы хотите короткое объяснение, сначала рассмотрим простой случай, когда Y - скаляр. Вы запустите систему, чтобы получить 3 Y (T) точки. Нарисуйте через них экспоненциальную кривую (простую алгебру). Затем положим Y на асимптоту и Теперь просто обобщаем, что Y является вектором. Предположим, что 3 точки находятся в плоскости - это нормально, если это не так.) Кроме того, если у вас нет принудительной функции (такой как постоянная капельница IV), устранение ММ будет распадаться и система будет приближаться к линейности. Надеюсь, что это поможет.
Ответ 2
Если вы можете решить свою проблему с помощью Matlab ode15s
, вы сможете решить ее с помощью решения vode
scipy. Чтобы имитировать ode15s
, я использую следующие настройки:
ode15s = scipy.integrate.ode(f)
ode15s.set_integrator('vode', method='bdf', order=15, nsteps=3000)
ode15s.set_initial_value(u0, t0)
а затем вы можете с радостью решить свою проблему с помощью ode15s.integrate(t_final)
. Это должно работать очень хорошо по жесткой проблеме.
(См. также http://www.scipy.org/NumPy_for_Matlab_Users)
Ответ 3
PyDSTool обертывает решение Radau, которое является отличным неявным жестким интегратором. У этого есть больше настройки, чем odeint, но намного меньше, чем PyGSL. Наибольшее преимущество заключается в том, что ваша функция RHS указана как строка (как правило, хотя вы можете создать систему с использованием символических манипуляций) и преобразуется в C, поэтому нет медленных обратных вызовов python, и все это будет очень быстро.
Ответ 4
В настоящее время я изучаю немного ODE и его решателей, поэтому ваш вопрос очень интересен мне...
Из того, что я слышал и читал, для жестких проблем правильный путь - выбрать неявный метод как функцию шага (исправьте меня, если я ошибаюсь, я все еще изучаю misteries реверсоров ODE). Я не могу ссылаться на вас, где я читал это, потому что я не помню, но вот thread из gsl-help, где аналогичный вопрос был спросил.
Итак, короче говоря, кажется, что метод bsimp
стоит сделать снимок, хотя для него требуется функция jacobian. Если вы не можете рассчитать якобиан, я попробую с помощью rk2imp
, rk4imp
или любого из методов передачи.