用于改进噪声频谱减法的估计器

信息处理 自由度 信号检测 估计 去噪 贝叶斯估计
2021-12-21 18:45:58

真正的零均值高斯白噪声,独立于一个干净的信号$x$和已知的方差被添加到$x$产生一个有噪声的信号$ y

$$Y_k = \frac{1}{N}\sum_{n=0}^{N-1}e^{-i2\pi kn/N}y_n.\tag{1}$$

这仅用于上下文,我们将在频域中定义噪声方差,因此归一化(或缺乏归一化)并不重要。时域的高斯白噪声就是频域的高斯白噪声,参见问题:“什么是高斯白噪声的离散傅里叶变换的统计量? ”。因此我们可以写:

$$Y_k = X_k + Z_k,$$

其中$X$$Z$是干净信号和噪声的 DFT,$Z_k$是遵循圆对称复高斯方差分布$\sigma^2$的噪声箱。$Z_k$的实部和虚部各自独立地遵循方差$\frac{1}{2}\sigma^2$的高斯分布。我们将 bin $Y_k$的信噪比 (SNR)定义为:

$$\mathrm{SNR} = \frac{\sigma^2}{|X_k|^2}.$$

然后尝试通过频谱减法来降低噪声,从而在保持原始相位的同时独立地减小每个 bin $Y_k$的幅度(除非在幅度减小中 bin 值变为零)。减少形成了对干净信号的 DFT 的每个 bin 的绝对值的平方$|X_k|^2$的估计$\widehat{|X_k|^2}$ :

$$\widehat{|X_k|^2} = |Y_k|^2 - \sigma^2,\tag{2}$$

其中$\sigma^2$是每个 DFT bin 中已知的噪声方差。为简单起见,我们不考虑甚至$N$的$k = 0,$$k = N/2$,这是真实$x.$的特殊情况。在低 SNR 下,(2) 中的公式有时可能结果为负$\widehat{| X_k|^2}.$我们可以通过从下面将估计值限制为零来消除这个问题,重新定义:

$$\widehat{|X_k|^2} = \max\left(|Y_k|^2 - \sigma^2,\,0\right).\tag{3}$$

在此处输入图像描述
图 1. 样本大小为$10^5,$的 Monte Carlo 估计: 实心:通过$\widehat{|X_k|}$估计$|X_k|$与使用$估计相比,误差平方和的增益|Y_k|,$虚线:通过$\widehat{|X_k|^2}$估计 $|X_k|^ 2 $ 与使用$|Y_k|^2,$进行估计相比 ,平方误差的增益$\widehat{|X_k|}e^{i\arg(Y_k)}$估计 $X_k$ 与用$ Y_k估计相比,平方误差和的增益。 $\widehat{ | X_k的定义使用来自 (3) 的|^2}$ 。

问题:是否有另一个$|X_k|$$|X_k|^2$的估计值在不依赖$Y_k$分布的情况下改进了(2)和(3) ?

我认为这个问题相当于用已知参数$\sigma_\mathrm{Rice} = \frac{估计Rice 分布(图 2)的参数$\displaystyle{\nu_\mathrm{Rice}}$的平方\sqrt{2}}{2}\sigma,$给定一个观察值。

在此处输入图像描述
图 2. Rice 分布是从一个点到原点的距离$R$的分布,该点遵循二元循环对称正态分布,均值绝对值为$\nu_\mathrm{Rice},$方差$2\sigma_\mathrm {Rice}^2 = \sigma^2$和分量方差$\sigma_\mathrm{Rice}^2 = \frac{1}{2}\sigma^2.$

我发现了一些似乎相关的文献:

  • Jan Sijbers、Arnold J. den Dekker、Paul Scheunders 和 Dirk Van Dyck,“Rician 分布参数的最大似然估计”IEEE Transactions on Medical Imaging(第 17 卷,第 3 期,1998 年 6 月)doipdf)。

用于估计曲线的 Python 脚本 A

可以扩展此脚本以在答案中绘制估计曲线。

import numpy as np
from mpmath import mp
import matplotlib.pyplot as plt

def plot_est(ms, est_as):
    fig = plt.figure(figsize=(4,4))
    ax = fig.add_subplot(1, 1, 1)
    if len(np.shape(est_as)) == 2:
        for i in range(np.shape(est_as)[0]):
            plt.plot(ms, est_as[i])
    else:
        plt.plot(ms, est_as)    
    plt.axis([ms[0], ms[-1], ms[0], ms[-1]])
    if ms[-1]-ms[0] < 5:
        ax.set_xticks(np.arange(np.int(ms[0]), np.int(ms[-1]) + 1, 1))
        ax.set_yticks(np.arange(np.int(ms[0]), np.int(ms[-1]) + 1, 1))
    plt.grid(True)
    plt.xlabel('$m$')
    h = plt.ylabel('$\hat a$')
    h.set_rotation(0)
    plt.show()

图 1 的 Python 脚本 B

此脚本可以扩展为答案中的误差增益曲线。

import math
import numpy as np
import matplotlib.pyplot as plt

def est_a_sub_fast(m):
    if m > 1:
        return np.sqrt(m*m - 1)
    else:
        return 0

def est_gain_SSE_a(est_a, a, N):
    SSE = 0
    SSE_ref = 0
    for k in range(N):  #Noise std. dev = 1, |X_k| = a
        m = abs(complex(np.random.normal(a, np.sqrt(2)/2), np.random.normal(0, np.sqrt(2)/2)))
        SSE += (a - est_a(m))**2 
        SSE_ref += (a - m)**2
    return SSE/SSE_ref

def est_gain_SSE_a2(est_a, a, N):
    SSE = 0
    SSE_ref = 0
    for k in range(N):  #Noise std. dev = 1, |X_k| = a
        m = abs(complex(np.random.normal(a, np.sqrt(2)/2), np.random.normal(0, np.sqrt(2)/2)))
        SSE += (a**2 - est_a(m)**2)**2
        SSE_ref += (a**2 - m**2)**2
    return SSE/SSE_ref

def est_gain_SSE_complex(est_a, a, N):
    SSE = 0
    SSE_ref = 0
    for k in range(N):  #Noise std. dev = 1, X_k = a
        Y = complex(np.random.normal(a, np.sqrt(2)/2), np.random.normal(0, np.sqrt(2)/2))        
        SSE += abs(a - est_a(abs(Y))*Y/abs(Y))**2
        SSE_ref += abs(a - Y)**2
    return SSE/SSE_ref

def plot_gains_SSE(as_dB, gains_SSE_a, gains_SSE_a2, gains_SSE_complex, color_number = 0):    
    colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
    fig = plt.figure(figsize=(7,4))
    ax = fig.add_subplot(1, 1, 1)
    if len(np.shape(gains_SSE_a)) == 2:
        for i in range(np.shape(gains_SSE_a)[0]):
            plt.plot(as_dB, gains_SSE_a[i], color=colors[i], )
            plt.plot(as_dB, gains_SSE_a2[i], color=colors[i], linestyle='--')
            plt.plot(as_dB, gains_SSE_complex[i], color=colors[i], linestyle=':')
    else:
        plt.plot(as_dB, gains_SSE_a, color=colors[color_number])
        plt.plot(as_dB, gains_SSE_a2, color=colors[color_number], linestyle='--')
        plt.plot(as_dB, gains_SSE_complex, color=colors[color_number], linestyle=':')
    plt.grid(True)
    plt.axis([as_dB[0], as_dB[-1], 0, 2])
    plt.xlabel('SNR (dB)')
    plt.ylabel('SSE gain')
    plt.show()

as_dB = range(-40, 41)
as_ = [10**(a_dB/20) for a_dB in as_dB]
gains_SSE_a_sub = [est_gain_SSE_a(est_a_sub_fast, a, 10**5) for a in as_]
gains_SSE_a2_sub = [est_gain_SSE_a2(est_a_sub_fast, a, 10**5) for a in as_]
gains_SSE_complex_sub = [est_gain_SSE_complex(est_a_sub_fast, a, 10**5) for a in as_]

plot_gains_SSE(as_dB, gains_SSE_a_sub, gains_SSE_a2_sub, gains_SSE_complex_sub, 1)
4个回答

最大似然 (ML) 估计器

这里将推导出干净信号功率的最大似然估计量,但与频谱功率减法相比,对于任何 SNR,它似乎都没有改善均方根误差。

介绍

让我们介绍归一化干净幅度$a$和归一化噪声幅度$m$由噪声标准偏差$\sigma:$

$$a = \frac{|X_k|}{\sigma},\quad m = \frac{|Y_k|}{\sigma}.\tag{1}$$

方程中的估计器。问题 3 给出了 $a$ 的估计$\hat a $

$$\hat a = \frac{1}{\sigma}\sqrt{\widehat{|X_k|^2}} = \frac{1}{\sigma}\sqrt{\max\left((\sigma m )^2 - \sigma^2, 0\right)} = \cases{\sqrt{m^2-1}&if $m > 1,$\\0&if $m \le 1.$}\tag{2} $$

最大似然估计器

为了使$a$ 的估计量可能比 Eq 更好。2,我们遵循 Sijbers 等人的程序。1998.(见问题)构造一个最大似然(ML)估计器$\hat{a}_\mathrm{ML}.$它给出了$a$的值,它使$m的给定值的概率最大化。 $

$|Y_k|$的 PDFRician参数,参数$\nu_\mathrm{Rice} = |X_k|$和参数(为清楚起见稍后替换)$\sigma_\mathrm{Rice} = \frac{1}{ \sqrt{2}}\sigma:$

$$\mathrm{PDF}(|Y_k|) = \frac{|Y_k|}{\sigma_\mathrm{Rice}^2}\exp\left(\frac{-\left(|Y_k|^2 + | X_k|^2\right)}{2\sigma_\mathrm{Rice}^2}\right)I_0\left(\frac{|Y_k||X_k|}{\sigma_\mathrm{Rice}^2}\right ),\标签{3}$$

其中$I_\alpha$第一类修正贝塞尔函数代入$|X_k| = \sigma a,$ $|Y_k| = \sigma m,$$\sigma_\mathrm{Rice}^2 = \frac{1}{2}\sigma^2:$

$$= \mathrm{PDF}(\sigma m) = \frac{2m}{\sigma}e^{-\left(m^2 + a^2\right)}I_0(2ma),\tag{3.1 }$$

和改造:

$$\Rightarrow \mathrm{PDF}(m) = \sigma\mathrm{PDF}(\sigma m) = 2m e^{-\left(m^2 + a^2\right)}I_0(2ma)。 \标签{3.2}$$

由$a$参数化的$m$的 Rician PDF独立于噪声方差$\sigma^2.$参数 $a$的最大似然估计量$\hat a_\mathrm{ML}$是$ a $的值最大化$\mathrm{PDF}(m)$这是一个解决方案:

$$m\frac{I_1(2m\hat a_\mathrm{ML})}{I_0(2m\hat a_\mathrm{ML})} - \hat a_\mathrm{ML} = 0.\tag{4} $$

方程的解决方案。4具有以下性质:

$$\hat a_\mathrm{ML} = 0\quad\text{ if }\quad m \le 1.\tag{5}$$

否则需要数值求解。

在此处输入图像描述
图 1. 蓝色,上部:最大似然估计器$\hat a_\mathrm{ML}$和橙色,下部:归一化干净幅度$a$的问题的功率谱减法估计器$\hat a $ ,作为归一化噪声的函数量级$m.$

$\sigma\hat a_\mathrm{ML}$$|X_k|,$的最大似然估计量,通过最大似然估计的函数不变性$\sigma^2\hat a_\mathrm{ML}^2$$|X_k|^2.$的最大似然估计量

ML 估计器的经验 Laurent 系列

我试图用数字计算(参见下面的脚本) $\hat a_\mathrm{ML}^2,$的 Laurent 系列,但它似乎并没有在所需的$m$范围内收敛。据我计算,这是 Laurent 系列的截断:

$$\hat a_\mathrm{ML}^2 \约 m^2 - \frac{1}{2^1m^0} - \frac{1}{2^3m^2} - \frac{3}{ 2^5m^4} - \frac{12}{2^7m^6} - \frac{57}{2^9m^8} - \frac{309}{2^{11}m^{10}} - \frac{1884}{2^{13}m^{12}} - \frac{12864}{2^{15}m^{14}} - \frac{98301}{2^{17}m^ {16}} - \frac{839919}{2^{19}m^{18}} - \frac{7999311}{2^{21}m^{20}}\tag{6}$$

我在整数序列在线百科全书 (OEIS) 中找不到分子或分母整数序列。仅对于前五个负幂项,分子系数与A027710匹配。但是,在将计算出的序列($1, -1, -1, -3, \ldots$)提交给 OEIS Superseeker 后,我在回复中得到了这个(我从中确认了接下来的三个建议数字$-84437184、-980556636、 -12429122844$通过扩展计算):

Guesss suggests that the generating function  F(x)
may satisfy the following algebraic or differential equation:

-1/2*x+1/2+(-x+1/2)*x*diff(F(x),x)+(x-3/2)*F(x)-1/2*F(x)*x*diff(F(x),x)+F(x)^2 = 0

If this is correct the next 6 numbers in the sequence are:

[-84437184, -980556636, -12429122844, -170681035692, -2522486871192, -39894009165525]

表格近似和估计误差增益

包含$\hat a_\mathrm{ML}^2-m^2$的$124071$非均匀分布样本的线性插值表(参见下面的脚本)给出了一个近似值,最大误差约为$6\times10^{-11 }.$

ML 估计器的最小二乘逼近

创建了估计曲线样本的最小二乘近似(在$m^2 = 1$处具有额外的权重),其形式受到 Laurent 系列实验的启发(请参阅下面的 Octave 脚本)。常数项- 0.5被更改为以消除$m^2 = 1时出现负$a^2$- 0.49999998237308493999的可能性。$近似值对$m^2 \ge 1$有效,最大误差约为$2\times10^ {-5}$(图 3)在近似$\hat a_\mathrm{ML}^2:$

a^2 = m^2 - 0.49999998237308493999 -0.1267853520007855/m^2 - 0.02264263789612356/m^4 - 1.008652066326489/m^6 + 4.961512935048501/m^8 - 12.27301424767318/m^10 + 5.713416605734312/m^12 + 21.55623892529696/m^14 - 38.15890985013438/m^16 + 24.77625343690267/m^18 - 5.917417766578400/m^20

在此处输入图像描述
图 3. $\hat a_\mathrm{ML}^2.$的最小二乘近似误差

该脚本似乎能够处理不断增加的$m^2,$负幂的数量,从而始终给出越来越小的错误,错误极值的数量在增加,但最大错误衰减非常缓慢。该近似值几乎是等波纹的,但仍会从Remez 交换细化中受益。

使用该近似值,获得了以下预期误差增益曲线:

在此处输入图像描述
图 2. 样本大小为$10^5,$的 Monte Carlo 估计: 实心:通过$\widehat{|X_k|}$估计$|X_k|$与使用$估计相比,误差平方和的增益|Y_k|,$虚线:通过$\widehat{|X_k|^2}$估计 $|X_k|^ 2 $ 与使用$|Y_k|^2,$进行估计相比 ,平方误差的增益:与使用 $Y_k 估计相比,通过$\widehat{|X_k|}e^{i\arg(Y_k)}$估计$X_k$时平方误差总和的增益蓝色:ML 估计器,橙色:钳位光谱功率减法。

令人惊讶的是,ML 估计器在几乎所有方面都比钳位频谱功率减法差,除了在 SNR > 约 5 dB 时的信号估计和 SNR > 约 3 dB 时的幅度估计略好。在这些 SNR 下,这两个估计器比仅使用噪声信号作为估计器更差。

图 1 的 Python 脚本 A

此脚本扩展了问题的脚本 A。

def est_a_sub(m):
    m = mp.mpf(m)
    if m > 1:
        return mp.sqrt(m**2 - 1)
    else:
        return 0

def est_a_ML(m):
    m = mp.mpf(m)
    if m > 1:
        return mp.findroot(lambda a: m*mp.besseli(1, 2*a*m)/(mp.besseli(0, 2*a*m)) - a, [mp.sqrt(2*m**2*(m**2 - 1)/(2*m**2 - 1)), mp.sqrt(m**2-0.5)])
    else:
        return 0

def est_a_ML_fast(m): 
    m = mp.mpf(m)
    if m > 1:
        return mp.sqrt(m**2 - mp.mpf('0.49999998237308493999') - mp.mpf('0.1267853520007855')/m**2 - mp.mpf('0.02264263789612356')/m**4 - mp.mpf('1.008652066326489')/m**6 + mp.mpf('4.961512935048501')/m**8 - mp.mpf('12.27301424767318')/m**10 + mp.mpf('5.713416605734312')/m**12 + mp.mpf('21.55623892529696')/m**14 - mp.mpf('38.15890985013438')/m**16 + mp.mpf('24.77625343690267')/m**18 - mp.mpf('5.917417766578400')/m**20)
    else:
        return 0

ms = np.arange(0, 5.0078125, 0.0078125)
est_as = [[est_a_ML(m) for m in ms], [est_a_sub(m) for m in ms]];
plot_est(ms, est_as)

用于劳伦级数数值计算的 Python 脚本

此脚本以数字方式计算$\hat a_\mathrm{ML}^2-m^2.$的 Laurent 系列的前几项。它基于此答案中的脚本。

from sympy import *
from mpmath import *
num_terms = 10
num_decimals = 12
num_use_decimals = num_decimals + 5 #Ad hoc headroom
def y(a2):
    return sqrt(m2)*besseli(1, 2*sqrt(a2*m2))/besseli(0, 2*sqrt(a2*m2)) - sqrt(a2)

c = []
h = mpf('1e'+str(num_decimals))
denominator = mpf(2)  # First integer denominator. Use 1 if unsure
denominator_ratio = 4  # Denominator multiplier per step. Use 1 if unsure
print("x")
for i in range(0, num_terms):
    mp.dps = 2*2**(num_terms - i)*num_use_decimals*(i + 2) #Ad hoc headroom
    m2 = mpf('1e'+str(2**(num_terms - i)*num_use_decimals))
    r = findroot(y, [2*m2*(m2 - 1)/(2*m2 - 1),  m2-0.5]) #Safe search range, must be good for the problem
    r = r - m2; # Part of the problem definition
    for j in range(0, i):
        r = (r - c[j])*m2
    c.append(r)
    mp.dps = num_decimals
    print '+'+str(nint(r*h)*denominator/h)+'/('+str(denominator)+'x^'+str(i)+')'
    denominator *= denominator_ratio

用于 ML 估计器制表的 Python 脚本

该脚本创建了一个适合线性插值的$\left[m^2, \hat{a}_\mathrm{ML}^2\right]$对的不均匀采样表,给出了近似定义的最大绝对线性插值误差$\hat{a}_\mathrm{ML}^2$ for the range $m = 0\ldots m_\max.$通过向困难部分添加样本来自动增加表格大小,直到峰值误差足够小. 如果$m_\max$等于$ 2$加上$2,$的整数幂,则所有采样间隔都是$2的幂$\hat{a}_\mathrm{ML}^2 = m^2 - \frac{1}{2}.$如果需要 $\hat{a}_\mathrm{ML}$,我的猜测是最好按原样插入表格,然后进行转换$\hat{a}_\mathrm{ML} = \sqrt{\hat{a}_\mathrm{ML}^2}.$

要与下一个脚本结合使用,请通过管道输出> linear.m.

import sys # For writing progress to stderr (won't pipe when piping output to a file)
from sympy import *
from mpmath import *
from operator import itemgetter
max_m2 = 2 + mpf(2)**31 # Maximum m^2
max_abs_error = 2.0**-34 #Maximum absolute allowed error in a^2
allow_over = 0 #Make the created samples have max error (reduces table size to about 7/10)
mp.dps = 24
print('# max_m2='+str(max_m2))
print('# max_abs_error='+str(max_abs_error))
def y(a2):
    return sqrt(m2)*besseli(1, 2*sqrt(a2*m2))/besseli(0, 2*sqrt(a2*m2)) - sqrt(a2)

# [m2, a2, following interval tested good]
samples = [[0, 0, True], [1, 0, False], [max_m2, max_m2 - 0.5, True]]

m2 = mpf(max_m2)
est_a2 = findroot(y, [2*m2*(m2 - 1)/(2*m2 - 1),  m2-0.5])
abs_error = abs(est_a2 - samples[len(samples) - 1][1])
if abs_error > max_abs_error:
    sys.stderr.write('increase max_m, or increase max_abs_error to '+str(abs_error)+'\n')
    quit()

peak_taken_abs_error = mpf(max_abs_error*allow_over)
while True:
    num_old_samples = len(samples)
    no_new_samples = True
    peak_trial_abs_error = peak_taken_abs_error
    for i in range(num_old_samples - 1):
        if samples[i][2] == False:
            m2 = mpf(samples[i][0] + samples[i + 1][0])/2
            est_a2 = mpf(samples[i][1] + samples[i + 1][1])/2
            a2 = findroot(y, [2*m2*(m2 - 1)/(2*m2 - 1),  m2-0.5])
            est_abs_error = abs(a2-est_a2)
            if peak_trial_abs_error < est_abs_error:
                peak_trial_abs_error = est_abs_error
            if est_abs_error > max_abs_error:                
                samples.append([m2, a2 + max_abs_error*allow_over, False])
                no_new_samples = False
            else:
                samples[i][2] = True
                if peak_taken_abs_error < est_abs_error:
                    peak_taken_abs_error = est_abs_error
    if no_new_samples == True:
        sys.stderr.write('error='+str(peak_taken_abs_error)+', len='+str(len(samples))+'\n')
        print('# error='+str(peak_taken_abs_error)+', len='+str(len(samples)))
        break
    sys.stderr.write('error='+str(peak_trial_abs_error)+', len='+str(len(samples))+'\n')
    samples = sorted(samples, key=itemgetter(0))

print('global m2_to_a2_table = [')
for i in range(len(samples)):
    if i < len(samples) - 1:
      print('['+str(samples[i][0])+', '+str(samples[i][1])+'],')
    else:
      print('['+str(samples[i][0])+', '+str(samples[i][1])+']')
print('];')

图 2 的 Python 脚本 B

此脚本扩展了问题的脚本 B。

def est_a_ML_fast(m): 
    mInv = 1/m
    if m > 1:
        return np.sqrt(m**2 - 0.49999998237308493999 - 0.1267853520007855*mInv**2 - 0.02264263789612356*mInv**4 - 1.008652066326489*mInv**6 + 4.961512935048501*mInv**8 - 12.27301424767318*mInv**10 + 5.713416605734312*mInv**12 + 21.55623892529696*mInv**14 - 38.15890985013438*mInv**16 + 24.77625343690267*mInv**18 - 5.917417766578400*mInv**20)
    else:
        return 0

gains_SSE_a_ML = [est_gain_SSE_a(est_a_ML_fast, a, 10**5) for a in as_]
gains_SSE_a2_ML = [est_gain_SSE_a2(est_a_ML_fast, a, 10**5) for a in as_]
gains_SSE_complex_ML = [est_gain_SSE_complex(est_a_ML_fast, a, 10**5) for a in as_]
plot_gains_SSE(as_dB, [gains_SSE_a_ML, gains_SSE_a_sub], [gains_SSE_a2_ML, gains_SSE_a2_sub], [gains_SSE_complex_ML, gains_SSE_complex_sub])

最小二乘的八度脚本

这个 Octave 脚本(对此答案的改编)对$m^2$的幂进行最小二乘拟合$\hat{a}_\mathrm{ML}^2 - (m^2 - \frac{1}{ 2})$样本是由上面的 Python 脚本准备的。

graphics_toolkit("fltk");
source("linear.m");
format long
dup_zero = 2000000  # Give extra weight to m2 = 1, a2 = 0
max_neg_powers = 10  # Number of negative powers in the polynomial
m2 = m2_to_a2_table(2:end-1,1);
m2 = vertcat(repmat(m2(1), dup_zero, 1), m2);
A = (m2.^-[1:max_neg_powers]);
a2_target = m2_to_a2_table(2:end-1,2);
a2_target = vertcat(repmat(a2_target(1), dup_zero, 1), a2_target);
fun_target = a2_target - m2 + 0.5;
disp("Cofficients for negative powers of m^2:")
x = A\fun_target
a2 = A*x + m2 - 0.5;
plot(sqrt(m2), sqrt(a2)) # Plot approximation
xlim([0, 3])
ylim([0, 3])
a2(1)  # value at m2 = 2
abs_residual = abs(a2-a2_target);
max(abs_residual) # Max abs error of a^2
max(abs(sqrt(a2)-sqrt(a2_target))) # Max abs error of a
plot(sqrt(log10(m2)), a2_target - a2) # Plot error
xlabel("sqrt(log(m^2))")
ylabel("error in approximation of hat a^2_{ML}")

使用切比雪夫多项式进行近似的 Python 脚本 A2

此脚本扩展了脚本 A,并使用 Chebyshev 多项式给出了 ML 估计器的替代近似值。第一个 Chebyshev 节点位于$m=1$并且 Chebyshev 多项式的数量使得近似值是非负的。

N = 20
est_a_ML_poly, err = mp.chebyfit(lambda m2Reciprocal: est_a_ML(mp.sqrt(1/m2Reciprocal))**2 - 1/m2Reciprocal, [0, 2/(mp.cos(mp.pi/(2*N)) + 1)], N, error=True)

def est_a_ML_fast(m): 
    global est_a_ML_poly
    m = mp.mpf(m)
    if m > 1:
        return mp.sqrt(m**2 + mp.polyval(est_a_ML_poly, 1/m**2))
    else:
        return 0

更新:

我很遗憾不得不说,测试表明以下论点似乎在嘈杂的噪音下崩溃了。这不是我所期望的,所以我肯定学到了一些新东西。我之前的测试都在高信噪比范围内,因为我的重点是在无噪声情况下找到精确的解决方案。


奥利,

如果您的目标是在嘈杂的信号中找到纯音的参数,您应该这么说。在这个问题上,我有很多经验和专业知识。

您说您正在寻找幅度(以及随之而来的相位),所以我敢打赌您正在排列 DFT 以获得整数个周期。这是这种情况下最糟糕的配置,因为您将在单个 bin 中处理您的信号,以对抗该单个 bin 中的噪声。

正如您在上面所展示的,SNR 越大,您的技巧执行得越差,达到有害或超出的程度。好吧,您感兴趣的垃圾箱将是 SNR 最高的垃圾箱。

您要做的是将您的 DFT 框架对齐整个加一个半周期。这会将您的信号传播到尽可能多的 bin 中。然后,您可以找到我的博客文章中描述的相位和幅度,主题为 DFT 中纯实音的相位和幅度计算:方法 1

简而言之,您将峰值附近的一组 bin 视为复向量空间。然后知道频率,您可以为您的信号构建一组基向量。矢量的系数充当虚拟箱,它将告诉您信号的幅度和相位。通过在多个 bin 中找到最佳拟合向量,该技术不允许任何给定 bin 中的噪声过于占优势,并且提供了一个噪声必须平衡的“杠杆”。降噪效果类似于随机变量一起平均时的效果。

构建基向量意味着以您的频率对正弦和余弦进行 DFT。我有一个直接计算的公式,它绕过了求和。该文章链接自上述文章。

我很想知道您的技术是否确实改善了这种方法的结果。我习惯于在更高的 SNR >> 1 下工作,所以我从来没有真正测试过你正在处理的噪音水平。

方法概要:

$$ x[n] = a \cdot \cos( \omega n ) + b \cdot \sin( \omega n ) + wgn[n] $$

因为 DFT 是线性算子:

$$ DFT( x[n] ) = a \cdot DFT( \cos( \omega n ) ) + b \cdot DFT( \sin( \omega n ) ) + DFT( wgn[n] ) $$

在矢量符号中:

$$ Z = a \cdot A + b \cdot B + W $$

您只需使用标准线性代数求解$a$$b$即可获得最佳拟合。一个好处是您还获得了 W 的估计值。因此,您可以尝试“扔掉流浪汉”的方法,并完全消除最差拟合箱中的估计噪声,然后重新计算。冲洗,重复。或者通过其他公式减少每个 bin 中的噪声。如果您按比例执行此操作,您的结果将保持不变,因为 W 与 A 和 B 正交。但是沿 W 而不是 Z 的恒定减法(如您的方法所做的那样)也应该会改善结果。

通常,我会在峰值周围进行四个 bin,但您可能希望将其扩展到 6 甚至 8 个。在某些时候,更多的 bin 会产生更差的结果,因为您带来的噪声多于信号。

您只需计算感兴趣的 DFT 箱。

通过使用渐近公式获得最大似然 (ML) 估计问题的一个有趣的近似解

$$I_0(x)\约 \frac{e^x}{\sqrt{2\pi x}},\qquad x\gg 1\tag{1}$$

使用Olli 的答案中的符号和公式,归一化干净信号幅度的最佳 ML 估计满足

$$\hat{a}=m\frac{I_1(2m\hat{a})}{I_0(2m\hat{a})}\tag{2}$$

使用$(1)$并注意到$I_1(x)=I_0'(x)$,我们获得了近似值

$$\frac{I_1(x)}{I_0(x)}\大约 1-\frac{1}{2x}\tag{3}$$

对于$x>4.5$,此近似值的相对误差小于$1$ %

$(3)$代入$(2)$给出近似解

$$\hat{a}\approx\frac12\left(m+\sqrt{m^2-1}\right)\tag{4}$$

通过$m=|Y_k|/\sigma$$a=|X_k|/\sigma$我们得到

$$\widehat{|X|_k}\approx\frac12\left(|Y_k|+\sqrt{|Y_k|^2-\sigma^2}\right)\tag{5}$$

这只是噪声观察$|Y_k|$的算术平均值和从光谱功率减法获得的估计值。


编辑:

我会很高兴有一个像$(3)$这样的近似值,它适用于整个范围$x\in[0,\infty)$这种近似的候选者是函数族

$$f(x)=\frac{x}{\sqrt{c_1+c_2x^2}}\tag{6}$$

考虑到$f(x)$$x=0$$x\rightarrow\infty$附近的属性,理论上正确的常数选择是$c_1=4$$c_2=1 $ 。但是,对于$x$的实际范围,通过稍微调整这些常数可能会在该范围内获得更好的近似值。

使用$c_1=4$$c_2=1$的近似值$(6)$得出以下估计值:

$$\hat{a}=m\sqrt{1-\frac{1}{m^4}}\tag{7}$$

或者,等效地,

$$\widehat{|X|_k}=|Y_k|\sqrt{1-\frac{\sigma^4}{|Y_k|^4}}\tag{8}$$


奥利编辑:

在此处输入图像描述
图 1. $\hat a_\text{ML}$(橙色)及其由方程式定义的近似值。4(蓝色)和等式。7(绿色),作为$m.$的函数,所有曲线接近$a = m$作为$m\to\infty$ (大$m$见右图)。$\hat a_\text{ML}^2$渐近地逼近其截断的 Laurent 级数$m^2-\frac{1}{2}$$m\to\infty,$这给出了一个奇怪的结果,即使$\hat a_\text{ML}$的近似值逐渐逼近它为$m\to\infty$,即等式的平方。7 在将$\hat a_\text{ML}^2$近似为$m\to\infty$时存在恒定误差因为其 Laurent 级数的常数项 0不同于$\hat a_\text{ML}^2$的 Laurent 级数的$-\frac{1}{2} $ (参见 Olli 的 ML 估计器答案)和Laurent 级数方程平方。4.由于$ \ lim_ {m\to\infty}\left(\sqrt{m^2 + c} - m\right) = 0.$

图 1 的 Python 脚本

此脚本需要模块导入和绘图函数的问题脚本,以及来自 Olli 的 ML 答案plot_est的函数定义。est_a_ML

def est_a_MattL_Eq_4(m):
    m = mp.mpf(m)
    if m > 1:
        return (m + mp.sqrt(m**2 - 1))/2
    else:
        return 0

def est_a_MattL_Eq_7(m):
    m = mp.mpf(m)
    if m > 1:
        return m*mp.sqrt(1 - 1/m**4)
    else:
        return 0

ms = np.arange(0, 2.00390625, 0.00390625)
est_as = [[est_a_MattL_Eq_4(m) for m in ms], [est_a_ML(m) for m in ms], [est_a_MattL_Eq_7(m) for m in ms]];
plot_est(ms, est_as)

ms = np.arange(18, 20.125, 0.125)
est_as = [[est_a_MattL_Eq_4(m) for m in ms], [est_a_ML(m) for m in ms], [est_a_MattL_Eq_7(m) for m in ms]];
plot_est(ms, est_as)

尺度不变的最小均方误差 (MMSE) 变换幅度的不正确的均匀先验估计器

这个答案提出了一个家庭尺度不变估计器,由一个参数参数化,该参数控制幅度的贝叶斯先验分布和幅度到另一个尺度的转换。估计器是变换幅度标度中的最小均方误差(MMSE) 估计器。假设变换幅度的不正确的均匀先验。可用的变换包括线性标度(无变换)并且可以接近对数标度,由此估计量处处接近零。可以对估计器进行参数化,以在负信噪比 (SNR) 下获得较低的平方误差和。

贝叶斯估计

我的第一个答案中的最大似然 (ML) 估计器表现相当差。ML 估计器也可以理解为给定不正确的均匀先验概率分布的贝叶斯最大后验(MAP) 估计器。在这里,不正确意味着先验以无穷小的密度从零扩展到无穷大。因为密度不是实数,所以先验不是适当的分布,但它仍然可以通过贝叶斯定理给出适当的后验分布,然后可以将其用于获得 MAP 或 MMSE 估计。

就概率密度函数 (PDF) 而言,他们的贝叶斯定理是:

$$\operatorname{PDF}(a\mid m) = \frac{\operatorname{PDF}(m\mid a)\,\operatorname{PDF}(a)}{\operatorname{PDF}(m)} = \frac{\operatorname{PDF}(m\mid a)\,\operatorname{PDF}(a)}{\int_0^\infty\operatorname{PDF}(m\mid a)\,\operatorname{PDF}( a)\,da}.\tag{1}$$

MAP 估计器$\hat a_\text{MAP}$是最大化它的后验 PDF 的参数:

$$\hat a_\text{MAP} = \underset{a}{\operatorname{arg\,max}}\operatorname{PDF}(a \mid m).\tag{2}$$

MMSE 估计器$\hat a_\text{MMSE}$是后验均值:

$$\hat a_\text{MMSE} = \underset{\hat a}{\operatorname{arg\,max}}\operatorname{E}[(a - \hat a)^2\mid m] = \operatorname {E}[a\mid m] = \int_0^\infty a \operatorname{PDF}(a\mid m)da.\tag{3}$$

不正确的统一先验并不是唯一的尺度不变先验。任何满足以下条件的先前 PDF:

$$\operatorname{PDF(|X_k|)} \propto |X_k|^{\varepsilon-1},\tag{4}$$

具有实指数$\varepsilon-1,$$ \ propto$含义:“等人2010 年)。

估算器家族

应呈现一个估计量族,具有以下属性:

  1. 尺度不变性:如果复杂的干净箱$X_k,$或等效的干净幅度$|X_k|,$和噪声标准偏差$\sigma$分别乘以相同的正常数,那么估计幅度$\widehat {|X_k|}$乘以该常数。
  2. 最小均方变换幅度误差。
  3. 变换幅度的不正确的均匀先验。

我们将使用标准化符号:

$$\begin{array}{ll} a &= \frac{|X_k|}{\sigma}&\text{归一化干净幅度,}\\ m &= \frac{|Y_k|}{\sigma}& \text{归一化噪声幅度,}\\ 1 &= \left(\frac{\sigma}{\sigma}\right)^2&\text{归一化噪声方差,}\\ \mathrm{SNR} &= \ left(\frac{|X_k|}{\sigma}\right)^2 = a^2&\text{信噪比 ($10\log_{10}(\mathrm{SNR})$dB),} \end{数组}\tag{5}$$

其中$|X_k|$是我们希望从bin 值$Y_k$的噪声幅度$|Y_k|$估计的干净幅度,它等于干净 bin 值$X_k$加上圆对称复高斯方差噪声$\ sigma^2.$等式中给出的$|X_k|$的尺度不变先验4 被转入归一化符号为:

$$\operatorname{PDF}(a) \propto a^{\varepsilon - 1}.\tag{6}$$

$g(a)$为幅度$a 的递增变换函数。$变换幅度的不适当均匀先验表示为:

$$\operatorname{PDF}\big(g(a)\big) \propto 1.\tag{7}$$

方程。6 和 7 一起确定了可能的幅度变换系列。它们通过变量的变化相关:

$$\begin{array}{rrcl}&g'(a) \operatorname{PDF}\big(g(a)\big) &=& \operatorname{PDF}(a)\\ \displaystyle\Rightarrow&\quad g '(a) &\propto& a^{\varepsilon - 1}\\ \Rightarrow&g(a) &\propto& \displaystyle\int a^{\varepsilon - 1} da = \frac{a^\varepsilon}{\varepsilon } + c\\ \Rightarrow&g(a) &=& \displaystyle\frac{c_1a^\varepsilon}{\varepsilon} + c_0.\end{array}\tag{8}$$

我们假设没有证据表明常数$c_0$$c_1$的选择不会影响幅度估计。为方便起见,我们设置:

$$\begin{array}{rc}&g(1) = 1\quad\text{and}\quad g'(1) = 1\\ \Rightarrow&c_0 = \displaystyle\frac{\varepsilon - 1}{\varepsilon }\quad\text{and}\quad c_1 = 1\\ \Rightarrow&g(a) = \displaystyle\frac{a^\varepsilon + \varepsilon - 1}{\varepsilon},\\ \end{array}\tag {9}$$

它有一个特殊的线性情况:

$$g(a) = a\quad\text{if}\quad \varepsilon = 1,\tag{10}$$

和一个限制:

$$\lim_{\varepsilon \to 0}g(a) = \log(a) + 1.\tag{11}$$

变换函数可以方便地表示线性幅度标度(在$\varepsilon = 1$处),并且可以接近对数幅度标度(如$\varepsilon \to 0$)。对于正$\varepsilon,$,变换幅度的 PDF 的支持为:

$$\begin{eqnarray}&0 < a < \infty&\\ \Rightarrow\quad&\frac{\varepsilon - 1}{\varepsilon} < g(a) < \infty,&\end{eqnarray}\tag{12 }$$

逆变换函数为:

$$g^{-1}\big(g(a)\big) = \big(\varepsilon g(a) - \varepsilon + 1\big)^{1/\varepsilon} = a.\tag{13 }$$

然后,使用无意识统计学家的定律,转换后的估计值:

$$\begin{gather}\hat a_\text{uni-MMSE-xform} = \underset{\hat a}{\operatorname{arg\,min}}\operatorname{E}\left[\big(g( a) - g(\hat a)\big)^2\mid m\right] = g^{-1}\big(\operatorname{E}[g(a) \mid m]\big)\\ = g^{-1}\left(\int_0^\infty g(a) \operatorname{PDF}(a \mid m)\,da\right)\\ = g^{-1}\left(\frac{ \int_0^\infty g(a) f(a \mid m)da}{\int_0^\infty f(a \mid m)da}\right),\end{gather}\tag{14}$$

其中$\operatorname{PDF}(a \mid b)$是后验 PDF,$f(a \mid m)$是使用贝叶斯定理(等式 1)定义的非归一化后验 PDF,Rician $\operatorname{ PDF}(m \mid a) = 2me^{-\left(m^2 + a^2\right)}I_0(2ma)$从方程。我的 ML 估计器答案的 3.2 和 Eq。6:

$$\begin{eqnarray}\operatorname{PDF}(a\mid m) &\propto& \operatorname{PDF}(m\mid a)\,\operatorname{PDF}(a)\\ &\propto&2me^{- \left(m^2 + a^2\right)}I_0(2ma)\times a^{\varepsilon - 1}\\ &\propto&e^{-a^2}I_0(2ma)\,a^{\ varepsilon - 1} = f(a \mid m),\end{eqnarray}\tag{15}$$

从中$\operatorname{PDF}(m)$被从贝叶斯公式中删除,因为它在$a.$上是常数。14、9 和 15,求解 Mathematica 中的积分并简化,给出:

$$\begin{gather}\hat a_\text{uni-MMSE-xform}=g^{-1}\left(\frac{\int_0^\infty \frac{a^\varepsilon + \varepsilon - 1} {\varepsilon} \times e^{-a^2}I_0(2ma)\,a^{\varepsilon - 1}\,da}{\int_0^\infty e^{-a^2}I_0(2ma) \,a^{\varepsilon - 1}\,da}\right)\\ = \left(\varepsilon\frac{\frac{1}{2\varepsilon}\left(\Gamma(\varepsilon) L_{- \varepsilon}(m^2) + (\varepsilon-1) \Gamma(\varepsilon/2) L_{-\varepsilon/2}(m^2)\right)}{\frac{1}{2} \ Gamma(\varepsilon/2) L_{-\varepsilon/2}(m^2)} - \varepsilon + 1\right)^{1/\varepsilon}\\ = \left(\frac{\Gamma(\varepsilon ) L_{-\varepsilon}(m^2) + (\varepsilon-1) \Gamma(\varepsilon/2) L_{-\varepsilon/2}(m^2)}{\Gamma(\varepsilon/2) L_{-\varepsilon/2}(m^2)} - \varepsilon + 1\right)^{1/\varepsilon}\\ = \left(\frac{\Gamma(\varepsilon) L_{-\varepsilon} (m^2)}{\Gamma(\varepsilon/2) L_{-\varepsilon/2}(m^2)}\right)^{1/\varepsilon},\end{聚集}\tag{16}$$

其中$\Gamma$伽马函数$L$拉盖尔函数$\varepsilon \to 0,$时,估计量随处塌陷为零,因此使用负值$\varepsilon,$没有意义,这将进一步强调$a$的小值并给出不正确的后验分布。一些特殊情况是:

$$\hat a_\text{uni-MMSE-xform} = \sqrt{m^2 + 1},\quad\text{if }\varepsilon = 2,\tag{17}$$

$$\hat a_\text{uni-MMSE} = \hat a_\text{uni-MMSE-xform}= \frac{e^{m^2/2}}{\sqrt{\pi} I_0(m^ 2/2)},\quad\text{如果 }\varepsilon = 1,\tag{18}$$

通过(参见计算)截断的 Laurent 级数近似于大$m$ :

$$\hat a_\text{uni-MMSE} \大约 m - \frac{1}{4m} - \frac{7}{32m^3} - \frac{59}{128m^5},\tag{ 19}$$

对于$m > 7.7.$ ,这种渐近近似的绝对最大振幅误差小于$10^{-6} $

估计曲线如图 1 所示。

在此处输入图像描述
图 1. 估计器$\hat a_\text{uni-MMSE-xform}$作为$m$的函数,对于不同的$\varepsilon,$值,从上到下:蓝色:$\varepsilon = 2, $假设不正确的均匀先验功率的均方功率误差,橙色:$\varepsilon = 1,$假设不正确的均匀先验幅度,最小化均方幅度误差,绿色:$\varepsilon = \frac{1}{2} ,$红色:$\varepsilon = \frac{1}{4},$和紫色:$\varepsilon = \frac{1}{8}.$

$m=0$处,曲线是水平的,具有值:

$$\hat a_\text{uni-MMSE-xform} = \frac{2^{1 - 1/\varepsilon} \bigg(\Gamma\Big(\frac{1 + \varepsilon}{2}\Big) \bigg)^{1/\varepsilon}}{\pi^{1/(2\varepsilon)}},\quad\text{如果 }m = 0.\tag{20}$$

在负 SNR 下,uni-MMSE-xform 估计器可以使用低$\varepsilon$参数化,以提供比钳位谱功率减法估计器更低的平方误差和,在接近 7 dB 的中间 SNR 值处有相应的惩罚(图2).

在此处输入图像描述
在此处输入图像描述
在此处输入图像描述
图 2. 样本大小为$10^5,$的 Monte Carlo 估计: 实心:通过$\widehat{|X_k|}$估计$|X_k|$与使用$估计相比,误差平方和的增益|Y_k|,$虚线:通过$\widehat{|X_k|^2}$估计 $|X_k|^ 2 $ 与使用$|Y_k|^2,$进行估计相比 ,平方误差的增益通过$\widehat{|X_k|}e^{i\arg(Y_k)}$估计 $X_k$ 与使用$ Y_k估计相比,平方误差和的增益。蓝色:uni-MMSE-xform 估计器$\varepsilon = 1$(顶部),$\varepsilon = \frac{1}{2}$(中),$\varepsilon = \frac{1}{4},$ orange:钳位谱功率减法。

图 1 的 Python 脚本

此脚本扩展了问题的脚本 A。

def est_a_uni_MMSE_xform(m, epsilon):
    m = mp.mpf(m)
    epsilon = mp.mpf(epsilon)
    if epsilon == 0:
        return mpf(0)
    elif epsilon == 1:
        return mp.exp(m**2/2)/(mp.sqrt(mp.pi)*mp.besseli(0, m**2/2))
    elif epsilon == 2:
        return mp.sqrt(m**2 + 1)
    else:
        return (mp.gamma(epsilon)*mp.laguerre(-epsilon, 0, m**2) / (mp.gamma(epsilon/2)*mp.laguerre(-epsilon/2, 0, m**2)))**(1/epsilon)

ms = np.arange(0, 6.0625, 0.0625)
est_as_uni_MMSE_xform = [[est_a_uni_MMSE_xform(m, 2) for m in ms], [est_a_uni_MMSE_xform(m, 1) for m in ms], [est_a_uni_MMSE_xform(m, 0.5) for m in ms], [est_a_uni_MMSE_xform(m, 0.25) for m in ms],  [est_a_uni_MMSE_xform(m, 0.125) for m in ms]]
plot_est(ms, est_as_uni_MMSE_xform)

图 2 的 Python 脚本

此脚本扩展了问题的脚本 B。该函数est_a_uni_MMSE_xform_fast可能在数值上不稳定。

from scipy import special

def est_a_uni_MMSE_fast(m):
    return 1/(np.sqrt(np.pi)*special.i0e(m**2/2))

def est_a_uni_MMSE_xform_fast(m, epsilon):
    if epsilon == 0:
        return 0
    elif epsilon == 1:
        return 1/(np.sqrt(np.pi)*special.i0e(m**2/2))
    elif epsilon == 2:
        return np.sqrt(m**2 + 1)
    else:
        return (special.gamma(epsilon)*special.eval_laguerre(-epsilon, m**2)/(special.gamma(epsilon/2)*special.eval_laguerre(-epsilon/2, m**2)))**(1/epsilon)

gains_SSE_a_uni_MMSE = [est_gain_SSE_a(est_a_uni_MMSE_fast, a, 10**5) for a in as_]
gains_SSE_a2_uni_MMSE = [est_gain_SSE_a2(est_a_uni_MMSE_fast, a, 10**5) for a in as_]
gains_SSE_complex_uni_MMSE = [est_gain_SSE_complex(est_a_uni_MMSE_fast, a, 10**5) for a in as_]
plot_gains_SSE(as_dB, [gains_SSE_a_uni_MMSE, gains_SSE_a_sub], [gains_SSE_a2_uni_MMSE, gains_SSE_a2_sub], [gains_SSE_complex_uni_MMSE, gains_SSE_complex_sub])

gains_SSE_a_uni_MMSE_xform_0e5 = [est_gain_SSE_a(lambda m: est_a_uni_MMSE_xform_fast(m, 0.5), a, 10**5) for a in as_]
gains_SSE_a2_uni_MMSE_xform_0e5 = [est_gain_SSE_a2(lambda m: est_a_uni_MMSE_xform_fast(m, 0.5), a, 10**5) for a in as_]
gains_SSE_complex_uni_MMSE_xform_0e5 = [est_gain_SSE_complex(lambda m: est_a_uni_MMSE_xform_fast(m, 0.5), a, 10**5) for a in as_]
plot_gains_SSE(as_dB, [gains_SSE_a_uni_MMSE_xform_0e5, gains_SSE_a_sub], [gains_SSE_a2_uni_MMSE_xform_0e5, gains_SSE_a2_sub], [gains_SSE_complex_uni_MMSE_xform_0e5, gains_SSE_complex_sub])

gains_SSE_a_uni_MMSE_xform_0e25 = [est_gain_SSE_a(lambda m: est_a_uni_MMSE_xform_fast(m, 0.25), a, 10**5) for a in as_]
gains_SSE_a2_uni_MMSE_xform_0e25 = [est_gain_SSE_a2(lambda m: est_a_uni_MMSE_xform_fast(m, 0.25), a, 10**5) for a in as_]
gains_SSE_complex_uni_MMSE_xform_0e25 = [est_gain_SSE_complex(lambda m: est_a_uni_MMSE_xform_fast(m, 0.25), a, 10**5) for a in as_]
plot_gains_SSE(as_dB, [gains_SSE_a_uni_MMSE_xform_0e25, gains_SSE_a_sub], [gains_SSE_a2_uni_MMSE_xform_0e25, gains_SSE_a2_sub], [gains_SSE_complex_uni_MMSE_xform_0e25, gains_SSE_complex_sub])

参考

Lieve Lauwers、Kurt Barbe、Wendy Van Moer 和 Rik Pintelon,分析 Rice 分布式功能磁共振成像数据:贝叶斯方法Meas。科学。技术。21 (2010) 115804 (12pp) DOI: 10.1088/0957-0233/21/11/115804