2010-01-18 2 views
16

Я ищу хорошую библиотеку, которая будет интегрировать жесткие ODE в Python. Проблема в том, что odeint scipy дает мне хорошие решения иногда, но малейшее изменение начальных условий заставляет его падать и сдаваться. Эта же проблема решается довольно успешно с помощью жестких решателей MATLAB (ode15s и ode23s), но я не могу ее использовать (даже с Python, потому что ни одна из привязок Python для API MATLAB C не реализует обратные вызовы, и мне нужно передать функцию к решателю ODE). Я пытаюсь PyGSL, но это ужасно сложно. Любые предложения будут ценны.Интегрируйте жесткие ODE с Python

EDIT: Конкретная проблема, с которой я столкнулась с PyGSL, заключается в выборе правильной функции шага. Есть несколько из них, но нет прямых аналогов ode15s или ode23s (формула bdf и модифицированный Rosenbrock, если это имеет смысл). Итак, что такое хорошая функция для выбора жесткой системы? Я должен решить эту систему на очень долгое время, чтобы убедиться, что она достигнет устойчивого состояния, и решатели GSL либо выбирают минимальный временной шаг, либо слишком большой.

+0

Я хотел бы помочь вам с PyGSL. Я никогда не использовал его, но у меня есть опыт работы с GSL. Я просто посмотрел на пример, представленный в pygsl (odeiv.py), и он выглядит примерно так же, как и в C. Считаете ли вы, что PyGSL ужасно сложна из-за интерфейса python или GSL как такового? – YuppieNetworking

+0

Ну, ужасно сложно, возможно, преувеличение :). Это на порядок сложнее, чем MATLAB или scipy. Чтобы уточнить, интерфейс python почти такой же, как интерфейс C, поэтому сама библиотека является сложной. Кроме того, PyGSL не документирует odeiv, поэтому я должен использовать документы C, чтобы выяснить, что делать в Python. Не весело. –

+0

Отредактировал вопрос. –

ответ

11

Python может звонить C. Стандарт LSODE в ODEPACK. Это общедоступный. Вы можете скачать C version. Эти решатели чрезвычайно сложны, поэтому лучше всего использовать некоторые проверенные коды.

Добавлено: Убедитесь, что у вас действительно жесткая система, т. Е. Если скорости (собственные значения) отличаются более чем на 2 или 3 порядка. Кроме того, если система жесткая, но вы ищете только стационарное решение, эти решатели дают вам возможность решать некоторые уравнения алгебраически. В противном случае хороший рейндж Runge-Kutta, такой как DVERK, станет хорошим и гораздо более простым решением.

Добавлен здесь, потому что не будет вписываться в комментариях: Это из док заголовка DLSODE:

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), ликвидация ММ будет распадаться и система будет приближаться к линейности. Надеюсь, это поможет.

+0

Спасибо за наконечник LSODE. Я обнаружил, что кто-то уже написал интерфейс Python для него по адресу http://www.cs.uiuc.edu/homes/mrgates2/ode/. Попробуй это завтра и примите свой ответ, если он сработает. –

+0

@Chinmay: Бинго! Надеюсь, это сработает для вас. –

+0

Я знаю, что у меня действительно есть жесткая система, но, глядя на источники LSODE, я понял, что у меня есть возможная ошибка в моей программе. Решатель scipy.integrate.odeint основан на LSODA и, как и все решатели LS *, принимает вектор временных точек, на которых вычисляется решение. Оказывается, я вычисляю этот вектор времени, чтобы быть слишком грубым. Я перешел на Python из MATLAB и думал, что numpy.arange будет работать аналогично i = t0: tn в MATLAB. Это не так. Так что я решал только целое число раз все время ... –

1

Я в настоящее время изучает немного ОДУ и ее решателей, поэтому ваш вопрос очень интересен для меня ...

Из того, что я слышал и читал, для жестких проблем, правильный путь, чтобы выбрать неявный метод как ступенчатая функция (исправьте меня, если я ошибаюсь, я все еще изучаю misteries решателей ODE). Я не могу ссылаться на вас, где я читал это, потому что не помню, но вот thread из gsl-help, где был задан аналогичный вопрос.

Итак, короче, похоже, что метод bsimp стоит сделать снимок, хотя для него требуется функция джакобиан. Если вы не можете рассчитать якобиан, я попробую с rk2imp, rk4imp или любым из методов передачи.

17

Если вы можете решить вашу проблему с помощью Matlab's 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)

+0

Nice! Спасибо за это. Я пришел к более или менее аналогичному решению в конце, используя 'vode'. –

+1

Максимальный заказ для '' 'bdf''' 5. Нет смысла настраивать порядок выше 12 в любом случае. Потому что 12 - это максимум для Адамса. –

2

PyDSTool оборачивает решатель Radau, который является отличным неявным жестким интегратором. У этого есть больше настройки, чем odeint, но намного меньше, чем PyGSL. Наибольшее преимущество заключается в том, что ваша функция RHS указана как строка (как правило, хотя вы можете создать систему с использованием символических манипуляций) и преобразуется в C, поэтому нет медленных обратных вызовов python, и все это будет очень быстро.

Смежные вопросы