维纳滤波原理及实现

问题描述:

设有一个线性系统,它的单位脉冲响应是 h ( n ) h(n) ,当输入一个观测到的随机信号 x ( n ) x(n) ,简称观测值,且该信号包含噪声 w ( n ) w(n) 和有用信号 s ( 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)
(如果该系统是因果系统,上式中的 m 0 1 2 m=0,1,2,… )

这里用 e ( n ) e(n) 来表示真值和估计值之间的误差:
e ( n ) = s ( n ) s ^ ( n ) e(n)=s(n)-\hat{s}(n)
维纳滤波的误差准则就是最小均方误差准则:
E ( e ( n ) 2 ) = E ( ( s ( n ) e ^ ( n ) ) 2 ) E(e(n)^2) = E((s(n)-\hat{e}(n))^2)

我们希望输出得到的 y ( n ) y(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)
要使得均方误差最小,可以对 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

用相关函数 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

在求解上面的方程得到 h o p t h_{opt} 的情况下,将其代入 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)

求解维纳-霍夫方程

这个还没看懂,以后再更。

代码实现

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)
发布了57 篇原创文章 · 获赞 4 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_38258767/article/details/103773873