微分方程的基本概念
微分方程:一般的,凡表示未知函数、未知函数的导数与自变量之间的关系的方程,叫做微分方程,有时也简称方程。
微分方程的阶:微分方程中所出现的未知函数的最高阶导数的阶数,叫做微分方程的阶。
微分方程的解:使得微分方程成立的函数称为微分方程的解。不含任意常数的解称为微分方程的特解。若微分方程的解中所含的相互独立的任意常数的个数与微分方程的阶数相等,称这个解为微分方程的通解。
微分方程的通解:如果微分方程的解中含有任意常数,且任意常数的个数与微分方程的阶数相同,这样的解叫做微分方程的通解。
微分方程的解析解
一般只有比较简单的微分方程才能求出解析解,后面做建模一般都是求数值解。
这里我们讲的基本都是直接用MATLAB程序算的
MATLAB求解命令为
dsolve(‘方程1’, ‘方程2’,…‘方程n’, ‘初始条件’, ‘自变量’)
记号:在表达微分方程时,用字母D表示求微分,D2、D3等表示求高阶微分.任何D后所跟的字母为因变量,自变量可以指定或由系统规则选定为确省.
例一:求 d u d t = 1 + u 2 \frac{du}{dt}=1+u^2dtdu=1+u2通解
dsolve('Du=1+u^2','t')
tan(C1 + t)%通解
1i%虚数+i、-i数值解
-1i
例二:
{ d 2 y d x 2 + 4 d y d x + 29 y = 0 y ( 0 ) = 0 y ′ ( 0 ) = 15 \begin{cases} \frac{d^2y}{dx^2}+4\frac{dy}{dx}+29y=0 \\ y(0)=0\\ y'(0)=15 \end{cases}⎩⎪⎨⎪⎧dx2d2y+4dxdy+29y=0y(0)=0y′(0)=15
y=dsolve('D2y+4*Dy+29*y=0','y(0)=0,Dy(0)=15','x')
y =
3*sin(5*x)*exp(-2*x)
[x,y,z]=dsolve('Dx=2*x-3*y+3*z','Dy=4*x-5*y+3*z','Dz=4*x-4*y+2*z', 't');
x=simplify(x) % 将x化简
y=simplify(y)
z=simplify(z)
x =
C1*exp(-t) + C3*exp(2*t)
y =
exp(-2*t)*(C2 + C1*exp(t) + C3*exp(4*t))
z =
C2*exp(-2*t) + C3*exp(2*t)
微分方程的数值解
定义
在生产和科研中所处理的微分方程往往很复杂且大多得不出一般解。而在实际上对初值问题,一般是要求得到解在若干个点上满足规定精确度的近似值,或者得到一个满足精确度要求的便于计算的表达式。因此,研究常微分方程的数值解法是十分必要的。
建立数值解法的一些途径
1、欧拉法。
用差商代替导数
若步长h较小,则有
故有公式:
改进的欧拉法
使用数值积分
对方程 y’=f(x, y), 两边由xi到xi+1积分,并利用梯形公式,有:
实际应用时,与欧拉公式结合使用:
使用泰勒公式
以此方法为基础,有龙格-库塔法、线性多步法等方法。具体的太麻烦了,用的时候直接用MATLAB调函数就行。k越大,则数值公式的精度越高。
数值公式的精度
当一个数值公式的截断误差可表示为$O(h^{k+1})时(k为正整数,h为步长),称它是一个k阶公式。
欧拉法是一阶公式,改进的欧拉法是二阶公式。
龙格-库塔法有二阶公式和四阶公式。
线性多步法有四阶阿达姆斯外插公式和内插公式。
用Matlab软件求常微分方程的数值解
具体详细的可以help一下看看,我也不是多明白,嘿嘿,就不说了。
注意:
在解n个未知函数的方程组时,x0和x均为n维向量,m-文件中的待解方程组应以x的分量形式写成.
使用Matlab软件求数值解时,高阶微分方程必须等价地变换成一阶微分方程组.
没看懂?不要紧,看个例子就会了
{ d 2 x d t 2 − 1000 ( 1 − x 2 ) d x d t + x = 0 x ( 0 ) = 2 x ′ ( 0 ) = 0 \begin{cases} \frac{d^2x}{dt^2}-1000(1-x^2)\frac{dx}{dt}+x=0 \\ x(0)=2\\ x'(0)=0 \end{cases}⎩⎪⎨⎪⎧dt2d2x−1000(1−x2)dtdx+x=0x(0)=2x′(0)=0
由上面第一个式子可以知道,这是一个二阶微分方程,我们先对其降阶。
令y 1 = x , y 2 = x ′ y_1=x,y_2=x'y1=x,y2=x′ 然后带入上面的方程可以得到
MATLAB求解过程:
建立 .m 文件vdp1000.m如下:
function dy=vdp1000(t,y)
dy=zeros(2,1);%初始化
dy(1)=y(2);
dy(2)=1000*(1-y(1)^2)*y(2)-y(1);
2、取t0=0,tf=3000,输入命令:
[T,Y]=ode15s('vdp1000',[0 3000],[2 0]); %[2 0]表示初值
plot(T,Y(:,1),'-')
结果如图所示,具体T Y的值看工作区
建模实例解析
导弹追踪问题
设位于坐标原点的甲舰向位于x轴上点A(1, 0)处的乙舰发射导弹,导弹头始终对准乙舰.如果乙舰以最大的速度v0(是常数)沿平行于y轴的直线行驶,导弹的速度是5v0,求导弹运行的曲线方程.又乙舰行驶多远时,导弹将它击中?
解法一、解析法
设t时刻,导弹的坐标为P : ( x ( t ) , y ( t ) ) , P:(x(t),y(t)),P:(x(t),y(t)),乙舰坐标为Q : ( 1 , v 0 t ) Q:(1,v_0t)Q:(1,v0t)示意图如下
可以得到y ′ y'y′的导数即t a n ( θ ) tan(\theta)tan(θ)为:
y ′ = t a n ( θ ) = v 0 t − y 1 − x y'=tan(\theta)=\frac{v_0t-y}{1-x}y′=tan(θ)=1−xv0t−y (1)
化简为
v 0 t = ( 1 − x ) y ′ + y v_0t=(1-x)y'+yv0t=(1−x)y′+y
根据题意,导弹的速度是战舰的5倍,所以导弹的弧长,为战舰路程的5倍(时间一样都为t),由弧长公式可以得到:
联立公式1,2,对x求导(注意这里不是求偏导,y是x的函数,所以( ( 1 − x ) y ′ ) ′ = − y ′ + ( 1 − x ) y ′ ′ ((1-x)y')'=-y'+(1-x)y''((1−x)y′)′=−y′+(1−x)y′′,)可以化简为
初始条件为y ( 0 ) = 0 , y ′ ( 0 ) = 0 y(0)=0,y'(0)=0y(0)=0,y′(0)=0
这里就可以求y的解析式了,也就是这个微分方程的通解
MATLAB代码和结果为
y=dsolve('(1-x)*D2y-sqrt(1+Dy^2)/5=0','y(0)=0','Dy(0)=0','x')
y=simplify(y)
(5*(-1)^(1/5)*(x - 1)^(4/5))/8 + (5*(-1)^(4/5)*(x - 1)^(6/5))/12 + 5/24
- (5*(-1)^(1/5)*(x - 1)^(4/5))/8 - (5*(-1)^(4/5)*(x - 1)^(6/5))/12 - 5/24
可以看到,有两个结果,上面那个是沿着y轴正向行驶,下面是负向行驶
当两者的坐标相等时,两者相遇,所以x=1时
syms x
f(x)= (5*(-1)^(1/5)*(x - 1)^(4/5))/8 + (5*(-1)^(4/5)*(x - 1)^(6/5))/12 + 5/24;
f(1)
ans =
5/24
所以击中时的坐标为(1,5/24),也就是行驶5/24时被击中
解法二、数值解
令y1=y,y2=y1’,将方程(3)化为一阶微分方程组。
然后MATLAB求数值解,先建立.m函数
function dy=eq1(x,y)
dy=zeros(2,1);
dy(1)=y(2);
dy(2)=1/5*sqrt(1+y(1)^2)/(1-x);
再求解画图
[x,y]=ode15s('eq1',[0 1],[0 0]);
plot(x,y(:,1),'b')
hold on
y=0:0.1:2;
plot(1,y,'b^')
y
2.0000
最后一个y值为0.2000与5/24=0.2083相差不大
解法三、建立参数方程求数值解
设时刻t乙舰的坐标为(X(t),Y(t)),导弹的坐标为(x(t),y(t)).设导弹速度恒为w,则 ( d x d t ) 2 + ( d y d t ) 2 = w 2 (\frac{dx}{dt})^2+(\frac{dy}{dt})^2=w^2(dtdx)2+(dtdy)2=w2
由于弹头始终对准乙舰,故导弹的速度平行于乙舰与导弹头位置的差向量,二者成比例
将(2)分开算带入(1),消去参数得
因乙舰以速度v0沿直线x=1运动,设v0=1,则w=5,X=1,Y=t
因此导弹运动轨迹的参数方程为:
令x = y x , y = y 2 x=y_x,y=y_2x=yx,y=y2
%.m函数文件来
function dy=eq2(t,y)
dy=zeros(2,1);
dy(1)=5*(1-y(1))/sqrt((1-y(1))^2+(t-y(2))^2);
dy(2)=5*(t-y(2))/sqrt((1-y(1))^2+(t-y(2))^2)
%主程序
[t,y]=ode45('eq2',[0 2],[0 0]);
Y=0:0.01:2;
plot(1,Y,'-'), hold on
plot(y(:,1),y(:,2),'*')
1.9891
结果 1.9891 三种算法结果都差不多