出现这个错误是因为pywt.WaveletPacket
类只适用于离散小波,而'cmor'
是连续小波。对于连续小波包变换,需要使用不同的方法来实现。
以下是修正后的代码,使用连续小波变换(CWT)来替代小波包变换,并对结果进行可视化。
import numpy as np
import pywt
import matplotlib.pyplot as plt
def complex_wavelet_transform(signal, wavelet, scales):
# 复数小波变换
coeffs, freqs = pywt.cwt(signal, scales, wavelet)
return coeffs, freqs
def energy_moment_entropy(coeffs):
# 计算能量矩熵
energy = np.sum(np.abs(coeffs)**2, axis=1)
energy_norm = energy / np.sum(energy)
entropy = -np.sum(energy_norm * np.log(energy_norm + 1e-10)) # 加入1e-10防止对数零
return energy_norm, entropy
# 示例信号
np.random.seed(42)
signal = np.sin(2 * np.pi * 5 * np.linspace(0, 1, 128)) + np.random.randn(128) * 0.1
# 复数小波变换
scales = np.arange(1, 64)
coeffs, freqs = complex_wavelet_transform(signal, 'cmor', scales)
# 计算能量矩熵
energy_norm, entropy = energy_moment_entropy(coeffs)
print("Energy Moment Entropy:", entropy)
# 可视化
plt.figure(figsize=(12, 8))
# 原始信号
plt.subplot(3, 1, 1)
plt.plot(signal)
plt.title('Original Signal')
plt.xlabel('Time')
plt.ylabel('Amplitude')
# 复数小波变换后的系数
plt.subplot(3, 1, 2)
plt.imshow(np.abs(coeffs), extent=[0, 1, scales[-1], scales[0]], cmap='jet', aspect='auto')
plt.colorbar(label='Coefficient Magnitude')
plt.title('Complex Wavelet Transform Coefficients')
plt.xlabel('Time')
plt.ylabel('Scale')
# 能量分布
plt.subplot(3, 1, 3)
plt.bar(np.arange(len(energy_norm)), energy_norm)
plt.title('Energy Distribution')
plt.xlabel('Scale Index')
plt.ylabel('Normalized Energy')
plt.tight_layout()
plt.show()
解释
- 复数小波变换:使用
pywt.cwt
函数进行连续小波变换,将信号分解为不同尺度(频带)。 - 能量矩熵计算:计算各尺度上的能量,并基于能量分布计算熵值。
- 可视化:
- 第一幅图显示了原始的示例信号。
- 第二幅图显示了信号经过连续小波变换后的系数图,颜色表示系数的大小。
- 第三幅图显示了各尺度上的归一化能量分布。
通过这种方法,可以直观地看到信号在不同尺度上的能量分布,以及复数小波变换后的系数变化,有助于理解信号的特征和复杂性。