当前位置: 首页 > 面试题库 >

奇怪的SciPy ODE集成错误

厍晋鹏
2023-03-14
问题内容

我正在实施一个非常简单的易感性感染恢复模型,该模型具有稳定的工作量,可以用于闲置的副项目-
通常是一项非常琐碎的任务。但是我遇到了使用PysCeS或SciPy的求解器错误,它们都使用lsoda作为其基础求解器。这仅在参数的特定值时发生,我为之困惑。我使用的代码如下:

import numpy as np
from pylab import *
import scipy.integrate as spi

#Parameter Values
S0 = 99.
I0 = 1.
R0 = 0.
PopIn= (S0, I0, R0)
beta= 0.50     
gamma=1/10.  
mu = 1/25550.
t_end = 15000.
t_start = 1.
t_step = 1.
t_interval = np.arange(t_start, t_end, t_step)

#Solving the differential equation. Solves over t for initial conditions PopIn
def eq_system(PopIn,t):
    '''Defining SIR System of Equations'''
    #Creating an array of equations
    Eqs= np.zeros((3))
    Eqs[0]= -beta * (PopIn[0]*PopIn[1]/(PopIn[0]+PopIn[1]+PopIn[2])) - mu*PopIn[0] + mu*(PopIn[0]+PopIn[1]+PopIn[2])
    Eqs[1]= (beta * (PopIn[0]*PopIn[1]/(PopIn[0]+PopIn[1]+PopIn[2])) - gamma*PopIn[1] - mu*PopIn[1])
    Eqs[2]= gamma*PopIn[1] - mu*PopIn[2]
    return Eqs

SIR = spi.odeint(eq_system, PopIn, t_interval)

这将产生以下错误:

 lsoda--  at current t (=r1), mxstep (=i1) steps   
       taken on this call before reaching tout     
      In above message,  I1 =       500
      In above message,  R1 =  0.7818108252072E+04
Excess work done on this call (perhaps wrong Dfun type).
Run with full_output = 1 to get quantitative information.

通常,当我遇到这样的问题时,我设置的方程组最终有问题,但是我都看不到任何问题。奇怪的是,如果将mu更改为,它也可以工作1/15550。如果系统出了问题,我
还可以 在R中实现模型,如下所示:

require(deSolve)

sir.model <- function (t, x, params) {
  S <- x[1]
  I <- x[2]
  R <- x[3]
  with (
    as.list(params),
{
    dS <- -beta*S*I/(S+I+R) - mu*S + mu*(S+I+R)
    dI <- beta*S*I/(S+I+R) - gamma*I - mu*I
    dR <- gamma*I - mu*R
  res <- c(dS,dI,dR)
  list(res)
}
  )
}

times <- seq(0,15000,by=1)
params <- c(
 beta <- 0.50,
 gamma <- 1/10,
 mu <- 1/25550
)

xstart <- c(S = 99, I = 1, R= 0)

out <- as.data.frame(lsoda(xstart,times,sir.model,params))

使用了lsoda,但似乎没有任何障碍。谁能看到Python代码出了什么问题?


问题答案:

我认为,对于您选择的参数,您会遇到刚度问题-
由于数值的不稳定性,求解器的步长在求解曲线的斜率实际上很浅的区域变得越来越小。lsoda由包裹的Fortran求解器scipy.integrate.odeint尝试在适用于“刚性”和“非刚性”系统的方法之间进行自适应切换,但是在这种情况下,它似乎无法转换为刚性方法。

非常粗略地讲,您可以大幅增加允许的最大步数,而求解器将最终达到目标:

SIR = spi.odeint(eq_system, PopIn, t_interval,mxstep=5000000)

更好的选择是使用面向对象的ODE求解器scipy.integrate.ode,它使您可以显式选择是使用刚性方法还是非刚性方法:

import numpy as np
from pylab import *
import scipy.integrate as spi

def run():
    #Parameter Values
    S0 = 99.
    I0 = 1.
    R0 = 0.
    PopIn= (S0, I0, R0)
    beta= 0.50     
    gamma=1/10.  
    mu = 1/25550.
    t_end = 15000.
    t_start = 1.
    t_step = 1.
    t_interval = np.arange(t_start, t_end, t_step)

    #Solving the differential equation. Solves over t for initial conditions PopIn
    def eq_system(t,PopIn):
        '''Defining SIR System of Equations'''
        #Creating an array of equations
        Eqs= np.zeros((3))
        Eqs[0]= -beta * (PopIn[0]*PopIn[1]/(PopIn[0]+PopIn[1]+PopIn[2])) - mu*PopIn[0] + mu*(PopIn[0]+PopIn[1]+PopIn[2])
        Eqs[1]= (beta * (PopIn[0]*PopIn[1]/(PopIn[0]+PopIn[1]+PopIn[2])) - gamma*PopIn[1] - mu*PopIn[1])
        Eqs[2]= gamma*PopIn[1] - mu*PopIn[2]
        return Eqs

    ode =  spi.ode(eq_system)

    # BDF method suited to stiff systems of ODEs
    ode.set_integrator('vode',nsteps=500,method='bdf')
    ode.set_initial_value(PopIn,t_start)

    ts = []
    ys = []

    while ode.successful() and ode.t < t_end:
        ode.integrate(ode.t + t_step)
        ts.append(ode.t)
        ys.append(ode.y)

    t = np.vstack(ts)
    s,i,r = np.vstack(ys).T

    fig,ax = subplots(1,1)
    ax.hold(True)
    ax.plot(t,s,label='Susceptible')
    ax.plot(t,i,label='Infected')
    ax.plot(t,r,label='Recovered')
    ax.set_xlim(t_start,t_end)
    ax.set_ylim(0,100)
    ax.set_xlabel('Time')
    ax.set_ylabel('Percent')
    ax.legend(loc=0,fancybox=True)

    return t,s,i,r,fig,ax


 类似资料:
  • 问题内容: 我正在使用此代码: 但是在编译时出现此错误: 然后是堆栈跟踪的编译器错误。 我将在课堂开始时同时进行这两种导入: 有什么事吗 在Netbeans中,我看到自动完成选项并且Locale对象没有语法错误… 问题答案: 您的设置有些麻烦,下面的程序对我来说很好用。 它要求源代码的事实使我相信它正在尝试以某种调试模式进行编译或运行。您不需要编译java.util。*的源代码,这很奇怪。 看看我

  • 问题内容: 我目前正在开发一个纯粹的HTML和JavaScript驱动的Web应用程序,该应用程序使用CORS来使用远程Web服务,但目前在IE 11发出GET请求时遇到了麻烦。有趣的是,我们在IE8 / 9/10中可以正常运行,而不仅仅是11。 问题是IE 11似乎超时,而不是等待服务器的响应。ajax调用很简单: 在“网络”选项卡中,使用Fiddler,我可以看到IE从不发送请求。 请问有人有

  • 我最近开始了我的第一个libGDX游戏,一切都进行得很好,所有的东西都呈现得很好,但是大约一分钟后什么都没有呈现,呈现调用仍然被发出,并且spritebatch工作得很好,我只是留下了一个黑屏,我甚至把'gl clearcolor()'改成了但我仍然留下了一个黑屏。我不知道这会是什么。 我的主要类: 编辑:我们已经确定,经过一段时间SpriteBatch渲染一个黑色屏幕的红色清晰颜色,它也停止渲染

  • 所以我在做这个素数家庭作业,举了一个很好的例子,我想我已经把大部分都记下来了。我遇到的一件事是“公共静态空隙筛(int n)”一行的错误,这也发生在“私有静态int twinPrime()”中 代码如下: 以下是错误: void是变量筛的无效类型 预期令牌 "(", ; 语法错误 令牌 “)” 上的语法错误, ;预期 和 标记“int”语法错误,应为@ 语法错误,请插入“EnumBody”以完成B

  • 当我集成Spring JPA数据和Spring缓存时,有一种奇怪的行为我无法解释。 我正在使用Spring Boot来设置我的演示项目。代码在下面。 我的配置bean: 我的实体豆。 我的单元测试类 输出很奇怪。 它应该只为我的期望打印出一条sql语句。不使用缓存对象。 我还注意到@query注释工作得很好。JpaRepository和PersonRepository引用都使用定制的SQL。 我想