├── myemd.m ├── fangzhen2.mat ├── NFastTV.m ├── alphaplus.m ├── estimate.m ├── theta.m ├── Cal_back_diagonal.m ├── mysvd.m ├── TV.m ├── svd_vmd.m ├── vmd_wtd.m ├── README.md ├── phi.m ├── CEECMSA.m ├── EEMD_SP.m ├── plotall.m ├── SWTTV.m ├── threshfun.m ├── VMD_SWTTV.m ├── RobustPCA.m ├── rpca.m ├── FastTV.m ├── eemd.m ├── test.m ├── ceemdan.m ├── randomizedSVD.m ├── VMD.m └── MyVMD.m /myemd.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noenemys/VMD-SWTTV/HEAD/myemd.m -------------------------------------------------------------------------------- /fangzhen2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/noenemys/VMD-SWTTV/HEAD/fangzhen2.mat -------------------------------------------------------------------------------- /NFastTV.m: -------------------------------------------------------------------------------- 1 | function X=NFastTV(Y,lamda,N) 2 | X=Y; 3 | for i=1:N 4 | X=FastTV(X,lamda); 5 | end 6 | end -------------------------------------------------------------------------------- /alphaplus.m: -------------------------------------------------------------------------------- 1 | function result=alphaplus(input) 2 | if input<0 3 | result=0; 4 | else 5 | result=input; 6 | end 7 | 8 | end -------------------------------------------------------------------------------- /estimate.m: -------------------------------------------------------------------------------- 1 | %Data为采样信号,Ndata为估计信号 2 | function [SNR,RMSE]=estimate(Data,Ndata) 3 | N=length(Data); 4 | SNR=10*log10(sum(Data.^2)/sum((Data-Ndata).^2)); 5 | RMSE=sqrt(sum((Data-Ndata).^2)/N); 6 | end -------------------------------------------------------------------------------- /theta.m: -------------------------------------------------------------------------------- 1 | function result=theta(input,lamda,a) 2 | [m,n]=size(input); 3 | result=zeros(m,n); 4 | for j=1:m 5 | for i=1:n 6 | if (abs(input(j,i))200 22 | ew=ewn'; 23 | break; 24 | else 25 | ewl=ewn; 26 | k=k+1; 27 | end 28 | end 29 | end -------------------------------------------------------------------------------- /svd_vmd.m: -------------------------------------------------------------------------------- 1 | function result=svd_vmd(x) 2 | N=length(x); 3 | m=floor(N/2); 4 | n=N+1-m; 5 | A=zeros(m,n); 6 | for k=1:m 7 | for j=1:n 8 | A(k,j)=x(k+j-1); 9 | end 10 | end 11 | [U,sigma,V]=svd(A); 12 | Sigma=zeros(m,1); 13 | 14 | for i=1:m 15 | Sigma(i)=sigma(i,i).^2; 16 | end 17 | Sve=abs(diff(Sigma)./Sigma(2:end)); 18 | [~,pos]=max(Sve(1:100)); 19 | 20 | sigma(pos+1:end,pos+1:end)=0; 21 | NewA=U*sigma*V'; 22 | result=Cal_back_diagonal(NewA); 23 | result=result'; 24 | end -------------------------------------------------------------------------------- /vmd_wtd.m: -------------------------------------------------------------------------------- 1 | function result=vmd_wtd(x) 2 | level=2; 3 | while 1 4 | v_d=vmd(x,'NumIMF',level); 5 | [~,m]=size(v_d); 6 | C=zeros(m,1); 7 | K=C; 8 | Kw=C; 9 | for i=1:m 10 | C(i)=sum(v_d(:,i).*x)/(norm(v_d(:,i))*norm(x)); 11 | K(i)=kurtosis(v_d(i,:)); 12 | Kw(i)=sign(C(i))*K(i)*abs(C(i)); 13 | end 14 | min_kw=min(Kw); 15 | if min_kw<1 16 | break; 17 | else 18 | level=level+1; 19 | end 20 | end 21 | v_d=vmd(x,'NumIMF',level); 22 | k_c=diff(Kw); 23 | [~,pos]=max(k_c); 24 | 25 | vmd_data=sum(v_d(:,pos+1:end),2); 26 | result=wden(vmd_data,'minimaxi','h','one',3,'db4'); 27 | 28 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VMD-SWTTV 2 | 未经允许,禁止转载!!!! 3 | Matlab版本使用的是2020b 4 | 5 | VMD-SWTTV是一种针对一维信号的二级框架降噪算法,结合了变分模态分解VMD与平稳小波变换SWT,并采用了小波变换全变分法优化了SWT。降噪效果还是不错的。 6 | 联合降噪算法VMD-SWTTV。首先使用VMD对信号进行自适应分解,在确定分解层级与主要IMF分量的选择时, 7 | 使用了峰度值与交叉相关系数进行评判,能够自适应地对信号进行分解与选择; 8 | SWTTV部分引入非凸惩罚项与TV正则项,为简化计算,使用了平稳小波变换以及一种快速全变分降噪算法。 9 | 该算法能够大幅提高信号信噪比,实验数据中分别提升了10.207dB、11.246dB、12.153dB。相比于VMD-WTD算法, 10 | 将SWTTV替换传统小波阈值降噪WTD的这一操作使信噪比分别提升了3.929dB、2.545dB、2.266dB。 11 | 使用仿真数据与最近的一些算法VMD-WTD、SVD-VMD、JANRR、EEMD-SP进行了降噪效果的对比,一定的信噪比范围, 12 | 此方法能更大程度地提升信噪比与降低均方根误差,同时也拥有着良好的稳定性。 13 | 14 | 程序入口为test.m 15 | 如有疑问请加qq:1617768486,或发邮件到1617768486@qq.com 16 | -------------------------------------------------------------------------------- /phi.m: -------------------------------------------------------------------------------- 1 | clear;clc; 2 | x=(0:0.01:3); 3 | N=length(x); 4 | t=-3:0.01:3; 5 | Nt=length(t); 6 | for i=1:Nt 7 | phi(i)=2/(0.95*sqrt(3))*(atan((1+2*0.95*abs(t(i)))/sqrt(3))-pi/6); 8 | end 9 | 10 | 11 | 12 | 13 | for i=1:N 14 | y(i)=x(i) + (4*sign(x(i)))/(3*(((19*abs(x(i)))/10 + 1)^2/3 + 1)); 15 | 16 | end 17 | subplot(1,2,1) 18 | plot(t,abs(t),'--');hold on; 19 | plot(t,phi); 20 | xlabel('(a)'); 21 | title('非凸函数Phi(x)'); 22 | legend('|x|','Phi(x)'); 23 | subplot(1,2,2) 24 | plot(y,x);hold on; 25 | y2=x;y2(1:100)=0; 26 | plot(x,y2,'--');hold on; 27 | plot(1:0.1:3,0:0.1:2,'.'); 28 | 29 | title('阈值函数Theta(y),Lamda=1,a=0.95'); 30 | xlabel('(b)'); 31 | legend('Theta(y)','hard(y)','soft(y)'); -------------------------------------------------------------------------------- /CEECMSA.m: -------------------------------------------------------------------------------- 1 | function result=CEECMSA(x) 2 | y=ceemdan(x,0.005,100,200); 3 | 4 | 5 | N=length(y(2,:)); 6 | m=floor(N/2); 7 | n=N+1-m; 8 | A=zeros(m,n); 9 | for k=1:m 10 | for j=1:n 11 | A(k,j)=x(k+j-1); 12 | end 13 | end 14 | [U,sigma,V]=svd(A); 15 | Sigma=zeros(m,1); 16 | 17 | for i=1:m 18 | Sigma(i)=sigma(i,i); 19 | end 20 | L=Sigma./sum(sum(Sigma)); 21 | deta=-L.*log(L); 22 | pos=deta<0.015; 23 | P=5; 24 | for i=1:length(pos) 25 | if pos(i) 26 | P=i; 27 | break; 28 | end 29 | end 30 | 31 | 32 | sigma(P+1:end,P+1:end)=0; 33 | NewA=U*sigma*V'; 34 | result=Cal_back_diagonal(NewA); 35 | result=result'; 36 | 37 | end -------------------------------------------------------------------------------- /EEMD_SP.m: -------------------------------------------------------------------------------- 1 | function result=EEMD_SP(x) 2 | %x为列向量 3 | [modos ,~]=eemd(x,0.001,30,100); 4 | r=x'-sum(modos); 5 | max_x=max(x); 6 | min_x=min(x); 7 | xi=linspace(min_x,max_x,100); 8 | [m,~]=size(modos); 9 | pdf_x=ksdensity(x,xi); 10 | 11 | like=zeros(m,1); 12 | for i=1:m 13 | pdf_modos(i,:)=ksdensity(modos(i,:),xi); 14 | like(i)=sum(sum((pdf_x-pdf_modos(i,:)).^2)); 15 | 16 | end 17 | pos=1; 18 | for i=2:m-1 19 | if like(i)>like(i-1)&&like(i)>like(i+1) 20 | pos=i; 21 | break; 22 | end 23 | end 24 | reemd=sum(modos(pos:end,:))+r; 25 | reemd=[zeros(1,100),reemd,zeros(1,100)]; 26 | 27 | 28 | 29 | S_P=stft(reemd); 30 | sp=abs(S_P); 31 | angle_sp=angle(S_P); 32 | 33 | [LL, SS] = RobustPCA(sp); 34 | 35 | M_AE=(abs(SS)>abs(LL)); 36 | M_AE=M_AE+0; 37 | S_hat=M_AE.*(abs(SS)+abs(LL)); 38 | rec_sp=S_hat.*sin(angle_sp)*sqrt(-1)+S_hat.*cos(angle_sp); 39 | 40 | 41 | result=(real(istft(rec_sp))); 42 | result=result(101:100+length(x)); 43 | % figure() 44 | % plot(result);hold on; 45 | % plot(x); 46 | 47 | end -------------------------------------------------------------------------------- /plotall.m: -------------------------------------------------------------------------------- 1 | %A 22db 2 | %B 18db 3 | %C 14db 4 | clear;clc; 5 | A=load("SNR_20db.mat"); 6 | A=A.SNR_(:,1:10); 7 | B=load("SNR_15db.mat"); 8 | B=B.SNR_(:,1:10); 9 | C=load("SNR_10db.mat"); 10 | C=C.SNR_(:,1:10); 11 | 12 | c=(1:10); 13 | figure() 14 | subplot(3,1,1); 15 | plot(c,A(1,:),"r-*");hold on; 16 | plot(c,A(2,:),"m-.^");hold on; 17 | plot(c,A(3,:),"k:o");hold on; 18 | plot(c,A(4,:),"g--s");hold on; 19 | plot(c,A(5,:),"b-d");hold on; 20 | ylabel("SNR(db)");xlabel("序号") 21 | 22 | title("原始信噪比20db"); 23 | 24 | 25 | subplot(3,1,2); 26 | plot(c,B(1,:),"r-*");hold on; 27 | plot(c,B(2,:),"m-.^");hold on; 28 | plot(c,B(3,:),"k:o");hold on; 29 | plot(c,B(4,:),"g--s");hold on; 30 | plot(c,B(5,:),"b-d");hold on; 31 | ylabel("SNR(db)");xlabel("序号") 32 | title("原始信噪比15db"); 33 | 34 | 35 | subplot(3,1,3); 36 | plot(c,C(1,:),"r-*");hold on; 37 | plot(c,C(2,:),"m-.^");hold on; 38 | plot(c,C(3,:),"k:o");hold on; 39 | plot(c,C(4,:),"g--s");hold on; 40 | plot(c,C(5,:),"b-d");hold on; 41 | ylabel("SNR(db)");xlabel("序号") 42 | title("原始信噪比10db"); 43 | legend({"VMD-SWTTV","VMD-WTD","SVD-VMD","JANRR","EEMD-SP"},'Location','northwest','NumColumns',3); 44 | -------------------------------------------------------------------------------- /SWTTV.m: -------------------------------------------------------------------------------- 1 | function result=SWTTV(y,miu,level) 2 | 3 | %初始化 4 | N=length(y); 5 | Wy=swt(y,level,"db4"); 6 | 7 | % Wy_4=swt(Wy(4,:),1,"db4"); 8 | % Wy_3=swt(Wy(3,:),1,"db4"); 9 | % Wy_2=swt(Wy(2,:),1,"db4"); 10 | % Wy=[Wy(1,:);Wy_2;Wy_3;Wy_4;Wy(level:end,:)]; 11 | 12 | 13 | u=Wy;d=0; 14 | [m,~]=size(Wy); 15 | sigma=zeros(m,1); 16 | sigma_1= median(abs(Wy(1,:)))/0.6745; 17 | for i=1:level 18 | if i==1 19 | sigma(i)=sigma_1; 20 | else 21 | sigma(i)=2*sigma_1; 22 | end 23 | 24 | end 25 | 26 | sigma=sqrt(sigma)*(0.3936+0.1829*log2(N)); 27 | 28 | yita=0.99; 29 | lamda=2.5*yita.*sigma; 30 | byta=(1-yita)*sqrt(N)*sigma(1)/4; 31 | a=1./lamda; 32 | 33 | % a=max(exp(lamda),1./lamda); 34 | isStop=0; 35 | iter=1; 36 | 37 | phi=Wy; 38 | while (isStop==0) 39 | 40 | rho=(Wy+miu*(u-d))/(miu+1); 41 | phi=theta(rho,lamda/(miu+1),a); 42 | v=phi+d; 43 | 44 | wtv=iswt(v,"db4"); 45 | ww=swt((NFastTV(wtv,byta/miu,1)-wtv),level,"db4"); 46 | 47 | u=v+ww; 48 | d=d-(u-phi); 49 | 50 | iter=iter+1; 51 | if( iter==50) 52 | isStop=1; 53 | 54 | end 55 | end 56 | % phi_2=iswt(phi(2:3,:),"db4"); 57 | % phi_3=iswt(phi(4:5,:),"db4"); 58 | % phi_4=iswt(phi(6:7,:),"db4"); 59 | % 60 | % phi=[phi(1,:);phi_2;phi_3;phi_4;phi(8:end,:)]; 61 | result=iswt(phi,"db4"); 62 | result=result'; 63 | end -------------------------------------------------------------------------------- /threshfun.m: -------------------------------------------------------------------------------- 1 | %alpha,beta in(0,1),(0,1] 2 | function result=threshfun(A,Lamda,SH,L,P) 3 | [m,n]=size(A); 4 | if (L>m||L<1) 5 | return; 6 | else 7 | 8 | result=A; 9 | for i=1:L 10 | for j=1:n 11 | absAij=abs(A(i,j)); 12 | lamda=Lamda(i); 13 | if SH~='n' 14 | if(absAijrow 7 | res=res'; 8 | end 9 | 10 | lambda = 1/ sqrt(max(size(res))); 11 | 12 | tol = 1e-7; 13 | 14 | maxIter = 1000; 15 | 16 | % initialize 17 | 18 | Y = res; 19 | 20 | [u,s,v]=svd(Y); 21 | 22 | norm_two=s(1); 23 | 24 | norm_inf=max(abs(Y(:)))/lambda; 25 | 26 | dual_norm = max(norm_two, norm_inf); 27 | 28 | Y = Y / dual_norm; 29 | 30 | A_hat = zeros( row, col); 31 | 32 | E_hat = zeros( row, col); 33 | 34 | mu = 0.01/norm_two; % this one can be tuned 35 | 36 | mu_bar = mu * 1e7; 37 | 38 | rho = 1.9 ; % this one can be tuned 39 | 40 | d_norm=sqrt(sum(res(:).^2)); 41 | 42 | iter = 0; 43 | 44 | total_svd = 0; 45 | 46 | converged = 0;%收敛 47 | 48 | stopCriterion = 1; 49 | 50 | sv = 10; 51 | 52 | while ~converged 53 | 54 | iter = iter + 1; 55 | 56 | temp_T = res - A_hat + (1/mu)*Y; 57 | 58 | E_hat=temp_T - lambda/mu; 59 | 60 | n1=find(E_hat<0); 61 | 62 | E_hat(n1)=0; 63 | 64 | tmp=temp_T + lambda/mu; 65 | 66 | n1=find(tmp>0); 67 | 68 | tmp(n1)=0; 69 | 70 | E_hat= E_hat+tmp; 71 | 72 | [U1 S1 V1] = svd(res - E_hat + (1/mu)*Y); 73 | U=u;S=s;V=v; 74 | if chsvd(col, sv) == 1 75 | 76 | U=U1(:,1:sv); 77 | 78 | S=S1(:,1:sv); 79 | 80 | V=V1(:,1:sv); 81 | 82 | end 83 | 84 | diagS = diag(S); 85 | 86 | svp = length(find(diagS > 1/mu)); 87 | 88 | if svp < sv 89 | 90 | sv = min(svp + 1, col); 91 | 92 | else 93 | 94 | sv = min(svp + round(0.05*col), col); 95 | 96 | end 97 | 98 | % A_hat = U(:, 1:svp) * diag(diagS(1:svp) - 1/mu) * V(:, 1:svp)'; 99 | 100 | U2=U(:, 1:svp); 101 | 102 | S2=diag(diagS(1:svp) - 1/mu); 103 | 104 | V2=V(:, 1:svp)'; 105 | 106 | A_hat=U2*S2*V2; 107 | 108 | total_svd = total_svd + 1; 109 | 110 | Z = res - A_hat - E_hat; 111 | 112 | Y = Y + mu*Z; 113 | 114 | mu = min(mu*rho, mu_bar); 115 | 116 | %% stop Criterion 117 | 118 | stopCriterion = sqrt(sum(Z(:).^2)) / d_norm; 119 | 120 | if stopCriterion < tol 121 | 122 | converged = 1; 123 | 124 | end 125 | 126 | if ~converged && iter >= maxIter 127 | 128 | disp('Maximum iterations reached') ; 129 | 130 | converged = 1 ; 131 | 132 | end 133 | 134 | end 135 | 136 | end 137 | 138 | function y=chsvd( n, d) 139 | 140 | y=0; 141 | 142 | if ((n<=100)&&(d/n<=0.02)) y=1;end 143 | 144 | if((n<=200)&&(d/n<=0.06)) y=1; end 145 | 146 | if((n<=300)&&(d/n<=0.26)) y=1;end 147 | 148 | if((n<=400)&&(d/n<=0.28)) y=1;end 149 | 150 | if((n<=500)&&(d/n<=0.34)) y=1;end 151 | 152 | if(n>500&&(d/n<=0.38)) y=1;end 153 | 154 | end -------------------------------------------------------------------------------- /FastTV.m: -------------------------------------------------------------------------------- 1 | %输入:需要降噪的实序列Y,实数lamda>0 2 | %输出:TV降噪后的数据 3 | function X=FastTV(Y,lamda) 4 | N=length(Y); 5 | X=Y; 6 | k=1; 7 | k0=k; 8 | kl=k; 9 | kr=k; 10 | vmin=Y(1)-lamda; 11 | vmax=Y(1)+lamda; 12 | umin=lamda; 13 | umax=-lamda; 14 | isterminate=0; 15 | while (isterminate==0) 16 | 17 | if k==N 18 | X(N)=vmin+umin; 19 | isterminate=1; 20 | end 21 | 22 | while kvmax+lamda %4 36 | X(k0)=vmax; 37 | X(kl)=vmax; 38 | X(kr)=vmax; 39 | kr=kr+1; 40 | k=kr; 41 | k0=kr; 42 | kl=kr; 43 | 44 | vmin=Y(k)-2*lamda; 45 | vmax=Y(k); 46 | umin=lamda; 47 | umax=-lamda; 48 | else %5 49 | k=k+1; 50 | 51 | umin=umin+Y(k)-vmin; 52 | umax=umax+Y(k)-vmax; 53 | if (umin>lamda||umin==lamda) 54 | vmin=vmin+(umin-lamda)/(k-k0+1); 55 | umin=lamda; 56 | kl=k; 57 | end 58 | if (umax<-lamda||umax==-lamda) 59 | vmax=vmax+(umax+lamda)/(k-k0+1); 60 | umax=-lamda; 61 | kr=k; 62 | end 63 | end 64 | end 65 | 66 | if umin<0 67 | X(k0)=vmin; 68 | X(kl)=vmin; 69 | 70 | kl=kl+1; 71 | k0=kl; 72 | k=k0; 73 | vmin=Y(k); 74 | umin=lamda; 75 | umax=Y(k)+lamda-vmax; 76 | %tiaozhuan 2 77 | if k==N 78 | X(N)=vmin+umin; 79 | isterminate=1; 80 | end 81 | elseif umax>0 82 | X(k0)=vmax; 83 | X(kl)=vmax; 84 | X(kr)=vmax; 85 | 86 | k=kr+1; 87 | k0=kr+1; 88 | kr=kr+1; 89 | vmax=Y(k); 90 | umax=-lamda; 91 | umin=Y(k)-lamda-vmin; 92 | %tiaozhuan 2 93 | if k==N 94 | X(N)=vmin+umin; 95 | isterminate=1; 96 | end 97 | else 98 | X(k0)=vmin+umin/(k-k0+1); 99 | X(kl)=X(k0); 100 | X(kr)=X(k0); 101 | X(N)=X(k0); 102 | X(k)=X(k0); 103 | isterminate=1; 104 | end 105 | 106 | end 107 | end 108 | -------------------------------------------------------------------------------- /eemd.m: -------------------------------------------------------------------------------- 1 | function [modos its]=eemd(x,Nstd,NR,MaxIter) 2 | %-------------------------------------------------------------------------- 3 | %WARNING: this code needs to include in the same 4 | %directoy the file emd.m developed by Rilling and Flandrin. 5 | %This file is available at %http://perso.ens-lyon.fr/patrick.flandrin/emd.html 6 | %We use the default stopping criterion. 7 | %We use the last modification: 3.2007 8 | % ------------------------------------------------------------------------- 9 | % OUTPUT 10 | % modos: contain the obtained modes in a matrix with the rows being the modes 11 | % its: contain the iterations needed for each mode for each realization 12 | % 13 | % INPUT 14 | % x: signal to decompose 15 | % Nstd: noise standard deviation 16 | % NR: number of realizations 17 | % MaxIter: maximum number of sifting iterations allowed. 18 | % ------------------------------------------------------------------------- 19 | % Syntax 20 | % 21 | % modos=eemd(x,Nstd,NR,MaxIter) 22 | % [modos its]=eemd(x,Nstd,NR,MaxIter) 23 | % ------------------------------------------------------------------------- 24 | % NOTE: if Nstd=0 and NR=1, the EMD decomposition is obtained. 25 | % ------------------------------------------------------------------------- 26 | % EEMD was introduced in 27 | % Wu Z. and Huang N. 28 | % "Ensemble Empirical Mode Decomposition: A noise-assisted data analysis method". 29 | % Advances in Adaptive Data Analysis. vol 1. pp 1-41, 2009. 30 | %-------------------------------------------------------------------------- 31 | % The present EEMD implementation was used in 32 | % M.E.TORRES, M.A. COLOMINAS, G. SCHLOTTHAUER, P. FLANDRIN, 33 | % "A complete Ensemble Empirical Mode decomposition with adaptive noise," 34 | % IEEE Int. Conf. on Acoust., Speech and Signal Proc. ICASSP-11, pp. 4144-4147, Prague (CZ) 35 | % 36 | % in order to compare the performance of the new method CEEMDAN with the performance of the EEMD. 37 | % 38 | % ------------------------------------------------------------------------- 39 | % Date: June 06,2011 40 | % Authors: Torres ME, Colominas MA, Schlotthauer G, Flandrin P. 41 | % For problems with the code, please contact the authors: 42 | % To: macolominas(AT)bioingenieria.edu.ar 43 | % CC: metorres(AT)santafe-conicet.gov.ar 44 | % ------------------------------------------------------------------------- 45 | % This version was run on Matlab 7.10.0 (R2010a) 46 | %-------------------------------------------------------------------------- 47 | 48 | desvio_estandar=std(x); 49 | x=x/desvio_estandar; 50 | xconruido=x+Nstd*randn(size(x)); 51 | [modos, o, it]=myemd(xconruido,'MAXITERATIONS',MaxIter); 52 | modos=modos/NR; 53 | iter=it; 54 | if NR>=2 55 | for i=2:NR 56 | xconruido=x+Nstd*randn(size(x)); 57 | [temp, ort, it]=myemd(xconruido,'MAXITERATIONS',MaxIter); 58 | temp=temp/NR; 59 | lit=length(it); 60 | [p liter]=size(iter); 61 | if litalto 74 | modos=[modos; zeros(abs(diferencia),ancho)]; 75 | end; 76 | if alto>filas 77 | temp=[temp;zeros(abs(diferencia),ancho)]; 78 | end; 79 | 80 | modos=modos+temp; 81 | end; 82 | end; 83 | its=iter; 84 | modos=modos*desvio_estandar; -------------------------------------------------------------------------------- /test.m: -------------------------------------------------------------------------------- 1 | clear;close all;clc; 2 | fangzhen2=load('fangzhen2.mat'); 3 | fangzhen2=fangzhen2.fangzhen2; 4 | s=fangzhen2(:,2)+fangzhen2(:,3); 5 | s=s(578:1601);%1024个点 6 | t=fangzhen2(:,1); 7 | t=t(578:1601); 8 | fs=1/(t(2)-t(1)); 9 | osignal=s*10^11; 10 | 11 | SNR=zeros(10,6); 12 | RMSE=zeros(10,6); 13 | Time=zeros(5,11); 14 | snr_t=5;%添加噪声时控制信噪比水平 15 | 16 | for i=1:10 17 | 18 | testsignal=awgn(osignal,snr_t,'measured'); 19 | 20 | tic; 21 | vmd_swttv_data=VMD_SWTTV(testsignal,1024,5);%VMD-SWTTV方法 22 | time_vmd_swttv=toc; 23 | 24 | tic; 25 | vmd_wtd_data=vmd_wtd(testsignal); 26 | time_vmd_wtd=toc; 27 | 28 | tic; 29 | svd_vmd_data=svd_vmd(testsignal); 30 | time_svd_vmd=toc; 31 | 32 | tic; 33 | ceecmsa_data=CEECMSA(testsignal); 34 | time_ceecmsa=toc; 35 | 36 | tic; 37 | eemd_sp_data=EEMD_SP(testsignal); 38 | time_eemd_sp=toc; 39 | 40 | 41 | Tt=[time_vmd_swttv,time_vmd_wtd,time_svd_vmd,time_ceecmsa,time_eemd_sp]; 42 | Time(:,i)=Tt'; 43 | 44 | 45 | 46 | [SNRvmd_swttv,RMSEvmd_swttv]=estimate(vmd_swttv_data,osignal); 47 | [SNRvmd_wtd,RMSEvmd_wtd]=estimate(vmd_wtd_data,osignal); 48 | [SNRvmd_data,RMSEvmd_data]=estimate(svd_vmd_data,osignal); 49 | [SNRceecmsa,RMSEceecmsa]=estimate(ceecmsa_data,osignal); 50 | [SNReemd_sp,RMSEeemd_sp]=estimate(eemd_sp_data,osignal); 51 | [SNRosignal,RMSEosignal]=estimate(testsignal,osignal); 52 | 53 | SNR(i,:)=[SNRvmd_swttv,SNRvmd_wtd,SNRvmd_data,SNRceecmsa,SNReemd_sp,SNRosignal]; 54 | RMSE(i,:)=[RMSEvmd_swttv,RMSEvmd_wtd,RMSEvmd_data,RMSEceecmsa,RMSEeemd_sp,RMSEosignal]; 55 | 56 | end 57 | 58 | 59 | Time(:,11)=mean(Time(:,1:10),2); 60 | SNRmean=mean(SNR); 61 | RMSEmean=mean(RMSE); 62 | isplot=1; 63 | if isplot 64 | figure(2); 65 | subplot(5,1,1); 66 | plot(t,testsignal);hold on; 67 | plot(t,vmd_swttv_data);hold on; 68 | ylabel("信号幅值(v)"); 69 | xlabel("时间(s)"); 70 | xlim([2.8,8]*10^-5); 71 | title("VMD-SWTTV"); 72 | 73 | 74 | 75 | subplot(5,1,2); 76 | plot(t,testsignal);hold on; 77 | plot(t,vmd_wtd_data);hold on; 78 | ylabel("信号幅值(v)"); 79 | xlabel("时间(s)"); 80 | xlim([2.8,8]*10^-5); 81 | title("VMD-WTD"); 82 | 83 | subplot(5,1,3); 84 | plot(t,testsignal);hold on; 85 | plot(t,svd_vmd_data);hold on; 86 | ylabel("信号幅值(v)"); 87 | xlim([2.8,8]*10^-5); 88 | xlabel("时间(s)"); 89 | title("SVD-VMD"); 90 | 91 | subplot(5,1,4); 92 | plot(t,testsignal);hold on; 93 | plot(t,ceecmsa_data);hold on; 94 | ylabel("信号幅值(v)"); 95 | xlabel("时间(s)"); 96 | xlim([2.8,8]*10^-5); 97 | title("JANRR"); 98 | 99 | subplot(5,1,5); 100 | plot(t,testsignal);hold on; 101 | plot(t,eemd_sp_data);hold on; 102 | legend("含噪信号","降噪信号",'NumColumns',2); 103 | ylabel("信号幅值(v)"); 104 | xlim([2.8,8]*10^-5); 105 | xlabel("时间(s)"); 106 | title("EEMD-SP"); 107 | end 108 | SNRmean_=SNRmean'; 109 | RMSEmean_=RMSEmean'; 110 | SNR=SNR'; 111 | RMSE=RMSE'; 112 | SNR_=[SNR(1:6,:),SNRmean_(1:6)]; 113 | RMSE_=[RMSE(1:6,:),RMSEmean_(1:6)]; 114 | 115 | figure() 116 | subplot(2,1,1); 117 | plot((1:10),SNR_(1,1:10),"r-*");hold on; 118 | plot((1:10),SNR_(2,1:10),"m-.^");hold on; 119 | plot((1:10),SNR_(3,1:10),"k:o");hold on; 120 | plot((1:10),SNR_(4,1:10),"g--s");hold on; 121 | plot((1:10),SNR_(5,1:10),"b-d");hold on; 122 | 123 | ylabel("SNR(db)");xlabel("序号") 124 | title_=strcat("原始信噪比",num2str(snr_t),"db"); 125 | title(title_); 126 | legend({"VMD-SWTTV","VMD-WTD","SVD-VMD","JANRR","EEMD-SP"},'NumColumns',3); 127 | DB=num2str(snr_t); 128 | S_Name=strcat("SNR_",DB,"db"); 129 | R_Name=strcat("RMSE_",DB,"db"); 130 | % save(S_Name,'SNR_');%数据保存 131 | % save(R_Name,'RMSE_'); 132 | -------------------------------------------------------------------------------- /ceemdan.m: -------------------------------------------------------------------------------- 1 | function [modes its]=ceemdan(x,Nstd,NR,MaxIter) 2 | 3 | % WARNING: for this code works it is necessary to include in the same 4 | %directoy the file emd.m developed by Rilling and Flandrin. 5 | %This file is available at %http://perso.ens-lyon.fr/patrick.flandrin/emd.html 6 | %We use the default stopping criterion. 7 | %We use the last modification: 3.2007 8 | % 9 | % This version was run on Matlab 7.10.0 (R2010a) 10 | %---------------------------------------------------------------------- 11 | % INPUTs 12 | % x: signal to decompose 13 | % Nstd: noise standard deviation 14 | % NR: number of realizations 15 | % MaxIter: maximum number of sifting iterations allowed. 16 | % 17 | % OUTPUTs 18 | % modes: contain the obtained modes in a matrix with the rows being the modes 19 | % its: contain the sifting iterations needed for each mode for each realization (one row for each realization) 20 | % ------------------------------------------------------------------------- 21 | % Syntax 22 | % 23 | % modes=ceemdan(x,Nstd,NR,MaxIter) 24 | % [modes its]=ceemdan(x,Nstd,NR,MaxIter) 25 | % 26 | %-------------------------------------------------------------------------- 27 | % This algorithm was presented at ICASSP 2011, Prague, Czech Republic 28 | % Plese, if you use this code in your work, please cite the paper where the 29 | % algorithm was first presented. 30 | % If you use this code, please cite: 31 | % 32 | % M.E.TORRES, M.A. COLOMINAS, G. SCHLOTTHAUER, P. FLANDRIN, 33 | % "A complete Ensemble Empirical Mode decomposition with adaptive noise," 34 | % IEEE Int. Conf. on Acoust., Speech and Signal Proc. ICASSP-11, pp. 4144-4147, Prague (CZ) 35 | % 36 | % ------------------------------------------------------------------------- 37 | % Date: June 06,2011 38 | % Authors: Torres ME, Colominas MA, Schlotthauer G, Flandrin P. 39 | % For problems with the code, please contact the authors: 40 | % To: macolominas(AT)bioingenieria.edu.ar 41 | % CC: metorres(AT)santafe-conicet.gov.ar 42 | % ------------------------------------------------------------------------- 43 | 44 | x=x(:)'; 45 | desvio_x=std(x); 46 | x=x/desvio_x; 47 | 48 | modes=zeros(size(x)); 49 | temp=zeros(size(x)); 50 | aux=zeros(size(x)); 51 | acum=zeros(size(x)); 52 | iter=zeros(NR,round(log2(length(x))+5)); 53 | 54 | for i=1:NR 55 | white_noise{i}=randn(size(x));%creates the noise realizations 56 | end; 57 | 58 | for i=1:NR 59 | modes_white_noise{i}=emd(white_noise{i});%calculates the modes of white gaussian noise 60 | end; 61 | 62 | for i=1:NR %calculates the first mode 63 | temp=x+Nstd*white_noise{i}; 64 | [temp, o, it]=myemd(temp,'MAXMODES',1,'MAXITERATIONS',MaxIter); 65 | temp=temp(1,:); 66 | aux=aux+temp/NR; 67 | iter(i,1)=it; 68 | end; 69 | 70 | modes=aux; %saves the first mode 71 | k=1; 72 | aux=zeros(size(x)); 73 | acum=sum(modes,1); 74 | 75 | while nnz(diff(sign(diff(x-acum))))>2 %calculates the rest of the modes 76 | for i=1:NR 77 | tamanio=size(modes_white_noise{i}); 78 | if tamanio(1)>=k+1 79 | noise=modes_white_noise{i}(k,:); 80 | noise=noise/std(noise); 81 | noise=Nstd*noise; 82 | try 83 | [temp, o, it]=emd(x-acum+std(x-acum)*noise,'MAXMODES',1,'MAXITERATIONS',MaxIter); 84 | temp=temp(1,:); 85 | catch 86 | it=0; 87 | temp=x-acum; 88 | end; 89 | else 90 | [temp, o, it]=emd(x-acum,'MAXMODES',1,'MAXITERATIONS',MaxIter); 91 | temp=temp(1,:); 92 | end; 93 | aux=aux+temp/NR; 94 | iter(i,k+1)=it; 95 | end; 96 | modes=[modes;aux]; 97 | aux=zeros(size(x)); 98 | acum=zeros(size(x)); 99 | acum=sum(modes,1); 100 | k=k+1; 101 | end; 102 | modes=[modes;(x-acum)]; 103 | % [a b]=size(modes); 104 | % iter=iter(:,1:a); 105 | modes=modes*desvio_x; 106 | its=iter; 107 | end 108 | 109 | 110 | -------------------------------------------------------------------------------- /randomizedSVD.m: -------------------------------------------------------------------------------- 1 | function [U,S,V] = randomizedSVD( X, r, rEst, nPower, seed, opts ) 2 | % [U,S,V] = randomizedSVD( X, r, rEst, nPower, seed, opts ) 3 | % returns V, S such that X ~ U*S*V' ( a m x n matrix) 4 | % where S is a r x r matrix 5 | % rEst >= r is the size of the random multiplies (default: ceil(r+log2(r)) ) 6 | % nPower is number of iterations to do the power method 7 | % (should be at least 1, which is the default) 8 | % seed can be the empty matrix; otherwise, it will be used to seed 9 | % the random number generator (useful if you want reproducible results) 10 | % opts is a structure containing further options, including: 11 | % opts.warmStart Set this to a matrix if you have a good estimate 12 | % of the row-space of the matrix already. By default, 13 | % a random matrix is used. 14 | % 15 | % X can either be a m x n matrix, or it can be a cell array 16 | % of the form {@(y)X*y, @(y)X'*y, n } 17 | % 18 | % Follows the algorithm from [1] 19 | % 20 | % [1] "Finding Structure with Randomness: Probabilistic Algorithms 21 | % for Constructing Approximate Matrix Decompositions" 22 | % by N. Halko, P. G. Martinsson, and J. A. Tropp. SIAM Review vol 53 2011. 23 | % http://epubs.siam.org/doi/abs/10.1137/090771806 24 | % 25 | 26 | % added to TFOCS in October 2014 27 | 28 | if isnumeric( X ) 29 | X_forward = @(y) X*y; 30 | X_transpose = @(y) X'*y; 31 | n = size(X,2); 32 | elseif iscell(X) 33 | if isa(X{1},'function_handle') 34 | X_forward = X{1}; 35 | else 36 | error('X{1} should be a function handle'); 37 | end 38 | if isa(X{2},'function_handle') 39 | X_transpose = X{2}; 40 | else 41 | error('X{2} should be a function handle'); 42 | end 43 | if size(X) < 3 44 | error('Please specify X in the form {@(y)X*y, @(y)X''*y, n }' ); 45 | end 46 | n = X{3}; 47 | else 48 | error('Unknown type for X: should be matrix or cell/function handle'); 49 | end 50 | function out = setOpts( field, default ) 51 | if ~isfield( opts, field ) 52 | out = default; 53 | else 54 | out = opts.(field); 55 | end 56 | end 57 | 58 | % If you want reproducible results for some reason: 59 | if nargin >= 6 && ~isempty(seed) 60 | % around 2013 or 14 (not sure exactly) 61 | % they start changing .setDefaultStream... 62 | if verLessThan('matlab','8.2') 63 | RandStream.setDefaultStream(RandStream('mt19937ar', 'seed', seed) ); 64 | else 65 | RandStream.setGlobalStream(RandStream('mt19937ar', 'seed', seed) ); 66 | end 67 | end 68 | if nargin < 3 || isempty( rEst ) 69 | rEst = ceil( r + log2(r) ); % for example... 70 | end 71 | rEst = min( rEst, n ); 72 | if r > n 73 | warning('randomizedSVD:r','Warning: r > # rows, so truncating it'); 74 | r = n; 75 | end 76 | 77 | % March 2015, do full SVD sometimes 78 | if isnumeric( X ) 79 | m = size(X,1); 80 | rEst = min( rEst, m ); 81 | r = min( r, m ); 82 | 83 | if r == min( m, n ) 84 | % do full SVD 85 | [U,S,V] = svd(X,'econ'); 86 | return; 87 | end 88 | end 89 | 90 | 91 | if nargin < 4 || isempty( nPower ) 92 | nPower = 1; 93 | end 94 | if nPower < 1, error('nPower must be >= 1'); end 95 | if nargin < 6, opts = []; end 96 | 97 | warmStart = setOpts('warmStart',[] ); 98 | if isempty( warmStart ) 99 | Q = randn( n, rEst ); 100 | else 101 | Q = warmStart; 102 | if size(Q,1) ~= n, error('bad height dimension for warmStart'); end 103 | if size(Q,2) > rEst 104 | % with Nesterov, we get this a lot, so disable it 105 | warning('randomizedSVD:warmStartLarge','Warning: warmStart has more columns than rEst'); 106 | % disp('Warning: warmStart has more columns than rEst'); 107 | else 108 | Q = [Q, randn(n,rEst - size(Q,2) )]; 109 | end 110 | end 111 | Q = X_forward(Q); 112 | % Algo 4.4 in "Structure in randomness" paper, but we re-arrange a little 113 | for j = 1:(nPower-1) 114 | [Q,R] = qr(Q,0); 115 | Q = X_transpose(Q); 116 | [Q,R] = qr(Q,0); 117 | Q = X_forward(Q); 118 | end 119 | [Q,R] = qr(Q,0); 120 | 121 | % We can now approximate: 122 | % X ~ QQ'X = QV' 123 | % Form Q'X, e.g. V = X'Q 124 | V = X_transpose(Q); 125 | 126 | [V,R] = qr(V,0); 127 | [U,S,VV] = svd(R','econ'); 128 | U = Q*U; 129 | V = V*VV; 130 | 131 | % Now, pick out top r. It's already sorted. 132 | U = U(:,1:r); 133 | V = V(:,1:r); 134 | S = S(1:r,1:r); 135 | 136 | 137 | end % end of function 138 | -------------------------------------------------------------------------------- /VMD.m: -------------------------------------------------------------------------------- 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 | 24 | % omega - estimated mode center-frequencies 25 | 26 | % 27 | 28 | % When using this code, please do cite our paper: 29 | 30 | % ----------------------------------------------- 31 | 32 | % K. Dragomiretskiy, D. Zosso, Variational Mode Decomposition, IEEE Trans. 33 | 34 | % on Signal Processing (in press) 35 | 36 | % please check here for update reference: 37 | 38 | % http://dx.doi.org/10.1109/TSP.2013.2288675 39 | 40 | 41 | 42 | 43 | %---------- Preparations 44 | 45 | 46 | % Period and sampling frequency of input signal 47 | 48 | save_T = length(signal); 49 | fs = 1/save_T; 50 | 51 | 52 | % extend the signal by mirroring 53 | 54 | T = save_T; 55 | f_mirror(1:T/2) = signal(T/2:-1:1); 56 | 57 | f_mirror(T/2+1:3*T/2) = signal; 58 | f_mirror(3*T/2+1:2*T) = signal(T:-1:T/2+1); 59 | 60 | f = f_mirror; 61 | % Time Domain 0 to T (of mirrored signal) 62 | T = length(f); 63 | t = (1:T)/T; 64 | % Spectral Domain discretization 65 | freqs = t-0.5-1/T; 66 | % Maximum number of iterations (if not converged yet, then it won't anyway) 67 | N = 500; 68 | % For future generalizations: individual alpha for each mode 69 | Alpha = alpha*ones(1,K); 70 | % Construct and center f_hat 71 | 72 | f_hat = fftshift((fft(f))); 73 | f_hat_plus = f_hat; 74 | 75 | f_hat_plus(1:T/2) = 0; 76 | 77 | 78 | % matrix keeping track of every iterant // could be discarded for mem 79 | 80 | u_hat_plus = zeros(N, length(freqs), K); 81 | 82 | 83 | % Initialization of omega_k 84 | omega_plus = zeros(N, K); 85 | 86 | switch init 87 | 88 | case 1 89 | for i = 1:K 90 | omega_plus(1,i) = (0.5/K)*(i-1); 91 | end 92 | case 2 93 | omega_plus(1,:) = sort(exp(log(fs) + (log(0.5)-log(fs))*rand(1,K))); 94 | otherwise 95 | omega_plus(1,:) = 0; 96 | end 97 | 98 | 99 | % if DC mode imposed, set its omega to 0 100 | 101 | if DC 102 | 103 | omega_plus(1,1) = 0; 104 | end 105 | 106 | 107 | % start with empty dual variables 108 | 109 | lambda_hat = zeros(N, length(freqs)); 110 | % other inits 111 | uDiff = tol+eps; % update step 112 | n = 1; % loop counter 113 | sum_uk = 0; % accumulator 114 | 115 | 116 | 117 | 118 | % ----------- Main loop for iterative updates 119 | 120 | 121 | 122 | 123 | 124 | while ( uDiff > tol && n < N ) % not converged and below iterations limit 125 | 126 | 127 | % update first mode accumulator 128 | k = 1; 129 | sum_uk = u_hat_plus(n,:,K) + sum_uk - u_hat_plus(n,:,1); 130 | 131 | % update spectrum of first mode through Wiener filter of residuals 132 | 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); 133 | 134 | % update first omega if not held at 0 135 | if ~DC 136 | 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); 137 | end 138 | 139 | % update of any other mode 140 | for k=2:K 141 | 142 | % accumulator 143 | sum_uk = u_hat_plus(n+1,:,k-1) + sum_uk - u_hat_plus(n,:,k); 144 | 145 | % mode spectrum 146 | 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); 147 | 148 | % center frequencies 149 | 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); 150 | 151 | end 152 | 153 | % Dual ascent 154 | lambda_hat(n+1,:) = lambda_hat(n,:) + tau*(sum(u_hat_plus(n+1,:,:),3) - f_hat_plus); 155 | 156 | % loop counter 157 | n = n+1; 158 | 159 | % converged yet? 160 | uDiff = eps; 161 | for i=1:K 162 | 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)))'; 163 | end 164 | uDiff = abs(uDiff); 165 | 166 | end 167 | 168 | 169 | 170 | %------ Postprocessing and cleanup 171 | 172 | 173 | 174 | % discard empty space if converged early 175 | 176 | N = min(N,n); 177 | 178 | omega = omega_plus(1:N,:); 179 | % Signal reconstruction 180 | u_hat = zeros(T, K); 181 | 182 | u_hat((T/2+1):T,:) = squeeze(u_hat_plus(N,(T/2+1):T,:)); 183 | u_hat((T/2+1):-1:2,:) = squeeze(conj(u_hat_plus(N,(T/2+1):T,:))); 184 | 185 | u_hat(1,:) = conj(u_hat(end,:)); 186 | 187 | 188 | u = zeros(K,length(t)); 189 | 190 | 191 | for k = 1:K 192 | 193 | u(k,:)=real(ifft(ifftshift(u_hat(:,k)))); 194 | end 195 | 196 | 197 | % remove mirror part 198 | 199 | u = u(:,T/4+1:3*T/4); 200 | % recompute spectrum 201 | clear u_hat; 202 | for k = 1:K 203 | u_hat(:,k)=fftshift(fft(u(k,:)))'; 204 | end 205 | end -------------------------------------------------------------------------------- /MyVMD.m: -------------------------------------------------------------------------------- 1 | %主程序 2 | 3 | %--------------- Preparation 4 | 5 | clear all; 6 | 7 | close all; 8 | 9 | clc; 10 | 11 | % Time Domain 0 to T 12 | 13 | T = 1000; 14 | 15 | fs = 1/T; 16 | 17 | t = (1:T)/T; 18 | 19 | freqs = 2*pi*(t-0.5-1/T)/(fs); 20 | 21 | % center frequencies of components 22 | 23 | f_1 = 2; 24 | f_2 = 24; 25 | 26 | f_3 = 288; 27 | % modes 28 | v_1 = (cos(2*pi*f_1*t)); 29 | v_2 = 1/4*(cos(2*pi*f_2*t)); 30 | 31 | v_3 = 1/16*(cos(2*pi*f_3*t)); 32 | % for visualization purposes 33 | wsub{1} = 2*pi*f_1; 34 | wsub{2} = 2*pi*f_2; 35 | wsub{3} = 2*pi*f_3; 36 | % composite signal, including noise 37 | f = v_1 + v_2 + v_3 + 0.1*randn(size(v_1)); 38 | % some sample parameters for VMD 39 | alpha = 2000; % moderate bandwidth constraint 40 | tau = 0; % noise-tolerance (no strict fidelity enforcement) 41 | K = 4; % 4 modes 42 | DC = 0; % no DC part imposed 43 | init = 1; % initialize omegas uniformly 44 | tol = 1e-7; 45 | %--------------- Run actual VMD code 46 | [u, u_hat, omega] = VMD(f, alpha, tau, K, DC, init, tol); 47 | 48 | subplot(size(u,1)+1,2,1); 49 | 50 | plot(t,f,'k');grid on; 51 | 52 | title('VMD分解'); 53 | 54 | subplot(size(u,1)+1,2,2); 55 | 56 | plot(freqs,abs(fft(f)),'k');grid on; 57 | 58 | title('对应频谱'); 59 | 60 | for i = 2:size(u,1)+1 61 | 62 | subplot(size(u,1)+1,2,i*2-1); 63 | plot(t,u(i-1,:),'k');grid on; 64 | subplot(size(u,1)+1,2,i*2); 65 | plot(freqs,abs(fft(u(i-1,:))),'k');grid on; 66 | end 67 | 68 | 69 | %---------------run EMD code 70 | 71 | imf = emd(f); 72 | 73 | figure; 74 | 75 | subplot(size(imf,1)+1,2,1); 76 | 77 | plot(t,f,'k');grid on; 78 | 79 | title('EMD分解'); 80 | 81 | subplot(size(imf,1)+1,2,2); 82 | 83 | plot(freqs,abs(fft(f)),'k');grid on; 84 | 85 | title('对应频谱'); 86 | 87 | for i = 2:size(imf,1)+1 88 | 89 | subplot(size(imf,1)+1,2,i*2-1); 90 | plot(t,imf(i-1,:),'k');grid on; 91 | subplot(size(imf,1)+1,2,i*2); 92 | plot(freqs,abs(fft(imf(i-1,:))),'k');grid on; 93 | end 94 | 95 | 96 | 97 | 98 | %%%%函数部分 99 | 100 | function [u, u_hat, omega] = VMD(signal, alpha, tau, K, DC, init, tol) 101 | % Variational Mode Decomposition 102 | % Authors: Konstantin Dragomiretskiy and Dominique Zosso 103 | % zosso@math.ucla.edu --- http://www.math.ucla.edu/~zosso 104 | % Initial release 2013-12-12 (c) 2013 105 | % 106 | % Input and Parameters: 107 | % --------------------- 108 | % signal - the time domain signal (1D) to be decomposed 109 | % alpha - the balancing parameter of the data-fidelity constraint 110 | % tau - time-step of the dual ascent ( pick 0 for noise-slack ) 111 | % K - the number of modes to be recovered 112 | % DC - true if the first mode is put and kept at DC (0-freq) 113 | % init - 0 = all omegas start at 0 114 | % 1 = all omegas start uniformly distributed 115 | % 2 = all omegas initialized randomly 116 | % tol - tolerance of convergence criterion; typically around 1e-6 117 | % 118 | % Output: 119 | % ------- 120 | % u - the collection of decomposed modes 121 | % u_hat - spectra of the modes 122 | 123 | % omega - estimated mode center-frequencies 124 | 125 | % 126 | 127 | % When using this code, please do cite our paper: 128 | 129 | % ----------------------------------------------- 130 | 131 | % K. Dragomiretskiy, D. Zosso, Variational Mode Decomposition, IEEE Trans. 132 | 133 | % on Signal Processing (in press) 134 | 135 | % please check here for update reference: 136 | 137 | % http://dx.doi.org/10.1109/TSP.2013.2288675 138 | 139 | 140 | 141 | 142 | %---------- Preparations 143 | 144 | 145 | % Period and sampling frequency of input signal 146 | 147 | save_T = length(signal); 148 | fs = 1/save_T; 149 | 150 | 151 | % extend the signal by mirroring 152 | 153 | T = save_T; 154 | f_mirror(1:T/2) = signal(T/2:-1:1); 155 | 156 | f_mirror(T/2+1:3*T/2) = signal; 157 | f_mirror(3*T/2+1:2*T) = signal(T:-1:T/2+1); 158 | 159 | f = f_mirror; 160 | % Time Domain 0 to T (of mirrored signal) 161 | T = length(f); 162 | t = (1:T)/T; 163 | % Spectral Domain discretization 164 | freqs = t-0.5-1/T; 165 | % Maximum number of iterations (if not converged yet, then it won't anyway) 166 | N = 500; 167 | % For future generalizations: individual alpha for each mode 168 | Alpha = alpha*ones(1,K); 169 | % Construct and center f_hat 170 | 171 | f_hat = fftshift((fft(f))); 172 | f_hat_plus = f_hat; 173 | 174 | f_hat_plus(1:T/2) = 0; 175 | 176 | 177 | % matrix keeping track of every iterant // could be discarded for mem 178 | 179 | u_hat_plus = zeros(N, length(freqs), K); 180 | 181 | 182 | % Initialization of omega_k 183 | omega_plus = zeros(N, K); 184 | 185 | switch init 186 | 187 | case 1 188 | for i = 1:K 189 | omega_plus(1,i) = (0.5/K)*(i-1); 190 | end 191 | case 2 192 | omega_plus(1,:) = sort(exp(log(fs) + (log(0.5)-log(fs))*rand(1,K))); 193 | otherwise 194 | omega_plus(1,:) = 0; 195 | end 196 | 197 | 198 | % if DC mode imposed, set its omega to 0 199 | 200 | if DC 201 | 202 | omega_plus(1,1) = 0; 203 | end 204 | 205 | 206 | % start with empty dual variables 207 | 208 | lambda_hat = zeros(N, length(freqs)); 209 | % other inits 210 | uDiff = tol+eps; % update step 211 | n = 1; % loop counter 212 | sum_uk = 0; % accumulator 213 | 214 | 215 | 216 | 217 | % ----------- Main loop for iterative updates 218 | 219 | 220 | 221 | 222 | 223 | while ( uDiff > tol && n < N ) % not converged and below iterations limit 224 | 225 | 226 | % update first mode accumulator 227 | k = 1; 228 | sum_uk = u_hat_plus(n,:,K) + sum_uk - u_hat_plus(n,:,1); 229 | 230 | % update spectrum of first mode through Wiener filter of residuals 231 | 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); 232 | 233 | % update first omega if not held at 0 234 | if ~DC 235 | 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); 236 | end 237 | 238 | % update of any other mode 239 | for k=2:K 240 | 241 | % accumulator 242 | sum_uk = u_hat_plus(n+1,:,k-1) + sum_uk - u_hat_plus(n,:,k); 243 | 244 | % mode spectrum 245 | 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); 246 | 247 | % center frequencies 248 | 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); 249 | 250 | end 251 | 252 | % Dual ascent 253 | lambda_hat(n+1,:) = lambda_hat(n,:) + tau*(sum(u_hat_plus(n+1,:,:),3) - f_hat_plus); 254 | 255 | % loop counter 256 | n = n+1; 257 | 258 | % converged yet? 259 | uDiff = eps; 260 | for i=1:K 261 | 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)))'; 262 | end 263 | uDiff = abs(uDiff); 264 | 265 | end 266 | 267 | 268 | 269 | %------ Postprocessing and cleanup 270 | 271 | 272 | 273 | % discard empty space if converged early 274 | 275 | N = min(N,n); 276 | 277 | omega = omega_plus(1:N,:); 278 | % Signal reconstruction 279 | u_hat = zeros(T, K); 280 | 281 | u_hat((T/2+1):T,:) = squeeze(u_hat_plus(N,(T/2+1):T,:)); 282 | u_hat((T/2+1):-1:2,:) = squeeze(conj(u_hat_plus(N,(T/2+1):T,:))); 283 | 284 | u_hat(1,:) = conj(u_hat(end,:)); 285 | 286 | 287 | u = zeros(K,length(t)); 288 | 289 | 290 | for k = 1:K 291 | 292 | u(k,:)=real(ifft(ifftshift(u_hat(:,k)))); 293 | end 294 | 295 | 296 | % remove mirror part 297 | 298 | u = u(:,T/4+1:3*T/4); 299 | % recompute spectrum 300 | clear u_hat; 301 | for k = 1:K 302 | u_hat(:,k)=fftshift(fft(u(k,:)))'; 303 | end 304 | end --------------------------------------------------------------------------------