0

我正在尝试与本文中描述的相同:https ://science.sciencemag.org/content/sci/early/2020/04/07/science.abb4557.full.pdf

我使用 GNU Octave。

这是 ODE 系统的函数文件:

function f = COVID19ODE(t,y0)

  alpha = 3.07*0.38;
  beta = 0.38;
  kappa = 0.5;
  kappa0 = 0.5;
  ydot =@(t,y,a) ([-alpha*y(1)*y(2) - kappa*y(1);
                  alpha*y(1)*y(2) - beta*y(2) - kappa0*y(2) - kappa*y(2);
                  (kappa0 + kappa)*y(2);
                  kappa0*y(1) + beta*y(2)]);
  odeopt = odeset ("InitialStep", 1e-2, "MaxStep", 1);           
  [t,y] = ode45(ydot, t, y0, odeopt);
  f = y;
endfunction

这是将数据拟合到 ODE 模型的脚本:

pkg load optim

Cases = [2,3,20,79,150,227,320,445,650,888,1128,1694,2036,2502,3089,3858,4636,5883,7375,9172,10149,12462,15113,17660,21157,24747,27980,31506,35713,41035,47021,53578,59138,63927,69176,74386,80539,86498,92472,97689,101739,105792,110574,115242,119827,124632,128948,132547,135586,139422,143626,147577,152271];
Days = (1:1:length(Cases));

% Fit
xdata = Days;
ydata = Cases';
F = @(a,xdata) COVID19ODE(xdata,a)(:,3);
a0=[1 1 1 1];
[a,resnorm,~,exitflag,output] = lsqcurvefit(F,a0,xdata,ydata);

% Plot
plot(Days,Cases,'-+' , Days,F(a,Days)) 
grid
legend("Cases" , "Fit" , "location","northwest")
title('Covid 19 pandemic')
xlabel('Days')
ylabel('Cases')

计算需要很长时间,最后出现错误消息:

warning:  Solving was not successful.  The iterative integration loop exited at time t = 1.000000 before the endpoint at tend= 53.000000 was reached.  This may happen if the stepsize becomes too small.  Try to reduce the value of 'InitialStep' and/or'MaxStep' with the command 'odeset'.
warning: called from
    integrate_adaptive at line 312 column 7
    ode45 at line 232 column 12
    COVID19ODE at line 12 column 8
    COVID19Model>@<anonymous> at line 9 column 16
    nonlin_curvefit>@<anonymous> at line 84 column 14
    __nonlin_residmin__>@<anonymous> at line 316 column 41
    __lm_svd__ at line 469 column 11
    __nonlin_residmin__ at line 452 column 21
    nonlin_curvefit at line 83 column 18
    lsqcurvefit at line 268 column 19
    COVID19Model at line 11 column 30

我试图降低“InitialStep”和/或“MaxStep”的值,但没有帮助。拟合函数似乎不是数据的一个很好的近似值: 绘图

4

1 回答 1

0

总结这篇论文,对于密度加起来为 1 的情况,我们有模型的“最佳”系数S+I+X+R=1,这相当于初始值的 3 个自由参数。在 IC 中的假设下X=R=0,保留一个参数,因此可以将初始条件参数化为S0 = 0.9+0.1/(1+x^2)I=1-S0。此外,假设病例数与X分量成比例,这将为比例因子提供第二个参数。

通过 使 kappas 变量在 0 到 0.2 的范围内kappa = 0.2/(1+5*exp(u))。即使这样,使用kappa0参数也会被拒绝

prop =  49040365.30572
y0 =

   1.0000e+00   1.1947e-06   1.0000e-16   1.0000e-16

kappa =  0.042094
kappa0 = 0

我得到对数图 在此处输入图像描述

在参数化的许多其他变体中,求解器找不到任何合理的解决方案,通常如果完全找到解决方案,则S组件下降得太快。

此图像的代码是

  % data and other initializations left out
  C = @(Y) Y(:,3);
  L = @(Y) log(1+Y);
  F = @(a,xdata) L(C(COVID19ODE(xdata,a)));

  a0=[0.1 log(1e9) 0 0 ];
  [a,resnorm,~,exitflag,output] = lsqcurvefit(F,a0,xdata,L(ydata));
  disp("a="); disp(a);
  % Plot
  time=Days(1):0.1:Days(end);
  semilogy(Days,Cases,'+r' , time,COVID19ODE(time,a)); 
  grid
  legend("Cases" , "S","I","X","R" ); % , "location","northwest")
  title('Covid 19 pandemic')
  xlabel('Days')
  ylabel('Cases')

  function f = COVID19ODE(t,para)
    ic = para(1);
    prop = exp(para(2))
    S0 =  0.9+0.1/(1+ic^2); 
    y0 = [ S0-2e-16, 1-S0, 1e-16, 1e-16 ]
    beta = 0.38;
    alpha = 3.07*beta;
    kappa = 0.2/(1+5*exp(para(3)))
    kappa0 = 0.2/(1+5*exp(para(4)))
    ydot =@(t,y,a) ([-alpha*y(1)*y(2) - kappa*y(1);
                    alpha*y(1)*y(2) - beta*y(2) - kappa0*y(2) - kappa*y(2);
                    (kappa0 + kappa)*y(2);
                    kappa0*y(1) + beta*y(2)]);
    odeopt = odeset ("InitialStep", 1e-2, "MaxStep", 0.1, "AbsTol", 1e6);           
    [t,y] = ode45(ydot, t, y0, odeopt);
    f = prop*y;
  end%function
于 2020-04-16T12:57:51.070 回答