四阶龙格库塔法的编程(赵)
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语言)

题目: 设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实现

% 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 法引言:数值计算是现代科学和工程中的一个重要领域,它涉及到通过计算机模拟来解决数学问题。
在数值计算中,求解微分方程是一个常见的任务。
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是一种用于算法开发、数据分析、可视化和数值计算的高级技术计算语言和交互式环境。
作为一个强大的工具,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算法求解原理四阶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)方法求常微分方程

中南大学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 圆。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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质点的轨迹。