作者:桂。

时间:2017-03-06  20:57:22

链接:http://www.cnblogs.com/xingshansi/p/6511916.html


前言

本文为Hilbert变换一篇的内容补充,主要内容为:

  1)EMD原理介绍

  2)代码分析

  3)一种权衡的小trick

  4)问题补充

内容主要为自己的学习总结,并多有借鉴他人,最后一并给出链接。

一、EMD原理介绍

  A-EMD的意义

很多人都知道EMD(Empirical Mode Decomposition)可以将信号分解不同频率特性,并且结合Hilbert求解包络以及瞬时频率。EMD、Hilbert、瞬时频率三者有无内在联系?答案是:有。

按照Hilbert变换一篇的介绍,

$f(t) = \frac{{d\Phi (t)}}{{d(t)}}$

然而,这样求解瞬时频率在某些情况下有问题,可能出现$f(t)$为负的情况:我1秒手指动5下,频率是5Hz;反过来,频率为8Hz时,手指1秒动8下,可如果频率为-5Hz呢?负频率没有意义。

考虑信号

$x(t) = {x_1}(t) + {x_2}(t) = {A_1}{e^{j{\omega _1}t}} + {A_2}{e^{j{\omega _2}t}} = A(t){e^{j\varphi (t)}}$

为了简单起见,假设$A_1$和$A_2$恒定,且$\omega_1$和$\omega_2$是正的。信号$x(t)$的频谱应由两个在$\omega_1$和$\omega_2$的$\delta$函数组成,即

$X(\omega ) = {A_1}\delta (\omega  - {\omega _1}) + {A_2}\delta (\omega  - {\omega _2})$

因为假设$\omega_1$和$\omega_2$是正的,所以该信号解析。求得相位

$\Phi (t) = \frac{{{A_1}\sin {\omega _1}t + {A_{\rm{2}}}\sin {\omega _{\rm{2}}}t}}{{{A_1}\cos {\omega _1}t + {A_{\rm{2}}}\cos {\omega _{\rm{2}}}t}}$

分别取两组参数,对$t$求导,得到对应参数下的瞬时频率:

参数

$\omega_1 = 10Hz$和$\omega_2 = 20Hz$.

  • 组1:{$A_1 = 0.2, A_2 = 1$};
  • 组2:{$A_1 = 1.2, A_2 = 1$}

对于组2,瞬时频率出现了负值。

可见

对任意信号进行Hilbert变换,可能出现无法解释、缺乏实际意义的频率分量。Norden E. Hung等人对瞬时频率进行研究后发现,只有满足特定条件的信号,其瞬时频率才具有物理意义,并将此类信号成为:IMF/基本模式分量。 

  B-EMD基本原理

此处给一个原理图:

  C-基本模式分量(IMF)

EMD分解的IMF其瞬时频率具有实际物理意义,原因有两点:

  • 限定1

    • 在整个数据序列中,极值点的数量$N_e$(包括极大值、极小值点)与过零点的数量必须相等,或最多相差1个,即$(N_e-1) \le N_e \ge (N_e+1)$.
  • 限定2
    • 在任意时间点$t_i$上,信号局部极大值确定的上包络线$f_{max}(t)$和局部极小值确定的下包络线$f_{min}(t)$的均值为0.

限定1即要求信号具有类似传统平稳高斯过程的分布;限定2要求局部均值为0,同时用局部最大、最小值的包络作为近似,从而信号局部对称,避免了不对称带来的瞬时频率波动。

  D-VMD

关于VMD(Variational Mode Decomposition),具体原理可以参考其论文,这里我们只要记住一点:其分解的各个基本分量——即各解析信号的瞬时频率具有实际的物理意义

二、代码分析

首先给出信号分别用VMD、EMD的分解结果:

给出对应的代码:

%--------------- Preparation
clear all;
close all;
clc;
% Time Domain 0 to T
T = 1000;
fs = 1/T;
t = (1:T)/T;
freqs = 2*pi*(t-0.5-1/T)/(fs);
% center frequencies of components
f_1 = 2;
f_2 = 24;
f_3 = 288;
% modes
v_1 = (cos(2*pi*f_1*t));
v_2 = 1/4*(cos(2*pi*f_2*t));
v_3 = 1/16*(cos(2*pi*f_3*t));
% for visualization purposes
wsub{1} = 2*pi*f_1;
wsub{2} = 2*pi*f_2;
wsub{3} = 2*pi*f_3;
% composite signal, including noise
f = v_1 + v_2 + v_3 + 0.1*randn(size(v_1));
% some sample parameters for VMD
alpha = 2000; % moderate bandwidth constraint
tau = 0; % noise-tolerance (no strict fidelity enforcement)
K = 4; % 4 modes
DC = 0; % no DC part imposed
init = 1; % initialize omegas uniformly
tol = 1e-7; %--------------- Run actual VMD code
[u, u_hat, omega] = VMD(f, alpha, tau, K, DC, init, tol);
subplot(size(u,1)+1,2,1);
plot(t,f,'k');grid on;
title('VMD分解');
subplot(size(u,1)+1,2,2);
plot(freqs,abs(fft(f)),'k');grid on;
title('对应频谱');
for i = 2:size(u,1)+1
subplot(size(u,1)+1,2,i*2-1);
plot(t,u(i-1,:),'k');grid on;
subplot(size(u,1)+1,2,i*2);
plot(freqs,abs(fft(u(i-1,:))),'k');grid on;
end %---------------run EMD code
imf = emd(f);
figure;
subplot(size(imf,1)+1,2,1);
plot(t,f,'k');grid on;
title('EMD分解');
subplot(size(imf,1)+1,2,2);
plot(freqs,abs(fft(f)),'k');grid on;
title('对应频谱');
for i = 2:size(imf,1)+1
subplot(size(imf,1)+1,2,i*2-1);
plot(t,imf(i-1,:),'k');grid on;
subplot(size(imf,1)+1,2,i*2);
plot(freqs,abs(fft(imf(i-1,:))),'k');grid on;
end

  附上两个子程序的code.

VMD:

function [u, u_hat, omega] = VMD(signal, alpha, tau, K, DC, init, tol)
% Variational Mode Decomposition
% Authors: Konstantin Dragomiretskiy and Dominique Zosso
% zosso@math.ucla.edu --- 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

EMD:

%EMD  computes Empirical Mode Decomposition
%
%
% Syntax
%
%
% IMF = EMD(X)
% IMF = EMD(X,...,'Option_name',Option_value,...)
% IMF = EMD(X,OPTS)
% [IMF,ORT,NB_ITERATIONS] = EMD(...)
%
%
% Description
%
%
% IMF = EMD(X) where X is a real vector computes the Empirical Mode
% Decomposition [1] of X, resulting in a matrix IMF containing 1 IMF per row, the
% last one being the residue. The default stopping criterion is the one proposed
% in [2]:
%
% at each point, mean_amplitude < THRESHOLD2*envelope_amplitude
% &
% mean of boolean array {(mean_amplitude)/(envelope_amplitude) > THRESHOLD} < TOLERANCE
% &
% |#zeros-#extrema|<=1
%
% where mean_amplitude = abs(envelope_max+envelope_min)/2
% and envelope_amplitude = abs(envelope_max-envelope_min)/2
%
% IMF = EMD(X) where X is a complex vector computes Bivariate Empirical Mode
% Decomposition [3] of X, resulting in a matrix IMF containing 1 IMF per row, the
% last one being the residue. The default stopping criterion is similar to the
% one proposed in [2]:
%
% at each point, mean_amplitude < THRESHOLD2*envelope_amplitude
% &
% mean of boolean array {(mean_amplitude)/(envelope_amplitude) > THRESHOLD} < TOLERANCE
%
% where mean_amplitude and envelope_amplitude have definitions similar to the
% real case
%
% IMF = EMD(X,...,'Option_name',Option_value,...) sets options Option_name to
% the specified Option_value (see Options)
%
% IMF = EMD(X,OPTS) is equivalent to the above syntax provided OPTS is a struct
% object with field names corresponding to option names and field values being the
% associated values
%
% [IMF,ORT,NB_ITERATIONS] = EMD(...) returns an index of orthogonality
% ________
% _ |IMF(i,:).*IMF(j,:)|
% ORT = \ _____________________
% /
% ? || X ||?% i~=j
%
% and the number of iterations to extract each mode in NB_ITERATIONS
%
%
% Options
%
%
% stopping criterion options:
%
% STOP: vector of stopping parameters [THRESHOLD,THRESHOLD2,TOLERANCE]
% if the input vector's length is less than 3, only the first parameters are
% set, the remaining ones taking default values.
% default: [0.05,0.5,0.05]
%
% FIX (int): disable the default stopping criterion and do exactly <FIX>
% number of sifting iterations for each mode
%
% FIX_H (int): disable the default stopping criterion and do <FIX_H> sifting
% iterations with |#zeros-#extrema|<=1 to stop [4]
%
% bivariate/complex EMD options:
%
% COMPLEX_VERSION: selects the algorithm used for complex EMD ([3])
% COMPLEX_VERSION = 1: "algorithm 1"
% COMPLEX_VERSION = 2: "algorithm 2" (default)
%
% NDIRS: number of directions in which envelopes are computed (default 4)
% rem: the actual number of directions (according to [3]) is 2*NDIRS
%
% other options:
%
% T: sampling times (line vector) (default: 1:length(x))
%
% MAXITERATIONS: maximum number of sifting iterations for the computation of each
% mode (default: 2000)
%
% MAXMODES: maximum number of imfs extracted (default: Inf)
%
% DISPLAY: if equals to 1 shows sifting steps with pause
% if equals to 2 shows sifting steps without pause (movie style)
% rem: display is disabled when the input is complex
%
% INTERP: interpolation scheme: 'linear', 'cubic', 'pchip' or 'spline' (default)
% see interp1 documentation for details
%
% MASK: masking signal used to improve the decomposition according to [5]
%
%
% Examples
%
%
%X = rand(1,512);
%
%IMF = emd(X);
%
%IMF = emd(X,'STOP',[0.1,0.5,0.05],'MAXITERATIONS',100);
%
%T=linspace(0,20,1e3);
%X = 2*exp(i*T)+exp(3*i*T)+.5*T;
%IMF = emd(X,'T',T);
%
%OPTIONS.DISLPAY = 1;
%OPTIONS.FIX = 10;
%OPTIONS.MAXMODES = 3;
%[IMF,ORT,NBITS] = emd(X,OPTIONS);
%
%
% References
%
%
% [1] N. E. Huang et al., "The empirical mode decomposition and the
% Hilbert spectrum for non-linear and non stationary time series analysis",
% Proc. Royal Soc. London A, Vol. 454, pp. 903-995, 1998
%
% [2] G. Rilling, P. Flandrin and P. Gon鏰lves
% "On Empirical Mode Decomposition and its algorithms",
% IEEE-EURASIP Workshop on Nonlinear Signal and Image Processing
% NSIP-03, Grado (I), June 2003
%
% [3] G. Rilling, P. Flandrin, P. Gon鏰lves and J. M. Lilly.,
% "Bivariate Empirical Mode Decomposition",
% Signal Processing Letters (submitted)
%
% [4] N. E. Huang et al., "A confidence limit for the Empirical Mode
% Decomposition and Hilbert spectral analysis",
% Proc. Royal Soc. London A, Vol. 459, pp. 2317-2345, 2003
%
% [5] R. Deering and J. F. Kaiser, "The use of a masking signal to improve
% empirical mode decomposition", ICASSP 2005
%
%
% See also
% emd_visu (visualization),
% emdc, emdc_fix (fast implementations of EMD),
% cemdc, cemdc_fix, cemdc2, cemdc2_fix (fast implementations of bivariate EMD),
% hhspectrum (Hilbert-Huang spectrum)
%
%
% G. Rilling, last modification: 3.2007
% gabriel.rilling@ens-lyon.fr function [imf,ort,nbits] = emd(varargin) [x,t,sd,sd2,tol,MODE_COMPLEX,ndirs,display_sifting,sdt,sd2t,r,imf,k,nbit,NbIt,MAXITERATIONS,FIXE,FIXE_H,MAXMODES,INTERP,mask] = init(varargin{:}); if display_sifting
fig_h = figure;
end %main loop : requires at least 3 extrema to proceed
while ~stop_EMD(r,MODE_COMPLEX,ndirs) && (k < MAXMODES+1 || MAXMODES == 0) && ~any(mask) % current mode
m = r; % mode at previous iteration
mp = m; %computation of mean and stopping criterion
if FIXE
[stop_sift,moyenne] = stop_sifting_fixe(t,m,INTERP,MODE_COMPLEX,ndirs);
elseif FIXE_H
stop_count = 0;
[stop_sift,moyenne] = stop_sifting_fixe_h(t,m,INTERP,stop_count,FIXE_H,MODE_COMPLEX,ndirs);
else
[stop_sift,moyenne] = stop_sifting(m,t,sd,sd2,tol,INTERP,MODE_COMPLEX,ndirs);
end % in case the current mode is so small that machine precision can cause
% spurious extrema to appear
if (max(abs(m))) < (1e-10)*(max(abs(x)))
if ~stop_sift
warning('emd:warning','forced stop of EMD : too small amplitude')
else
disp('forced stop of EMD : too small amplitude')
end
break
end % sifting loop
while ~stop_sift && nbit<MAXITERATIONS if(~MODE_COMPLEX && nbit>MAXITERATIONS/5 && mod(nbit,floor(MAXITERATIONS/10))==0 && ~FIXE && nbit > 100)
disp(['mode ',int2str(k),', iteration ',int2str(nbit)])
if exist('s','var')
disp(['stop parameter mean value : ',num2str(s)])
end
[im,iM] = extr(m);
disp([int2str(sum(m(im) > 0)),' minima > 0; ',int2str(sum(m(iM) < 0)),' maxima < 0.'])
end %sifting
m = m - moyenne; %computation of mean and stopping criterion
if FIXE
[stop_sift,moyenne] = stop_sifting_fixe(t,m,INTERP,MODE_COMPLEX,ndirs);
elseif FIXE_H
[stop_sift,moyenne,stop_count] = stop_sifting_fixe_h(t,m,INTERP,stop_count,FIXE_H,MODE_COMPLEX,ndirs);
else
[stop_sift,moyenne,s] = stop_sifting(m,t,sd,sd2,tol,INTERP,MODE_COMPLEX,ndirs);
end % display
if display_sifting && ~MODE_COMPLEX
NBSYM = 2;
[indmin,indmax] = extr(mp);
[tmin,tmax,mmin,mmax] = boundary_conditions(indmin,indmax,t,mp,mp,NBSYM);
envminp = interp1(tmin,mmin,t,INTERP);
envmaxp = interp1(tmax,mmax,t,INTERP);
envmoyp = (envminp+envmaxp)/2;
if FIXE || FIXE_H
display_emd_fixe(t,m,mp,r,envminp,envmaxp,envmoyp,nbit,k,display_sifting)
else
sxp=2*(abs(envmoyp))./(abs(envmaxp-envminp));
sp = mean(sxp);
display_emd(t,m,mp,r,envminp,envmaxp,envmoyp,s,sp,sxp,sdt,sd2t,nbit,k,display_sifting,stop_sift)
end
end mp = m;
nbit=nbit+1;
NbIt=NbIt+1; if(nbit==(MAXITERATIONS-1) && ~FIXE && nbit > 100)
if exist('s','var')
warning('emd:warning',['forced stop of sifting : too many iterations... mode ',int2str(k),'. stop parameter mean value : ',num2str(s)])
else
warning('emd:warning',['forced stop of sifting : too many iterations... mode ',int2str(k),'.'])
end
end end % sifting loop
imf(k,:) = m;
if display_sifting
disp(['mode ',int2str(k),' stored'])
end
nbits(k) = nbit;
k = k+1; r = r - m;
nbit=0; end %main loop if any(r) && ~any(mask)
imf(k,:) = r;
end ort = io(x,imf); if display_sifting
close
end
end %---------------------------------------------------------------------------------------------------
% tests if there are enough (3) extrema to continue the decomposition
function stop = stop_EMD(r,MODE_COMPLEX,ndirs)
if MODE_COMPLEX
for k = 1:ndirs
phi = (k-1)*pi/ndirs;
[indmin,indmax] = extr(real(exp(i*phi)*r));
ner(k) = length(indmin) + length(indmax);
end
stop = any(ner < 3);
else
[indmin,indmax] = extr(r);
ner = length(indmin) + length(indmax);
stop = ner < 3;
end
end %---------------------------------------------------------------------------------------------------
% computes the mean of the envelopes and the mode amplitude estimate
function [envmoy,nem,nzm,amp] = mean_and_amplitude(m,t,INTERP,MODE_COMPLEX,ndirs)
NBSYM = 2;
if MODE_COMPLEX
switch MODE_COMPLEX
case 1
for k = 1:ndirs
phi = (k-1)*pi/ndirs;
y = real(exp(-i*phi)*m);
[indmin,indmax,indzer] = extr(y);
nem(k) = length(indmin)+length(indmax);
nzm(k) = length(indzer);
[tmin,tmax,zmin,zmax] = boundary_conditions(indmin,indmax,t,y,m,NBSYM);
envmin(k,:) = interp1(tmin,zmin,t,INTERP);
envmax(k,:) = interp1(tmax,zmax,t,INTERP);
end
envmoy = mean((envmin+envmax)/2,1);
if nargout > 3
amp = mean(abs(envmax-envmin),1)/2;
end
case 2
for k = 1:ndirs
phi = (k-1)*pi/ndirs;
y = real(exp(-i*phi)*m);
[indmin,indmax,indzer] = extr(y);
nem(k) = length(indmin)+length(indmax);
nzm(k) = length(indzer);
[tmin,tmax,zmin,zmax] = boundary_conditions(indmin,indmax,t,y,y,NBSYM);
envmin(k,:) = exp(i*phi)*interp1(tmin,zmin,t,INTERP);
envmax(k,:) = exp(i*phi)*interp1(tmax,zmax,t,INTERP);
end
envmoy = mean((envmin+envmax),1);
if nargout > 3
amp = mean(abs(envmax-envmin),1)/2;
end
end
else
[indmin,indmax,indzer] = extr(m);
nem = length(indmin)+length(indmax);
nzm = length(indzer);
[tmin,tmax,mmin,mmax] = boundary_conditions(indmin,indmax,t,m,m,NBSYM);
envmin = interp1(tmin,mmin,t,INTERP);
envmax = interp1(tmax,mmax,t,INTERP);
envmoy = (envmin+envmax)/2;
if nargout > 3
amp = mean(abs(envmax-envmin),1)/2;
end
end
end %-------------------------------------------------------------------------------
% default stopping criterion
function [stop,envmoy,s] = stop_sifting(m,t,sd,sd2,tol,INTERP,MODE_COMPLEX,ndirs)
try
[envmoy,nem,nzm,amp] = mean_and_amplitude(m,t,INTERP,MODE_COMPLEX,ndirs);
sx = abs(envmoy)./amp;
s = mean(sx);
stop = ~((mean(sx > sd) > tol | any(sx > sd2)) & (all(nem > 2)));
if ~MODE_COMPLEX
stop = stop && ~(abs(nzm-nem)>1);
end
catch
stop = 1;
envmoy = zeros(1,length(m));
s = NaN;
end
end %-------------------------------------------------------------------------------
% stopping criterion corresponding to option FIX
function [stop,moyenne]= stop_sifting_fixe(t,m,INTERP,MODE_COMPLEX,ndirs)
try
moyenne = mean_and_amplitude(m,t,INTERP,MODE_COMPLEX,ndirs);
stop = 0;
catch
moyenne = zeros(1,length(m));
stop = 1;
end
end %-------------------------------------------------------------------------------
% stopping criterion corresponding to option FIX_H
function [stop,moyenne,stop_count]= stop_sifting_fixe_h(t,m,INTERP,stop_count,FIXE_H,MODE_COMPLEX,ndirs)
try
[moyenne,nem,nzm] = mean_and_amplitude(m,t,INTERP,MODE_COMPLEX,ndirs);
if (all(abs(nzm-nem)>1))
stop = 0;
stop_count = 0;
else
stop_count = stop_count+1;
stop = (stop_count == FIXE_H);
end
catch
moyenne = zeros(1,length(m));
stop = 1;
end
end %-------------------------------------------------------------------------------
% displays the progression of the decomposition with the default stopping criterion
function display_emd(t,m,mp,r,envmin,envmax,envmoy,s,sb,sx,sdt,sd2t,nbit,k,display_sifting,stop_sift)
subplot(4,1,1)
plot(t,mp);hold on;
plot(t,envmax,'--k');plot(t,envmin,'--k');plot(t,envmoy,'r');
title(['IMF ',int2str(k),'; iteration ',int2str(nbit),' before sifting']);
set(gca,'XTick',[])
hold off
subplot(4,1,2)
plot(t,sx)
hold on
plot(t,sdt,'--r')
plot(t,sd2t,':k')
title('stop parameter')
set(gca,'XTick',[])
hold off
subplot(4,1,3)
plot(t,m)
title(['IMF ',int2str(k),'; iteration ',int2str(nbit),' after sifting']);
set(gca,'XTick',[])
subplot(4,1,4);
plot(t,r-m)
title('residue');
disp(['stop parameter mean value : ',num2str(sb),' before sifting and ',num2str(s),' after'])
if stop_sift
disp('last iteration for this mode')
end
if display_sifting == 2
pause(0.01)
else
pause
end
end %---------------------------------------------------------------------------------------------------
% displays the progression of the decomposition with the FIX and FIX_H stopping criteria
function display_emd_fixe(t,m,mp,r,envmin,envmax,envmoy,nbit,k,display_sifting)
subplot(3,1,1)
plot(t,mp);hold on;
plot(t,envmax,'--k');plot(t,envmin,'--k');plot(t,envmoy,'r');
title(['IMF ',int2str(k),'; iteration ',int2str(nbit),' before sifting']);
set(gca,'XTick',[])
hold off
subplot(3,1,2)
plot(t,m)
title(['IMF ',int2str(k),'; iteration ',int2str(nbit),' after sifting']);
set(gca,'XTick',[])
subplot(3,1,3);
plot(t,r-m)
title('residue');
if display_sifting == 2
pause(0.01)
else
pause
end
end %---------------------------------------------------------------------------------------
% defines new extrema points to extend the interpolations at the edges of the
% signal (mainly mirror symmetry)
function [tmin,tmax,zmin,zmax] = boundary_conditions(indmin,indmax,t,x,z,nbsym) lx = length(x); if (length(indmin) + length(indmax) < 3)
error('not enough extrema')
end % boundary conditions for interpolations : if indmax(1) < indmin(1)
if x(1) > x(indmin(1))
lmax = fliplr(indmax(2:min(end,nbsym+1)));
lmin = fliplr(indmin(1:min(end,nbsym)));
lsym = indmax(1);
else
lmax = fliplr(indmax(1:min(end,nbsym)));
lmin = [fliplr(indmin(1:min(end,nbsym-1))),1];
lsym = 1;
end
else if x(1) < x(indmax(1))
lmax = fliplr(indmax(1:min(end,nbsym)));
lmin = fliplr(indmin(2:min(end,nbsym+1)));
lsym = indmin(1);
else
lmax = [fliplr(indmax(1:min(end,nbsym-1))),1];
lmin = fliplr(indmin(1:min(end,nbsym)));
lsym = 1;
end
end if indmax(end) < indmin(end)
if x(end) < x(indmax(end))
rmax = fliplr(indmax(max(end-nbsym+1,1):end));
rmin = fliplr(indmin(max(end-nbsym,1):end-1));
rsym = indmin(end);
else
rmax = [lx,fliplr(indmax(max(end-nbsym+2,1):end))];
rmin = fliplr(indmin(max(end-nbsym+1,1):end));
rsym = lx;
end
else
if x(end) > x(indmin(end))
rmax = fliplr(indmax(max(end-nbsym,1):end-1));
rmin = fliplr(indmin(max(end-nbsym+1,1):end));
rsym = indmax(end);
else
rmax = fliplr(indmax(max(end-nbsym+1,1):end));
rmin = [lx,fliplr(indmin(max(end-nbsym+2,1):end))];
rsym = lx;
end
end tlmin = 2*t(lsym)-t(lmin);
tlmax = 2*t(lsym)-t(lmax);
trmin = 2*t(rsym)-t(rmin);
trmax = 2*t(rsym)-t(rmax); % in case symmetrized parts do not extend enough
if tlmin(1) > t(1) || tlmax(1) > t(1)
if lsym == indmax(1)
lmax = fliplr(indmax(1:min(end,nbsym)));
else
lmin = fliplr(indmin(1:min(end,nbsym)));
end
if lsym == 1
error('bug')
end
lsym = 1;
tlmin = 2*t(lsym)-t(lmin);
tlmax = 2*t(lsym)-t(lmax);
end if trmin(end) < t(lx) || trmax(end) < t(lx)
if rsym == indmax(end)
rmax = fliplr(indmax(max(end-nbsym+1,1):end));
else
rmin = fliplr(indmin(max(end-nbsym+1,1):end));
end
if rsym == lx
error('bug')
end
rsym = lx;
trmin = 2*t(rsym)-t(rmin);
trmax = 2*t(rsym)-t(rmax);
end zlmax =z(lmax);
zlmin =z(lmin);
zrmax =z(rmax);
zrmin =z(rmin); tmin = [tlmin t(indmin) trmin];
tmax = [tlmax t(indmax) trmax];
zmin = [zlmin z(indmin) zrmin];
zmax = [zlmax z(indmax) zrmax];
end %---------------------------------------------------------------------------------------------------
%extracts the indices of extrema
function [indmin, indmax, indzer] = extr(x,t) if(nargin==1)
t=1:length(x);
end m = length(x); if nargout > 2
x1=x(1:m-1);
x2=x(2:m);
indzer = find(x1.*x2<0); if any(x == 0)
iz = find( x==0 );
indz = [];
if any(diff(iz)==1)
zer = x == 0;
dz = diff([0 zer 0]);
debz = find(dz == 1);
finz = find(dz == -1)-1;
indz = round((debz+finz)/2);
else
indz = iz;
end
indzer = sort([indzer indz]);
end
end d = diff(x); n = length(d);
d1 = d(1:n-1);
d2 = d(2:n);
indmin = find(d1.*d2<0 & d1<0)+1;
indmax = find(d1.*d2<0 & d1>0)+1; % when two or more successive points have the same value we consider only one extremum in the middle of the constant area
% (only works if the signal is uniformly sampled) if any(d==0) imax = [];
imin = []; bad = (d==0);
dd = diff([0 bad 0]);
debs = find(dd == 1);
fins = find(dd == -1);
if debs(1) == 1
if length(debs) > 1
debs = debs(2:end);
fins = fins(2:end);
else
debs = [];
fins = [];
end
end
if length(debs) > 0
if fins(end) == m
if length(debs) > 1
debs = debs(1:(end-1));
fins = fins(1:(end-1)); else
debs = [];
fins = [];
end
end
end
lc = length(debs);
if lc > 0
for k = 1:lc
if d(debs(k)-1) > 0
if d(fins(k)) < 0
imax = [imax round((fins(k)+debs(k))/2)];
end
else
if d(fins(k)) > 0
imin = [imin round((fins(k)+debs(k))/2)];
end
end
end
end if length(imax) > 0
indmax = sort([indmax imax]);
end if length(imin) > 0
indmin = sort([indmin imin]);
end end
end %--------------------------------------------------------------------------------------------------- function ort = io(x,imf)
% ort = IO(x,imf) computes the index of orthogonality
%
% inputs : - x : analyzed signal
% - imf : empirical mode decomposition n = size(imf,1); s = 0; for i = 1:n
for j =1:n
if i~=j
s = s + abs(sum(imf(i,:).*conj(imf(j,:)))/sum(x.^2));
end
end
end ort = 0.5*s;
end
%--------------------------------------------------------------------------------------------------- function [x,t,sd,sd2,tol,MODE_COMPLEX,ndirs,display_sifting,sdt,sd2t,r,imf,k,nbit,NbIt,MAXITERATIONS,FIXE,FIXE_H,MAXMODES,INTERP,mask] = init(varargin) x = varargin{1};
if nargin == 2
if isstruct(varargin{2})
inopts = varargin{2};
else
error('when using 2 arguments the first one is the analyzed signal X and the second one is a struct object describing the options')
end
elseif nargin > 2
try
inopts = struct(varargin{2:end});
catch
error('bad argument syntax')
end
end % default for stopping
defstop = [0.05,0.5,0.05]; opt_fields = {'t','stop','display','maxiterations','fix','maxmodes','interp','fix_h','mask','ndirs','complex_version'}; defopts.stop = defstop;
defopts.display = 0;
defopts.t = 1:max(size(x));
defopts.maxiterations = 2000;
defopts.fix = 0;
defopts.maxmodes = 0;
defopts.interp = 'spline';
defopts.fix_h = 0;
defopts.mask = 0;
defopts.ndirs = 4;
defopts.complex_version = 2; opts = defopts; if(nargin==1)
inopts = defopts;
elseif nargin == 0
error('not enough arguments')
end names = fieldnames(inopts);
for nom = names'
if ~any(strcmpi(char(nom), opt_fields))
error(['bad option field name: ',char(nom)])
end
if ~isempty(eval(['inopts.',char(nom)])) % empty values are discarded
eval(['opts.',lower(char(nom)),' = inopts.',char(nom),';'])
end
end t = opts.t;
stop = opts.stop;
display_sifting = opts.display;
MAXITERATIONS = opts.maxiterations;
FIXE = opts.fix;
MAXMODES = opts.maxmodes;
INTERP = opts.interp;
FIXE_H = opts.fix_h;
mask = opts.mask;
ndirs = opts.ndirs;
complex_version = opts.complex_version; if ~isvector(x)
error('X must have only one row or one column')
end if size(x,1) > 1
x = x.';
end if ~isvector(t)
error('option field T must have only one row or one column')
end if ~isreal(t)
error('time instants T must be a real vector')
end if size(t,1) > 1
t = t';
end if (length(t)~=length(x))
error('X and option field T must have the same length')
end if ~isvector(stop) || length(stop) > 3
error('option field STOP must have only one row or one column of max three elements')
end if ~all(isfinite(x))
error('data elements must be finite')
end if size(stop,1) > 1
stop = stop';
end L = length(stop);
if L < 3
stop(3)=defstop(3);
end if L < 2
stop(2)=defstop(2);
end if ~ischar(INTERP) || ~any(strcmpi(INTERP,{'linear','cubic','spline'}))
error('INTERP field must be ''linear'', ''cubic'', ''pchip'' or ''spline''')
end %special procedure when a masking signal is specified
if any(mask)
if ~isvector(mask) || length(mask) ~= length(x)
error('masking signal must have the same dimension as the analyzed signal X')
end if size(mask,1) > 1
mask = mask.';
end
opts.mask = 0;
imf1 = emd(x+mask,opts);
imf2 = emd(x-mask,opts);
if size(imf1,1) ~= size(imf2,1)
warning('emd:warning',['the two sets of IMFs have different sizes: ',int2str(size(imf1,1)),' and ',int2str(size(imf2,1)),' IMFs.'])
end
S1 = size(imf1,1);
S2 = size(imf2,1);
if S1 ~= S2
if S1 < S2
tmp = imf1;
imf1 = imf2;
imf2 = tmp;
end
imf2(max(S1,S2),1) = 0;
end
imf = (imf1+imf2)/2; end sd = stop(1);
sd2 = stop(2);
tol = stop(3); lx = length(x); sdt = sd*ones(1,lx);
sd2t = sd2*ones(1,lx); if FIXE
MAXITERATIONS = FIXE;
if FIXE_H
error('cannot use both ''FIX'' and ''FIX_H'' modes')
end
end MODE_COMPLEX = ~isreal(x)*complex_version;
if MODE_COMPLEX && complex_version ~= 1 && complex_version ~= 2
error('COMPLEX_VERSION parameter must equal 1 or 2')
end % number of extrema and zero-crossings in residual
ner = lx;
nzr = lx; r = x; if ~any(mask) % if a masking signal is specified "imf" already exists at this stage
imf = [];
end
k = 1; % iterations counter for extraction of 1 mode
nbit=0; % total iterations counter
NbIt=0;
end
%---------------------------------------------------------------------------------------------------

关于EMD,有对应的工具箱。VMD也有扩展的二维分解,此处不再展开。

三、一种权衡的小trick

关于瞬时频率的原理以及代码,参考另一篇博文

比较来看:

  • EMD分解的IMF分量个数不能人为设定,而VMD(Variational Mode Decomposition)则可以;
  • 但VMD也有弊端:分解过多,则信号断断续续,没有多少规律可言。

能不能取长补短呢?

自己之前做了一个小code,放在这里,供大家交流使用(此理论为自己首创,版权所有,拿去也不介意!(●'◡'●))。
给定一个信号,下图是EMD分解结果,分解出了5个分量。

再来一个VMD(设定分量个数为3)的分解结果:

比较两个结果,可以发现:VMD的低频分量,更容易表达出经济波动的大趋势,而EMD则不易观察该特性。
或许有人会说:几个EMD分量叠加一下,也会有该效果,但如果不观察分解的数据,如何确定几个分量相加呢?更何况EMD总的IMF个数也是未知!

VMD的优势观察到了,但如何确定分量个数呢?
再来一个效果图:

这里分析了VMD分量从1~9,9种情况下某特征的曲线,可以观察到:个数增加到一定数量,曲线有了明显的下弯曲现象(该特性容易借助曲率,进行量化分析,不再展开),这个临界的个数就是分解的合适数量,此处:K=3,因为到4就有了明显的下弯曲。

可见通过该特征,即可理论上得出最优K。下面讲一讲这个某特征为何物?
上一段代码:

for st=1:9
K=st+1;
[u, u_hat, omega] = VMD(data, length(data), 0, K, 0, 1, 1e-5);
u=flipud(u);
resf=zeros(1,K);
for i=1:K
testdata=u(i,:);
hilbert(testdata');
z=hilbert(testdata'); % 希尔伯特变换
a=abs(z); % 包络线
fnor=instfreq(z); % 瞬时频率
resf(i)=mean(fnor);
end
subplot(3,3,st)
plot(resf,'k');title(['个数为',num2str(st)]);grid on;
end

  没错,该特征就是:分量瞬时频率的均值。如果分解个数过大,则分量会出现断断絮絮地现象,特别是在高频,这样一来,即使是高频,平均瞬时频率反而低一些,这也是下弯曲的根本原因。

这个小trick就介绍到这里。

四、问题补充

HHT算法中,有两处存在端点效应,VMD是否也有呢?这一点没有再去验证。另外,关于Hilbert的端点效应,在另一篇博文已经给出。

参考:

宋知用:《MATLAB在语音信号分析和合成中的应用》

了凡春秋: http://blog.sina.com.cn/s/blog_6163bdeb0102e2cd.html

VMD-code:https://cn.mathworks.com/matlabcentral/fileexchange/44765-variational-mode-decomposition

EMD原理图:http://blog.sciencenet.cn/blog-244606-256958.html

信号处理——EMD、VMD的一点小思考的更多相关文章

  1. Golang - 关于 proto 文件的一点小思考

    目录 前言 helloworld.proto 小思考 小结 推荐阅读 前言 ProtoBuf 是什么? ProtoBuf 是一套接口描述语言(IDL),通俗的讲是一种数据表达方式,也可以称为数据交换格 ...

  2. MySQL-Front 建表引发的一点小思考(数据表格模版)

    我们建表的时候,有一些字段总是会常用到的.也就是每一张表都会有这些字段. 我用mysql有一点时间了,今天(2016-02-27 21:53:38)在用mysql-front建表的时候,感觉有点点不太 ...

  3. xss和实体编码的一点小思考

    首先,浏览器渲染分以下几步: 解析HTML生成DOM树. 解析CSS生成CSSOM规则树. 将DOM树与CSSOM规则树合并在一起生成渲染树. 遍历渲染树开始布局,计算每个节点的位置大小信息. 将渲染 ...

  4. sqlserver数据库不能重命名报错5030——我的一点小思考

    在学习asp.net的时候使用mssql‘经常会出现这种错误,数据库不能重名名5030的错误,其实很简单原因就是有应用程序正在占用这个连接,使用这样一行命令就可以查询出正在占用的连接 use mast ...

  5. [原创].NET 分布式架构开发实战之三 数据访问深入一点的思考

    原文:[原创].NET 分布式架构开发实战之三 数据访问深入一点的思考 .NET 分布式架构开发实战之三 数据访问深入一点的思考 前言:首先,感谢园子里的朋友对文章的支持,感谢大家,希望本系列的文章能 ...

  6. 关于win8开发的一点小总结

    我今天做画面的时候,发现了一点小问题. 我在xmal文件里面加了一个CheckBox控件,设置IsChecked属性为True,并添加了Checked事件.Checked事件里面有对另外一个TextB ...

  7. 关于PHP魔术方法__call的一点小发现

    好久没有上博客园写文章了,今晚终于有点空了,就来写一下昨天的一点小发现. 我自己所知,C++,Java的面向对象都有多态的特点,而PHP没有,但PHP可以通过继承链方法的重写来实现多态的属性.而魔术方 ...

  8. net core体系-web应用程序-4net core2.0大白话带你入门-8asp.net core 内置DI容器(DependencyInjection,控制翻转)的一点小理解

    asp.net core 内置DI容器的一点小理解   DI容器本质上是一个工厂,负责提供向它请求的类型的实例. .net core内置了一个轻量级的DI容器,方便开发人员面向接口编程和依赖倒置(IO ...

  9. C与C++在形參的一点小差别

    先看一下以下的代码: int fun(a,b) int a; int b; { return 10; } void main(int argc, char ** argv) { fun(10); re ...

随机推荐

  1. C. Books Queries

    链接 [http://codeforces.com/contest/1066/problem/C] 题意 开始空队列,可以进行前插和后插,还可以查询使某个数的为最左或最右需要去掉的最少数字 分析 模拟 ...

  2. 个人阅读作业WEEK7 (软件工程的瀑布, 大泥球, 教堂,集市,和银弹)

    一 . 关于银弹 (Silver Bullet) 银弹,被引申为解决问题的有效办法.IBM大型机之父福瑞德·布鲁克斯在1986年的论文<没有银弹>中表达了他的观点:软件工程中不存在银弹—— ...

  3. SVN解决冲突

    SVN冲突出现场景 如今是一个团结协作的时代,开发一个系统,往往会多人协作共同完成.版本管理是必不可少的,常用的软件有Git,SVN等.今天说一下,SVN管理版本时,如果出现冲突后,如何快速解决冲突. ...

  4. 单工程搭建springmvc+spring+mybatis(maven,idea)

    单工程搭建springmvc+spring+mybatis(maven,idea) 1.pom.xml <properties> <project.build.sourceEncod ...

  5. 四则运算安卓版ver.mk3

    在原有的基础上做了些许改动以及添加了一点小功能,以下是代码: package com.example.add; import java.io.File; import com.example.add. ...

  6. 广商博客冲刺第六七天new

    第四五天沖刺傳送門 第一版的網頁已經放到 云服務器(估計快到期了) 傳送門. (不怎么會玩服務器啊..求指教..目前問題如下: 1.我的電腦mysql密碼跟服務器的密碼不一樣..上傳的時候要把代碼里面 ...

  7. 在XShell中使用sz和rz命令下载和上传文件

    借助XShell,使用linux命令sz可以很方便的将服务器上的文件下载到本地,使用rz命令则是把本地文件上传到服务器 工具/原料   XShell CentOS 6.5 使用sz下载文件   1 输 ...

  8. HTML 选择器

    c56 div:nth-of-type(1) { margin-left: 12px; margin-top: 25px; } .c56 div:nth-of-type(2) { margin-top ...

  9. java中的equals和==

    下面是我看别人博客和java API总结的 首先得明确一个概念就是: == 的用法   ==比较对象在内存中的地址是否相等.如是是两个基本数据类型变量的比较则比较的是这两个变量值是否相等,若是比较两个 ...

  10. 设计模式之抽象工厂模式(附带类似反射功能的实现/c++)

    问题描述 假设我们要开发一款游戏, 当然为了吸引更多的人玩, 游戏难度不能太大(让大家都没有信心了,估计游戏也就没有前途了),但是也不能太简单(没有挑战性也不符合玩家的心理).于是我们就可以采用这样一 ...