????????變分模態(tài)分解(variational mode decomposition经伙,VMD)是一種新的信號分解估計方法扶叉,其整體框架是變分問題,使得每個模態(tài)的估計帶寬之和最小帕膜,其中假設(shè)每個‘模態(tài)’是具有不同中心頻率的有限帶寬枣氧,為解決這一變分問題,采用了交替方向乘子法垮刹,不斷更新各模態(tài)及其中心頻率达吞,逐步將各模態(tài)解調(diào)到相應(yīng)的基頻帶,最終各個模態(tài)及相應(yīng)的中心頻率被一同提取出來荒典。相比 EMD 和 LMD 的遞歸‘篩選’模式酪劫,VMD 將信號分解轉(zhuǎn)化非遞歸、變分模態(tài)分解模式寺董,并具有堅實的理論基礎(chǔ)覆糟,其實質(zhì)是多個自適應(yīng)維納濾波組,表現(xiàn)出更好的噪聲魯棒性遮咖。
????????VMD 的分解過程是變分問題的求解過程滩字,該算法可分為變分問題的構(gòu)造和求解,其中涉及了 3個重要概念:經(jīng)典維納濾波、希爾伯特變換和頻率混合麦箍。
1. 受約束的變分問題如下:
2.?變分問題的求解:
????????引入二次懲罰因子α和拉格朗日乘法算子λ(t)漓藕,將約束性變分問題變?yōu)榉羌s束性變分問題:
采 用 了 乘 法 算 子 交 替 方 向 法(alternate direction method of multipliers)ADMM 解決以上變分問題,通過交替更新計算挟裂,求擴(kuò)展拉格朗日表達(dá)式的‘鞍點’:
最終可整理為:
時間復(fù)雜度:
關(guān)于VMD(Variational Mode Decomposition)享钞,具體原理可以參考其論文? ?:
K. Dragomiretskiy and D. Zosso, "Variational Mode Decomposition," in IEEE Transactions on Signal Processing, vol. 62, no. 3, pp. 531-544, Feb.1, 2014, doi: 10.1109/TSP.2013.2288675.
附上VMD源程序的MATLAB code:
在R軟件中使用VED的代碼:
R code:
rm(list = ls())
# install.packages("vmd")
library(vmd)
library(R.matlab)
ff <- "E:/office/......../data"
ff <- paste0(ff,"/", list.files(ff)[2])
mat<-readMat(ff)# str(mat)
m.u<-as.vector(mat$CH1)
m.i<-as.vector(mat$CH2)
? plot.ts(m.i)
signal <- m.i
plot.ts(signal);rm(m.u,m.i,ff,mat)
依據(jù)傅里葉分析可知,這段數(shù)據(jù)包含了4個頻譜话瞧,因此選擇K=4+1
#tau=梯度步長
k=5; v = vmd(signal,alpha=length(signal),tau=0,DC=F,init=0,tol=1e-6,K=k,orderModes=TRUE)
# #To Data Frame
# df = as.data.frame(v)# head(df)
# #Plot Results# plot(v)
plot(v,facet='bymode',scales='free')
# #List of Results
l = v$getResult()? #? names(l)
#? u? ? ? - the collection of decomposed modes
#? u_hat? - spectra of the modes
#? omega? - estimated mode center-frequencies
# # compute HZ
ff <- 10^4
matplot(l$omega*ff,type = "l",ylab = "HZ")
text(dim(l$omega)[1],l$omega[dim(l$omega)[1],]*ff,
? ? labels = round(l$omega[dim(l$omega)[1],],3)*ff,col = 1)
? ? 可見包含了50HZ的基波嫩与,3、5交排、7次諧波和噪聲數(shù)據(jù)(收斂的不夠)
#Spectral Decomposition
v$plot.spectral.decomposition()
信息重構(gòu):
matplot(cbind(l$u[,1],rowSums(l$u[,2:4]),signal),type = "l",col = c(3,4,2) ,ylab = "amplitude")
matplot(cbind(rowSums(l$u[,1:4]),signal),type = "l",col = c(4,2) ,ylab = "amplitude")