分形维数是描述信号复杂性和不规则程度的重要度量指标,广泛应用于生物医学信号分析、机械故障诊断、金融时间序列分析等领域。以下是几种常用的分形维数计算方法及其MATLAB实现:
一、盒计数法(Box Counting Method)
基本原理
通过将信号覆盖在不同尺寸的网格上,统计覆盖信号所需的盒子数量,利用盒子数与尺寸的对数关系计算分形维数。
MATLAB实现代码
matlab
function D = box_counting_dimension(signal, min_scale, max_scale)
% 输入参数:
% signal: 输入信号(一维向量)
% min_scale: 最小尺度(通常为1)
% max_scale: 最大尺度(通常为信号长度的1/10)
N = length(signal);
scales = min_scale:max_scale;
counts = zeros(size(scales));
for i = 1:length(scales)
scale = scales(i);
box_size = scale;
num_boxes = 0;
% 创建网格
x_edges = 1:box_size:N;
if x_edges(end) < N
x_edges = [x_edges, N];
end
% 统计覆盖信号的盒子数
for j = 1:(length(x_edges)-1)
segment = signal(x_edges(j):min(x_edges(j+1), N));
y_min = min(segment);
y_max = max(segment);
y_edges = y_min:box_size:y_max;
if y_edges(end) < y_max
y_edges = [y_edges, y_max];
end
num_boxes = num_boxes + length(y_edges) - 1;
end
counts(i) = num_boxes;
end
% 线性回归计算分形维数
log_scales = log(scales);
log_counts = log(counts);
valid_idx = isfinite(log_scales) & isfinite(log_counts);
p = polyfit(log_scales(valid_idx), log_counts(valid_idx), 1);
D = p(1); % 斜率即为分形维数
% 可视化结果
figure;
scatter(log_scales, log_counts, 'filled');
hold on;
plot(log_scales, polyval(p, log_scales), 'r-', 'LineWidth', 2);
xlabel('log(Scale)');
ylabel('log(Box Count)');
title(['Box Counting Dimension: D = ', num2str(D)]);
grid on;
end
使用示例
matlab
% 生成测试信号(布朗运动)
N = 1000;
brownian = cumsum(randn(1, N));
% 计算分形维数
D = box_counting_dimension(brownian, 1, 50);
disp(['分形维数: ', num2str(D)]);
二、Higuchi方法(适用于时间序列)
基本原理
通过重构信号的不同子序列并计算其长度,利用长度与时间间隔的关系估计分形维数。
MATLAB实现代码
matlab
function D = higuchi_dimension(signal, max_k)
% 输入参数:
% signal: 输入信号(一维向量)
% max_k: 最大时间延迟(通常为信号长度的1/10)
N = length(signal);
if nargin < 2
max_k = floor(N/10);
end
L = zeros(1, max_k);
for k = 1:max_k
Lk = 0;
for m = 1:k
% 构造子序列
subseq = [];
idx = m:k:N;
if length(idx) > 1
subseq = signal(idx);
% 计算曲线长度
Lmk = sum(abs(diff(subseq))) * (N - 1) / (floor((N - m)/k) * k);
Lk = Lk + Lmk;
end
end
L(k) = Lk / k;
end
% 线性回归计算分形维数
valid_idx = find(L > 0);
log_k = log(1:max_k);
log_L = log(L(valid_idx));
p = polyfit(log_k(valid_idx), log_L, 1);
D = -p(1); % 斜率为负值,取反
% 可视化结果
figure;
scatter(log_k, log_L, 'filled');
hold on;
plot(log_k, polyval(p, log_k), 'r-', 'LineWidth', 2);
xlabel('log(k)');
ylabel('log(L(k))');
title(['Higuchi Dimension: D = ', num2str(D)]);
grid on;
end
使用示例
matlab
% 生成测试信号(正弦波叠加噪声)
t = linspace(0, 10, 1000);
signal = sin(2*pi*t) + 0.5*randn(1, 1000);
% 计算分形维数
D = higuchi_dimension(signal);
disp(['分形维数: ', num2str(D)]);
三、Petrosian算法(快速计算方法)
基本原理
通过计算信号导数的符号变化率来估计分形维数,计算效率高。
MATLAB实现代码
matlab
function D = petrosian_dimension(signal)
% 输入参数:
% signal: 输入信号(一维向量)
N = length(signal);
% 计算导数近似
diff_signal = diff(signal);
% 计算符号变化次数
sign_changes = sum(abs(diff(sign(diff_signal))) > 0) / 2;
% 计算分形维数
D = log10(N) / (log10(N) + log10(N/(N+0.4*sign_changes)));
disp(['Petrosian分形维数: ', num2str(D)]);
end
四、Katz方法(基于信号整体特征)
基本原理
利用信号的总长度和平均点到起点的距离计算分形维数。
MATLAB实现代码
matlab
function D = katz_dimension(signal)
% 输入参数:
% signal: 输入信号(一维向量)
N = length(signal);
d = max(signal) - min(signal); % 信号振幅
% 计算总路径长度
L = sum(sqrt(1 + diff(signal).^2));
% 计算平均距离
a = mean(signal);
dist_sum = 0;
for i = 1:N
dist_sum = dist_sum + sqrt((i-1)^2 + (signal(i)-a)^2);
end
a_dist = dist_sum / N;
% 计算分形维数
D = log10(N) / (log10(d/L) + log10(N));
disp(['Katz分形维数: ', num2str(D)]);
end
五、多重分形分析方法(Multifractal Analysis)
基本原理
通过配分函数计算广义分形维数,分析信号的多重分形特性。
MATLAB实现代码
matlab
function [Dq, tau_q] = multifractal_analysis(signal, q_values, scales)
% 输入参数:
% signal: 输入信号
% q_values: q值数组(通常为-5到5)
% scales: 尺度数组(通常为2的幂次)
N = length(signal);
Dq = zeros(size(q_values));
tau_q = zeros(size(q_values));
for i = 1:length(scales)
scale = scales(i);
num_segments = floor(N / scale);
segments = reshape(signal(1:num_segments*scale), scale, num_segments);
% 计算每个子段的局部分形维数(使用盒计数法)
local_D = zeros(num_segments, 1);
for j = 1:num_segments
seg = segments(:, j);
local_D(j) = box_counting_dimension(seg, 1, floor(scale/10));
end
% 计算配分函数
for q_idx = 1:length(q_values)
q = q_values(q_idx);
Z_q(i) = sum(local_D.^q);
end
end
% 线性回归计算广义维数
for q_idx = 1:length(q_values)
q = q_values(q_idx);
log_scales = log(scales);
log_Zq = log(Z_q(:, q_idx));
valid_idx = isfinite(log_scales) & isfinite(log_Zq);
p = polyfit(log_scales(valid_idx), log_Zq(valid_idx), 1);
tau_q(q_idx) = p(1);
Dq(q_idx) = tau_q(q_idx) / q;
end
% 可视化广义维数谱
figure;
plot(q_values, Dq, 'o-');
xlabel('q');
ylabel('D(q)');
title('广义分形维数谱');
grid on;
end
六、应用示例:ECG信号分形分析
matlab
% 加载心电图数据(示例)
load('ecg_signal.mat'); % 假设包含ecg信号和采样率fs
% 预处理信号
ecg = detrend(ecg); % 去除趋势项
ecg = ecg - mean(ecg); % 去除直流分量
% 计算不同方法的分形维数
D_box = box_counting_dimension(ecg, 1, 50);
D_higuchi = higuchi_dimension(ecg);
D_petrosian = petrosian_dimension(ecg);
D_katz = katz_dimension(ecg);
% 显示结果
fprintf('盒计数法分形维数: %.4f\n', D_box);
fprintf('Higuchi方法分形维数: %.4f\n', D_higuchi);
fprintf('Petrosian方法分形维数: %.4f\n', D_petrosian);
fprintf('Katz方法分形维数: %.4f\n', D_katz);
% 多重分形分析
scales = 2.^(1:6); % 尺度范围
q_values = -5:0.5:5; % q值范围
[Dq, tau_q] = multifractal_analysis(ecg, q_values, scales);
七、方法比较与选择指南
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 盒计数法 | 理论基础坚实,直观易懂 | 计算量大,边界效应明显 | 静态信号分析,图像处理 |
| Higuchi方法 | 抗噪性好,适合短时间序列 | 对短信号敏感 | 生物医学信号分析 |
| Petrosian算法 | 计算速度快 | 精度较低 | 实时监测系统 |
| Katz方法 | 全局特征明显 | 对端点敏感 | 长信号分析 |
| 多重分形分析 | 揭示信号复杂结构 | 计算复杂,参数选择敏感 | 复杂系统分析 |
参考代码 求信号的分形维数 www.youwenfan.com/contentcsp/96061.html
八、注意事项
-
信号预处理:计算前应进行去噪、归一化等预处理
-
参数选择:尺度范围和q值范围需要根据信号特性调整
-
结果验证:建议使用多种方法交叉验证结果
-
计算效率:对于长信号,优先选择高效算法(如Petrosian)
-
物理意义:分形维数通常在1-2之间(一维信号),超过此范围需检查算法实现