0


浅谈VMD---变分模态分解

很多场景下,我们需要将信号进行分解,为我们下一步操作提供方便,常用的分解方法可以有EMD族类,例如EMD、EEMD、FEEMD、CEEMDAN、ICEEMDAN等,当然也有小波分解、经验小波分解等,总之分解方式多种多样,根据样本的特点,选用不同的分解方式。这里简要介绍VMD分解。

  1. Konstantin等人在2014年提出了一个完全非递归的变分模态分解(VMD)它可以实现分解模态的同时提取。该模型寻找一组模态和它们各自的中心频率,以便这些模态共同再现输入信号,同时每个模态在解调到基带后都是平滑的。算法的本质是将经典的维纳滤波器推广到多个自适应波段,使得其具有坚实的理论基础,并且容易理解。采用交替方向乘子法对变分模型进行有效优化,使得模型对采样噪声的鲁棒性更强。

VMD分解的具体过程可以理解为变分问题的最优解,可以相应转化为变分问题的构造和求解。

以上就是VMD(变分模态分解)的理论部分,大家不一定全弄明白,因为本人看了原文,也不能完全弄懂里面的数学关系。大体知道分解的过程包含哪几个步骤即可,知网上面关于这类分解的文章也很多,大家可以参考浏览学习下。

下面直接上代码。

  1. function [u, u_hat, omega] = VMD(signal, alpha, tau, K, DC, init, tol)
  2. % Variational Mode Decomposition
  3. % Authors: Konstantin Dragomiretskiy and Dominique Zosso
  4. % zosso@math.ucla.edu --- http://www.math.ucla.edu/~zosso
  5. % Initial release 2013-12-12 (c) 2013
  6. %
  7. % Input and Parameters:
  8. % ---------------------
  9. % signal - the time domain signal (1D) to be decomposed
  10. % alpha - the balancing parameter of the data-fidelity constraint
  11. % tau - time-step of the dual ascent ( pick 0 for noise-slack )
  12. % K - the number of modes to be recovered
  13. % DC - true if the first mode is put and kept at DC (0-freq)
  14. % init - 0 = all omegas start at 0
  15. % 1 = all omegas start uniformly distributed
  16. % 2 = all omegas initialized randomly
  17. % tol - tolerance of convergence criterion; typically around 1e-6
  18. %
  19. % Output:
  20. % -------
  21. % u - the collection of decomposed modes
  22. % u_hat - spectra of the modes
  23. % omega - estimated mode center-frequencies
  24. %
  25. % When using this code, please do cite our paper:
  26. % -----------------------------------------------
  27. % K. Dragomiretskiy, D. Zosso, Variational Mode Decomposition, IEEE Trans.
  28. % on Signal Processing (in press)
  29. % please check here for update reference:
  30. % http://dx.doi.org/10.1109/TSP.2013.2288675
  31. %---------- Preparations
  32. % Period and sampling frequency of input signal
  33. save_T = length(signal);
  34. fs = 1/save_T;
  35. % extend the signal by mirroring
  36. T = save_T;
  37. f_mirror(1:T/2) = signal(T/2:-1:1);
  38. f_mirror(T/2+1:3*T/2) = signal;
  39. f_mirror(3*T/2+1:2*T) = signal(T:-1:T/2+1);
  40. f = f_mirror;
  41. % Time Domain 0 to T (of mirrored signal)
  42. T = length(f);
  43. t = (1:T)/T;
  44. % Spectral Domain discretization
  45. freqs = t-0.5-1/T;
  46. % Maximum number of iterations (if not converged yet, then it won't anyway)
  47. N = 500;
  48. % For future generalizations: individual alpha for each mode
  49. Alpha = alpha*ones(1,K);
  50. % Construct and center f_hat
  51. f_hat = fftshift((fft(f)));
  52. f_hat_plus = f_hat;
  53. f_hat_plus(1:T/2) = 0;
  54. % matrix keeping track of every iterant // could be discarded for mem
  55. u_hat_plus = zeros(N, length(freqs), K);
  56. % Initialization of omega_k
  57. omega_plus = zeros(N, K);
  58. switch init
  59. case 1
  60. for i = 1:K
  61. omega_plus(1,i) = (0.5/K)*(i-1);
  62. end
  63. case 2
  64. omega_plus(1,:) = sort(exp(log(fs) + (log(0.5)-log(fs))*rand(1,K)));
  65. otherwise
  66. omega_plus(1,:) = 0;
  67. end
  68. % if DC mode imposed, set its omega to 0
  69. if DC
  70. omega_plus(1,1) = 0;
  71. end
  72. % start with empty dual variables
  73. lambda_hat = zeros(N, length(freqs));
  74. % other inits
  75. uDiff = tol+eps; % update step
  76. n = 1; % loop counter
  77. sum_uk = 0; % accumulator
  78. % ----------- Main loop for iterative updates
  79. while ( uDiff > tol && n < N ) % not converged and below iterations limit
  80. % update first mode accumulator
  81. k = 1;
  82. sum_uk = u_hat_plus(n,:,K) + sum_uk - u_hat_plus(n,:,1);
  83. % update spectrum of first mode through Wiener filter of residuals
  84. 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);
  85. % update first omega if not held at 0
  86. if ~DC
  87. 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);
  88. end
  89. % update of any other mode
  90. for k=2:K
  91. % accumulator
  92. sum_uk = u_hat_plus(n+1,:,k-1) + sum_uk - u_hat_plus(n,:,k);
  93. % mode spectrum
  94. 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);
  95. % center frequencies
  96. 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);
  97. end
  98. % Dual ascent
  99. lambda_hat(n+1,:) = lambda_hat(n,:) + tau*(sum(u_hat_plus(n+1,:,:),3) - f_hat_plus);
  100. % loop counter
  101. n = n+1;
  102. % converged yet?
  103. uDiff = eps;
  104. for i=1:K
  105. 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)))';
  106. end
  107. uDiff = abs(uDiff);
  108. end
  109. %------ Postprocessing and cleanup
  110. % discard empty space if converged early
  111. N = min(N,n);
  112. omega = omega_plus(1:N,:);
  113. % Signal reconstruction
  114. u_hat = zeros(T, K);
  115. u_hat((T/2+1):T,:) = squeeze(u_hat_plus(N,(T/2+1):T,:));
  116. u_hat((T/2+1):-1:2,:) = squeeze(conj(u_hat_plus(N,(T/2+1):T,:)));
  117. u_hat(1,:) = conj(u_hat(end,:));
  118. u = zeros(K,length(t));
  119. for k = 1:K
  120. u(k,:)=real(ifft(ifftshift(u_hat(:,k))));
  121. end
  122. % remove mirror part
  123. u = u(:,T/4+1:3*T/4);
  124. % recompute spectrum
  125. clear u_hat;
  126. for k = 1:K
  127. u_hat(:,k)=fftshift(fft(u(k,:)))';
  128. end
  129. end

代码很长,尽量看,能看懂多少看懂多少。这里不再讲解,因为这里都是对数学原理的复现,如果要弄懂原理,建议比照原文和代码相结合,逐行去看。如果只是利用这种分解方式,关心得出的结果,那么就没有必要大费周章了。

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

函数的输入输出,这里要解释一下。

函数的输入部分:signal代表输入信号,alpha表示数据保真度约束的平衡参数 ,tau表示时间步长,K表示分解层数,DC表示如果将第一模式置于DC(0频率),则为true。 init表示信号的初始化,tol表示收敛容错准则。通常除了K,也就是分解模态数之外,其他参数都有相应的经验值。绝大部分文献对VMD的探索也是对分解模态数的确定,顶多再加上tau的讨论。(博主后面的文章中也会进行相应的讨论。)

函数的输出部分:u表示分解模式的集合,u_hat表示模式的光谱范围,omega 表示估计模态的中心频率。

下面是调用VMD分解的主程序。主要步骤就是输入信号值,确定VMD的分解参数,画图。

  1. tic
  2. clc
  3. clear all
  4. load('IMF1_7.mat')
  5. x=IMF1_7;
  6. t=1:length(IMF1_7);
  7. %--------- 对于VMD参数进行设置---------------
  8. alpha = 2000; % moderate bandwidth constraint:适度的带宽约束/惩罚因子
  9. tau = 0.0244; % noise-tolerance (no strict fidelity enforcement):噪声容限(没有严格的保真度执行)
  10. K = 7; % modes:分解的模态数
  11. DC = 0; % no DC part imposed:无直流部分
  12. init = 1; % initialize omegas uniformly omegas的均匀初始化
  13. tol = 1e-6 ;
  14. %--------------- Run actual VMD code:数据进行vmd分解---------------------------
  15. [u, u_hat, omega] = VMD(x, alpha, tau, K, DC, init, tol);
  16. figure;
  17. imfn=u;
  18. n=size(imfn,1); %size(X,1),返回矩阵X的行数;size(X,2),返回矩阵X的列数;N=size(X,2),就是把矩阵X的列数赋值给N
  19. for n1=1:n
  20. subplot(n,1,n1);
  21. plot(t,u(n1,:));%输出IMF分量,a(:,n)则表示矩阵a的第n列元素,u(n1,:)表示矩阵un1行元素
  22. ylabel(['IMF' ,int2str(n1)],'fontsize',11);%int2str(i)是将数值i四舍五入后转变成字符,y轴命名
  23. end
  24. xlabel('样本序列','fontsize',14,'fontname','宋体');
  25. %时间\itt/s
  26. toc;

下图记为分解的结果。

以上就是对VMD分解的简单描述,下面的博文中将探讨如何对分解层数进行相应固定。


本文转载自: https://blog.csdn.net/weixin_46062179/article/details/122268070
版权归原作者 soap皂 所有, 如有侵权,请联系我们删除。

“浅谈VMD---变分模态分解”的评论:

还没有评论