在MATLAB中实现混沌序列的相空间重构 ,核心是使用延迟坐标法 重建系统的动力学吸引子。其关键在于确定两个参数:延迟时间 τ 和嵌入维度 m。
下图概括了相空间重构的核心工作流程与参数选择方法:

核心MATLAB函数
1. 计算延迟时间 τ (互信息法)
互信息法通常比自相关函数法更适合非线性系统。
matlab
function tau = calculateTau_MI(series, maxTau)
% 计算时间序列的互信息,以确定最佳延迟时间tau
% series: 输入的一维时间序列
% maxTau: 搜索的最大延迟
N = length(series);
mi = zeros(1, maxTau);
% 将连续值离散化(分为20段)
edges = linspace(min(series), max(series), 21);
[~, ~, binIndices] = histcounts(series, edges);
Px = histcounts(binIndices, 1:21) / N;
for t = 1:maxTau
% 计算联合概率分布 P(x(t), x(t+tau))
jointHist = accumarray([binIndices(1:end-t), binIndices(1+t:end)], 1, [20, 20]);
Pxy = jointHist / sum(jointHist(:));
% 计算互信息
mi_sum = 0;
for i = 1:20
for j = 1:20
if Pxy(i,j) > 0 && Px(i) > 0
mi_sum = mi_sum + Pxy(i,j) * log2( Pxy(i,j) / (Px(i) * Px(j)) );
end
end
end
mi(t) = mi_sum;
end
% 寻找互信息函数的第一个局部最小值
diffs = diff(mi);
tau = find(diffs > 0, 1);
if isempty(tau)
tau = find(mi < 0.2*mi(1), 1); % 备选方案:降至初始值的20%
end
if isempty(tau), tau = 1; end
% 可视化
figure;
plot(1:maxTau, mi, 'b-o', 'LineWidth', 1.5);
hold on; plot([tau tau], [0 mi(tau)], 'r--');
xlabel('延迟 \tau'); ylabel('互信息 I(\tau)');
title(['最佳延迟时间 \tau = ', num2str(tau)]);
grid on;
end
2. 计算嵌入维度 m (虚假最近邻法)
matlab
function [m, fnnPercent] = calculateEmbeddingDim_FNN(series, tau, maxM)
% 使用虚假最近邻法确定最小嵌入维度
% series: 时间序列
% tau: 延迟时间
% maxM: 尝试的最大嵌入维度
N = length(series);
fnnPercent = zeros(1, maxM-1);
% 预先构建所有延迟序列
delayedSeries = zeros(N - (maxM-1)*tau, maxM);
for i = 1:maxM
delayedSeries(:, i) = series(1+(i-1)*tau : end - (maxM-i)*tau);
end
for m = 2:maxM
% 在m维空间中重构
X = delayedSeries(:, 1:m);
[numPoints, ~] = size(X);
% 寻找每个点的最近邻 (使用欧氏距离)
fnnCount = 0;
totalChecked = 0;
for i = 1:numPoints-1
% 计算距离
distances = sqrt(sum((X - X(i,:)).^2, 2));
distances(1:i) = inf; % 排除自身和前i个点
[minDist, nnIdx] = min(distances);
if isinf(minDist), continue; end
totalChecked = totalChecked + 1;
% 在m+1维空间中检查距离变化
if m < maxM
dist_m = minDist;
dist_mp1 = sqrt( sum( (delayedSeries(i, 1:m+1) - delayedSeries(nnIdx, 1:m+1)).^2 ) );
% 判断是否为虚假最近邻 (两个常用判据)
R1 = abs(dist_mp1 - dist_m) / dist_m;
R2 = dist_mp1 / (std(series)); % 与整个序列标准差的比值
if R1 > 0.15 || R2 > 2.0
fnnCount = fnnCount + 1;
end
end
end
fnnPercent(m-1) = (fnnCount / max(totalChecked, 1)) * 100;
end
% 确定m:FNN比率首次低于阈值
threshold = 5; % 5% 阈值
m = find(fnnPercent < threshold, 1) + 1;
if isempty(m), m = maxM; end
% 可视化
figure;
plot(2:maxM, fnnPercent, 's-b', 'LineWidth', 1.5, 'MarkerFaceColor', 'b');
hold on; plot([1, maxM+1], [threshold, threshold], 'r--');
plot([m, m], [0, 100], 'g--', 'LineWidth', 1.5);
xlabel('嵌入维度 m'); ylabel('虚假最近邻比例 (%)');
title(['最佳嵌入维度 m = ', num2str(m)]);
xlim([2, maxM]); grid on;
legend('FNN比例', '阈值', '选定维度', 'Location', 'best');
end
3. 主重构函数
matlab
function [X, tau, m] = phaseSpaceReconstruction(series, varargin)
% 相空间重构主函数
% 输入:series - 一维时间序列
% 可选输入:tau - 延迟时间(不指定则自动计算)
% m - 嵌入维度(不指定则自动计算)
% 输出:X - 重构的相空间轨迹矩阵 (每行是一个m维点)
% tau, m - 使用的参数
p = inputParser;
addRequired(p, 'series', @isvector);
addOptional(p, 'tau', 0, @isscalar);
addOptional(p, 'm', 0, @isscalar);
parse(p, series, varargin{:});
series = series(:); % 确保是列向量
N = length(series);
% 1. 确定延迟时间 tau
if p.Results.tau <= 0
maxTau = min(50, floor(N/10));
tau = calculateTau_MI(series, maxTau);
fprintf('自动计算延迟时间: tau = %d\n', tau);
else
tau = p.Results.tau;
end
% 2. 确定嵌入维度 m
if p.Results.m <= 0
maxM = 10;
m = calculateEmbeddingDim_FNN(series, tau, maxM);
fprintf('自动计算嵌入维度: m = %d\n', m);
else
m = p.Results.m;
end
% 3. 执行重构 (构建轨迹矩阵)
L = N - (m-1)*tau; % 重构相空间中的点数
X = zeros(L, m);
for i = 1:m
X(:, i) = series(1+(i-1)*tau : L+(i-1)*tau);
end
fprintf('相空间重构完成:\n');
fprintf(' 原序列长度:%d\n', N);
fprintf(' 重构后点数:%d\n', L);
fprintf(' 延迟时间 tau:%d\n', tau);
fprintf(' 嵌入维度 m:%d\n', m);
% 4. 可视化 (当m=2或3时)
if m == 2
figure;
plot(X(:,1), X(:,2), 'b.', 'MarkerSize', 8);
xlabel('x(t)'); ylabel(sprintf('x(t+%d)', tau));
title('二维相空间吸引子');
axis equal; grid on;
elseif m == 3
figure;
plot3(X(:,1), X(:,2), X(:,3), 'b.', 'MarkerSize', 8);
xlabel('x(t)'); ylabel(sprintf('x(t+%d)', tau));
zlabel(sprintf('x(t+%d)', 2*tau));
title('三维相空间吸引子');
grid on; box on;
rotate3d on;
else
fprintf('嵌入维度m>3,已重构但无法直接可视化全部维度。\n');
% 可以绘制前三个主成分
[~, score] = pca(X);
figure;
plot3(score(:,1), score(:,2), score(:,3), 'b.', 'MarkerSize', 8);
xlabel('PC1'); ylabel('PC2'); zlabel('PC3');
title('重构吸引子的前三个主成分');
grid on; box on;
rotate3d on;
end
end
使用示例:分析洛伦兹系统
matlab
%% 示例:生成洛伦兹系统数据并进行相空间重构
clear; clc; close all;
% 1. 生成洛伦兹系统数据 (混沌系统)
dt = 0.01; T = 1000; steps = floor(T/dt);
x = zeros(steps,1); y = zeros(steps,1); z = zeros(steps,1);
% 洛伦兹参数 (经典混沌值)
sigma = 10; rho = 28; beta = 8/3;
x(1)=1; y(1)=1; z(1)=1; % 初始条件
for i=1:steps-1
dx = sigma*(y(i)-x(i));
dy = x(i)*(rho-z(i))-y(i);
dz = x(i)*y(i)-beta*z(i);
x(i+1)=x(i)+dx*dt;
y(i+1)=y(i)+dy*dt;
z(i+1)=z(i)+dz*dt;
end
% 2. 使用x分量进行相空间重构
chaoticSeries = x(1:10:end); % 降采样以突出主要动力学
fprintf('分析洛伦兹系统x分量...\n');
% 方法1: 全自动计算参数
[X_reconstructed, tau_auto, m_auto] = phaseSpaceReconstruction(chaoticSeries);
% 方法2: 手动指定参数 (如果已有经验值)
% [X_reconstructed, tau, m] = phaseSpaceReconstruction(chaoticSeries, 17, 3);
%% 3. 计算最大Lyapunov指数 (验证混沌特性)
fprintf('\n计算最大Lyapunov指数...\n');
lyapExp = computeLyapunovExponent(X_reconstructed, tau_auto, dt*10);
fprintf('最大Lyapunov指数估计值: %.4f\n', lyapExp);
if lyapExp > 0
fprintf(' 指数为正,确认系统具有混沌特性。\n');
end
%% 4. 比较原始三维吸引子与重构吸引子 (当m=3时)
if m_auto == 3
figure('Position', [100 100 1200 500]);
subplot(1,2,1);
plot3(x(1:5000), y(1:5000), z(1:5000), 'b.', 'MarkerSize', 3);
xlabel('x'); ylabel('y'); zlabel('z');
title('原始洛伦兹吸引子 (三维)');
grid on; box on; view([-13, 20]);
subplot(1,2,2);
plot3(X_reconstructed(:,1), X_reconstructed(:,2), X_reconstructed(:,3), 'r.', 'MarkerSize', 3);
xlabel(sprintf('x(t)'));
ylabel(sprintf('x(t+%d)', tau_auto));
zlabel(sprintf('x(t+%d)', 2*tau_auto));
title(sprintf('重构吸引子 (从x一维序列重构, m=%d)', m_auto));
grid on; box on; view([-13, 20]);
end
参考代码 混沌序列的相空间重构的MATLABT程序 www.3dddown.com/csb/97060.html
分析方向
重构相空间后,你可以进行以下分析:
- 计算关联维数 :使用
correlationDimension函数量化吸引子复杂度。 - 计算Lyapunov指数谱:判断系统混沌强度。
- 非线性预测:在重构相空间中进行局部或全局预测。
- 奇异谱分析(SSA):用于去噪和趋势提取。