-
$\开始组$ 有关参考,请参见 SO上的这个答案 . $\端组$ – 约翰·亚历克休 评论 2018年3月24日15:22
5个答案
$k_0=hf(x_i,y_i,z_i)$ $l_0=hg(x_i,y_i,z_i)$ $k_1=hf(x_i+压裂{1} {2} 小时 ,y_i+\压裂{1} {2} 千0 ,z_i+\压裂{1} {2} l0(零) )$ $1=hg(x_i+压裂{1} {2} 小时 ,y_i+\压裂{1} {2} 千0 ,z_i+\压裂{1} {2} l0(零) )$ $k_2=hf(x_i+压裂{1} {2} 小时 ,y_i+\压裂{1} {2} k_1 ,z_i+\压裂{1} {2} l_1级 )$ $l_2=hg(x_i+压裂{1} {2} 小时 ,y_i+\压裂{1} {2} k_1 ,z_i+\压裂{1} {2} l_1级 )$ $k_3=hf(x_i+h,y_i+k_2,z_i+l_2)$ $l3=hg(x_i+h,y_i+k_2,z_i+l2)$ $y_{i+1}=y_i+\压裂{1}{6}(k_0+2k_1+2k_2+k_3)$ $z_{i+1}=z_i+\frac{1}{6}(l0+2l1+2l2+l3)$
我们要计算的范围是:$A\le t\le b$,让我们使用$A=0,b=1$。 步骤数$N$,例如$N=10$。 步骤大小$h=\dfrac{b-a}{N}=\dfras{1}{10}$
$k_0=hf(x_0,y_0,z_0)=\dfrac{1}{10}(z_0$ $l_0=hg(x_0,y_0,z_0)=\dfrac{1}{10}(6y_0-z_0$ $k_1=hf(x_0+\压裂{1} {2} 小时 ,y_0+\压裂{1} {2} 千0 ,z0+\压裂{1} {2} l_0 )=\dfrac{1}{10}(1+\dfrac{1}{2}\dfrac}{1}}{10}(17))~~$(请继续计算。) $1=hg(x_0+\压裂{1} {2} 小时 ,y_i+\压裂{1} {2} 千0 ,z0+\压裂{1} {2} l0(零) )$ $k_2=hf(x_0+\压裂{1} {2} 小时 ,y_0+\压裂{1} {2} k_1 ,z0+\压裂{1} {2} l_1级 )$ $l_2=汞(x_0+\压裂{1} {2} 小时 ,y_0+\压裂{1} {2} k_1 ,z0+\压裂{1} {2} l_1级 )$ $k_3=hf(x_0+h,y_0+k_2,z_0+l_2)$ $l_3=汞(x_0+h,y_0+k_2,z_0+l_2)$ $y_{1}=y_0+\压裂{1}{6}(k_0+2k_1+2k_2+k_3)$ $z{1}=z_0+\压裂{1}{6}(l0+2l1+2l2+l3)$
$k_0=hf(x_1,y_1,z_1)=\dfrac{1}{10}(z_1$ $l_0=hg(x_1,y_1,z_1)=\dfrac{1}{10}(6y_1-z_1$ $k_1=hf(x_1+\压裂{1} {2} 小时 ,y_1+\压裂{1} {2} k_0 ,z_1+\压裂{1} {2} l0(零) )$ $1=hg(x_1+\压裂{1} {2} 小时 ,y1+\压裂{1} {2} 千0 ,z_1+\压裂{1} {2} l0(零) )$ $k_2=hf(x_1+\压裂{1} {2} 小时 ,y1+\压裂{1} {2} k_1 ,z_1+\frac{1} {2} l_1级 )$ $l_2=汞(x_1+\压裂{1} {2} 小时 ,y1+\压裂{1} {2} k_1 ,z_1+\压裂{1} {2} l_1级 )$ $k_3=hf(x_1+h,y_1+k_2,z_1+l_2)$ $l3=汞(x_1+h,y_1+k_2,z_1+l_2)$ $y_{2}=y_1+\压裂{1}{6}(k_0+2k_1+2k_2+k_3)$ $z{2}=z_1+\压裂{1}{6}(l0+2l1+2l2+l3)$
-
-
1 -
1 -
1 $\开始组$ 延迟回复,但$y_i$或$z_i$是原始ODE的解决方案吗? 比较一下这些值,结果似乎是由$y_i$给出的,但我不确定。 $\端组$ 评论 2016年5月4日15:47 -
1
程序RK4 隐式无 整数,参数::dp=kind(0.d0) 整数,参数::m=2! ODE的顺序 实数(dp)::Y(m) 实数(dp)::a,b,x,h 整数::N,i ! 步骤数 N=10 ! 首字母x a=0 x=a ! 最终x b=1 ! 步长 h=(b-a)/否 ! 初始条件 Y(1)=3! y(0) Y(2)=1! y’(0) ! 迭代N次 do i=1,N Y=迭代(x,Y) x=x+h 结束do 打印*,Y 包含 ! 函数f计算向量f 函数f(x,Yvec)结果(fvec) 实数(dp)::x 实数(dp)::Yvec(m),fvec(m) fvec(1)=Yvec(2)! z(z) fvec(2)=6*Yvec(1)-Yvec! 6y-z型 末端函数 ! 函数迭代计算Y(t_n+1) 函数迭代(x,Y_n)结果(Y_nplus1) 实数(dp)::x 实数(dp)::Y_n(m),Y_nplus1(m) 实(dp)::k1(m),k2(m)、k3(m)和k4(m) k1=h*f(x,Y_n) k2=h*f(x+h/2,Y_n+k1/2) k3=h*f(x+h/2,Y_n+k2/2) k4=h*f(x+h,Y_n+k3) Y_nplus1=Y_n+(k1+2*k2+2*k3+k4)/6 end函数 结束程序
-
1 -
-
1 $\开始组$ 神奇的答案@Kai+1。 如果可能的话,会给+50! 许多人与ODE和RK方法体系斗争。 不过,关于您的Fortran实现,我有一个问题。 如果你想变花样,可以使用for循环正确地编写$k_i$? 基本上是将它们放在数组中? 那么你会有一个数组$k(i,n)$,其中i是阶段数,n是状态向量的维数? 您知道在Fortran中有这样的文档吗? 我现在正在写类似的东西,有点困惑!! $\端组$ 评论 2019年2月10日0:03 -
$\开始组$ 我注意到函数没有明确的依赖性 (f) 关于变量 x个 这是因为我们用来降低导数阶数的代换吗? 这种依赖 x个 算法通过其他变量自动拾取? $\端组$ – 疯狂物理学家 评论 2022年6月10日10:31 -
1
%它使用Runge-Kutta四阶方法计算ODE %作者Ido Schwartz %最初可用的形式: http://www.mathworks.com/matlabcentral/fileexchange/29851-runge-kutta-4th-order-ode/content/runge_kutta_4.m %阿明·A·穆罕默德(Amin A.Mohammed)主编,2部ODE(2016年4月) 分类代码;% 清除屏幕 清除所有; h=0.1;% 步长 x=0:h:1;% 最多计算y(1) y=零(1,长度(x)); z=零(1,长度(x)); y(1)=3;% 初始条件 z(1)=1;% 初始条件 %F_xy=@(t,r)3.*exp(-t)-0.4*r;% 根据需要更改功能 F_xyz=@(x,y,z)z;% 根据需要更改功能 G_xyz=@(x,y,z)6*y-z; i=1时:(长度(x)-1)%计算循环 k_1=F_xyz(x(i)、y(i)和z(i)); L_1=G_xyz(x(i),y(i)和z(i)); k_2=F_xyz(x(i)+0.5*h,y(i)=0.5*h*k_1,z(i)+0.5*h*L_1); L_2=G_xyz(x(i)+0.5*h,y(i)=0.5*h*k_1,z(i)+0.5*h*L_1); k_3=F_xyz((x(i)+0.5*h),(y(i)=0.5*h*k_2),(z(i)+0.5*h*L_2)); L_3=G_xyz((x(i)+0.5*h),(y(i)=0.5*h*k_2),(z(i)+0.5*h*L_2)); k_4=F_xyz((x(i)+h),(y(i)+k_3*h) 已更正 L_4=G_xyz((x(i)+h),(y(i)+k_3*h); y(i+1)=y(i)+(1/6)*(k_1+2*k_2+2*k_3+k_4)*h;% 主方程 z(i+1)=z(i)+(1/6)*(L_1+2*L_2+2*L_3+L_4)*h;% 主方程 结束
! Runge-Kutta四阶方法 ! 对于二阶微分方程 ! 首先必须定义函数 F(x,y,z)=z! 年月日 G(x,y,z)=6*y-z! dz/dx=d2y/dx2 整数::n,i 真实::k1,l1,k2,l2,k3,l3,k4,l4! 最重要的 写下(*,*)“给定方程'(y2)-6(y1)+(y0)=0'” 写入(*,*)“Xo=0,Yo=3,Zo=Y'o=1,Xn=1,n=?” Xo=0! 给定条件 Yo=3! 给定条件 Zo=1! 给定条件 Xn=1! 给定条件 读取(*,*)n! n=截距数 h=(Xn-Xo)/n 做i=1,n! 您必须进行“n”次计算 k1=h*F(Xo,Yo,Zo) l1=h*G(Xo,Yo,Zo) k2=h*F(Xo+h/2,Yo+k1/2,Zo+l1/2) l2=h*G(Xo+h/2,Yo+k1/2,Zo+l1/2) k3=h*F(Xo+h/2,Yo+k2/2,Zo+l2/2) l3=h*G(Xo+h/2,Yo+k2/2,Zo+l2/2) k4=h*F(Xo+h,Yo+k3,Zo+l3) l4=h*G(Xo+h,Yo+k3,Zo+l3) ! 总结 Yn=Yo+(k1+2*k2+2*k3+k4)/6 Zn=Zo+(l1+2*l2+2*l3+l4)/6 ! 下一次计算的操作 Xo=Xo+h! (+h)比上一学期 Yo=Yn! 现在Yn变成Yo Zo=锌! 现在Zn变成了Zo 结束Do 写入(*,*)“Xn,Yn=”,Xo,Yo 停止 终点
常数M:usize=2;// 系统的大小 fn主(){ 设mut y:[f64;M]=[0.0;M]; 设muta:f64=0.0; 设mut x:f64=a; 设mut b:f64=0.0; 设n:usize=10; 设h:f64=(b-a)/n为f64; //初始条件 y[0]=3.0;// y(0) y[1]=1.0;// y’(0) 对于0..n中的_i{ y=rk4_步长(x,y,h,&导数); x+=小时; } 打印! (“{:?}”,y); } //定义方程组的导数 fn导数(x:f64,y:[f64;M])->[f64,M]{ 设mut dy_dx:[f64;M]=[0.0;M]; dy_dx[0]=y[1];// dy/dx=z dy_dx[1]=6.0*y[0]-y[1];// dz/dx=6y-z dy_dx(发送日期) } //执行RK4的一步 fn rk4_步长(x:f64,y_n:[f64;M],h:f64{ 设mut k1:[f64;M]=[0.0;M]; 设mut k2:[f64;M]=[0.0;M]; 设mut k3:[f64;M]=[0.0;M]; 设mut k4:[f64;M]=[0.0;M]; 设mut y_n_plus_1:[f64;M]=[0.0;M]; k1=比例vec(&f(x,y_n),h); k2=比例vec(&f(x+h/2.0,添加vec(y_n,&scalevec(k1,0.5))),h); k3=比例vec(&f(x+h/2.0,添加vec(y_n,&scalevec(k2,0.5))),h); k4=缩放向量(&f(x+h,add_vec(&y_n,&k3)),h); y_n_plus_1=添加vec( &y_n, &缩放vec( &添加vec(&k1,&addvec(&缩放vec(-k2,2.0),&addvesc(&scalevec(k3,2.0)和&k4))), 1.0 / 6.0, ), ); y_n加1 } //Helper函数:元素向量加法 fn add_vec(a:&[f64;M],b:&[f64;M])->[f64;M]{ 设mut结果:[f64;M]=[0.0;M]; 对于0…M中的i{ 结果[i]=a[i]+b[i]; } 结果 } //Helper函数:向量的元素级标量乘法 fn scale_vec(a:&[f64;M],标量:f64)->[f64;M]{ 让多个结果:[f64;M]=[0.0;M]; 对于0…M中的i{ 结果[i]=a[i]*标量; } 结果 }