小波交叉功率谱分析是一种强大的时频分析工具,它能够揭示两个时间序列在不同时间尺度和频率上的相互关系。与传统的傅里叶变换相比,小波分析具有局部化特性,可以同时提供时间和频率信息,特别适合分析非平稳信号。
在MATLAB环境中实现小波交叉功率谱分析,我们需要理解几个核心概念:
小波基函数选择:Morlet小波因其良好的时频局部化特性成为首选,它由一个正弦波乘以高斯窗构成,数学表达式为ψ(t)=π^(-1/4)e^(iω0t)e^(-t^2/2),其中ω0是无量纲频率参数,通常取6以获得良好的时频平衡。
尺度与频率关系:在小波分析中,尺度参数s与频率f的关系为f=ω0/(2πs),这意味着较大的尺度对应较低的频率。尺度参数的选择直接影响分析的频率范围和分辨率。
交叉功率谱:计算两个信号小波变换的共轭乘积,其模的平方即为交叉功率谱,反映了两个信号在不同时频区域的能量耦合程度。
提示:小波分析中的"影响锥"(Cone of Influence, COI)概念非常重要,它标识了边界效应显著的区域,分析时应特别关注COI内的结果。
数据预处理是小波分析的关键第一步。我们通常需要:
数据标准化:消除不同变量间的量纲差异,使它们具有可比性。常用的标准化方法是z-score标准化:
matlab复制data1 = (data1 - mean(data1)) / std(data1);
data2 = (data2 - mean(data2)) / std(data2);
数据对齐:确保两个时间序列具有相同的长度和采样间隔。如果原始数据长度不一致,需要进行截断或插值处理:
matlab复制n = min(length(data1), length(data2));
data1 = data1(1:n);
data2 = data2(1:n);
缺失值处理:实际数据中常存在缺失值,可采用线性插值或邻近值填充:
matlab复制data1 = fillmissing(data1, 'linear');
data2 = fillmissing(data2, 'linear');
正确设置采样间隔dt至关重要,它直接影响频率分析的准确性:
采样间隔dt:表示相邻数据点间的时间间隔,单位为秒/年/天等,取决于数据性质。例如,年数据dt=1.0,月数据dt=1/12。
时间轴创建:明确的时间轴有助于结果解释:
matlab复制time = (0:n-1)*dt; % 创建时间轴
数据平稳性检查:小波分析虽能处理非平稳数据,但显著的趋势仍会影响结果。可通过ADF检验或简单的去趋势处理:
matlab复制data1 = detrend(data1);
data2 = detrend(data2);
MATLAB小波工具箱支持多种小波基函数,各有特点:
Morlet小波:最常用,时频局部化良好,适合周期分析:
matlab复制mother = 'morlet';
Paul小波:适合分析具有陡峭变化特征的信号:
matlab复制mother = 'paul';
DOG小波:高斯导数小波,适合分析信号的奇异点:
matlab复制mother = 'dog';
选择依据:
尺度参数决定分析的频率范围和分辨率:
最小尺度s0:对应最高分析频率,应满足s0≥2*dt以避免频谱泄漏:
matlab复制s0 = 2*dt; % 最小尺度
尺度分辨率dj:控制尺度间的间隔,值越小分辨率越高但计算量越大:
matlab复制dj = 0.1; % 推荐0.1-0.25
最大尺度数j1:决定最低分析频率,需根据数据长度调整:
matlab复制j1 = fix(log2(n*dt/s0))/dj; % 自动计算最大尺度数
尺度向量生成:
matlab复制scales = s0*2.^((0:j1)*dj); % 生成尺度向量
注意:过高的尺度分辨率(dj太小)会导致计算量剧增,而过大则可能漏掉重要频率成分。
MATLAB中实现连续小波变换的核心步骤:
单信号小波变换:
matlab复制[c1, period, scale, coi1] = wavelet(data1, dt, pad, dj, s0, j1, mother);
[c2, ~, ~, coi2] = wavelet(data2, dt, pad, dj, s0, j1, mother);
参数说明:
填充选项:
matlab复制pad = 1; % 自动填充零使长度为2的幂次
交叉功率谱揭示两个信号的共同变化特征:
交叉小波系数:
matlab复制cross_wave = c1 .* conj(c2); % 复数形式
交叉功率谱密度:
matlab复制cross_power = abs(cross_wave).^2; % 实数功率
相位谱提取:
matlab复制phase = angle(cross_wave); % 相位差(-π到π)
相干性计算(可选):
matlab复制wavelet_coherence = abs(cross_wave).^2./(abs(c1).^2 .* abs(c2).^2);
评估交叉谱结果的统计显著性:
自谱显著性:
matlab复制[signif1, ~] = wave_signif(1.0, dt, scale, 0, 0.72, -1, -1, mother);
[signif2, ~] = wave_signif(1.0, dt, scale, 0, 0.72, -1, -1, mother);
交叉谱显著性:
matlab复制signif_cross = sqrt(signif1' .* signif2');
matlab复制n_surr = 1000; % 替代数据数量
cross_surr = zeros(length(scale), n);
for i = 1:n_surr
[~, c_surr] = wavelet(phase_rand(data2), dt, pad, dj, s0, j1, mother);
cross_surr = cross_surr + abs(c1 .* conj(c_surr)).^2;
end
sig95_cross = prctile(cross_surr, 95, 3);
小波变换的边界区域可靠性较低:
影响锥(COI)计算:
matlab复制[~, ~, ~, coi] = wavelet(data1, dt, pad, dj, s0, j1, mother);
可视化处理:
matlab复制contour(period, log2(scale), sig95_cross, [1,1], 'k'); % 显著性线
plot(period, log2(coi), 'k', 'LineWidth', 1.5); % 影响锥
结果解释原则:
完整的可视化应包括:
原始时间序列:
matlab复制subplot(3,1,1);
plot(time, data1, 'r'); hold on;
plot(time, data2, 'b');
xlabel('Time'); ylabel('Normalized Value');
legend('Series1', 'Series2');
交叉功率谱:
matlab复制subplot(3,1,2);
contourf(time, log2(period), log2(cross_power), 20, 'LineColor','none');
hold on;
contour(time, log2(period), sig95_cross, [1,1], 'k');
plot(time, log2(coi), 'k--');
set(gca, 'YDir', 'reverse');
colorbar;
全局交叉谱:
matlab复制subplot(3,1,3);
plot(log2(period), mean(cross_power,2), 'b-');
hold on;
plot(log2(period), signif_cross, 'r--');
set(gca, 'XDir', 'reverse');
提升可视化效果的关键设置:
颜色映射:
matlab复制colormap(jet(64)); % 使用jet色图
坐标轴调整:
matlab复制ytick = 2.^(fix(log2(min(period))):fix(log2(max(period))));
set(gca, 'YTick', log2(ytick), 'YTickLabel', ytick);
相位箭头(可选):
matlab复制[X,Y] = meshgrid(time, log2(period));
U = cos(phase); V = sin(phase);
quiver(X,Y,U,V, 0.5, 'k');
从相位谱提取时间延迟信息:
相位-时延转换:
matlab复制time_delay = zeros(size(phase,1),1);
for i = 1:size(phase,1)
p = polyfit(time, unwrap(phase(i,:)), 1);
time_delay(i) = -p(1)/(2*pi/period(i));
end
可视化时延谱:
matlab复制figure;
plot(log2(period), time_delay, 'b-o');
set(gca, 'XDir', 'reverse');
xlabel('Period (log2)'); ylabel('Time Delay');
扩展至多变量分析:
多变量相干计算:
matlab复制% 假设有data1, data2, data3三个变量
[c1,~,~,~] = wavelet(data1, dt, pad, dj, s0, j1, mother);
[c2,~,~,~] = wavelet(data2, dt, pad, dj, s0, j1, mother);
[c3,~,~,~] = wavelet(data3, dt, pad, dj, s0, j1, mother);
% 计算多变量相干
S_xy = c1.*conj(c2) + c1.*conj(c3) + c2.*conj(c3);
S_xx = abs(c1).^2 + abs(c2).^2 + abs(c3).^2;
multi_coher = abs(S_xy)./S_xx;
显著性检验:
matlab复制nvars = 3; % 变量数量
[signif, ~] = wave_signif(1.0, dt, scale, 0, 0.72, nvars, -1, mother);
处理长序列时的优化策略:
分段处理:
matlab复制segment_len = 1024; % 分段长度
n_segments = ceil(n/segment_len);
cross_power = zeros(length(scale), n);
for k = 1:n_segments
idx = (k-1)*segment_len+1 : min(k*segment_len, n);
[c1,~,~,~] = wavelet(data1(idx), dt, pad, dj, s0, j1, mother);
[c2,~,~,~] = wavelet(data2(idx), dt, pad, dj, s0, j1, mother);
cross_power(:,idx) = abs(c1.*conj(c2)).^2;
end
并行计算:
matlab复制parfor k = 1:n_segments
% 并行处理各段
end
实际应用中的典型问题及解决方案:
频率混叠:
边界效应过强:
显著性水平异常:
内存不足:
matlab复制data1 = single(data1);
data2 = single(data2);
分析气温与降水的关系:
数据特点:
参数设置:
matlab复制dt = 1.0; % 年数据
dj = 0.125; % 较高分辨率
s0 = 2*dt;
j1 = 10/dj; % 覆盖约1-30年周期
结果解读:
股票指数与汇率关系分析:
数据处理:
matlab复制% 对数收益率转换
data1 = diff(log(stock_price));
data2 = diff(log(exchange_rate));
参数调整:
matlab复制dt = 1/252; % 交易日间隔(年)
dj = 0.2; % 稍低分辨率
mother = 'paul'; % 更好捕捉突变
应用扩展:
matlab复制% 计算超前-滞后关系
[max_power, idx] = max(cross_power,[],1);
dominant_period = period(idx);
lead_lag = phase(idx) .* dominant_period/(2*pi);
创建可复用的分析函数:
matlab复制function [cross_power, period, scale, coi, phase] = ...
wavelet_xspectrum(data1, data2, dt, varargin)
% 解析可选参数
p = inputParser;
addParameter(p, 'dj', 0.1, @isnumeric);
addParameter(p, 's0', 2*dt, @isnumeric);
addParameter(p, 'j1', [], @isnumeric);
addParameter(p, 'mother', 'morlet', @ischar);
addParameter(p, 'pad', 1, @isnumeric);
parse(p, varargin{:});
% 设置默认j1
if isempty(p.Results.j1)
j1 = fix(log2(length(data1)*dt/p.Results.s0))/p.Results.dj;
else
j1 = p.Results.j1;
end
% 执行小波变换
[c1, period, scale, coi] = wavelet(data1, dt, p.Results.pad, ...
p.Results.dj, p.Results.s0, j1, p.Results.mother);
[c2, ~, ~, ~] = wavelet(data2, dt, p.Results.pad, ...
p.Results.dj, p.Results.s0, j1, p.Results.mother);
% 计算交叉谱
cross_wave = c1 .* conj(c2);
cross_power = abs(cross_wave).^2;
phase = angle(cross_wave);
end
保存分析结果供后续使用:
MAT文件保存:
matlab复制save('analysis_results.mat', 'cross_power', 'period', 'scale', 'coi', ...
'phase', 'time_delay', '-v7.3');
图形导出:
matlab复制print(gcf, '-dpng', '-r300', 'cross_wavelet_plot.png');
表格数据导出:
matlab复制T = table(period', mean(cross_power,2), 'VariableNames', {'Period','MeanPower'});
writetable(T, 'global_spectrum.csv');
在实际应用中,我发现小波交叉谱分析对参数设置非常敏感,特别是尺度参数dj和s0的选择会显著影响结果。经过多次实践,对于气候数据我推荐dj=0.125,s0=2dt;而对于高频金融数据,dj=0.2配合s0=4dt往往能得到更稳定的结果。另一个实用技巧是:在计算显著性水平时,使用基于AR(1)模型的噪声假设通常比白噪声假设更符合实际数据的特性。