四阶龙格库塔法的编程(赵)

合集下载

c++经典四阶龙格库塔法解一阶微分方程组

c++经典四阶龙格库塔法解一阶微分方程组

首先,龙格库塔法(Runge-Kutta method)是一种常用的数值积分算法,它可以用来数值地求解一阶常微分方程(ODE)。

对于一维ODE,经典的四阶龙格库塔法(RK4)是最常用的方法之一。

下面是一个使用C++实现经典四阶龙格库塔法解一阶微分方程组的示例代码:cpp#include <iostream>#include <vector>// 定义微分方程组dy/dx = f(x, y)std::vector<double> f(double x, const std::vector<double>& y) {std::vector<double> dy(y.size());// 此处为具体的微分方程组表达式,请根据实际需求来定义dy[0] = x * y[0]; // 示例中假设有一个一维微分方程y' = x*yreturn dy;}// 经典四阶龙格库塔法void rk4(double x0, double y0, double h, int numSteps) {double x = x0;double y = y0;for (int i = 0; i < numSteps; ++i) {std::vector<double> k1 = f(x, std::vector<double>{y});std::vector<double> k2 = f(x + h / 2, std::vector<double>{y + h * k1[0] / 2});std::vector<double> k3 = f(x + h / 2, std::vector<double>{y + h * k2[0] / 2});std::vector<double> k4 = f(x + h, std::vector<double>{y + h * k3[0]});y += h * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]) / 6;x += h;std::cout << "x: " << x << ", y: " << y << std::endl;}}int main() {double x0 = 0.0; // 初值xdouble y0 = 1.0; // 初值ydouble h = 0.1; // 步长int numSteps = 10; // 迭代次数rk4(x0, y0, h, numSteps);return 0;}请注意,这只是一个简单的示例代码,用于演示如何使用经典四阶龙格库塔法求解一维微分方程组。

四阶龙格库塔求解边界层问题(C语言)

四阶龙格库塔求解边界层问题(C语言)

题目: 设52/ 1.110/m s μρ-=⨯的气体以10/v m s ∞=的速度以零攻角定常扰流长度为L =1m 的大平板,用数值解讨论边界层内的流动规律。

如图所示,沿板面方向取x 坐标,板的法线方向取y 坐标。

在流体力学中,介绍了存在相似性解的二维平面不可压缩流体的边界层方程:C.E :0=∂∂+∂∂yx u υM.E : 221y udx dp y u x u u ∂∂+-=∂∂+∂∂νρυ0p y∂=∂ 边界条件为:y = 0;u = v = 0y =∞;u =v ∞ ( u = u (x) 为x 点处壁面势流流速 )在外边界上221122e e p v p v c ρρ∞+=+=所以 00e dpdx+=对于平板扰流,则平板扰流的边界层方程可简化为 C.E :0=∂∂+∂∂yx u υ M.E : 22u u uu x y yυν∂∂∂+=∂∂∂ 其定解的边界条件为y = 0;u = v = 0y =∞;u =v ∞为了求解边界层方程,我们可以利用“相似性解”的方法,对其进行转化,由C.E ,引进流函数),(y x ψ,令xy u ∂∂-=∂∂=ψυψ, 由M.E 式的偏导阶次,可望减少自变量数目令()yg x η==()()f f v g x η∞== 其中2x x ηη∂=-∂1()y g x η∂=∂ 由()v g x f ψ∞=,得()'v g x fu v f y yψ∞∞∂∂===∂∂ ()()(')2v g x f v g x v f f x x xψη∞∞∂∂=-==-∂∂ 所以,(')"2v u v f f x x x η∞∞∂∂==-∂∂(')"()v u v f f y y g x ∞∞∂∂==∂∂222(")"'()()v v u f f y y g x g x ∞∞∂∂==∂∂ 将其都代入M.E ,化简可得"'"0f ff += 这就使原方程变化为:"'"0f ff +=此时的边界条件为:η = 0;f(0) = 0 , f’(0) = 0η = ∞;f’(∞) = 1那么,如何利用编辑程序的方法求解这个变化后的边界层微分方程呢?一. 解方程的基本思路为了简化运算,此时边界层微分方程化简成:"'"0f ff +=,边界条件不变。

四阶龙格——库塔法

四阶龙格——库塔法

四阶龙格——库塔法2013-2014(1)专业课程实践论文题目:四阶龙格—库塔法一、算法理论由定义可知,一种数值方法的精度与局部截断误差()po h有关,用一阶泰勒展开式近似函数得到欧拉方法,其局部截断误差为一阶泰勒余项2()o h,故是一阶方法,完全类似地若用p阶泰勒展开式2'''()11()()()......()()2!!pp p n n n n n h h y y x hy x y x y x O h p ++=+++++ 进行离散化,所得计算公式必为p 阶方法,式中'''''()(,),()(,)(,)(,)....x y x f x y y x f x y f x y f x y ==++由此,我们能够想到,通过提高泰勒展开式的阶数,可以得到高精度的数值方法,从理论上讲,只要微分方程的解()y x 充分光滑,泰勒展开方法可以构造任意的有限阶的计算公式,但事实上,具体构造这种公式往往相当困难,因为符合函数(,())f x y x 的高阶导数常常是很烦琐的,因此,泰勒展开方法一般不直接使用,但是我们可以间接使用泰勒展开方法,求得高精度的计算方法。

首先,我们对欧拉公式和改进欧拉公式的形式作进一步的分析。

如果将欧拉公式和改进的欧拉公式改写成如下的形式:欧拉公式{111(,)n n n n y y hK K f x y +==+改进的欧拉公式11211()22n n y y h K K +=++, 1(,)n n K f x y =,21(,)n n K f x h y hK =++。

这两组公式都是用函数(,)f x y 在某些点上的值的线性组合来计算1()n y x +的近似值1n y +,欧拉公式每前进一步,就计算一次(,)f x y 的值。

另一方面它是1()n y x +在n x 处的一阶泰勒展开式,因而是一阶方法。

改进的欧拉公式每前进一步,需要计算两次(,)f x y 的值。

四阶龙格库塔法matlab实现

四阶龙格库塔法matlab实现
% [x0 xn]是计算范围
% hh 是步长
%% ===输入判断===
if (4 == nargin) % == 当没有给步长的时候使用默认步长==
h = 0.1 ;
elseif (5 == nargin)
h = hh ;
end
%% ===参数初始化(可以修改,可从网上找相关参数的值),以下是通用参数===
废话不多说直接复制就可以运行文章底部有参考例子不明白就看看
四阶龙格库塔法matlab实现
% 废话不多说,直接复制就可以运行,文章底部有参考例子,不明白就看看
function [ yy ] = R_K_4( f , y0 , x0 , xn , hh )
% f 是inline function的句柄
% y0 是初始值
end
elseif (1 == nargout)
yy = y ;
else
disp('error : please check your input') ;
return ;
end
end
%% === 例子=======
%
% === input =========
% f = inline('x+y'') ;
% x: 0.800000 y: 2.651042
% x: 1.000000 y: 3.436502
y(k+1) = y(k) + h* ( c(1)*kk(1) + c(2)*kk(2) + c(3)*kk(3) + c(4)*kk(4) ) ;
end
%% ===输出处理===
if (0 == nargout)

matlab经典的4级4阶runge kutta法 -回复

matlab经典的4级4阶runge kutta法 -回复

matlab经典的4级4阶runge kutta法-回复使用MATLAB 实现经典的4 阶4 级Runge-Kutta 法引言:数值计算是现代科学和工程中的一个重要领域,它涉及到通过计算机模拟来解决数学问题。

在数值计算中,求解微分方程是一个常见的任务。

Runge-Kutta 法是求解微分方程的一种常见方法,它可以用于数值求解常微分方程和偏微分方程。

本文将介绍经典的4 级4 阶Runge-Kutta 法的原理,并使用MATLAB 来实现该方法。

一、原理介绍:Runge-Kutta 法是数值计算领域中最常用的方法之一。

它通过将微分方程的解逐步逼近来求解微分方程。

经典的4 级4 阶Runge-Kutta 法基于以下公式:\begin{align*}k_1 &= h f(t_n, y_n) \\k_2 &= h f(t_n + \frac{h}{2}, y_n + \frac{k_1}{2}) \\k_3 &= h f(t_n + \frac{h}{2}, y_n + \frac{k_2}{2}) \\k_4 &= h f(t_n + h, y_n + k_3) \\y_{n+1} &= y_n + \frac{1}{6}(k_1 + 2k_2 + 2k_3 + k_4)\end{align*}其中,h 是步长,t_n 是当前时间点,y_n 是当前的解,f(t, y) 是微分方程的右手函数。

二、算法实现:现在我们将使用MATLAB 实现经典的4 级4 阶Runge-Kutta 法,并解决一个简单的一阶常微分方程。

首先,我们定义一个MATLAB 函数,用于实现4 级4 阶Runge-Kutta 法。

函数接受输入参数为微分方程的右手函数f(t, y),初始时间t_0,初始解y_0,以及步长h。

函数输出为一个数组,包含了每个时间点的解。

以下是MATLAB 代码实现:matlabfunction y = runge_kutta(f, t0, y0, h, num_steps)初始化解数组y = zeros(num_steps+1, 1);y(1) = y0;循环计算每个时间点的解for i = 1:num_stepst = t0 + (i-1)*h;计算k1, k2, k3, 和k4k1 = h * f(t, y(i));k2 = h * f(t + h/2, y(i) + k1/2);k3 = h * f(t + h/2, y(i) + k2/2);k4 = h * f(t + h, y(i) + k3);计算下一个时间点的解y(i+1) = y(i) + (k1 + 2*k2 + 2*k3 + k4)/6;endend接下来,我们使用这个函数来解决一个简单的一阶常微分方程。

matlab经典的4级4阶runge kutta法

matlab经典的4级4阶runge kutta法

MATLAB是一种用于算法开发、数据分析、可视化和数值计算的高级技术计算语言和交互式环境。

作为一个强大的工具,MATLAB提供了许多数值计算方法,其中4级4阶Runge-Kutta方法就是其中之一。

1. Runge-Kutta方法简介Runge-Kutta方法是求解常微分方程(ODE)的数值方法之一。

在MATLAB中,用户可以使用内置的ode45函数来调用4级4阶Runge-Kutta方法。

具体来说,4级4阶Runge-Kutta方法是一种单步迭代方法,通过在每个步骤中计算斜率来逐步逼近解析解。

它的优点是数值稳定性好,适用于多种类型的微分方程。

2. Runge-Kutta方法的公式4级4阶Runge-Kutta方法的一般形式如下:$$k_1 = hf(t_n, y_n)$$$$k_2 = hf(t_n + \frac{1}{2}h, y_n + \frac{1}{2}k_1)$$$$k_3 = hf(t_n + \frac{1}{2}h, y_n + \frac{1}{2}k_2)$$$$k_4 = hf(t_n + h, y_n + k_3)$$$$y_{n+1} = y_n + \frac{1}{6}(k_1 + 2k_2 + 2k_3 + k_4)$$其中,$t_n$是当前的独立变量值,$y_n$是当前的解向量,h是步长,$f(t_n, y_n)$是给定点$(t_n, y_n)$处的斜率。

通过不断迭代上述公式,可以逐步求解微分方程的数值解。

3. MATLAB中的4级4阶Runge-Kutta方法的应用在MATLAB中,用户可以使用ode45函数调用4级4阶Runge-Kutta方法来求解常微分方程。

使用ode45函数的基本语法如下:```matlab[t, y] = ode45(odefun, tspan, y0)```其中,odefun是用户定义的ODE函数句柄,tspan指定了求解的时间范围,y0是初始条件。

matlab利用四阶runge-kutta算法求解原理

matlab利用四阶runge-kutta算法求解原理

matlab利用四阶runge-kutta算法求解原理四阶Runge-Kutta(RK4)方法是一种常用的数值求解常微分方程(ODEs)的方法。

下面是RK4方法的基本原理,以及如何在MATLAB中实现:###基本原理:1.ODE表示:我们考虑形如dy/dx=f(x,y)的常微分方程,其中y是未知函数,f是给定的函数。

2.离散化:我们将x轴上的区间分成若干小步长h。

我们的目标是找到每一步上的y值。

3.四阶Runge-Kutta公式:这个方法的核心是通过四个中间步骤来逼近每一步的斜率,然后计算新的y值。

具体的步骤如下:-k1=h*f(x_n,y_n)-k2=h*f(x_n+h/2,y_n+k1/2)-k3=h*f(x_n+h/2,y_n+k2/2)-k4=h*f(x_n+h,y_n+k3)其中,x_n和y_n是当前步的x和y值,h是步长。

新的y值计算为:y_{n+1}=y_n+(k1+2*k2+2*k3+k4)/6###在MATLAB中的实现:在MATLAB中,你可以使用以下的代码来实现四阶Runge-Kutta算法:```matlabfunction[x,y]=runge_kutta_4th_order(f,x0,y0,h,x_end)x=x0:h:x_end;y=zeros(size(x));y(1)=y0;for i=1:(length(x)-1)k1=h*f(x(i),y(i));k2=h*f(x(i)+h/2,y(i)+k1/2);k3=h*f(x(i)+h/2,y(i)+k2/2);k4=h*f(x(i)+h,y(i)+k3);y(i+1)=y(i)+(k1+2*k2+2*k3+k4)/6;endend```这个函数接受一个ODE的右侧函数f,初始值x0和y0,步长h,以及求解的终点x_end。

返回的x和y包含了在给定区间内的解。

你可以调用这个函数并提供你自己的ODE右侧函数f。

四阶龙格-库塔(R-K)方法求常微分方程

四阶龙格-库塔(R-K)方法求常微分方程

中南大学MATLAB程序设计实践材料科学与工程学院2013年3月26日一、编程实现“四阶龙格-库塔(R-K)方法求常微分方程”,并举一例应用之。

【实例】采用龙格-库塔法求微分方程:,0)(1'00x x y y y 1、算法说明:在龙格-库塔法中,四阶龙格-库塔法的局部截断误差约为o(h5),被广泛应用于解微分方程的初值问题。

其算法公式为:)22(63211k k k h y y nn其中:),()21,21()21,21(),(3423121hk y h x f k hk y h x f k hk y h x f k y x f k n nn n n n n n 2、流程图:2.1、四阶龙格-库塔(R-K )方法流程图:2.2、实例求解流程图:输入待求微分方程、求解的自变量范围、初值以及求解范围内的取点数等。

确定求解范围内的步长k = 取点数?否求解:),()21,21()21,21(),(3423121hk y h x f k hk y h x f k hk y h x f k y x f k n nnn n n n n 求解并输出:)22(63211k k k h y y nn是结束算法开始输入求解的自变量范围求出待求简单微分方程的真值解用MA TLAB自带函数ode23求解待求微分方程用自编函数四阶龙格-库塔(R-K)方法求解待求微分方程结束3、源程序代码3.1、四阶龙格-库塔(R-K)方法源程序:function [x,y] = MyRunge_Kutta(fun,x0,xt,y0,PointNum,varargin)%Runge-Kutta 方法解微分方程形为 y'(t)=f(x,y(x))%此程序可解高阶的微分方程。

只要将其形式写为上述微分方程的向量形式%函数 f(x,y): fun%自变量的初值和终值:x0, xt%y0表示函数在x0处的值,输入初值为列向量形式%自变量在[x0,xt]上取的点数:PointNum%varargin为可输入项,可传适当参数给函数f(x,y)%x:所取的点的x值%y:对应点上的函数值if nargin<4 | PointNum<=0PointNum=100;endif nargin<3y0=0;endy(1,:)=y0(:)'; %初值存为行向量形式h=(xt-x0)/(PointNum-1); %计算步长x=x0+[0:(PointNum-1)]'*h; %得x向量值for k=1:(PointNum) %迭代计算f1=h*feval(fun,x(k),y(k,:),varargin{:});f1=f1(:)'; %得公式k1 f2=h*feval(fun,x(k)+h/2,y(k,:)+f1/2,varargin{:});f2=f2(:)'; %得公式k2 f3=h*feval(fun,x(k)+h/2,y(k,:)+f2/2,varargin{:});f3=f3(:)'; %得公式k3 f4=h*feval(fun,x(k)+h,y(k,:)+f3,varargin{:});f4=f4(:)'; %得公式k4 y(k+1,:)=y(k,:)+(f1+2*(f2+f3)+f4)/6; %得y(n+1) end3.2、实例求解源程序:%运行四阶R-K法clear, clc %清除内存中的变量x0=0;xt=2;Num=100;h=(xt-x0)/(Num-1);x=x0+[0:Num]*h;a=1;yt=1-exp(-a*x); %真值解fun=inline('-y+1','x','y'); %用inline构造函数f(x,y)y0=0; %设定函数初值PointNum=5; %设定取点数[x1,y1]=ode23(fun,[0,2],0);[xr,yr]=MyRunge_Kutta(fun,x0,xt,y0,PointNum);MyRunge_Kutta_x=xr'MyRunge_Kutta_y=yr'plot(x,yt,'k',x1,y1,'b--',xr,yr,'r-')legend('真值','ode23','Rung-Kutta法解',2)hold onplot(x1,y1,'bo',xr,yr,'r*')4、程序运行结果:MyRunge_Kutta_x =0 0.5000 1.0000 1.5000 2.0000MyRunge_Kutta_y =0 0.3932 0.6318 0.7766 0.8645二、变成解决以下科学计算问题:(一)[例7-2-4] 材料力学复杂应力状态的分析——Moore 圆。

常微分方程组的四阶RUNGEKUTTA龙格库塔法MATLAB实现

常微分方程组的四阶RUNGEKUTTA龙格库塔法MATLAB实现

常微分方程组的四阶RUNGEKUTTA龙格库塔法MATLAB实现欢迎使用 Python 版的实现!数值解常微分方程组的四阶 Runge-Kutta 方法(也被称为 RK4 方法)可以通过迭代的方式逐步逼近精确解。

对于一阶常微分方程组:dy/dt = f(t, y)我们可以通过下面的公式来计算下一个时间步长上的近似解:y(n+1)=y(n)+(1/6)(k1+2k2+2k3+k4)其中k1=h*f(t(n),y(n))k2=h*f(t(n)+h/2,y(n)+k1/2)k3=h*f(t(n)+h/2,y(n)+k2/2)k4=h*f(t(n)+h,y(n)+k3)这里,h代表时间步长,t(n)代表当前时间,y(n)代表当前解。

f(t,y)是给定的方程组。

对于四阶 Runge-Kutta 方法的 MATLAB 实现,可以按照以下步骤进行。

1.首先,定义需要求解的常微分方程组。

function dydt = equations(t, y)dydt = zeros(2, 1);dydt(1) = y(2); % 根据方程组的具体形式修改dydt(2) = -y(1); % 根据方程组的具体形式修改end2.定义RK4方法的求解函数。

function [t, y] = rk4_solver(equations, tspan, y0, h) t = tspan(1):h:tspan(2);y = zeros(length(y0), length(t));y(:,1)=y0;for i = 1:length(t)-1k1 = h * equations(t(i), y(:, i));k2 = h * equations(t(i) + h/2, y(:, i) + k1/2);k3 = h * equations(t(i) + h/2, y(:, i) + k2/2);k4 = h * equations(t(i) + h, y(:, i) + k3);y(:,i+1)=y(:,i)+(k1+2*k2+2*k3+k4)/6;endend3. 调用 rk4_solver 函数求解常微分方程组。

四阶龙格库塔法程序——FORTRAN语言编写

四阶龙格库塔法程序——FORTRAN语言编写

四阶龙格库塔法程序——FORTRAN语言编写代码:SUBROUTINE runge_kutta()!关于Runge-Kutta方法,该方法是用来解形如y'=f(t,y)的常微分方程的!经典的4阶R-K方法的公式如下:! Yn+1 = Yn + h/6 * (K1+2K2+2K3+K4)!其中! K1=f(Tn,Yn)! K2=f(Tn+h/2,Yn+h/2*K1)! K3=f(Tn+h/2,Yn+h/2*K2)! K4=f(Tn+h,Yn+h*K3)!type(node_fish),pointer :: p!integer :: i,j!!-----STEP 1 :保存Yndo i=1,Num_londo j=1,Num_latYn%nutrients(i,j) = patches(i,j)%core%nutrientsYn%planktons(i,j) = patches(i,j)%core%planktonsend doend do!if (anchovy%Num_node>Lim_fish) call abort('ERROR(dt01):too many fishes')!p=>anchovy%head%nextdo i=1,anchovy%Num_nodeYn%fish(i)=p%value%weightp=>p%nextend do!!-----STEP 2 :依次计算K1-K4!-------STEP 2.1 :求K1,时间是t,Yn不变K1=integral_function(rt_current,Yn)!-------STEP 2.2 :求K2,时间更新到t+h/2,Yn更新到Yn+(h/2)*K1K2=integral_function(rt_current+rt_step/2.0,Yn+(rt_step/2.0 )*K1)!-------STEP 2.3 :求K3,时间更新到t+h/2,Yn更新到Yn+(h/2)*K2K3=integral_function(rt_current+rt_step/2.0,Yn+(rt_step/2.0 )*K2)!-------STEP 2.4 :求K4,时间更新到t+h,Yn更新到Yn+h*K3 K4=integral_function(rt_current+rt_step,Yn+rt_step*K3)!!-----STEP 3 :由Yn和K1-K4计算Yn+1Yn_1 = Yn + (rt_step/6.0)*(K1+2.0*K2+2.0*K3+K4)!!-----STEP 4 :赋值do i=1,Num_londo j=1,Num_latif (Yn_1%nutrients(i,j)%NO3 < min_nutrient%NO3 ) Yn_1%nutrients(i,j)%NO3 = min_nutrient%NO3if (Yn_1%nutrients(i,j)%NH4 < min_nutrient%NH4 )Yn_1%nutrients(i,j)%NH4 = min_nutrient%NH4if (Yn_1%nutrients(i,j)%PON < min_nutrient%PON ) Yn_1%nutrients(i,j)%PON = min_nutrient%PONif (Yn_1%nutrients(i,j)%DON < min_nutrient%DON ) Yn_1%nutrients(i,j)%DON = min_nutrient%DONif (Yn_1%nutrients(i,j)%SiOH4 < min_nutrient%SiOH4) Yn_1%nutrients(i,j)%SiOH4 = min_nutrient%SiOH4if (Yn_1%nutrients(i,j)%Opal < min_nutrient%Opal ) Yn_1%nutrients(i,j)%Opal = min_nutrient%Opalif (Yn_1%nutrients(i,j)%HPO4 < min_nutrient%HPO4 ) Yn_1%nutrients(i,j)%HPO4 = min_nutrient%HPO4if (Yn_1%nutrients(i,j)%POP < min_nutrient%POP ) Yn_1%nutrients(i,j)%POP = min_nutrient%POPif (Yn_1%nutrients(i,j)%DOP < min_nutrient%DOP ) Yn_1%nutrients(i,j)%DOP = min_nutrient%DOPpatches(i,j)%core%nutrients = Yn_1%nutrients(i,j)if (Yn_1%planktons(i,j)%phyto_small < min_plankton%phyto_small ) Yn_1%planktons(i,j)%phyto_small = min_plankton%phyto_smallif (Yn_1%planktons(i,j)%phyto_large < min_plankton%phyto_large ) Yn_1%planktons(i,j)%phyto_large = min_plankton%phyto_largeif (Yn_1%planktons(i,j)%zoo_small < min_plankton%zoo_small ) Yn_1%planktons(i,j)%zoo_small = min_plankton%zoo_smallif (Yn_1%planktons(i,j)%zoo_large < min_plankton%zoo_large) Yn_1%planktons(i,j)%zoo_large= min_plankton%zoo_largeif (Yn_1%planktons(i,j)%zoo_predatory <min_plankton%zoo_predatory ) Yn_1%planktons(i,j)%zoo_predatory = min_plankton%zoo_predatorypatches(i,j)%core%planktons = Yn_1%planktons(i,j)end doend do!p=>anchovy%head%nextdo i=1,anchovy%Num_nodep%value%weight = Yn_1%fish(i)p%value%growth = Yn_1%fish(i) - Yn%fish(i)call update_half_gene(p%value,rt_current+rt_step)call update_fish_state(p%value,rt_current+rt_step)p=>p%nextend do!END SUBROUTINE runge_kutta。

微分方程的数值解法matlab(四阶龙格—库塔法).ppt

微分方程的数值解法matlab(四阶龙格—库塔法).ppt

3月15日作业: 1.Van der Pol 方程的两种解法:1)采 用ode45命令 2)Runge-Kutta方法 2.Duffing 方程的求解(Runge-Kutta方法,计算步长h=0.005,计
算时间t0=0.0,tN=100)
要求:写出程序体,打印所绘图形,图形标题用个 人的名字。
Duffing 方程Fra bibliotek子程序:RK_sub.m function ydot = vdpol (t, y) ydot=zeros(size(y)); ydot(1) = y(2); ydot(2) = -y(2)*(y(1)^2-1)-y(1); 或写为:
ydot = [y(1) ;-y(2)*(y(1)^2-1)-y(1)];
K4 = ZCX_sub (t0 + h, y0 + hK3, P) Y1 = y0 + (h/6) (K1 + 2K2 + 2K3 + K4) t1, Y1 (输出 t1, y1) next i 输出数据或图形
(t ) AY (t ) P (t ) Y
Matlab 程序(子程序:ZCX_sub.m)
多步法-Admas方法
计算
的近似值 y(tn1 )
时只用到 n1
y
,是自开始方法 n n
t ,y

Runge-Kutta法是常微分方程的一种经典解法 MATLAB 对应命令:ode45
四阶Runge-Kutta公式
h yn 1 yn (k1 2k 2 2k3 k 4 ) 6 k1 f (t n , yn ) 1 h k 2 f (t n h, yn k1 ) 2 2 1 h k3 f (t n h, yn k 2 ) 2 2 k 4 f (t n h, yn hk3 )

fortran四阶龙格库塔法

fortran四阶龙格库塔法
!-------STEP 2.2 :求K2,时间更新到t+h/2,Yn更新到Yn+(h/2)*K1
K2=integral_function(rt_current+rt_step/2.0,Yn+(rt_step/2.0)*K1)
!-------STEP 2.3 :求K3,时间更新到t+h/2,Yn更新到Yn+(h/2)*K2
if (Yn_1%planktons(i,j)%zoo_small < min_plankton%zoo_small ) Yn_1%planktons(i,j)%zoo_small = min_plankton%zoo_small
if (Yn_1%planktons(i,j)%zoo_large < min_plankton%zoo_large ) Yn_1%planktons(i,j)%zoo_large = min_plankton%zoo_large
!
!-----STEP 3 :由Yn和K1-K4计算Yn+1
Yn_1 = Yn + (rt_step/6.0)*(K1+2.0*K2+2.0*K3+K4)
!
!-----STEP 4 :赋值
do i=1,Num_lon
do j=1,Num_lat
代码:
SUBROUTINE 是用来解形如y'=f(t,y)的常微分方程的
!经典的4阶R-K方法的公式如下:
! Yn+1 = Yn + h/6 * (K1+2K2+2K3+K4)
!其中
if (Yn_1%planktons(i,j)%phyto_small < min_plankton%phyto_small ) Yn_1%planktons(i,j)%phyto_small = min_plankton%phyto_small

四阶龙格库塔法

四阶龙格库塔法

经典四阶龙格库塔法
系统方程和表述如下:
则系统的输出按如下求解:
其中:
这样,下一个值(y n+1)由现在的值(y n)加上时间间隔(h)和一个估算的斜率的乘积决定。

该斜率是以下斜率的加权平均:
k1是时间段开始时的斜率;
k2是时间段中点的斜率,通过欧拉法采用斜率k1来决定y在点tn + h/2的值;
k3也是中点的斜率,但是这次采用斜率k2决定y值;
k4是时间段终点的斜率,其y值用k3决定。

当四个斜率取平均时,中点的斜率有更大的权值:
龙格库塔方法二:
当系统的稳定在一定范围内时,龙格库塔法可采用以下方法:
其中
要给定一个特定的方法,必须提供级数s以及系数a ij b i和c i .龙格库塔表如下:
龙格库塔法是自治的,如果
对第一种方法,龙格库塔表如下:
1/2 1/2
1/2 0 1/2
1 0 0 1
1/6 1/3 1/3 1/6
龙格库塔方法三:
对刚性系统,龙格库塔方法具有以下形式:其中:。

四阶龙格库塔法的编程(赵)

四阶龙格库塔法的编程(赵)

例题一四阶龙格-库塔法的具体形式为:1.1程序:/*e.g: y'=t-y,t∈[0,1]/*y(0)=0/*使用经典四阶龙格-库塔算法进行高精度求解/* y(i+1)=yi+( K1+ 2*K2 +2*K3+ K4)/6/* K1=h*f(ti,yi)/* K2=h*f(ti+h/2,yi+K1*h/2)/* K3=h*f(ti+h/2,yi+K2*h/2)/* K4=h*f(ti+h,yi+K3*h)*/#include <stdio.h>#include <math.h>#define N 20float f(float d,float p) //要求解的微分方程的右部的函数e.g: t-y {float derivative;derivative=d-p;return(derivative);}void main(){float t0; //范围上限float t; //范围下限float h; //步长float nn; //计算出的点的个数,即迭代步数int n; //对nn取整float k1,k2,k3,k4;float y[N]; //用于存放计算出的常微分方程数值解float yy; //精确值float error;//误差int i=0,j;//以下为函数的接口printf("input t0:");scanf("%f",&t0);printf("input t:");scanf("%f",&t);printf("input y[0]:");scanf("%f",&y[0]);printf("input h:");scanf("%f",&h);// 以下为核心程序nn=(t-t0)/h;printf("nn=%f\n",nn);n=(int)nn;printf("n=%d\n",n);for(j=0;j<=n;j++){yy=t0-1+exp(-t0); //解析解表达式error=y[i]-yy; //误差计算printf("y[%f]=%f yy=%f error=%f\n",t0,y[i],yy,error);//结果输出k1=h*f(t0,y[i]); //求K1k2=h*f((t0+h/2),(y[i]+k1*h/2)); //求K2k3=h*f((t0+h/2),(y[i]+k2*h/2)); //求K3k4=h*f((t0+h),(y[i]+k3*h)); //求K4y[i+1]=y[i]+((k1+2*k2+2*k3+k4)/6); //求y[i+1]t0+=float(h);i++;}}1.2结果:input t0:0input t:1input y[0]:0input h:0.2nn=5.000000n=5ti yi yy error0 0 0 00.2 0.019736 0.018731 0.001005 0.4 0.074813 0.070320 0.004493 0.6 0.158303 0.148812 0.0094910.8 0.264635 0.249329 0.0153061.0 0.389331 0.367879 0.021452图一例题二(见《高等流体力学》P45页例1.6)给定速度场u=x+t, v=-y-t, 求t=1时过(1,1)点的质点的迹线。

龙格库塔法的编程

龙格库塔法的编程

龙格库塔法的编程#include<stdlib.h>#include<stdio.h>/*n表示几等分,n+1表示他输出的个数*/int RungeKutta(double y0,double a,double b,int n,double *x,double *y,int style,double (*function)(double,double)){double h=(b-a)/n,k1,k2,k3,k4;int i;// x=(double*)malloc((n+1)*sizeof(double));// y=(double*)malloc((n+1)*sizeof(double));x[0]=a;y[0]=y0;switch(style){case 2:for(i=0;i<n;i++){x[i+1]=x[i]+h;k1=function(x[i],y[i]);k2=function(x[i]+h/2,y[i]+h*k1/2);y[i+1]=y[i]+h*k2;}break;case 3:for(i=0;i<n;i++){x[i+1]=x[i]+h;k1=function(x[i],y[i]);k2=function(x[i]+h/2,y[i]+h*k1/2);k3=function(x[i]+h,y[i]-h*k1+2*h*k2);y[i+1]=y[i]+h*(k1+4*k2+k3)/6;}break;case 4:for(i=0;i<n;i++){x[i+1]=x[i]+h;k1=function(x[i],y[i]);k2=function(x[i]+h/2,y[i]+h*k1/2);k3=function(x[i]+h/2,y[i]+h*k2/2);k4=function(x[i]+h,y[i]+h*k3);y[i+1]=y[i]+h*(k1+2*k2+2*k3+k4)/6;}break;default:return 0;}return 1;}double function(double x,double y){return y-2*x/y;}//例子求y'=y-2*x/y(0<x<1);y0=1;/*int main(){double x[6],y[6];printf("用二阶龙格-库塔方法\n"); RungeKutta(1,0,1,5,x,y,2,function);for(int i=0;i<6;i++)printf("x[%d]=%f,y[%d]=%f\n",i,x[i],i,y[i]); printf("用三阶龙格-库塔方法\n"); RungeKutta(1,0,1,5,x,y,3,function);for(i=0;i<6;i++)printf("x[%d]=%f,y[%d]=%f\n",i,x[i],i,y[i]); printf("用四阶龙格-库塔方法\n"); RungeKutta(1,0,1,5,x,y,4,function);for(i=0;i<6;i++)printf("x[%d]=%f,y[%d]=%f\n",i,x[i],i,y[i]); return 1;龙格库塔法的c++编程2007-08-12 22:41:52| 分类:MatLab/Maple/Mat|字号订阅from: /forum/viewthread.php?tid=25801&highlight=%BF% E2%CB%FE龙格库塔法的c++编程CODE:#include<stdlib.h>#include<stdio.h>/*n表示几等分,n+1表示他输出的个数*/int RungeKutta(double y0,double a,double b,int n,double *x,double *y,intstyle,double (*function)(double,double)){double h=(b-a)/n,k1,k2,k3,k4;int i;// x=(double*)malloc((n+1)*sizeof(double));// y=(double*)malloc((n+1)*sizeof(double));x[0]=a;y[0]=y0;switch(style){case 2:for(i=0;i<n;i++){x[i+1]=x[i]+h;k1=function(x[i],y[i]);k2=function(x[i]+h/2,y[i]+h*k1/2);y[i+1]=y[i]+h*k2;}break;case 3:for(i=0;i<n;i++){x[i+1]=x[i]+h;k1=function(x[i],y[i]);k2=function(x[i]+h/2,y[i]+h*k1/2);k3=function(x[i]+h,y[i]-h*k1+2*h*k2); y[i+1]=y[i]+h*(k1+4*k2+k3)/6;}break;case 4:for(i=0;i<n;i++){x[i+1]=x[i]+h;k1=function(x[i],y[i]);k2=function(x[i]+h/2,y[i]+h*k1/2);k3=function(x[i]+h/2,y[i]+h*k2/2);k4=function(x[i]+h,y[i]+h*k3);y[i+1]=y[i]+h*(k1+2*k2+2*k3+k4)/6; }break;default:return 0;}return 1;}double function(double x,double y){return y-2*x/y;}//例子求⎩⎨⎧=<<*-='1)10(/20y x y x y y/*int main(){double x[6],y[6];printf("用二阶龙格-库塔方法\n");RungeKutta(1,0,1,5,x,y,2,function);for(int i=0;i<6;i++)printf("x[%d]=%f,y[%d]=%f\n",i,x[i],i,y[i]);printf("用三阶龙格-库塔方法\n");RungeKutta(1,0,1,5,x,y,3,function);for(i=0;i<6;i++)printf("x[%d]=%f,y[%d]=%f\n",i,x[i],i,y[i]);printf("用四阶龙格-库塔方法\n");RungeKutta(1,0,1,5,x,y,4,function);for(i=0;i<6;i++)printf("x[%d]=%f,y[%d]=%f\n",i,x[i],i,y[i]);return 1;龙格库塔求解微分方程数值解工程中很多的地方用到龙格库塔求解微分方程的数值解,龙格库塔是很重要的一种方法,尤其是四阶的,精确度相当的高。

定步长四阶龙格-库塔(Runge-Kutta)法

定步长四阶龙格-库塔(Runge-Kutta)法

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''' 模块名:定步长四阶龙格_库塔_Runge_Kutta_法.bas' 功能:解一阶常微分方程组的初值问题。

子过程Runge_Kutta由给定步长h和初始点上的值用四阶龙格-库塔法' 求解给定的初值问题,调用它一次向前积分一步,一般用于求解某一小区间中某几点的函数值;' 子过程Runge_KuttaDumb是连续调用于过程Runge_Kutta()计算出某一区间上的值,此时该区间长度可较' 大,但积分步长都较小。

一般来说,在精度要求不高时,可采用该方法''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''Option Explicit''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''' 模块名:定步长四阶龙格_库塔_Runge_Kutta_法.bas' 函数名:Runge_KuttaDumb(n,x1,x2,nstep,vstart(),xx(),y())' 功能:解一阶常微分方程组的初值问题。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

例题一
四阶龙格-库塔法的具体形式为:
1.1程序:
/*e.g: y'=t-y,t∈[0,1]
/*y(0)=0
/*使用经典四阶龙格-库塔算法进行高精度求解
/* y(i+1)=yi+( K1+ 2*K2 +2*K3+ K4)/6
/* K1=h*f(ti,yi)
/* K2=h*f(ti+h/2,yi+K1*h/2)
/* K3=h*f(ti+h/2,yi+K2*h/2)
/* K4=h*f(ti+h,yi+K3*h)
*/
#include <stdio.h>
#include <math.h>
#define N 20
float f(float d,float p) //要求解的微分方程的右部的函数e.g: t-y {
float derivative;
derivative=d-p;
return(derivative);
}
void main()
{
float t0; //范围上限
float t; //范围下限
float h; //步长
float nn; //计算出的点的个数,即迭代步数
int n; //对nn取整
float k1,k2,k3,k4;
float y[N]; //用于存放计算出的常微分方程数值解
float yy; //精确值
float error;//误差
int i=0,j;
//以下为函数的接口
printf("input t0:");
scanf("%f",&t0);
printf("input t:");
scanf("%f",&t);
printf("input y[0]:");
scanf("%f",&y[0]);
printf("input h:");
scanf("%f",&h);
// 以下为核心程序
nn=(t-t0)/h;
printf("nn=%f\n",nn);
n=(int)nn;
printf("n=%d\n",n);
for(j=0;j<=n;j++)
{
yy=t0-1+exp(-t0); //解析解表达式
error=y[i]-yy; //误差计算
printf("y[%f]=%f yy=%f error=%f\n",t0,y[i],yy,error);//结果输出k1=h*f(t0,y[i]); //求K1
k2=h*f((t0+h/2),(y[i]+k1*h/2)); //求K2
k3=h*f((t0+h/2),(y[i]+k2*h/2)); //求K3
k4=h*f((t0+h),(y[i]+k3*h)); //求K4
y[i+1]=y[i]+((k1+2*k2+2*k3+k4)/6); //求y[i+1]
t0+=float(h);
i++;
}
}
1.2结果:
input t0:0
input t:1
input y[0]:0
input h:0.2
nn=5.000000
n=5
ti yi yy error
0 0 0 0
0.2 0.019736 0.018731 0.001005 0.4 0.074813 0.070320 0.004493 0.6 0.158303 0.148812 0.009491
0.8 0.264635 0.249329 0.015306
1.0 0.389331 0.367879 0.021452
图一
例题二(见《高等流体力学》P45页例1.6)
给定速度场u=x+t, v=-y-t, 求t=1时过(1,1)点的质点的迹线。

解答:由迹线微分方程dx/dt= x+t, dy/dt=-y-t
积分得x=Ae t – t -1, y=Be-t – t + 1
t=1时过(1,1)点的质点有
A=3/e , B=e
最后得此质点的迹线方程为:
x=3e t -1– t -1, y=e-1-t – t + 1
2.1 程序
#include <stdio.h>
#include <math.h>
#define N 20
//定义微分方程
float fx(float dd,float pp)
{
float der;
der=dd+pp;
return(der);
}
float fy(float d,float p)
{
float derivative;
derivative=-d-p;
return(derivative);
}
void main()
{
float t0; //范围上限
float t; //范围下限
float h; //步长
float nn; //计算出的点的个数,即迭代步数
int n; //对nn取整
float k1,k2,k3,k4,k11,k22,k33,k44;
float x[N],y[N]; //用于存放计算出的常微分方程数值解
float xx,yy; //精确值
float errorx,errory;//误差
int i=0,j;
//以下为函数的接口
printf("input t0:");
scanf("%f",&t0);
printf("input t:");
scanf("%f",&t);
printf("input x[0]:");
scanf("%f",&x[0]);
printf("input y[0]:");
scanf("%f",&y[0]);
printf("input h:");
scanf("%f",&h);
// 以下为核心程序
nn=(t-t0)/h;
printf("nn=%f\n",nn);
n=int(nn);
printf("n=%d\n",n);
for(j=0;j<=n;j++)
{
xx=3*exp(t0-1)-t0-1; //解析解表达式
yy=exp(1-t0)-t0+1;
errorx=x[i]-xx; //误差计算
errory=y[i]-yy;
printf("x[%f]=%f xx=%f errorx=%f\n",t0,x[i],xx,errorx);//结果输出printf("y[%f]=%f yy=%f errory=%f\n",t0,y[i],yy,errory);
k1=h*fx(t0,x[i]); //求K1
k2=h*fx((t0+h/2),(x[i]+k1*h/2)); //求K2
k3=h*fx((t0+h/2),(x[i]+k2*h/2)); //求K3
k4=h*fx((t0+h),(x[i]+k3*h)); //求K4
x[i+1]=x[i]+((k1+2*k2+2*k3+k4)/6); //求x[i+1]
k11=h*fy(t0,y[i]); //求K11
k22=h*fy((t0+h/2),(y[i]+k11*h/2)); //求K22
k33=h*fy((t0+h/2),(y[i]+k22*h/2)); //求K33
k44=h*fy((t0+h),(y[i]+k33*h)); //求K44
y[i+1]=y[i]+((k11+2*k22+2*k33+k44)/6); //求y[i+1]
t0+=float(h);
i++;
}
}
2.2 结果
input t0:1
input t:2
input x[0]:1
input y[0]:1
input h:0.2
nn=5.000000
n=5
ti xi xx errorx yi yy errory 1.0 1 1 0 1 1 0
1.2 1.428377 1.464208 -0.035831 0.588158 0.618731 -0.030573 1.4 1.984977
2.075475 -0.090498 0.217849 0.270320 -0.052471 1.6 2.695964 2.866357 -0.170393 -0.119071 -0.051189 -0.067882
1.8 3.592841 3.876624 -0.283783 -0.429147 -0.350671 -0.078476
2.0 4.713541 5.154847 -0.441306 -0.717643 -0.632121 -0.085522
图二:t=1至t=2质点的轨迹。

相关文档
最新文档