Talking about VMD---Variational Mode Decomposition

In many scenarios, we need to decompose the signal to facilitate our next operation. Commonly used decomposition methods include EMD, such as EMD, EEMD, FEEMD, CEEMDAN, ICEEMDAN, etc. Of course, there are also wavelet decomposition, empirical wavelet decomposition, etc. , in short, there are various decomposition methods, and different decomposition methods are selected according to the characteristics of the sample. Here is a brief introduction to VMD decomposition.

     In 2014, Konstantin et al. proposed a fully non-recursive variational mode decomposition (VMD) which enables the simultaneous extraction of decomposed modes. The model looks for a set of modes and their respective center frequencies such that the modes together reproduce the input signal while each mode is smooth after demodulation to baseband. The essence of the algorithm is to extend the classic Wiener filter to multiple adaptive bands, so that it has a solid theoretical foundation and is easy to understand. The variational model is effectively optimized by using the alternating direction multiplier method, which makes the model more robust to sampling noise.

The specific process of VMD decomposition can be understood as the optimal solution of the variational problem, which can be correspondingly transformed into the construction and solution of the variational problem.

 

 

The above is the theoretical part of VMD (Variational Mode Decomposition). You may not understand it all, because I read the original text, and I can't fully understand the mathematical relationship inside. It is enough to know roughly which steps are involved in the decomposition process. There are also many articles on this kind of decomposition on HowNet. You can refer to it for browsing and learning.

The code is directly below.

function [u, u_hat, omega] = VMD(signal, alpha, tau, K, DC, init, tol)
% Variational Mode Decomposition
% Authors: Konstantin Dragomiretskiy and Dominique Zosso
% [email protected] --- http://www.math.ucla.edu/~zosso
% Initial release 2013-12-12 (c) 2013
%
% Input and Parameters:
% ---------------------
% signal  - the time domain signal (1D) to be decomposed
% alpha   - the balancing parameter of the data-fidelity constraint
% tau     - time-step of the dual ascent ( pick 0 for noise-slack )
% K       - the number of modes to be recovered
% DC      - true if the first mode is put and kept at DC (0-freq)
% init    - 0 = all omegas start at 0
%                    1 = all omegas start uniformly distributed
%                    2 = all omegas initialized randomly
% tol     - tolerance of convergence criterion; typically around 1e-6
%
% Output:
% -------
% u       - the collection of decomposed modes
% u_hat   - spectra of the modes
% omega   - estimated mode center-frequencies
%
% When using this code, please do cite our paper:
% -----------------------------------------------
% K. Dragomiretskiy, D. Zosso, Variational Mode Decomposition, IEEE Trans.
% on Signal Processing (in press)
% please check here for update reference: 
%          http://dx.doi.org/10.1109/TSP.2013.2288675


%---------- Preparations

% Period and sampling frequency of input signal
save_T = length(signal);
fs = 1/save_T;

% extend the signal by mirroring
T = save_T;
f_mirror(1:T/2) = signal(T/2:-1:1);
f_mirror(T/2+1:3*T/2) = signal;
f_mirror(3*T/2+1:2*T) = signal(T:-1:T/2+1);
f = f_mirror;

% Time Domain 0 to T (of mirrored signal)
T = length(f);
t = (1:T)/T;

% Spectral Domain discretization
freqs = t-0.5-1/T;

% Maximum number of iterations (if not converged yet, then it won't anyway)
N = 500;

% For future generalizations: individual alpha for each mode
Alpha = alpha*ones(1,K);

% Construct and center f_hat
f_hat = fftshift((fft(f)));
f_hat_plus = f_hat;
f_hat_plus(1:T/2) = 0;

% matrix keeping track of every iterant // could be discarded for mem
u_hat_plus = zeros(N, length(freqs), K);

% Initialization of omega_k
omega_plus = zeros(N, K);
switch init
    case 1
        for i = 1:K
            omega_plus(1,i) = (0.5/K)*(i-1);
        end
    case 2
        omega_plus(1,:) = sort(exp(log(fs) + (log(0.5)-log(fs))*rand(1,K)));
    otherwise
        omega_plus(1,:) = 0;
end

% if DC mode imposed, set its omega to 0
if DC
    omega_plus(1,1) = 0;
end

% start with empty dual variables
lambda_hat = zeros(N, length(freqs));

% other inits
uDiff = tol+eps; % update step
n = 1; % loop counter
sum_uk = 0; % accumulator



% ----------- Main loop for iterative updates




while ( uDiff > tol &&  n < N ) % not converged and below iterations limit
    
    % update first mode accumulator
    k = 1;
    sum_uk = u_hat_plus(n,:,K) + sum_uk - u_hat_plus(n,:,1);
    
    % update spectrum of first mode through Wiener filter of residuals
    u_hat_plus(n+1,:,k) = (f_hat_plus - sum_uk - lambda_hat(n,:)/2)./(1+Alpha(1,k)*(freqs - omega_plus(n,k)).^2);
    
    % update first omega if not held at 0
    if ~DC
        omega_plus(n+1,k) = (freqs(T/2+1:T)*(abs(u_hat_plus(n+1, T/2+1:T, k)).^2)')/sum(abs(u_hat_plus(n+1,T/2+1:T,k)).^2);
    end
    
    % update of any other mode
    for k=2:K
        
        % accumulator
        sum_uk = u_hat_plus(n+1,:,k-1) + sum_uk - u_hat_plus(n,:,k);
        
        % mode spectrum
        u_hat_plus(n+1,:,k) = (f_hat_plus - sum_uk - lambda_hat(n,:)/2)./(1+Alpha(1,k)*(freqs - omega_plus(n,k)).^2);
        
        % center frequencies
        omega_plus(n+1,k) = (freqs(T/2+1:T)*(abs(u_hat_plus(n+1, T/2+1:T, k)).^2)')/sum(abs(u_hat_plus(n+1,T/2+1:T,k)).^2);
        
    end
    
    % Dual ascent
    lambda_hat(n+1,:) = lambda_hat(n,:) + tau*(sum(u_hat_plus(n+1,:,:),3) - f_hat_plus);
    
    % loop counter
    n = n+1;
    
    % converged yet?
    uDiff = eps;
    for i=1:K
        uDiff = uDiff + 1/T*(u_hat_plus(n,:,i)-u_hat_plus(n-1,:,i))*conj((u_hat_plus(n,:,i)-u_hat_plus(n-1,:,i)))';
    end
    uDiff = abs(uDiff);
    
end


%------ Postprocessing and cleanup


% discard empty space if converged early
N = min(N,n);
omega = omega_plus(1:N,:);

% Signal reconstruction
u_hat = zeros(T, K);
u_hat((T/2+1):T,:) = squeeze(u_hat_plus(N,(T/2+1):T,:));
u_hat((T/2+1):-1:2,:) = squeeze(conj(u_hat_plus(N,(T/2+1):T,:)));
u_hat(1,:) = conj(u_hat(end,:));

u = zeros(K,length(t));

for k = 1:K
    u(k,:)=real(ifft(ifftshift(u_hat(:,k))));
end

% remove mirror part
u = u(:,T/4+1:3*T/4);

% recompute spectrum
clear u_hat;
for k = 1:K
    u_hat(:,k)=fftshift(fft(u(k,:)))';
end

end

The code is very long, try to read as much as you can understand. I won’t explain it here, because this is a reproduction of the mathematical principle. If you want to understand the principle, it is recommended to compare the original text and code, and read it line by line. If you just use this decomposition method and care about the results, then there is no need to spend a lot of time.

function [u, u_hat, omega] = VMD(signal, alpha, tau, K, DC, init, tol)

The input and output of the function are explained here.

The input part of the function: signal represents the input signal, alpha represents the balance parameter of the data fidelity constraint, tau represents the time step, K represents the number of decomposition layers, and DC represents if the first mode is placed at DC (0 frequency), then it is true. init represents the initialization of the signal, and tol represents the convergence fault tolerance criterion. Usually, except for K, which is the number of decomposition modes, other parameters have corresponding empirical values. The exploration of VMD in most literatures is also the determination of the number of decomposition modes, and at most the discussion of tau is added. (Corresponding discussions will also be discussed in the blogger's subsequent articles.)

The output part of the function: u represents the set of decomposed modes, u_hat represents the spectral range of the mode, and omega represents the center frequency of the estimated mode.

The following is the main program that calls VMD decomposition. The main steps are to input the signal value, determine the decomposition parameters of VMD, and draw the graph.

tic
clc
clear all

load('IMF1_7.mat')
x=IMF1_7;
t=1:length(IMF1_7);


%--------- 对于VMD参数进行设置---------------
alpha = 2000;       % moderate bandwidth constraint:适度的带宽约束/惩罚因子
tau = 0.0244;          % noise-tolerance (no strict fidelity enforcement):噪声容限(没有严格的保真度执行)
K = 7;              % modes:分解的模态数
DC = 0;             % no DC part imposed:无直流部分
init = 1;           % initialize omegas uniformly  :omegas的均匀初始化
tol = 1e-6 ;        
%--------------- Run actual VMD code:数据进行vmd分解---------------------------
[u, u_hat, omega] = VMD(x, alpha, tau, K, DC, init, tol);
figure;
imfn=u;
n=size(imfn,1); %size(X,1),返回矩阵X的行数;size(X,2),返回矩阵X的列数;N=size(X,2),就是把矩阵X的列数赋值给N




for n1=1:n
    subplot(n,1,n1);
    plot(t,u(n1,:));%输出IMF分量,a(:,n)则表示矩阵a的第n列元素,u(n1,:)表示矩阵u的n1行元素
    ylabel(['IMF' ,int2str(n1)],'fontsize',11);%int2str(i)是将数值i四舍五入后转变成字符,y轴命名
end
 xlabel('样本序列','fontsize',14,'fontname','宋体');

%时间\itt/s
 toc;
 

The figure below is the result of the decomposition.

 The above is a brief description of VMD decomposition. The following blog post will discuss how to fix the number of decomposition layers accordingly.

Guess you like

Origin blog.csdn.net/weixin_46062179/article/details/122268070