我正在寻找一个可以在Python中集成僵硬的ODE的好库。问题是,scipy的odeint给了我很好的解决方案有时,但初始条件的微小变化导致它倒下并放弃。 MATLAB的僵硬求解器(ode15s和ode23s)很快就解决了同样的问题,但我不能使用它(即使是Python,因为MATLAB C API的Python绑定都没有实现回调,我需要传递一个函数到ODE求解器)。我正在尝试PyGSL,但它非常复杂。任何建议都将不胜感激。
编辑:我在使用PyGSL时遇到的具体问题是选择正确的步进功能。有几个,但没有直接类似ode15s或ode23s(bdf公式和修改Rosenbrock,如果这是有道理的)。那么选择刚性系统有什么好的步骤功能呢?我必须在很长一段时间内解决这个系统以确保它达到稳态,并且GSL求解器要么选择一个微小的时间步,要么选择一个太大的时间步。答案 0 :(得分:17)
如果您可以使用Matlab的ode15s
解决问题,那么您应该能够使用scipy的vode
求解器来解决它。要模拟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)
愉快地解决您的问题。它应该在一个僵硬的问题上运作良好。
答案 1 :(得分:11)
Python可以调用C. ODEPACK中的行业标准是LSODE。它是公共领域。您可以下载C version。这些解算器非常棘手,因此最好使用一些经过良好测试的代码。
补充:确保你真的有一个僵硬的系统,即如果费率(特征值)相差超过2或3个数量级。此外,如果系统很僵硬,但您只是在寻找稳态解,那么这些求解器可以让您选择以代数方式求解某些方程。否则,像DVERK这样的好的Runge-Kutta解算器将是一个很好的,更简单的解决方案。
这里添加了因为它不适合评论:这是来自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).
此外,是的Michaelis-Menten动力学是非线性的。不过,Aitken加速可以使用它。 (如果你想要一个简短的解释,首先要考虑Y是标量的简单情况。你运行系统得到3个Y(T)点。通过它们拟合指数曲线(简单代数)。然后将Y设置为渐近线和重复。现在只是概括为Y是一个向量。假设3个点在一个平面上 - 如果它们不是那就没关系。)此外,除非你有一个强制函数(如恒定的静脉滴注),MM消除会衰减离开,系统将接近线性。希望有所帮助。
答案 2 :(得分:2)
PyDSTool包裹Radau求解器,这是一个优秀的隐式刚性积分器。这比odeint有更多的设置,但比PyGSL要少得多。最大的好处是你的RHS函数被指定为一个字符串(通常,虽然你可以使用符号操作构建一个系统)并转换为C,所以没有慢速python回调,整个事情将非常快。
答案 3 :(得分:1)
我目前正在研究一些ODE及其求解器,所以你的问题对我来说非常有趣......
从我所听到和读到的,对于僵硬的问题,正确的方法是选择一个隐式方法作为一个步骤函数(纠正我,如果我错了,我仍在学习ODE求解器的misteries)。我不能在你读到这里的地方引用你,因为我不记得了,但是这里有一个来自gsl-help的thread,其中提出了类似的问题。
因此,简而言之,似乎bsimp
方法值得一试,尽管它需要jacobian函数。如果您无法计算雅可比行列式,我会尝试使用rk2imp
,rk4imp
或任何齿轮方法。