MATLAB混沌系统仿真其一:Lorenz系统和Rossler系统

文章目录

  • 前言
  • 一、混沌产生系统:Lorenz和Rossler
  • 二、龙格库塔四阶算法
  • 三、混沌吸引子轨迹
  • 四、最大李亚普诺夫指数
  • 附:完整程序


前言

MATLAB是集编程、计算及数据可视化三者于一体的软件系统。其强大的矩阵运算能力和丰富的工具箱保证了其在处理工程问题上的性能和质量。本系列主要MATLAB 2020a进行系统仿真,绘图。

一、混沌产生系统:Lorenz和Rossler

Lorenz系统是一个按Rayleigh-Bénard配置的大气对流简化模型,包含3个微分方程。Lorenz在1963年证明了这个系统中存在混沌(Lorenz认为由三变量非线性耦合微分方程描述的系统都能产生chaos,1975)。变量X、Y、Z分别表示循环流体的流速、上升和下降流体的温差和垂直温度剖面的畸变。其微分形式如下:
d x = − σ ( x − y ) dx\mathrm{=}-\sigma\left(x-y\right) dx=σ(xy) d y = r x − y − x z dy\mathrm{=}rx-y-xz dy=rxyxz d z = − β   z + x y dz\mathrm{=}-\beta\ z+xy dz=β z+xy其中控制参数 σ = 10 \sigma\mathrm{=}10 σ=10 r = 28 r\mathrm{=}28 r=28 β = 8 / 3 \beta\mathrm{=}8/3 β=8/3时也叫经典Lorenz系统,本次展示也是用这些参数。经典参数下Lorenz系统最大李亚普诺夫指数计算得2.12,系统最终将走向混沌。同时洛伦兹方程是耗散的,所有的轨迹最终进入吸收域(Viana,2000): Ω   = { x ∈   R 3 : r x 2 + σ y 2 + σ ( z − 2 r ) 2 < β 2 r 2 β − 1 } \Omega\ \mathrm{=}\left\{ {x\in}\ \mathrm{R^3}: rx^2+σy^2+σ(z-2r)^2< \frac{β^2r^2}{β-1}\right\} Ω ={x R3:rx2+σy2+σ(z2r)2<β1β2r2}这就是那个蝴蝶型的区域,Lorenz吸引子的每一条轨迹在空间上都不重合,并且总不会超出这个区域。

Rossler系统是与人为构造的与Lorenz类似可以产生混沌的系统,并没有实际的物理意义,因此不做过多赘述。其方程如下:
d x = − ( y + z ) dx=-\left(y+z\right) dx=(y+z) d y = x + a y dy=x+ay dy=x+ay d z = b + z ( x − c ) dz=b+z\left(x-c\right) dz=b+z(xc)

二、龙格库塔四阶算法

求解上述两个方程组,MATLAB提供ode函数求解,在精度要求不高时,与龙格库塔四阶算法差别不大。龙格库塔四阶算法在每个步长 h h h上使用 k 1 、 k 2 、 k 3 、 k 4 k_1、k_2、k_3、k_4 k1k2k3k4四个分别代表开始斜率、考虑 k 1 k_1 k1的中点斜率、考虑 k 2 k_2 k2的中点斜率、考虑 k 3 k_3 k3的末端斜率,取加权平均 y ( n + 1 ) = y ( n ) + h 6 ∗ ( k 1 + 2 ∗ k 2 + 2 ∗ k 3 + k 4 ) y(n+1)=y(n)+\frac{h}{6}*(k_1+2*k_2+2*k_3+k_4) y(n+1)=y(n)+6h(k1+2k2+2k3+k4)这个方法的求解具有4阶精度,跟DDE方法(实质为三阶变步长的龙格库塔算法)精度相近,但是运算更快。其代码如下:

function [t,y]=rk4(f,tspan,y0,n)
%四阶Runge-Kutta算法
%f:dy/dt=f(t,y);求解区间tspan:[t0,tf];初值y0=y(t0)=[x0,y0,z0];n采样点数
h=(tspan(2)-tspan(1))/n;
t=tspan(1):h:tspan(2);
y=zeros(length(y0),length(t));
y(:,1)=y0;
for m=2:length(t)
    k1=f(t(m-1),y(:,m-1));
    k2=f(t(m-1)+h/2,y(:,m-1)+k1*h/2);
    k3=f(t(m-1)+h/2,y(:,m-1)+k2*h/2);
    k4=f(t(m-1)+h,y(:,m-1)+k3*h);
    y(:,m)=y(:,m-1)+(k1+2*k2+2*k3+k4)*h/6;
end
t=t';
y=y';
end

其中需要首先传入一个函数的句柄,函数可由如下形式定义:

function dy_dt=lorenz(t,y)
%y=[x,y,z]储存三个变量的矩阵
p=10;
r=28;
b=8/3;

dx_dt=p*(y(2)-y(1));
dy_dt=r*y(1)-y(2)-y(1)*y(3);
dz_dt=y(1)*y(2)-b*y(3);

dy_dt=[dx_dt;dy_dt;dz_dt];
end

Rossler函数的定义相同,从Lorenz形式的方程和代码很容易写出,这里不做累述。值得一提的是,如果不是做半导体激光器速率方程那样时滞的仿真,实际上只需要简单一行代码调用ode45函数就可以出结果,但是ode函数是变步长的,因此传入的需要传入固定距离的长矩阵(见下文)。

三、混沌吸引子轨迹

运行后(完整代码见附录)即可得到蝴蝶型的吸引子。使用常规的frame方法保存图像如下:(用view函数将图像稍稍转了下)。与自带的ODE函数运行的结果几乎一致。
MATLAB混沌系统仿真其一:Lorenz系统和Rossler系统_第1张图片
Rossler吸引子如下:
Rossler吸引子

四、最大李亚普诺夫指数

如何将chaos与“噪声”和“周期特别长的序列”中区别开,最大李指数是一种不错的方法。如果一个系统具有一个正的李指数,那么它就是混沌的;正的数值越大,系统越混沌。因此也有人(吕金虎,2002,如果没记错的话)认为李指数的倒数系统可预测时间的测度,超过这个值,系统将不可预测。

此处参考Wolf博士的程序(at the University of Texas at Austin)。他用BASGEN生成数据库,与用FET生成的时间序列一起应用于监测邻近轨迹的散度来估计最大李指数。FET和BASGEN实际上都使用了延时重建和相空间重构的方法,因此实际上对结果影响较大的参数也就主要是嵌入维度、延时、演化时间,此处分别设为3,10,20。对采样出16384个点的Lorenz系统进行估计。对轨道的检测结果如下如下:
可以看出,在大部分的演化时间里,两个轨道紧紧贴合,发散程度低。下面是FET的输出,第5列是李雅普诺夫指数的估计。第5列是轨道角修正数值。
李指数预测结果
程序预测出的李指数结果为2.15,与计算值接近,因此Lorenz系统是混沌的。

(2023.7更新)
当然,MATLAB自带的程序也可以实现重构相空间与计算最大李指数。使用MATLAB自带的Lorenz数据,频率fs为100。使用phaseSpaceReconstruction函数使用平均互信息重构数据的相空间,得到维度为3,重构延时为10。数据量较大时重构的速度慢。此处lyapunovExponent的算法同样可以表示闭合相空间的轨迹分离率,计算得1.62。李指数是有单位的,由频率 f s fs fs决定,此处为 s − 1 s^{-1} s1。如果两个点处于同一起点,那么经过平均1.62s后它们的轨道将完全分离。

%使用matlab自带的Lorenz数据
load('lorenzAttractorExampleData.mat','data','fs');
xdata = data(:,1);
[~,lag,dim] = phaseSpaceReconstruction(xdata)
eg=[80 150]
lyp=lyapunovExponent(xdata,fs,lag,dim,'ExpansionRange',eg);%取值
lyapunovExponent(xdata,fs,lag,dim,'ExpansionRange',eg);%绘图

MATLAB混沌系统仿真其一:Lorenz系统和Rossler系统_第2张图片
参数ExpansionRange的选取,线性拟合越好的区间越合适。下图是一个特别大的区间[0 500],无法线性拟合,计算结果偏差就很大。
MATLAB混沌系统仿真其一:Lorenz系统和Rossler系统_第3张图片

附:完整程序

y0=[1;0;0];
tspan=[0,1e2];
[t1,y1]=rk4(@lorenz,tspan,y0,1e5);
[t2,y2]=ode45(@lorenz,tspan,y0);
plot3(y1(:,1),y1(:,2),y1(:,3));
figure();plot3(y2(:,1),y2(:,2),y2(:,3));

function [t,y]=rk4(f,tspan,y0,n)
%四阶Runge-Kutta算法
%f:dy/dt=f(t,y);求解区间tspan:[t0,tf];初值y0=y(t0)=[x0,y0,z0];n采样点数
h=(tspan(2)-tspan(1))/n;
t=tspan(1):h:tspan(2);
y=zeros(length(y0),length(t));
y(:,1)=y0;
for m=2:length(t)
    k1=f(t(m-1),y(:,m-1));
    k2=f(t(m-1)+h/2,y(:,m-1)+k1*h/2);
    k3=f(t(m-1)+h/2,y(:,m-1)+k2*h/2);
    k4=f(t(m-1)+h,y(:,m-1)+k3*h);
    y(:,m)=y(:,m-1)+(k1+2*k2+2*k3+k4)*h/6;
end
t=t';
y=y';
end

function dy_dt=lorenz(t,y)
%y=[x,y,z]储存三个变量的矩阵
p=10;
r=28;
b=8/3;
dx_dt=p*(y(2)-y(1));
dy_dt=r*y(1)-y(2)-y(1)*y(3);
dz_dt=y(1)*y(2)-b*y(3);
dy_dt=[dx_dt;dy_dt;dz_dt];
end

你可能感兴趣的:(MATLAB系统仿真,matlab)