Open iganggang opened 1 week ago
here is the code.
import torch
import numpy as np
import matplotlib.pyplot as plt
from svmdpy_torch import SVMD_VKnet_torch
from signal_generator import generate_triharmonic_signal
# Sampling parameters
fs = 1000 # Sampling frequency in Hz
T = 1 # Period in seconds
t = np.linspace(0, 5 * T, 5 * T * fs) # Time vector (1:5T)
# Generate the tri-harmonic signal
signal = generate_triharmonic_signal(t, sigma=0.1)
# Convert the signal to a PyTorch tensor
waveforms = torch.from_numpy(signal).float().unsqueeze(0).unsqueeze(0) # Shape (batch_size, channel_size, signal_size)
# Other parameters
max_iter_num = 300 # Max number of iterations
max_mode_num = 3 # Maximum number of modes to extract
device = 'cpu' # Device, use 'cuda' for GPU if available
# waveforms parameters
batch_size = waveforms.size(0)
channel_size = waveforms.size(1)
# Set Alpha, Omega_init, Tau, and Tol
Alpha = torch.from_numpy(np.array([100, 100, 100])) # Mode compactness
omega_init = torch.zeros(batch_size, channel_size, max_mode_num) # Initialize frequencies to zero
tau = torch.from_numpy(np.array([0.]))
tol = torch.from_numpy(np.array([1e-7]))
# Call SVMD_VKnet_torch function
modes, modes_fn, modes_fc, omega_axis, sum_omega_old, f_hat_plus, f_hat_negt_ = SVMD_VKnet_torch(
waveforms, Alpha, omega_init, tau, tol, max_iter_num, max_mode_num, device
)
# Output the result
print("Modes: ", modes)
# signal_generator.py
import numpy as np
def generate_triharmonic_signal(t, sigma=0.1):
"""
Generate tri-harmonic signal with added Gaussian noise.
Parameters:
t : ndarray
Time vector (in seconds).
sigma : float
Standard deviation of Gaussian noise.
Returns:
signal : ndarray
The noisy tri-harmonic signal.
"""
# Tri-harmonic signal components
signal = np.cos(4 * np.pi * t) + \
(1 / 4) * np.cos(48 * np.pi * t) + \
(1 / 16) * np.cos(576 * np.pi * t)
# Add Gaussian noise with standard deviation sigma
noise = np.random.normal(0, sigma, size=signal.shape)
noisy_signal = signal + noise
return noisy_signal
Even I set the initial frequencies as 2 Hz, 24 Hz, and 288 Hz. the results are still 3, 288 and 448 Hz.
Dear iganggang,
Thank you for reporting this issue. I think the problem may mainly come from the inappropriate alpha for each model, which affects the compactness and moveability. Of course, other parameters, such as the initial central frequencies, may also contribute to the problem. I have run your example on Kaggle and recovered approximately the sub-signals with the desired frequencies, see https://www.kaggle.com/code/zhenlingmo/svmd-torch
Here are the key changes for setting the parameters:
max_iter_num = 500 # Max number of iterations
Alpha = torch.from_numpy(np.array([1000, 3000, 50])) # Mode compactness
Thank you for getting back to me. Alpha can affect the mode decomposition results so much. When I run VMD, the accuracy of its results is about 0.1. And we just need to choose one alpha. I want to know whether SVMD is better than VMD.
Thank you for asking. I have not compared VMD and SVMD systematically. So, I am unable to formally comment on their performance in terms of accuracy. But if choosing the right parameters, they should have similar accuracies. In addition, two advantages of SVMD I noticed are 1) the speed of producing modes, and 2) customizing the compactness of each mode. My last comment is that if VMD particularly suits your application, just use it :)
signal = np.cos(4 np.pi t) + (1 / 4) np.cos(48 np.pi t) + (1 / 16) np.cos(576 np.pi t) the signals' frequencies are 2 Hz, 24 Hz, and 288 Hz). after I use your codes svmdpy_torch.py to decompose the tri-harmonic signals I run many times, but the centre frequencies are 3, 288 and 142Hz. I feel very strange. Is SVMD worse than VMD?