英文:
Runge-Kutta-4th-order solution of 3 ODEs MATLAB
问题
Lorenz方程如下:
参数值:sigma = 10,b = 8/3,r = 28。采用初始条件x = y = z = 5,从t = 0到20进行积分。对于这种情况,我们将使用四阶RK方法以恒定时间步长h = 0.03125来获得解。
需要在绘制x相对于t的图后获得的图形如下:
然而,获得的数值收敛到零,因此yl(end,1) = -6.49e-48。我们实际得到的图形是:
给出的代码如下。运行LorenzPlot.m以获得图形。你能提供代码的修正吗?谢谢。
LorenzPlot.m
h = 0.03125; % 步长
tspan = [0 20]; % 时间间隔
y0 = [5 5 5]; % 初始条件
a = 10;
b = 8/3;
r = 28;
[tl, yl] = rk4sys(@lorenz,tspan,y0,h,a,b,r); % RK4解
% 使用RK4方法的时间序列图
figure(1)
plot(tl,yl(1:end,1))
legend('x = y = z = 5')
title('RK4时间图')
xlabel('时间')
ylabel('数量')
rk4sys.m
function [tp,yp] = rk4sys(dydt,tspan,y0,h,varargin)
% 参考: Chapra, S. C. (2018). 应用数值方法与 MATLAB® 工程师和科学家的第四版,pp.602-603
% rk4sys: 用于一组ODE的四阶Runge-Kutta
% [t,y] = rk4sys(dydt,tspan,y0,h,p1,p2,...): 用四阶RK方法积分ODE组
% 输入:
% dydt = 评估ODE的M文件的名称
% tspan = [ti, tf]; 输出的初始和最终时间间隔
% 使用间隔h,或者
% = [t0 t1 ... tf]; 在特定时间生成解决方案输出
% y0 = 依赖变量的初始值
% h = 步长
% p1,p2,... = dydt使用的附加参数
% 输出:
% tp = 自变量向量
% yp = 依赖变量的解向量
if nargin < 4,error('至少需要4个输入参数'), end
if any(diff(tspan) <= 0),error('tspan不是升序的'), end
n = length(tspan);
ti = tspan(1);tf = tspan(n);
if n == 2
t = (ti:h:tf)'; n = length(t);
if t(n) < tf
t(n + 1) = tf;
n = n + 1;
end
else
t = tspan;
end
tt = ti; y(1,:) = y0;
np = 1; tp(np) = tt; yp(np,:) = y(1,:);
i = 1;
while(1)
tend = t(np + 1);
hh = t(np + 1) - t(np);
if hh > h,hh = h;end
while(1)
if tt+hh > tend,hh = tend-tt;end
k1 = dydt(tt,y(i,:),varargin{:})';
ymid = y(i,:) + k1*hh/2;
k2 = dydt(tt + hh/2,ymid,varargin{:})';
ymid = y(i,:) + k2*hh/2;
k3 = dydt(tt + hh/2,ymid,varargin{:})';
yend = y(i,:) + k3*hh;
k4 = dydt(tt + hh,yend,varargin{:})';
phi = (k1 + 2*(k2 + k3) + k4)/6;
y(i + 1,:) = y(i,:) + phi*hh;
tt = tt + hh;
i = i + 1;
if tt >= tend,break,end
end
np = np + 1; tp(np) = tt; yp(np,:) = y(i,:);
if tt >= tf,break,end
end
lorenz.m
function yl = lorenz(t,y,a,b,r)
yl = [-a*y(1)-a*y(2);
r*y(1)-y(2)-y(1)*y(3);
-b*y(3)+y(1)*y(2)];
end
英文:
Lorenz equations are as follows:
Lorenz Equations
Parameter values: sigma = 10, b = 8/3, and r = 28. Employ initial conditions of x = y = z = 5 and integrate from t = 0 to 20. For this case, we will use the fourth-order RK method to obtain solutions with a constant time step of h = 0.03125.
Graph we need to obtain after plotting x, which is y(1), versus t is as follows:
t vs x actual
However obtained numerical values converge to zero, so that yl(end,1) = -6.49e-48. The graph we get instead is:
Codes are given below. LorenzPlot.m is run to obtain the graph.Can you please provide the corrections for the code? Thanks.
LorenzPlot.m
h = 0.03125; % Stepsize
tspan = [0 20]; % Time interval
y0 = [5 5 5]; % Initial conditions
a = 10;
b = 8/3;
r = 28;
[tl, yl] = rk4sys(@lorenz,tspan,y0,h,a,b,r); % RK4 solution
% Time-series plot using RK4 method
figure(1)
plot(tl,yl(1:end,1))
legend('x = y = z = 5')
title('RK4 time plot')
xlabel("Time")
ylabel("Quantity")
rk4sys.m
function [tp,yp] = rk4sys(dydt,tspan,y0,h,varargin)
% Reference: Chapra, S. C. (2018). Applied Numerical Methods
% with MATLAB® for Engineers and Scientists Fourth Edition, pp.602-603
% rk4sys: fourth-order Runge-Kutta for a system of ODEs
% [t,y] = rk4sys(dydt,tspan,y0,h,p1,p2,...): integrates
% a system of ODEs with fourth-order RK method
% input:
% dydt = name of the M-file that evaluates the ODEs
% tspan = [ti, tf]; initial and final times with output
% generated at interval of h, or
% = [t0 t1 ... tf]; specific times where solution output
% y0 = initial values of dependent variables
% h = step size
% p1,p2,... = additional parameters used by dydt
% output:
% tp = vector of independent variable
% yp = vector of solution for dependent variables
if nargin < 4,error('at least 4 input arguments required'), end
if any(diff(tspan)<= 0),error('tspan not ascending order'), end
n = length(tspan);
ti = tspan(1);tf = tspan(n);
if n == 2
t = (ti:h:tf)'; n = length(t);
if t(n)<tf
t(n + 1) = tf;
n = n + 1;
end
else
t = tspan;
end
tt = ti; y(1,:) = y0;
np = 1; tp(np) = tt; yp(np,:) = y(1,:);
i = 1;
while(1)
tend = t(np + 1);
hh = t(np + 1) - t(np);
if hh > h,hh = h;end
while(1)
if tt+hh > tend,hh = tend-tt;end
k1 = dydt(tt,y(i,:),varargin{:})';
ymid = y(i,:) + k1*hh/2;
k2 = dydt(tt + hh/2,ymid,varargin{:})';
ymid = y(i,:) + k2*hh/2;
k3 = dydt(tt + hh/2,ymid,varargin{:})';
yend = y(i,:) + k3*hh;
k4 = dydt(tt + hh,yend,varargin{:})';
phi = (k1 + 2*(k2 + k3) + k4)/6;
y(i + 1,:) = y(i,:) + phi*hh;
tt = tt + hh;
i = i + 1;
if tt >= tend,break,end
end
np = np + 1; tp(np) = tt; yp(np,:) = y(i,:);
if tt >= tf,break,end
end
lorenz.m
function yl = lorenz(t,y,a,b,r)
yl = [-a*y(1)-a*y(2);
r*y(1)-y(2)-y(1)*y(3);
-b*y(3)+y(1)*y(2)];
end
答案1
得分: 1
你的第一个Lorenz方程似乎有误,应该如下:
更改lorenz函数中的符号似乎可以纠正错误:
function yl = lorenz(t,y,a,b,r)
yl = [-a*y(1)+a*y(2);
r*y(1)-y(2)-y(1)*y(3);
-b*y(3)+y(1)*y(2)];
end
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论