一阶时滞微分方程三种求解方法的MATLAB实现及稳定性分析

本文探讨了一阶时滞微分方程的数值解法,包括欧拉法、改进欧拉法及龙格库塔法。通过MATLAB编程实现,对比了不同方法的解与稳定性分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言: 大学期间只学习过《常微分方程》,没想到有些学校竟然还学《时滞微分方程》,于是找到一本由内藤敏机(日本)等著,马万彪等译的《时滞微分方程——泛函数微分方程引论》(有需要的可以私聊,优快云貌似上传不了书籍,说侵权emmm),看着头秃,不过受到不少启发,尤其是对Logistic方程的改进,真真是长见识了。没找到有人用欧拉法解一阶时滞微分方程的,于是一不做二不休便用MATLAB实现了一下下,顺便改进了点点。

一阶时滞微分方程在求解时常常会解着解着就变成了解超越方程了,而超越方程很难求解,很头疼,因此常常都是计算方程的数值解,而非解析解。本文也只计算数值解。

对于一阶时滞微分方程(方程(1))
x′=−px(t−τ)+qx(t)r+xα(t),t≥0, x'=-px\left( t-\tau \right) +\frac{qx\left( t \right)}{r+x^{\alpha}\left( t \right)},t\ge 0, x=px(tτ)+r+xα(t)qx(t),t0,
这里p,q,rp,q,rp,q,r都是正的常数,τ\tauτ是时滞量,α∈N={1,2,3,...}\alpha \in N=\{1,2,3,...\}αN={1,2,3,...},并且满足
qp>r. \frac{q}{p}>r. pq>r.
啊,不想打字了,直接放我写的报告的截图了。

取步长
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
p=10,q=2,r=0.1,α=3,r=0.01p=10,q=2,r=0.1,\alpha=3,r=0.01p=10,q=2,r=0.1α=3,r=0.01时,写出上述方程的欧拉法和改进欧拉法的Matlab程序,并进行稳定性分析和与解析解比较。

欧拉法是一种解决数值微分方程的最基本的方法,其基本思想是迭代。其中分为前进的欧拉法、后退的欧拉法、改进的欧拉法,本文使用的是前进的欧拉法。所谓迭代,就是逐次替代,最后求出所要求的解,并达到一定的精度。误差可以很容易地计算出来。

该方法有明显的优势:单步、显式、一阶求导精度、截断误差为二阶,以上优势能够大大减小运算的难度。但是不可避免的,欧拉法也存在着一定的缺陷。欧拉法简单地取切线的端点作为下一步的起点进行计算,当步数增多时,误差会因积累而越来越大。

为了提高精度,需要在欧拉格式的基础上进行改进。本文采用区间两端的函数值的平均值作为直线方程的斜率得到改进的欧拉格式。改进欧拉法的精度为二阶。

除了改进的欧拉格式以外,还有许多比较好的改进方法,龙格库塔法便是其中一种。在数值分析中,龙格库塔法是用于模拟微分方程的解的重要的一类隐式或显式迭代法。实际上,龙格库塔法是欧拉法的一种推广,向前欧拉格式将导数项简单取为 ,而龙格库塔法则是在区间 内多取几点,将他们的斜率加权平均,作为导数的近似。

综合使用以上的欧拉法、改进欧拉法和龙格库塔法,取初值为1,步长 h=0.5h=0.5h=0.5,求解时滞微分方程(1)。编程时,我们先利用三中方法求解 uku_kuk的值,由于u(t)=x(τt)u(t)=x(\tau t)u(t)=x(τt) ,因此为了得到 x(t)x(t)x(t),需要对解得的u(t)u(t)u(t) 做如下逆变换
x(t)=u(tτ) x(t)=u(\frac{t}{\tau}) x(t)=u(τt)
得到的结果对比图如图1-4所示。
在这里插入图片描述
图1 方程(1)的解,步长h=1/2h=1/2h=1/2
在这里插入图片描述
图2 方程(1)的解,步长 h=1/4h=1/4h=1/4
在这里插入图片描述
图2 方程(1)的解,步长 h=1/8h=1/8h=1/8

在这里插入图片描述
图2 方程(1)的解,步长 h=1/16h=1/16h=1/16

对模型做稳定性分析,计算q2hατ\frac{q^2}{h\alpha \tau}hατq2p(q−pr)−q2p(q-pr)-q^2p(qpr)q2 的值分别为266.67与6,因此该方程的解只有当 小于某个值时才会稳定,而τ=0.01\tau=0.01τ=0.01 恰好在该范围内,因此解是稳定的。

①欧拉法代码:

function x = Eu(a,b,m,x0)
% a,b为x的取值范围
% m为单位时间的分段数,如将单位时间分为2段则m=2
% x0为x初始时刻的取值

%% 参数设置
p = 10;
q = 2;
r = 0.1;
alpha=3;
tao = 0.01;

h = 1/m;   % 步长
a_u = a/tao;   % 这是u的起始时间
b_u = b/tao;    % 这是u的终止时间
n = (b_u-a_u)/h;   % 总区间段数

t0 = a;   % 初始时间
u0 = x0;   % 初始值

%% 初始化0时刻之前的那些时间的值,有m个,再加上0时刻,总共有m+1个
u(1,1:m+1) = u0;     % 这是u_k
u(2,1:m+1) = -m:0;    % 这是t

%% 迭代计算后面时刻的值
for k = 0:n-1
    u(2,m+1+k+1) = k+1;   
    u_k = u(1,m+1+k);     % u_k
    u_km = u(1,m+1+k-m);   % u_{k-m}
    u(1,m+1+k+1) = (1 + q*h*tao/(r + (u_k)^alpha) )*u_k - tao*h*p*u_km;
end
u(2,:) = h*u(2,:);   % 转为真实时间

%% 转为x(t)
x(1,1) = x0;
x(2,1) = t0;
for k = 0:n-1
    x(1,k+2) = u(1,m+1+k+1);
    x(2,k+2) = u(2,m+1+k+1)*tao;
end
end

②改进欧拉法的代码:

function x = Eu_improve(a,b,m,x0)
% a,b为x的取值范围
% m为单位时间的分段数,如将单位时间分为2段则m=2
% x0为x初始时刻的取值

%% 参数设置
p = 10;
q = 2;
r = 0.1;
alpha=3;
tao = 0.01;

h = 1/m;    % 步长
a_u = a/tao;   % 这是u的起始时间
b_u = b/tao;    % 这是u的终止时间
n = (b_u-a_u)/h;   % 总区间段数

t0 = a;
u0 = x0;

%% 初始化0时刻之前的那些时间的值,有m个,再加上0时刻,总共有m+1个
u(1,1:m+1) = u0;     % 这是u_k
u(2,1:m+1) = -m:0;    % 这是t

%% 迭代计算后面时刻的值
for k = 0:n-1
    u(2,m+1+k+1) = k+1;   
    u_k = u(1,m+1+k);     % u_k
    u_km = u(1,m+1+k-m);   % u_{k-m}
    u_km1 = u(1,m+1+k-m+1);  % u_{k-m+1}
    a_k1 = q*tao*u_k/(r + (u_k)^alpha) - p*tao*u_km;
    a_k2 = q*tao*(u_k+h*a_k1)/( r + (u_k+h*a_k1)^alpha ) - p*tao*u_km1; 
    u(1,m+1+k+1) = u_k +h/2*(a_k1 + a_k2);
end
u(2,:) = h*u(2,:);   % 转为真实时间

%% 转为x(t)
x(1,1) = x0;
x(2,1) = t0;
for k = 0:n-1
    x(1,k+2) = u(1,m+1+k+1);
    x(2,k+2) = u(2,m+1+k+1)*tao;
end
end

③龙格库塔法

function x = LK(a,b,x0)

tao = 0.01;
lags = tao;
history = x0;
tspan = [a,b];
sol = dde23(@myddefun,lags,history,tspan);
x = [sol.y;sol.x];

% figure
% [t,x] = ode45(@myfun,[0 5],1);
% plot(t,x)
end


% function dxdt = myfun(t,x)
% p = 10;
% q = 2;
% r = 0.1;
% alpha=3;
% tao = 0.01;
% dxdt = -p*x.*(t-tao) + q*x./(r + (x).^alpha);
% 
% end

④主程序

clear,clc

% 参数设置
m =2;    % 步长h=1/m
x0 = 1;  % 初始值
a = 0;   % 区间左端点
b = 10;   % 区间右端点

% 欧拉法
x1 = Eu(a,b,m,x0);

% 改进欧拉法
x2 = Eu_improve(a,b,m,x0);

% 龙格-库塔法
x3 = LK(a,b,x0);

% 平稳性分析
p = 10;
q = 2;
r = 0.1;
alpha=3;
tao = 0.01;
h = 1/m;   % 步长
suan1 = q^2/(h*alpha*tao);
suan2 = p*(q-p*r)-q^2;
if suan1 < suan2
    disp('对任意tau>=0都是渐进稳定的')
else
    disp('在[0,tau_0)上是渐进稳定的')
end

% 绘图
plot(x1(2,:),x1(1,:),'*');
hold on
plot(x2(2,:),x2(1,:),'x');
plot(x3(2,:),x3(1,:),'o');
legend('欧拉法','改进欧拉法','龙格-库塔法','location','best')
xlabel('t')
ylabel('x(t)')
set(gca,'linewidth',1.1)

(4)比较两种方法的差别。
通过综合观察图1-4,不难发现,对于一阶时滞微分方程(1)的求解,两种方法得到的结果几乎一致,且都与准确解吻合得非常好。因此可以认为,即使在大多数情况下或者说从理论的角度来讲,欧拉法存在着明显的不足,但是在某些情况下欧拉法求得的解仍然比较好,且由于欧拉法相较于改进欧拉法以及龙格库塔法而言逻辑简单通俗易懂且容易实现的特点,往往更具有实用价值。

### 使用MATLAB求解时滞微分方程的数值解法 在MATLAB中,可以通过内置函数 `dde23` 来解决具有固定延迟的时滞微分方程。该方法适用于求解形式为 \(y'(t) = f(t, y(t), y(t-\tau))\) 的时滞微分方程[^5]。 #### 函数定义 首先需要定义描述系统的函数文件。假设我们有时滞微分方程: \[ y'(t) = g(y(t), y(t-\tau)) \] 其中 \(\tau\) 是固定的时滞时间。下面是个具体的例子来说明如何设置此函数。 ```matlab function dydt = ddefun(t,y,Z) % Z(:,1) is the value of y(t-tau). tau = 1; % Example delay time. dydt = y - Z; % Replace with your actual equation. end ``` 在这个例子中,\(g(y(t), y(t-\tau)) = y(t) - y(t-\tau)\)。 #### 初始历史条件 接着要指定初始的历史状态。这通常通过个匿名函数或者单独的个函数文件完成。 ```matlab history = @(t) 1; % Initial condition or history function. ``` 这里设定的是在整个延迟时间段内的初始值都等于1。 #### 调用dde23并绘图 最后调用 `dde23` 并绘制结果。 ```matlab sol = dde23(@ddefun,[1],@history,[0, 5]); % Solve from t=0 to t=5. % Plotting the result figure; plot(sol.x,sol.y); title('Solution of DDE'); xlabel('Time t'); ylabel('y(t)'); grid on; % Evaluate and plot at specific points if needed tint = linspace(0,5,10); Sint = deval(sol,tint); hold on; plot(tint,Sint,'o','MarkerFaceColor','red'); legend('DDE Solution','Evaluated Points'); ``` 以上代码展示了完整的流程:从定义模型到获取解决方案以及可视化结果[^5]。 ### 注意事项 - 确保所使用的延迟时间和范围合理。 - 如果遇到复杂的非线性情况可能需要调整参数或尝试其他更高级的方法如ddesd等[^5]。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三只佩奇不结义

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值