设有一个线性系统,它的单位脉冲响应是 h ( n ) h(n) h(n),当输入一个观测到的随机信号 x ( n ) x(n) x(n),简称观测值,且该信号包含噪声 w ( n ) w(n) w(n)和有用信号 s ( n ) s(n) s(n),也即
x ( n ) = w ( n ) + s ( n ) x(n)=w(n)+s(n) x(n)=w(n)+s(n)
则输出(估计值)为:
y ( n ) = x ( n ) ∗ h ( n ) = Σ m = − ∞ + ∞ h ( m ) x ( n − m ) = s ^ ( n ) y(n)=x(n)*h(n)=\Sigma_{m=-\infty}^{+\infty} h(m)x(n-m)=\hat{s}(n) y(n)=x(n)∗h(n)=Σm=−∞+∞h(m)x(n−m)=s^(n)
(如果该系统是因果系统,上式中的 m = 0 , 1 , 2 , … m=0,1,2,… m=0,1,2,…)
这里用 e ( n ) e(n) e(n)来表示真值和估计值之间的误差:
e ( n ) = s ( n ) − s ^ ( n ) e(n)=s(n)-\hat{s}(n) e(n)=s(n)−s^(n)
维纳滤波的误差准则就是最小均方误差准则:
E ( e ( n ) 2 ) = E ( ( s ( n ) − e ^ ( n ) ) 2 ) E(e(n)^2) = E((s(n)-\hat{e}(n))^2) E(e(n)2)=E((s(n)−e^(n))2)
我们希望输出得到的 y ( n ) y(n) y(n)与有用信号 s ( n ) s(n) s(n)尽量接近,也就是使上式尽量小。
E [ e ( n ) 2 ] = E ( ( s ( n ) − Σ m = 0 + ∞ h ( m ) x ( n − m ) ) 2 ) E[e(n)^2] = E((s(n)-\Sigma_{m=0}^{+\infty} h(m)x(n-m))^2) E[e(n)2]=E((s(n)−Σm=0+∞h(m)x(n−m))2)
要使得均方误差最小,可以对 h ( m ) , m = 0 , 1 , 2... h(m),m=0,1,2... h(m),m=0,1,2...求偏导,并令结果等于0。
即:
2 E [ ( s ( n ) − Σ m = 0 + ∞ h o p t ( m ) x ( n − m ) ) x ( n − j ) ] j ≥ 0 2E[(s(n)-\Sigma_{m=0}^{+\infty} h_{opt}(m)x(n-m))x(n-j)] \qquad j\geq 0 2E[(s(n)−Σm=0+∞hopt(m)x(n−m))x(n−j)]j≥0
用相关函数 R R R来表达上式,则得到维纳-霍夫方程的离散形式:
R x s ( j ) = Σ m = 0 + ∞ h o p t ( m ) R x x ( j − m ) j ≥ 0 R_{xs}(j)=\Sigma_{m=0}^{+\infty}h_{opt}(m)R_{xx}(j-m) \qquad j\geq 0 Rxs(j)=Σm=0+∞hopt(m)Rxx(j−m)j≥0
在求解上面的方程得到 h o p t h_{opt} hopt的情况下,将其代入 E [ e ( n ) 2 ] E[e(n)^2] E[e(n)2]的表达式中得:
E [ e ( n ) 2 ] m i n = R s s ( 0 ) − Σ m = 0 + ∞ h o p t ( m ) R x s ( m ) E[e(n)^2]_{min}=R_{ss}(0)-\Sigma_{m=0}^{+\infty}h_{opt}(m)R_{xs}(m) E[e(n)2]min=Rss(0)−Σm=0+∞hopt(m)Rxs(m)
这个还没看懂,以后再更。
import numpy as np
def cross_correlation_wiener(ts, new_order, old_order):
n_taps = ts.size
n_size = n_taps if n_taps>new_order else new_order
out_data = []
for i in range(-n_taps,n_taps+1):
ts_sum = 0.0
for j in range(n_size):
if ((j+i)<n_taps and j<new_order and (j+i)>-1):
ts_sum += ts[j+i]
out_data.append(ts_sum)
out = out_data[-old_order-n_taps-1:-old_order-1]
return np.asarray(out)
def wiener_filter_1d(t_series,order):
new_order = 2*order+1
t_2_series = pow(t_series,2)
t_lmean = cross_correlation_wiener(t_series, new_order, order)
lmean = t_lmean/new_order
t_lvar = cross_correlation_wiener(t_2_series, new_order, order)
lvar = t_lvar/new_order - pow(lmean,2)
est_n = sum(lvar)/lvar.size
res = []
for i in range(t_series.size):
if lvar[i] <est_n:
res.append(lmean[i])
else:
res.append((t_series[i]-lmean[i])*(1-(est_n/lvar[i]))+lmean[i])
return np.asarray(res)
if __name__ == "__main__":
time_series = np.asarray([112,31,42,54,432,245,23,34,567,8,468,623,232,743,121])
order = 2
wf1d = wiener_filter_1d(time_series, order)
print(wf1d)