使用ode45时获得意外结果

时间:2012-06-23 22:44:45

标签: matlab ode differential-equations

我试图通过在Matlab中编写代码来解决微分方程系统。我在这个论坛上发帖,希望有人能以某种方式帮助我。 我有一个10耦合微分方程组。它是一种载体 - 宿主流行病模型,它捕获人类与昆虫种群之间疾病的传播。由于它是一个简单的微分方程系统,我使用求解器(ode45)来表示非刚性问题类型。

有10个微分方程,每个微分方程代表10个不同的状态变量。有两个函数具有10个耦合的ODE的相同系统。一个称为NoEffects_derivative_6_15_2012.m,其中包含原始的ODE系统。另一个函数称为OnlyLethal_derivative_6_15_2012.m,其中包含相同的ODE系统,其退出率从时间gamma=32 %days开始增加,并且退出率随着时间呈指数衰减。

我使用ode45来解决两个系统,使用相同的初始条件。两个系统的时间向量也相同,从t0tfinal。向量tspan包含从t0tfinal的时间值,每个时间值的增量为0.25天,总计157个时间值。

解决方案值存储在矩阵ye0yeL中。这两个矩阵都包含157行和10列(对于10个状态变量值)。当我通过绘制差异来比较第10个状态变量的值,对于time=tfinal,在矩阵ye0yeL中,我发现它对某些时间值变为负值。 (使用命令:plot(te0,ye0(:,10)-yeL(:,10)))。这不是预期的。对于从t0tfinal的所有时间值,10状态变量的值应该更大,因为它是从没有提高提款率的ODE系统获得的解决方案它

我被告知我的matlab代码中存在错误。我不知道如何找出那个bug。或者也许我正在使用的matlab中的求解器(ode45)效率不高,并且确实存在这种问题。任何人都可以提供帮助。

我也尝试了ode23ode113,但却遇到了同样的问题。图(2)表示对时间值32和34变为负的曲线,这表示不期望的结果。对于所有时间值,该曲线应始终具有正值。还有其他人可以提出建议吗?

这是主要的脚本文件:

clear memory; clear all;
global Nc capitalambda muh lambdah del1 del2 p eta alpha1 alpha2 muv lambdav global dims Q t0 tfinal gamma Ct0 b1 b2 Ct0r b3 H C m_tilda betaHV bitesPERlanding IC global tspan Hs Cs betaVH k landingARRAY muARRAY
Nhh=33898857; Nvv=2*Nhh; Nc=21571585; g=354; % number of public health centers in Bihar state %Fix human parameters capitalambda= 1547.02; muh=0.000046142; lambdah= 0.07; del1=0.001331871263014; del2=0.000288658; p=0.24; eta=0.0083; alpha1=0.044; alpha2=0.0217; %Fix vector parameters muv=0.071428; % UNIT:2.13 SANDFLIES DEAD/SAND FLY/MONTH, SOURCE: MUBAYI ET AL., 2010 lambdav=0.05; % UNIT:1.5 TRANSMISSIONS/MONTH, SOURCE: MUBAYI ET AL., 2010
Ct0=0.054;b1=0.0260;b2=0.0610; Ct0r=0.63;b3=0.0130;
dimsH=6; % AS THERE ARE FIVE HUMAN COMPARTMENTS dimsV=3; % AS THERE ARE TWO VECTOR COMPARTMENTS dims=dimsH+dimsV; % THE TOTAL NUMBER OF COMPARTMENTS OR DIFFERENTIAL EQUATIONS
gamma=32; % spraying is done of 1st feb of the year
Q=0.2554; H=7933615; C=5392890;
m_tilda=100000; % assumed value 6.5, later I will have to get it for sand flies or mosquitoes betaHV=66.67/1000000; % estimated value from the short technical report sent by Anuj bitesPERlanding=lambdah/(m_tilda*betaHV); betaVH=lambdav/bitesPERlanding; IC=zeros(dims+1,1); % CREATES A MATRIX WITH DIMS+1 ROWS AND 1 COLUMN WITH ALL ELEMENTS AS ZEROES
t0=1; tfinal=40; for j=t0:1:(tfinal*4-4) tspan(1)= t0; tspan(j+1)= tspan(j)+0.25; end clear j;
% INITIAL CONDITION OF HUMAN COMPARTMENTS q1=0.8; q2=0.02; q3=0.0005; q4=0.0015; IC(1,1) = q1*Nhh; IC(2,1) = q2*Nhh; IC(3,1) = q3*Nhh; IC(4,1) = q4*Nhh; IC(5,1) = (1-q1-q2-q3-q4)*Nhh; IC(6,1) = Nhh; % INTIAL CONDITIONS OF THE VECTOR COMPARTMENTS IC(7,1) = 0.95*Nvv; %80 PERCENT OF TOTAL ARE ASSUMED AS SUSCEPTIBLE VECTORS IC(8,1) = 0.05*Nvv; %20 PRECENT OF TOTAL ARE ASSUMED AS INFECTED VECTORS IC(9,1) = Nvv; IC(10,1)=0;
Hs=2000000; Cs=3000000; k=1; landingARRAY=zeros(tfinal*50,2); muARRAY=zeros(tfinal*50,2);

[te0 ye0]=ode45(@NoEffects_derivative_6_15_2012,tspan,IC); [teL yeL]=ode45(@OnlyLethal_derivative_6_15_2012,tspan,IC);

figure(1) subplot(4,3,1); plot(te0,ye0(:,1),'b-',teL,yeL(:,1),'r-'); xlabel('time'); ylabel('S'); legend('susceptible humans'); subplot(4,3,2); plot(te0,ye0(:,2),'b-',teL,yeL(:,2),'r-'); xlabel('time'); ylabel('I'); legend('Infectious Cases'); subplot(4,3,3); plot(te0,ye0(:,3),'b-',teL,yeL(:,3),'r-'); xlabel('time'); ylabel('G'); legend('Cases in Govt. Clinics'); subplot(4,3,4); plot(te0,ye0(:,4),'b-',teL,yeL(:,4),'r-'); xlabel('time'); ylabel('T'); legend('Cases in Private Clinics'); subplot(4,3,5); plot(te0,ye0(:,5),'b-',teL,yeL(:,5),'r-'); xlabel('time'); ylabel('R'); legend('Recovered Cases');
subplot(4,3,6);plot(te0,ye0(:,6),'b-',teL,yeL(:,6),'r-'); hold on; plot(teL,capitalambda/muh); xlabel('time'); ylabel('Nh'); legend('Nh versus time');hold off;
subplot(4,3,7); plot(te0,ye0(:,7),'b-',teL,yeL(:,7),'r-'); xlabel('time'); ylabel('X'); legend('Susceptible Vectors');
subplot(4,3,8); plot(te0,ye0(:,8),'b-',teL,yeL(:,8),'r-'); xlabel('time'); ylabel('Z'); legend('Infected Vectors');
subplot(4,3,9); plot(te0,ye0(:,9),'b-',teL,yeL(:,9),'r-'); xlabel('time'); ylabel('Nv'); legend('Nv versus time');
subplot(4,3,10);plot(te0,ye0(:,10),'b-',teL,yeL(:,10),'r-'); xlabel('time'); ylabel('FS'); legend('Total number of human infections');
figure(2) plot(te0,ye0(:,10)-yeL(:,10)); xlabel('time'); ylabel('FS(without intervention)-FS(with lethal effect)'); legend('Diff. bet. VL cases with and w/o intervention:ode45');

功能文件:NoEffects_derivative_6_15_2012

function dx = NoEffects_derivative_6_15_2012( t , x )
global Nc capitalambda muh del1 del2 p eta alpha1 alpha2 muv global dims m_tilda betaHV bitesPERlanding betaVH
dx       = zeros(dims+1,1); % t % dx 
dx(1,1)  = capitalambda-(m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/(x(7,1)+x(8,1))-muh*x(1,1); 
dx(2,1)  = (m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/(x(7,1)+x(8,1))-(del1+eta+muh)*x(2,1); 
dx(3,1)  = p*eta*x(2,1)-(del2+alpha1+muh)*x(3,1); 
dx(4,1)  = (1-p)*eta*x(2,1)-(del2+alpha2+muh)*x(4,1);
dx(5,1)  = alpha1*x(3,1)+alpha2*x(4,1)-muh*x(5,1); 
dx(6,1)  = capitalambda -del1*x(2,1)-del2*x(3,1)-del2*x(4,1)-muh*x(6,1); 
dx(7,1)  = muv*(x(7,1)+x(8,1))-bitesPERlanding*betaVH*x(7,1)*x(2,1)/(x(6,1)+Nc)-muv*x(7,1);
%dx(8,1) = lambdav*x(7,1)*x(2,1)/(x(6,1)+Nc)-muvIOFt(t)*x(8,1); 
dx(8,1)  = bitesPERlanding*betaVH*x(7,1)*x(2,1)/(x(6,1)+Nc)-muv*x(8,1); 
dx(9,1)  = (muv-muv)*x(9,1); 
dx(10,1) = (m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/x(9,1);

功能文件:OnlyLethal_derivative_6_15_2012

function dx=OnlyLethal_derivative_6_15_2012(t,x) 
global Nc capitalambda muh del1 del2 p eta alpha1 alpha2 muv global dims m_tilda betaHV bitesPERlanding betaVH k muARRAY
dx=zeros(dims+1,1);
% the below code saves some values into the second column of the two arrays % t muARRAY(k,1)=t; muARRAY(k,2)=artificialdeathrate1(t); k=k+1; 
dx(1,1)= capitalambda-(m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/(x(7,1)+x(8,1))-muh*x(1,1);    
dx(2,1)= (m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/(x(7,1)+x(8,1))-(del1+eta+muh)*x(2,1);
dx(3,1)=p*eta*x(2,1)-(del2+alpha1+muh)*x(3,1);
dx(4,1)=(1-p)*eta*x(2,1)-(del2+alpha2+muh)*x(4,1);
dx(5,1)=alpha1*x(3,1)+alpha2*x(4,1)-muh*x(5,1);
dx(6,1)=capitalambda -del1*x(2,1)-del2*( x(3,1)+x(4,1) ) - muh*x(6,1);
dx(7,1)=muv*( x(7,1)+x(8,1) )- bitesPERlanding*betaVH*x(7,1)*x(2,1)/(x(6,1)+Nc) - (artificialdeathrate1(t) + muv)*x(7,1);
dx(8,1)= bitesPERlanding*betaVH*x(7,1)*x(2,1)/(x(6,1)+Nc)-(artificialdeathrate1(t) + muv)*x(8,1);
dx(9,1)= -artificialdeathrate1(t) * x(9,1);
dx(10,1)= (m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/x(9,1);

功能文件:artificialdeathrate1

function art1=artificialdeathrate1(t) 
global Q Hs H Cs C   
art1= Q*Hs*iOFt(t)/H + (1-Q)*Cs*oOFt(t)/C ;

功能文件:iOFt

function i = iOFt(t) 
global gamma tfinal Ct0 b1
if t>=gamma && t<=tfinal 
    i = Ct0*exp(-b1*(t-gamma)); 
else 
    i =0; 
end

功能文件:oOFt

function o = oOFt(t)
global gamma Ct0 b2 tfinal    
if (t>=gamma && t<=tfinal) 
    o = Ct0*exp(-b2*(t-gamma)); 
else 
    o = 0; 
end

1 个答案:

答案 0 :(得分:1)

如果您的工作代码甚至远远超出您发布的代码,那么恕我直言,您应该首先解决这个问题。

我为你清理了iOFtoOFt,因为这些很容易处理。我在NoEffects_derivative_6_15_2012努力了。我个人改变你的代码是使用体面的索引。你有10个变量,如果你让你的代码休息几周或几个月,你将无法记住状态7是什么。因此,您可能希望使用详细名称重写ODE,然后在(7,1)x向量中检索/存储它们,而不是使用dx。或者使用能明确发生了什么的索引。

E.g。

function ODE(t,x)
insectsInfected = x(1);
humansInfected  = x(2);
%etc

dInsectsInfected = %some function of the rest
dHumansInfected  = %some function of the rest
% etc

dx = [dInsectsInfected; dHumansInfected; ...];

function ODE(t,x)
iInsectsInfected = 1;
iHumansInfected  = 2;
%etc

dx(iInsectsInfected) = %some function of x(i...)
dx(iHumansInfected)  = %some function of x(i...)
%etc

当您不执行此类操作时,最终可能会使用x(6,1)而不是在某些公式中x(3,1)可能需要数小时才能发现这样的事情。如果你使用详细名称,输入需要更长的时间,但它使调试变得更容易,如果你理解你的方程式,那么当发生这样的错误时,它应该更加明显。

另外,不要犹豫,在公式中加入空格,这样可以更轻松地阅读。如果您有一些有意义的子表达式(例如,如果(1-p)*eta*x(2,1)是疾病死亡的昆虫数量,只需将其放入变量dyingInsects并在其出现的任何地方使用它。如果你对齐你的作业(正如我上面所做的那样),这可能会增加更容易阅读和理解的代码。

关于ODE求解器,如果你确定你的实现是正确的,我也会尝试解决僵硬的问题(除非你绝对确定你没有一个僵硬的系统)。