Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.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
Python ODE系统不';当步长(h)大于1时不工作_Python_Numerical Methods_Ode_Runge Kutta - Fatal编程技术网

Python ODE系统不';当步长(h)大于1时不工作

Python ODE系统不';当步长(h)大于1时不工作,python,numerical-methods,ode,runge-kutta,Python,Numerical Methods,Ode,Runge Kutta,我是Python的初学者。目前,我正在编写一个代码,为具有初始值的非线性ODE系统开发一个简单的求解器。该系统的方程如下所示 首先计算myu的函数以获得myu的值,然后将其用于dX/dt、dS/dt和dDO/dt。在下一步中,根据S和DO的新值再次计算myu以获得其新值 我使用J.C.Butcher提出的一般线性方法(GLM)作为我的方法。该方法使用一个转移矩阵,其值和大小取决于我们使用的数值方法。在这种情况下,我使用龙格库塔现金卡普 虽然你可能会在方程中发现D也是一个函数,但这里我把D的值设为

我是Python的初学者。目前,我正在编写一个代码,为具有初始值的非线性ODE系统开发一个简单的求解器。该系统的方程如下所示

首先计算myu的函数以获得myu的值,然后将其用于dX/dt、dS/dt和dDO/dt。在下一步中,根据S和DO的新值再次计算myu以获得其新值

我使用J.C.Butcher提出的一般线性方法(GLM)作为我的方法。该方法使用一个转移矩阵,其值和大小取决于我们使用的数值方法。在这种情况下,我使用龙格库塔现金卡普

虽然你可能会在方程中发现D也是一个函数,但这里我把D的值设为一个常数

在初始化中,首先设置h的值,以获得步数。我创建了一个名为“initValue”的向量,有8列4行,包括每个方程的k值(第1行到第6行)、Runge-Kutta四阶的初始值(第7行。我将其设置为0,因为它只是一个“预测器”),以及每个方程的初始值(第8行)

过渡矩阵是基于GLM创建的,其中的值来自Runge-Kutta-Cash-Karp的阶段方程(求k1到k6的值)和阶跃方程(求解)的常数

在循环中,我第一次只是将初始值添加到名为“result”的数组中。在第一步,我简单地将转移矩阵乘以向量“initValue”。在下一步直到最后一步,我根据上一步的结果初始化“initValue”

我要寻找的是解决方案,应该是这样的。 如果h小于1,则我的代码有效。我将我的结果与scipy.integrate.odeint的结果进行比较。但是当我把h设置为大于1时,它显示的结果与它应该显示的结果不同。例如,在代码中,我设置h=100,这意味着它将只显示初始值和最终值(当时间=100时)。X和S应该向上,DO和Xr应该向下,而我的正好相反。当h设置为大于1时,odeint的结果显示与预期解决方案相同的结果

我需要帮助来修复我的代码,以便它可以显示任何h值的预期解决方案


谢谢。

为什么您希望对于大得离谱的步长有任何合理的结果

最简单的演示是
y'=-y
和显式Euler方法。如果您使用较小的步长
1
,您将获得质量正确的解决方案。对于小于0.1的步长,您将开始获得正确的步长

但是,如果使用步长
h=10
,则迭代

y[k+1]= y[k] - h*y[k] = -9*y[k]

会爆炸的。高阶方法也是如此,足够小的步长可以给出定量正确的结果,中等步长仍然可以给出定性正确的图像,较大的步长会导致比解值大得多的误差。

是的,实际上,我不需要像100甚至10这样大的h。我只是想知道如果h很大,odeint如何解决系统,如果可能的话,我可以在代码中实现这个方法吗?如果这是不可能的,那么我会让我的代码那样。谢谢你清楚的回答和解释。现在我可以专注于工作中的其他方面,比如缩短运行时间。当我将h设置为小于0.05时,显示结果将花费很长时间。您对此有什么建议吗?这些“专业”实现使用内部自适应步长,并通过插值生成输出。内部步骤可以比用户提供的时间列表中的步骤大或小得多。您也可以这样做,因为您的方法是嵌入式方法。但是您的实现有点奇怪。首先用已知的精确解在更简单的ODE上进行测试。我用一个简单的捕食者-食饵系统方程进行测试:
dR=0.2*r-0.001*r*f
dF=0.001*r*f-0.5*f
,r=rabbit,f=fox。使用上面相同的方法,我得到了错误消息“RuntimeWarning:在双_标量中遇到溢出”,h>=1。我会使用一些您真正了解解决方案的其他ODE,如
x'=-y,y'=x
y'(xt)=cos(t)+100*(y(t)-sin(t))
y(0)=0
,然后用步长
h=2^{-k}
k=8,9,10,
计算
t=1
的解,以查看错误行为是否与方法预测的顺序相同。这也有助于了解在什么时候遇到溢出。随着错误范围呈指数增长,这种情况只会持续更长的时间。