Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将刚性ODE与Python集成_Python_Scipy_Pygsl - Fatal编程技术网

将刚性ODE与Python集成

将刚性ODE与Python集成,python,scipy,pygsl,Python,Scipy,Pygsl,我正在寻找一个好的库,它将在Python中集成僵硬的ODE。问题是,scipy的odeint有时给我提供了很好的解决方案,但初始条件的微小变化会导致它崩溃并放弃。MATLAB的stiff solver(ode15s和ode23s)很好地解决了同样的问题,但我不能使用它(即使是从Python中,因为MATLAB C API的Python绑定都没有实现回调,我需要将函数传递给ODE解算器)。我正在尝试PyGSL,但它非常复杂。如有任何建议,将不胜感激 编辑:PyGSL的具体问题是选择正确的步长函数。

我正在寻找一个好的库,它将在Python中集成僵硬的ODE。问题是,scipy的odeint有时给我提供了很好的解决方案,但初始条件的微小变化会导致它崩溃并放弃。MATLAB的stiff solver(ode15s和ode23s)很好地解决了同样的问题,但我不能使用它(即使是从Python中,因为MATLAB C API的Python绑定都没有实现回调,我需要将函数传递给ODE解算器)。我正在尝试PyGSL,但它非常复杂。如有任何建议,将不胜感激


编辑:PyGSL的具体问题是选择正确的步长函数。其中有几种,但没有ode15s或ode23s的直接类似物(bdf公式和修改的Rosenbrock,如果有意义的话)。那么,对于刚性系统,选择什么样的阶跃函数比较好呢?我必须花很长时间来解决这个系统,以确保它达到稳定状态,而GSL解算器要么选择很小的时间步长,要么选择太大的时间步长。

我目前正在研究一些ODE及其解算器,所以你的问题对我来说非常有趣

根据我所听到和阅读的,对于僵硬的问题,正确的方法是选择隐式方法作为阶跃函数(如果我错了,请纠正我,我仍然在学习ODE解算器的错误序列)。我不记得在哪里读到过这篇文章,但这里有一篇来自gsl帮助的文章,里面有一个类似的问题


因此,简而言之,
bsimp
方法似乎值得一试,尽管它需要一个雅可比函数。如果您无法计算雅可比矩阵,我将尝试使用
rk2imp
rk4imp
,或任何齿轮方法。

Python可以调用C。行业标准在ODEPACK中。这是公共领域。你可以下载。这些解算器非常复杂,因此最好使用一些经过良好测试的代码

补充:确保你真的有一个僵硬的系统,即如果速率(特征值)相差超过2或3个数量级。此外,如果系统是刚性的,但您只是在寻找稳态解,那么这些解算器可以让您选择用代数方法解一些方程。否则,像Runge-Kutta这样的优秀解算器将是一个很好且简单得多的解决方案

添加到此处是因为它不适合注释:这来自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).

此外,米氏动力学是非线性的。然而,艾特肯加速度与之配合使用。(如果你想要一个简短的解释,首先考虑Y是标量的一个简单的例子。你运行系统得到3个Y(t)点。通过它们(简单代数)拟合指数曲线。然后将y设为渐近线并重复。现在只需将Y归纳为向量。假设3个点在一个平面中-如果它们不是,就可以。)除非有强制功能(如持续静脉滴注),否则MM消除将逐渐消失,系统将接近线性。希望有帮助。

如果你能用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)
愉快地解决您的问题。它应该能很好地解决一个棘手的问题


(另请参见)

包装Radau解算器,它是一种优秀的隐式刚性积分器。这比odeint有更多的设置,但比PyGSL少得多。最大的好处是您的RHS函数被指定为字符串(通常,尽管您可以使用符号操作构建系统),并被转换为C,因此没有缓慢的python回调,整个过程将非常快。

我想帮助您使用PyGSL。我从未使用过它,但我有使用GSL的经验。我刚刚查看了pygsl(odeiv.py)中提供的示例,它看起来与C中的非常相似。您是否认为pygsl由于python接口或GSL本身而非常复杂?嗯,非常复杂可能是言过其实:)。它比MATLAB或scipy复杂一个数量级。为了澄清这一点,python接口与C接口几乎相同,因此复杂的是库本身。另外,PyGSL不记录odeiv,所以我必须使用C文档来确定在Python中要做什么。不好玩。OT:我不记得
t0:tn
在Matlab中做了什么,但是
numpy.r\u0:1:11j]
可能会有帮助。感谢LSODE提示。我发现有人已经在为它编写了Python接口。我知道我确实有一个僵硬的系统,但看看LSODE的源代码,我意识到我的程序中可能有一个bug。scipy.integrate.odeint解算器基于LSODA,与所有LS*解算器一样,它需要一个时间点向量来计算解。结果是,我计算的这个时间向量太粗糙了。我从MATLAB切换到Python,并认为numpy.arange的工作原理与MATLAB中的I=t0:tn类似。没有。所以我一直只求解整数次…@Chinmay:它需要一个时间点向量?根据我的经验,从第一次运行到第二次,在这一点上,如果愿意,可以对状态进行不连续的更改,然后运行到第三次,依此类推。这就是我们所有药理学建模的方法。顺便说一句,我忘了提到如果你的ODE系统是线性的(常数雅可比),你可以使用DGPADM-它很快,从来没有刚度问题。另外,如果系统是线性的,你可以用代数方法求解稳态解。。。。我忘了提一下,因为你说你在寻找稳态,所以我使用了一种叫做艾特肯加速度的方法(系统不必是线性的)。基本上,我们假设它将以某种近似指数的方式收敛到渐近线。所以你得3分