微分方程的数值求解
一阶差分求解微分方程原理:
d y d x = f ( x n , y n ) \dfrac{dy}{dx}=f(x_n,y_n) dxdy=f(xn,yn)
y n + 1 − y n x n + 1 − x n = f ( x n , y n ) \dfrac{y_{n+1}-y_n}{x_{n+1}-x_n}=f(x_n,y_n) xn+1−xnyn+1−yn=f(xn,yn)
令 h = x n + 1 − x n h = x_{n+1} - x_n h=xn+1−xn
y n + 1 = y n + h f ( x n , y n ) y_{n+1}=y_n+hf(x_n,y_n) yn+1=yn+hf(xn,yn)
例子:
{
d
y
d
x
=
x
y
y
0
=
1
\begin{cases} \dfrac{dy}{dx}=xy\\ y_0 = 1 \end{cases}
⎩
⎨
⎧dxdy=xyy0=1
通过高等数学可以求得解析解为: y = e 1 2 x 2 y=e^{\frac{1}{2}x^2} y=e21x2
如果通过一阶差分求解
{
y
n
+
1
=
y
n
+
h
x
n
y
n
x
n
+
1
=
x
n
+
h
y
0
=
1
x
0
=
0
\begin{cases} y_{n+1}=y_n+hx_ny_n\\ x_{n+1}=x_n+h\\ y_0 = 1\\ x_0 = 0 \end{cases}
⎩
⎨
⎧yn+1=yn+hxnynxn+1=xn+hy0=1x0=0
matlab求解:
y = zeros(1,1000);
x = zeros(1,1000);
y(1)=1;
x(1)=0;
h=0.1;
for n=1:1000
y(n+1)=y(n)+h*x(n)*y(n);
x(n+1)=x(n)+h;
end
plot(x,y,'-');
xlim([0,6]);
ylim([0,100]);
如果再加上解析解
y = zeros(1,1000);
x = zeros(1,1000);
y(1)=1;
x(1)=0;
h=0.1;
for n=1:1000
y(n+1)=y(n)+h*x(n)*y(n);
x(n+1)=x(n)+h;
end
plot(x,y,'-');
hold on;
ezplot('exp(x^2/2)');
xlim([0,6]);
ylim([0,100]);
h=0.01如下图
四阶龙格-库塔方法
原理/公式
优点:精度高
ezplot('exp(x^2/2)');
hold on;
%四阶龙格-库塔方法
y = zeros(1,1000);
x = zeros(1,1000);
y(1)=1;
x(1)=0;
h=0.1;
for n=1:1000
k1 = h*(x(n)*y(n));%h*f(x(n),y(n))
k2 = h*((x(n)+h/2)*(y(n)+k1/2));%h*f(x(n)+h/2,y(n)+k1/2)
k3 = h*((x(n)+h/2)*(y(n)+k2/2));%h*f(x(n)+h/2,y(n)+k2/2)
k4 = h*((x(n)+h)*(y(n)+k3));%h*f(x(n)+h,y(n)+k3)
y(n+1)=y(n)+(1/6)*(k1+2*k2+2*k3+k4);
y(1)=1;
x(n+1)=x(n)+h;
end
plot(x,y,'-');
xlim([0,6]);
ylim([0,100]);
细看是两条线
应用:小船渡河问题:
河宽100米,A(0,100) , O(0,0),水流速
V
1
V_1
V1,小船速度
V
2
V_2
V2,水流速度始终垂直OA并向下流冲(方向不变)
从O到A点,求轨迹路线图和时间
与
V
2
V_2
V2平行的相量
(
−
x
,
100
,
−
y
)
(-x,100,-y)
(−x,100,−y)
c o s θ = − x x 2 + ( 100 − y ) 2 cos_{\theta} = \dfrac{-x}{\sqrt{x^2}+(100-y)^2} cosθ=x2+(100−y)2−x
s i n θ = 100 − y x 2 + ( 100 − y ) 2 sin_{\theta} = \dfrac{100-y}{\sqrt{x^2}+(100-y)^2} sinθ=x2+(100−y)2100−y
{ d y d t = V 2 s i n θ d x d t = X 1 + V 2 c o s θ \begin{cases} \dfrac{dy}{dt}=V_2sin_{\theta}\\ \dfrac{dx}{dt}=X_1+V_2cos_{\theta} \end{cases} ⎩ ⎨ ⎧dtdy=V2sinθdtdx=X1+V2cosθ
d y d x = V 2 s i n θ V 1 + V 2 c o s θ = V 2 ( 100 − y ) x 2 + ( 100 − y ) 2 V 1 − V 2 x \dfrac{dy}{dx}=\dfrac{V_2sin_{\theta}}{V_1+V_2cos_{\theta}}=\dfrac{V_2(100-y)}{\sqrt{x^2+(100-y)^2}V_1-V_2x} dxdy=V1+V2cosθV2sinθ=x2+(100−y)2V1−V2xV2(100−y)
因为 x x x变量随着 y y y增大有增有减,而 y y y变量随着 x x x增大有递增,所以 y y y为自变量可以求解
变换后:
d
x
d
y
=
V
1
+
V
2
c
o
s
θ
V
2
s
i
n
θ
=
x
2
+
(
100
−
y
)
2
V
1
−
V
2
x
V
2
(
100
−
y
)
\dfrac{dx}{dy}=\dfrac{V_1+V_2cos_{\theta}}{V_2sin_{\theta}}=\dfrac{\sqrt{x^2+(100-y)^2}V_1-V_2x}{V_2(100-y)}
dydx=V2sinθV1+V2cosθ=V2(100−y)x2+(100−y)2V1−V2x
x 0 = y 0 = 0 x_0 = y_0 = 0 x0=y0=0
y = zeros(1,1000);
x = zeros(1,1000);
x(1)=0;
y(1)=0;
v1=30;
v2=200;
h=0.1;
%差分求解轨迹
for n=1:1000 %1000*h = 100
x(n+1)=x(n)+h*((sqrt(x(n)^2+(100-y(n))^2)*v1-v2*x(n))/(v2*(100-y(n))));
y(n+1)=y(n)+h;
end
plot(x,y,'-');
hold on;
%四阶龙格-库塔方法求轨迹
y = zeros(1,1000);
x = zeros(1,1000);
x(1)=0;
y(1)=0;
for n=1:1000
k1 = h*((sqrt(x(n)^2+(100-y(n))^2)*v1-v2*x(n))/(v2*(100-y(n))));%h*f(x(n),y(n))
k2 = h*((sqrt((x(n)+h/2)^2+(100-(y(n)+k1/2))^2)*v1-v2*(x(n)+h/2))/(v2*(100-(y(n)+k1/2))));%h*f(x(n)+h/2,y(n)+k1/2)
k3 = h*((sqrt((x(n)+h/2)^2+(100-(y(n)+k2/2))^2)*v1-v2*(x(n)+h/2))/(v2*(100-(y(n)+k2/2))));%h*f(x(n)+h/2,y(n)+k2/2)
k4 = h*((sqrt((x(n)+h)^2+(100-(y(n)+k3))^2)*v1-v2*(x(n)+h))/(v2*(100-(y(n)+k3))));%h*f(x(n)+h,y(n)+k3)
x(n+1)=x(n)+(1/6)*(k1+2*k2+2*k3+k4);
y(n+1)=y(n)+h;
end
plot(x,y,'-');
%(sqrt(x(n)^2+(100-y(n))^2)
%差分求解时间
t = zeros(1,1000);
for n=1:1000
t(n+1)=t(n)+h*(1/(v2*(100-y(n))/(sqrt(x(n)^2+(100-y(n))^2))));
end
xlim([0,10]);
ylim([0,100]);
使用特解验证时间算的对不对
进阶求二阶微分方程
例子:
{
y
′
′
−
2
y
′
+
y
=
0
y
0
=
1
y
0
′
=
2
\begin{cases} y''-2y'+y=0\\ y_0=1\\ y'_0=2 \end{cases}
⎩
⎨
⎧y′′−2y′+y=0y0=1y0′=2
解析解为:
y
=
e
x
+
x
e
x
y=e^x+xe^x
y=ex+xex
差分求解:
设
y
1
=
y
,
y
2
=
y
′
y_1=y,y_2=y'
y1=y,y2=y′
则
{
y
1
′
=
y
2
y
2
′
=
2
y
2
−
y
1
y
1
0
=
1
y
2
0
=
2
\begin{cases} y_1'=y2\\ y_2'=2y_2-y_1\\ y_{1_0}=1\\ y_{2_0}=2 \end{cases}
⎩
⎨
⎧y1′=y2y2′=2y2−y1y10=1y20=2
y1 = zeros(1,1000);
y2 = zeros(1,1000);
x = zeros(1,1000);
y1(1)=1;
y2(1)=2;
x(1)=0;
h=0.01;
xlim([0,6]);
ylim([0,100]);
for n=1:1000
y2(n+1)=y2(n)+h*(2*y2(n)-y1(n));
y1(n+1)=y1(n)+h*y2(n);
x(n+1)=x(n)+h;
end
%plot(x,y1,'-');
hold on;
%四阶龙格-库塔方法
y1 = zeros(1,1000);
y2 = zeros(1,1000);
x = zeros(1,1000);
y1(1)=1;
y2(1)=2;
x(1)=0;
for n=1:1000
k1 = h*(2*y2(n)-y1(n));%h*f(x(n),y(n))
k2 = h*(2*(y2(n)+k1/2)-(y1(n)+h/2));%h*f(x(n)+h/2,y(n)+k1/2)
k3 = h*(2*(y2(n)+k2/2)-(y1(n)+h/2));%h*f(x(n)+h/2,y(n)+k2/2)
k4 = h*(2*(y2(n)+k3)-(y1(n)+h));%h*f(x(n)+h,y(n)+k3)
y2(n+1)=y2(n)+(1/6)*(k1+2*k2+2*k3+k4);
k1 = h*y2(n);%h*f(x(n),y1(n))
k2 = h*(y2(n)+h/2);%h*f(x(n)+h/2,y(n)+k1/2)
k3 = h*(y2(n)+h/2);%h*f(x(n)+h/2,y(n)+k2/2)
k4 = h*(y2(n)+h);%h*f(x(n)+h,y(n)+k3)
y1(n+1)=y1(n)+(1/6)*(k1+2*k2+2*k3+k4);
x(n+1)=x(n)+h;
end
plot(x,y1,'-');
%解析解
ezplot('exp(x)+x*exp(x)');
xlim([0,6]);
ylim([0,100]);