数值解常微分方程(三)

数值解常微分方程(三)

使用R语言数值求解ODE方程的包为deSolve,基本语法格式为

ode(y, times, func, parms, ...)

y为初始条件,time表示时间(自变量),func为函数,parms表示参数。绝对和相对误差默认为atol = 1e-6,rtol = 1e-6


1 一元微分方程

使用deSolve包求解如下微分方程
y ′ = s i n ( 2 x ) + c o s ( y ) , y ( 0 ) = 1 y' = sin(2x)+cos(y),y(0)=1 y=sin(2x)+cos(y),y(0)=1

library(deSolve) 
# 一元微分方程
# 参数和初值
m <- 2; n <- 1; yini <- 1
# 微分方程
derivs <- function(x, y, parms) list(sin(m*x)+cos(n*y))
# 自变量区间离散化
x <- seq(from = -10, to = 5, by = 0.1) 
# ode求解
out <- ode(y = yini, times = x, func = derivs, parms = NULL)

yini <- 2
out2 <- ode(y = yini, times = x, func = derivs, parms = NULL)

yini <- 3
out3 <- ode(y = yini, times = x, func = derivs, parms = NULL)

plot(out,out2,out3, main = " ", lwd = 5,xlab = "x",
     ylab = "y",cex.lab = 1.5,cex.axis = 1.5)
grid(lwd = 1,col = "black")

在这里插入图片描述


2 多元微分方程组

对于多元一阶微分方程组,也可以使用对应的数值方法求解。例如
y i ′ = f i ( x , y 1 , y 2 , … y N ) y i ( 0 ) = y i 0 , i = 1 , 2 … N \begin{aligned} y'_i=f_i(x,y_1,y_2,\dots y_N)\\ y_i(0)& = y_i^0,i = 1,2\dots N \end{aligned} yi=fi(x,y1,y2,yN)yi(0)=yi0,i=1,2N
将其写作向量格式
y ′ = f ( x , y ) y ( x 0 ) = y 0 \begin{aligned} &\boldsymbol{y'} = \boldsymbol{f}(x,\boldsymbol{y})\\ &\boldsymbol{y}(x_0)=\boldsymbol{y}_0 \end{aligned} y=f(x,y)y(x0)=y0
对应的R-K四阶公式为
{ y k + 1 = y k + h ( 1 6 K 1 + 2 6 K 2 + 2 6 K 3 + 1 6 K 4 ) K 1 = f ( x k , y k ) K 2 = f ( x k + h / 2 , y k + h K 1 / 2 ) K 3 = f ( x k + h / 2 , y k + h K 2 / 2 ) K 4 = f ( x k + h , y k + h K 3 ) \left\{\begin{array}{l} \boldsymbol{y}_{k+1}&=\boldsymbol{y}_k+h(\dfrac{1}{6}\boldsymbol{K}_1+\dfrac{2}{6}\boldsymbol{K}_2+\dfrac{2}{6}\boldsymbol{K}_3+\dfrac{1}{6}\boldsymbol{K}_4)\\ \boldsymbol{K}_1&=f(x_k,\boldsymbol{y}_k)\\ \boldsymbol{K}_2&=f(x_k+h/2,\boldsymbol{y}_k+h\boldsymbol{K}_1/2)\\ \boldsymbol{K}_3&=f(x_k+h/2,\boldsymbol{y}_k+h\boldsymbol{K}_2/2)\\ \boldsymbol{K}_4&=f(x_k+h,\boldsymbol{y}_k+h\boldsymbol{K}_3)\\ \end{array}\right. yk+1K1K2K3K4=yk+h(61K1+62K2+62K3+61K4)=f(xk,yk)=f(xk+h/2,yk+hK1/2)=f(xk+h/2,yk+hK2/2)=f(xk+h,yk+hK3)
使用deSlove包采用rk4方法即可求解。例如求解如下三元一阶常微分方程组
{ y 1 ′ = s i n ( y 2 y 3 ) y 2 ′ = c o s ( y 1 y 3 ) y 3 ′ = s i n ( y 1 − y 2 ) ( y 1 , y 2 , y 3 ) = ( 0 , 0 , 0 ) , x ∈ ( 0 , 20 ) \left\{\begin{array}{l} y_1' = sin(y_2y_3)\\ y_2' =cos(y_1y_3)\\ y_3' = sin(y_1-y_2)\\ (y_1,y_2,y_3)=(0,0,0),x\in(0,20) \end{array}\right. y1=sin(y2y3)y2=cos(y1y3)y3=sin(y1y2)(y1,y2,y3)=(0,0,0),x(0,20)

# 多元微分方程组
yini <- c(0,0,0)
multieq <- function(x,y,parms){
  dy1 <- sin(y[2] * y[3]+y[2])
  dy2 <- cos(y[1] * y[3])
  dy3 <- y[2]*y[1]
  list(c(dy1, dy2, dy3))
}
t <- seq(from = 0, to = 10, by = 0.05) 
out <- ode (times = t, y = yini, func = multieq, 
            parms = NULL, method = rkMethod("rk45ck"))
matplot(x = out[,1], y = out[,-1], type = "l", lwd = 2, lty = "solid", 
        col = c("red", "blue", "black"), xlab = "time", ylab = "y") 
legend("bottomleft", col = c("red", "blue", "black"), 
       legend = c("y1", "y2", "y3"), lwd = 2)
grid(lwd = 1,col = "black")

在这里插入图片描述

参数method可以替换为其他数值方法

# R-K方法
rkMethod()
# [1] "euler"   "rk2"     "rk4"     "rk23"    "rk23bs"  "rk34f"   "rk45f"  
# [8] "rk45ck"  "rk45e"   "rk45dp6" "rk45dp7" "rk78dp"  "rk78f"   "irk3r"  
# [15] "irk5r"   "irk4hh"  "irk6kb"  "irk4l"   "irk6l"   "ode23"   "ode45"

# 经典4阶RK方法
rkMethod("rk4")

y 1 , y 2 , y 3 y_1,y_2,y_3 y1,y2,y3绘制为3D坐标曲线

library(scatterplot3d) 
library(FactoClass)
scatterplot3d(out[,-1], type = "l", lwd = 2, xlab = "x", ylab = "y",
              zlab = "z",angle = 50,color = "red", grid=FALSE,box = FALSE,
              cex.lab = 1.3,cex.axis = 1.3)

addgrids3d(out[,-1], grid = c("xy", "xz", "yz"),angle = 50,col.grid = "blue",
           lty.grid = 5)

在这里插入图片描述


3 高阶微分方程

高阶微分方程可以通过换元法使高阶微分方程转化为一阶微分方程组。例如对于一般形式的高阶微分方程
y ( m ) = f ( x , y , y ′ , y ′ ′ … y ( m − 1 ) ) y^{(m)} = f(x,y,y',y''\dots y^{(m-1)}) y(m)=f(x,y,y,y′′y(m1))
其中初始条件
y ( x 0 ) = y 0 , y ′ ( x 0 ) = y 0 ′ , … y ( m − 1 ) ( x 0 ) = y 0 ( m − 1 ) y(x_0) = y_0,y'(x_0)=y'_0,\dots y^{(m-1)}(x_0)=y^{(m-1)}_0 y(x0)=y0,y(x0)=y0,y(m1)(x0)=y0(m1)
引进新变量
y 1 = y , y 2 = y 1 ′ , … , y m = y ( m − 1 ) y_1=y, y_2=y'_1 ,\dots,y_m=y^{(m-1)} y1=y,y2=y1,,ym=y(m1)
得到如下一阶 m m m元微分方程组
{ y 1 ′ = y 2 y 2 ′ = y 3 ⋮ y m − 1 ′ = y m y m ′ = f ( x , y 1 , y 2 , … , y m ) \left\{\begin{array}{l} y_1'=y_2\\ y_2'=y_3\\ \vdots \\ y'_{m-1}=y_m\\ y'_m = f(x,y_1,y_2,\dots,y_m) \end{array}\right. y1=y2y2=y3ym1=ymym=f(x,y1,y2,,ym)
对应初始条件为
y 1 ( x 0 ) = y 0 , y 2 ( x 0 ) = y 0 ′ , … , y m ( x 0 ) = y 0 ( m − 1 ) y_1(x_0)=y_0,y_2(x_0)=y'_0,\dots,y_m(x_0)=y^{(m-1)}_0 y1(x0)=y0,y2(x0)=y0,,ym(x0)=y0(m1)
此时使用多元一阶微分方程组的数值解法即可。


参考书籍:

李庆扬等,数值分析[M]. 北京: 清华大学出版社, 2008.

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值