Python scipy odeint:保守的ode方程之和不会保持为零——这正常吗?

Python scipy odeint:保守的ode方程之和不会保持为零——这正常吗?,python,numpy,scipy,Python,Numpy,Scipy,假设我们有以下方程式: dy1/dt = f(y1, t) [1] dy2/dt = g(y2, t) [2] 方程式是“保守”的,即以下条件应成立: dy1/dt + dy2/dt = 0 [3] 使用scipy.odeint,我发现对于简单的常微分方程组,我可以像这样积分保守方程 然而,对于较大的问题,我有以下问题 假设这是我的导数函数: def deriv_function(y0s, t): ...body defines equations 1, a

假设我们有以下方程式:

dy1/dt = f(y1, t)      [1]
dy2/dt = g(y2, t)      [2]
方程式是“保守”的,即以下条件应成立:

dy1/dt + dy2/dt = 0    [3]
使用
scipy.odeint
,我发现对于简单的常微分方程组,我可以像这样积分保守方程

然而,对于较大的问题,我有以下问题

假设这是我的导数函数:

def deriv_function(y0s, t):
    ...body defines equations 1, and 2...

    print np.sum(ode)
    return ode
注意print语句

我在
derivu函数上使用
scipy.odeint
,如下所示:

odeint(deriv_fun, y0s, [0, 0.5])
由于打印语句,将打印以下内容:

-1.38555833473e-13 <--- note, close to zero
-0.00679107743937
-0.0067907211796
-0.0135814423985
-0.0135810861584
-0.416522145214
-0.416523165887
-0.818209018574
-0.818211056221
-1.21864678558
-1.21864881584
-2.86735888212
-2.8673729885
-2.46855840934
-2.46856658088
-3.70632102566
-3.70631206163
-4.93200749506
-4.93200691488
-6.14577326158
-6.14577268283
-8.53799987128
-8.53799713959
-10.8839304356
-10.8839320212
-13.1845005689
-13.1845021725
-15.4406122011
-15.4406123927
-17.6531469917
-17.653147185
-24.6238415795
-24.6238498033
-31.1628867985
-31.1628947266
-37.2974784594
-37.2974547092
-35.463527103
-35.4635192949
-39.5777426955
-39.5777472677
-43.5137135424
-43.5137108017
-47.2791485087
-47.2791483993
-50.881424906
-50.8814244751
-54.3275507164
-54.3275502654    <--- note, not close to zero
-1.13686837722e-13
0.0
0.0
0.0
-1.13686837722e-13
1.13686837722e-13
0.0
0.0
0.0
0.0
0.0
0.0
0.0
-1.13686837722e-13
0.0
0.0
0.0
1.13686837722e-13
0.0
0.0
0.0
0.0
-1.13686837722e-13
0.0
0.0
-1.13686837722e-13
0.0
0.0
0.0
0.0
0.0
0.0
-1.13686837722e-13
0.0
0.0
5.68434188608e-14
-5.68434188608e-14
-5.68434188608e-14
0.0
我花了很多时间试图弄清楚这个问题是否与我定义方程的方式有关,现在我相当肯定事实并非如此。为了证实这一点,我想问:一个非保守的方程组是否可能首先打印一个接近零的ode和,然后打印不接近零的值

思考这个问题的另一种方式是:在更大的方程组中,ode和初始值打印出来大约为零,然后再增加。这个问题发生时,解算器内部会发生什么



给后代:.

就我对微分方程理论的理解而言:除非你有一些额外的约束(比如你的例子),否则你无法确定你的解的偏差

一般来说,可以说积分总是要处理数值误差。特别是在高维情况下,当被积函数表现不好时(例如近极点),数值误差可能很快成为主要误差。这是许多模拟任务的一个关键问题,需要针对每类问题采用专门的方法(例如,请参阅)


你也可以尝试一种符号化的方法,检查一下。

你看到的是数字错误。我不知道你所说的“更大的方程”是什么意思,但是如果你指的是大的长表达式,你可能会在函数的求值中使用舍入(你可以很容易地检查这个)。如果是这样的话,通过数学运算得到一个更好更准确的表达式

另一件事是同时积分两个方程。如果您可以将它们解耦,请独立解决它们。该算法有一个自适应步长选择,该值可能不同于使用一个或多个方程:当您有多个方程时,步长必须足够适合所有方程

关于你关于肠道的问题,看看积分曲线。这是马瑟寄来的

如果你在分岔点附近,初始条件中的一个小误差可以给你相当不同的结果,它们可能会收敛,也可能不会收敛


没有解决这个问题的通用方法。我认为你的第一个赌注是分析:使用方程中的结构来简化它们。或者,如果你的轨迹附近有极点,应用变换将它们推开。另一方面,这种差异可以给你一个积分误差的估计。

如果我理解正确,Symphy无法解决ODE系统?ODE模块无法解决,除非你能将它们解耦(如你的例子)。感谢这个非常好的答案!我会尽快给你一个小小的奖励,因为我真的想奖励你的答案。如果dy1/dt+dy2/dt=0,那么y1(t)+y2(t)=C=y1(0)+y2(0)(一个取决于初始条件的常数),那么你可以解微分方程,比如说,只要y1(t),然后y2(t)=C-y1(t).@WarrenWeckesser这正是我最后所做的!因为我有一个更复杂的系统,所以使用scipy.odeint管理所有额外的参数等会有点痛苦。现在还可以!