Estimadores para la sustracción espectral mejorada del ruido


8

Ruido blanco real gaussiano de media cero, independiente de una señal limpia x y de la varianza conocida se agrega a x produciendo una señal ruidosa y. Transformada discreta de Fourier (DFT) Y de la señal ruidosa se calcula mediante:

(1)Yk=1Nn=0N1ei2πkn/Nyn.

Esto es solo para el contexto, y definiremos la varianza del ruido en el dominio de la frecuencia, por lo que la normalización (o falta de ella) no es importante. El ruido blanco gaussiano en el dominio del tiempo es el ruido blanco gaussiano en el dominio de la frecuencia, vea la pregunta: " ¿Cuál es la estadística de la transformada discreta de Fourier del ruido blanco gaussiano? ". Por lo tanto podemos escribir:

Yk=Xk+Zk,

dónde X y Z son los DFT de la señal limpia y el ruido, y Zk el contenedor de ruido que sigue una distribución de varianza gaussiana compleja simétrica circular σ2. Cada parte real e imaginaria deZk sigue independientemente una distribución de varianza gaussiana 12σ2. Definimos la relación señal-ruido (SNR) de binYk como:

SNR=σ2|Xk|2.

Luego se intenta reducir el ruido mediante sustracción espectral, por lo que la magnitud de cada contenedor Ykse reduce de forma independiente mientras se conserva la fase original (a menos que el valor de bin llegue a cero en la reducción de magnitud). La reducción forma una estimación.|Xk|2^ de la plaza |Xk|2 del valor absoluto de cada bin del DFT de la señal limpia:

(2)|Xk|2^=|Yk|2σ2,

dónde σ2es la variación conocida del ruido en cada contenedor DFT. Por simplicidad, no estamos considerandok=0, o k=N/2 incluso para N, que son casos especiales de verdad x. A una SNR baja, la formulación en (2) a veces puede resultar en negativo |Xk|2^. Podemos eliminar este problema ajustando la estimación a cero desde abajo, redefiniendo:

(3)|Xk|2^=max(|Yk|2σ2,0).

ingrese la descripción de la imagen aquí
Figura 1. Estimaciones de Monte Carlo con un tamaño de muestra de de: Sólido: ganancia de suma de error cuadrado en la estimaciónpor en comparación con estimarlo con discontinuo: ganancia de la suma del error cuadrado al estimar por en comparación con estimar con punteado: ganancia de la suma del error cuadrado al estimar por en comparación con estimarlo conSe definición de de (3).105,|Xk||Xk|^|Yk|,|Xk|2|Xk|2^|Yk|2,Xk|Xk|^eiarg(Yk)Yk.|Xk|2^

Pregunta: ¿Hay otra estimación deo que mejora sobre (2) y (3) sin depender de la distribución de ?|Xk||Xk|2Yk

Creo que el problema es equivalente a estimar el cuadrado del parámetro νRicede una distribución de arroz (Fig. 2) con parámetro conocidoσRice=22σ, dada una sola observación.

ingrese la descripción de la imagen aquí
Figura 2. La distribución del arroz es la distribución de la distancia. R originarse desde un punto que sigue una distribución normal simétrica circular bivariada con un valor absoluto de la media νRice, diferencia 2σRice2=σ2 y varianza de componentes σRice2=12σ2.

Encontré algo de literatura que parece relevante:

  • Jan Sijbers, Arnold J. den Dekker, Paul Scheunders y Dirk Van Dyck, "Estimación de máxima verosimilitud de los parámetros de distribución de Rician" , IEEE Transactions on Medical Imaging (Volumen: 17, Edición: 3, junio de 1998) ( doi , pdf ).

Python script A para curvas de estimador

Este script se puede extender para trazar curvas de estimador en las respuestas.

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()

Python script B para la Fig. 1

Este script se puede ampliar para obtener curvas de ganancia de error en las respuestas.

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)

2
Gosh Olli, una pregunta de aclaración: "Esto es solo para el contexto, por lo que la normalización no es importante. El ruido se reduce por sustracción espectral, por lo que la magnitud de cada bin Yk se reduce de forma independiente mientras se mantiene la fase original (a menos que el valor del bin vaya a cero en la reducción de magnitud). "¿Qué te hace decir que esta es una operación de reducción de ruido? Si el ruido puede ir en cualquier dirección, me parece que esto probablemente amplificará cualquier ruido como lo es atenuarlo.
Cedron Dawg


2
@CedronDawg: Si asumimos la independencia de la señal y el ruido, sus potencias se sumarán, por lo que la señal (potencia) se obtiene restando la potencia de ruido estimada. Entonces, en términos de potencia, el ruido solo puede ir en una dirección.
Matt L.

1
@OlliNiemitalo: ¿Conoces este artículo fundamental de Efraín y Malah? Derivan un estimador óptimo para la amplitud de la señal, que es una mejora sobre la sustracción espectral simple.
Matt L.

1
@OlliNiemitalo: se supone que los coeficientes DFT son gaussianos (tanto para la señal deseada como para el ruido), por lo que las amplitudes tienen una distribución de Rayleigh. Cf. Ecs (5) y (6) en el documento.
Matt L.

Respuestas:


7

Estimador de máxima verosimilitud (ML)

Aquí se derivará un estimador de máxima verosimilitud de la potencia de la señal limpia, pero no parece estar mejorando en términos de error cuadrático medio, para cualquier SNR, en comparación con la sustracción de potencia espectral.

Introducción

Vamos a introducir la amplitud limpia normalizada. a y magnitud ruidosa normalizada m normalizado por la desviación estándar de ruido σ:

(1)a=|Xk|σ,m=|Yk|σ.

El estimador en la ecuación. 3 de la pregunta da una estimacióna^ de a como:

(2)a^=1σ|Xk|2^=1σmax((σm)2σ2,0)={m21if m>1,0if m1.

Estimador de máxima verosimilitud

Para hacer un estimador posiblemente mejor de aque la ecuación 2, seguimos el procedimiento de Sijbers et al. 1998. (ver pregunta) para construir un estimador de máxima verosimilitud (NM)a^ML. Da el valor de a que maximiza la probabilidad del valor dado de m.

El PDF de |Yk|es Rician con parámetroνRice=|Xk| y parámetro (para ser sustituido más tarde por claridad) σRice=12σ:

(3)PDF(|Yk|)=|Yk|σRice2exp((|Yk|2+|Xk|2)2σRice2)I0(|Yk||Xk|σRice2),

dónde Iαes una función de Bessel modificada del primer tipo . Sustituyendo|Xk|=σa, |Yk|=σm, y σRice2=12σ2:

(3.1)=PDF(σm)=2mσe(m2+a2)I0(2ma),

y transformador:

(3.2)PDF(m)=σPDF(σm)=2me(m2+a2)I0(2ma).

El PDF de Rician m parametrizado por a es independiente de la variación de ruido σ2. El estimador de máxima verosimilitud a^ML de parámetro a es el valor de a que maximiza PDF(m). Es una solución de:

(4)mI1(2ma^ML)I0(2ma^ML)a^ML=0.

La solución a la ecuación. 4 tiene la propiedad de que:

(5)a^ML=0 if m1.

De lo contrario, debe resolverse numéricamente.

ingrese la descripción de la imagen aquí
Figura 1. azul, superior: el estimador de máxima verosimilitud a^ML y naranja, más bajo: el estimador de sustracción espectral de potencia de la pregunta a^ de amplitud limpia normalizada a, en función de la magnitud ruidosa normalizada m.

σa^ML es el estimador de máxima verosimilitud de |Xk|,y por invariancia funcional de la estimación de máxima verosimilitud,σ2a^ML2 es el estimador de máxima verosimilitud de |Xk|2.

Serie empírica Laurent del estimador ML

Traté de calcular numéricamente (ver script más abajo) la serie Laurent dea^ML2, pero no parece converger para el rango de mnecesario. Aquí hay un truncamiento de la serie Laurent hasta donde lo calculé:

(6)a^ML2m2121m0123m2325m41227m65729m8309211m101884213m1212864215m1498301217m16839919219m187999311221m20

No pude encontrar las secuencias enteras de numerador o denominador en la Enciclopedia en línea de secuencias enteras (OEIS). Solo para los primeros cinco términos de potencia negativa, los coeficientes del numerador coinciden con A027710 . Sin embargo, después de enviar la secuencia calculada (1,1,1,3,) a OEIS Superseeker , recibí esto en la respuesta (de la cual confirme los siguientes tres números sugeridos84437184,980556636,12429122844 por un cálculo extendido):

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]

Aproximación tabulada y ganancia de error de estimación

Una tabla interpolada linealmente (ver scripts a continuación) que contiene 124071 muestras no distribuidas uniformemente de a^ML2m2 da una aproximación con un error máximo de aproximadamente 6×1011.

Aproximación de mínimos cuadrados del estimador de ML

Una aproximación de mínimos cuadrados (con peso extra en m2=1) de las muestras de la curva del estimador fue creada, en forma inspirada por los experimentos de la serie Laurent (ver el guión de Octave más abajo). El término constante - 0.5se cambió a - 0.49999998237308493999para eliminar la posibilidad de negativoa2 a m2=1. La aproximación es válida para m21 y tiene un error máximo de aproximadamente 2×105 (Fig. 3) en aproximación a^ML2:

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

ingrese la descripción de la imagen aquí
Figura 3. Error de la aproximación de mínimos cuadrados de a^ML2.

El script parece capaz de manejar el aumento del número de poderes negativos de m2,consistentemente dando errores cada vez más pequeños, con el número de errores extremos creciendo, pero con una decadencia de error máxima bastante lenta. La aproximación es casi equiripple, pero aún se beneficiaría un poco del refinamiento del intercambio de Remez .

Usando la aproximación, se obtuvieron las siguientes curvas de ganancia de error esperadas:

ingrese la descripción de la imagen aquí
Figura 2. Estimaciones de Monte Carlo con un tamaño de muestra de 105, de: Sólido: ganancia de la suma del error cuadrado en la estimación |Xk| por |Xk|^ en comparación con estimarlo con |Yk|, discontinuo: ganancia de la suma del error cuadrado en la estimación |Xk|2 por |Xk|2^ en comparación con estimarlo con |Yk|2, punteado: ganancia de la suma del error cuadrado en la estimación Xk por |Xk|^eiarg(Yk) en comparación con estimarlo con Yk. Azul: estimador ML, naranja: sustracción de potencia espectral sujeta.

Sorprendentemente, el estimador ML es peor que la sustracción de potencia espectral fija en casi todos los aspectos, excepto por ser marginalmente mejor para la estimación de señal a SNR> aproximadamente 5 dB, y la estimación de amplitud a SNR> aproximadamente 3 dB. En esos SNR, los dos estimadores son peores que simplemente usar la señal ruidosa como la estimación.

Python script A para la Fig. 1

Este guión extiende el guión de la pregunta 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)

Script de Python para el cálculo numérico de series Laurent

Este script calcula numéricamente los primeros términos de la serie Laurent de a^ML2m2.Se basa en el guión de esta respuesta .

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

Script de Python para la tabulación del estimador ML

Este script crea una tabla de muestra desigualmente de [m2,a^ML2] pares adecuados para la interpolación lineal, dando aproximadamente el error de interpolación lineal absoluto máximo definido de aproximación a^ML2 para el rango m=0mmax.El tamaño de la tabla aumenta automáticamente al agregar muestras a las partes difíciles, hasta que el error máximo es lo suficientemente pequeño. Simmax es igual 2 más un poder entero de 2, entonces todos los intervalos de muestreo serán potencias de 2. Al final de la tabla habrá una transición libre de discontinuidades a una granm aproximación a^ML2=m212. Si a^ML es necesario, supongo que es mejor interpolar la tabla como está y luego hacer la conversión a^ML=a^ML2.

Para usar junto con el siguiente script, canalice la salida > 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('];')

Python script B para la Fig. 2

Este guión extiende el guión de la pregunta 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])

Script de octava para mínimos cuadrados

Este guión de octava (una adaptación de esta respuesta ) hace un ajuste de mínimos cuadrados de poderes dem2 dentro a^ML2(m212). Las muestras fueron preparadas por el script de Python un poco más arriba.

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 script A2 para aproximación usando polinomios de Chebyshev

Esta secuencia de comandos amplía la secuencia de comandos A y ofrece una aproximación alternativa del estimador de ML utilizando polinomios de Chebyshev. El primer nodo de Chebyshev está enm=1 y el número de polinomios de Chebyshev es tal que la aproximación no es negativa.

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

4

Actualizar:

Lamento tener que decir que las pruebas muestran que el siguiente argumento parece descomponerse con mucho ruido. Esto no es lo que esperaba, por lo que definitivamente he aprendido algo nuevo. Mis pruebas anteriores habían estado en el rango alto de SNR ya que mi enfoque se había centrado en encontrar soluciones exactas en el caso silencioso.


Olli

Si su objetivo es encontrar los parámetros de un tono puro en una señal ruidosa, debería haberlo dicho. En este tema, tengo mucha experiencia y pericia en.

Dices que estás buscando la amplitud (y la fase viene con ella), así que apuesto a que estás alineando tu DFT para tener un número entero de ciclos. Esta es la peor configuración para esta situación, ya que entonces está tratando con su señal en un solo contenedor contra el ruido en ese único contenedor.

Como ha demostrado anteriormente, cuanto mayor sea la SNR, peor será su truco, hasta el punto de perjudicar o más. Bueno, su depósito de interés será el que tenga la SNR más alta.

Lo que quiere hacer es alinear su marco DFT en un ciclo completo más un medio ciclo. Esto extenderá su señal a tantos contenedores como sea posible. Luego puede encontrar la fase y la amplitud como se describe en el artículo de mi blog sobre el tema Cálculo de fase y amplitud para un tono real puro en un DFT: Método 1 .

En resumen, trata el conjunto de contenedores cerca del pico como un espacio vectorial complejo. Luego, conociendo la frecuencia, construyes un conjunto de vectores básicos para tu señal. Los coeficientes de los vectores actúan como un contenedor virtual que le indicará la amplitud de la señal y la fase. Al encontrar el mejor vector de ajuste en varios contenedores, la técnica no permite que el ruido en cualquier contenedor sea demasiado dominante y de alguna manera proporciona una "palanca" que el ruido tiene que equilibrar. Los efectos de reducción de ruido son similares a cuando las variables aleatorias se promedian juntas.

Construir los vectores base significa tomar el DFT de un seno y coseno a su frecuencia. Tengo una fórmula para su cálculo directo que evita tener que hacer una suma. El artículo para eso está vinculado desde el artículo anterior.

Me interesaría saber si su técnica mejora los resultados de este método. Estoy acostumbrado a trabajar en SNR >> 1 más alto, por lo que nunca he probado realmente con los niveles de ruido con los que está lidiando.

Sinopsis del enfoque:

X[norte]=unacos(ωnorte)+sipecado(ωnorte)+wsolnorte[norte]

Debido a que el DFT es un operador lineal:

DFT(x[n])=aDFT(cos(ωn))+bDFT(sin(ωn))+DFT(wgn[n])

En notación vectorial:

Z=aA+bB+W

Simplemente estás resolviendo a y busando álgebra lineal estándar para darle un mejor ajuste. Una ventaja es que también obtienes una estimación de W. Por lo tanto, puedes intentar un enfoque de "tirar el vagabundo" y eliminar por completo el ruido estimado en el contenedor de peor ajuste y luego volver a calcular. Enjuague, repita. O reduzca el ruido en cada contenedor mediante alguna otra fórmula. Si lo hace proporcionalmente, sus resultados seguirán siendo los mismos ya que W es ortogonal a A y B. Pero una resta constante a lo largo de W, en lugar de Z (como lo hace su método) también debería mejorar los resultados.

Normalmente, hago los cuatro bins alrededor del pico, pero es posible que desee extender eso a 6 o incluso 8. En algún momento, más bins producen peores resultados ya que trae más ruido que señal.

Solo tiene que calcular los contenedores DFT de interés.


Creo que debería haber otra pregunta donde se podrían comparar los suyos y otros métodos.
Olli Niemitalo

@OlliNiemitalo, hagámoslo ambos y publiquemos los resultados aquí. ¿Cuál es un valor razonable para el número de muestras por ciclo? Para el caso, ¿cuántos ciclos por cuadro?
Cedron Dawg

No aquí por favor, en otra pregunta.
Olli Niemitalo

@OlliNiemitalo, Ok, si insistes, pero en realidad no será una pregunta. Por curiosidad, ¿es este un problema que estás tratando de resolver de verdad o es más un ejercicio académico?
Cedron Dawg

Creo que el resultado podría ser útil en un sentido general, por lo que me interesa trabajar en él.
Olli Niemitalo

2

Se obtiene una solución aproximada interesante del problema de estimación de máxima verosimilitud (ML) utilizando la fórmula asintótica

(1)I0(x)ex2πx,x1

Usando la notación y las fórmulas de la respuesta de Olli , la estimación óptima de ML de la amplitud de señal limpia normalizada satisface

(2)a^=mI1(2ma^)I0(2ma^)

Utilizando (1) y observando que I1(x)=I0(x), obtenemos la aproximación

(3)I1(x)I0(x)112x

Esta aproximación tiene un error relativo de menos de 1% para x>4.5.

Enchufar (3) dentro (2) da la solución aproximada

(4)a^12(m+m21)

Con m=|Yk|/σ y a=|Xk|/σ obtenemos

(5)|X|k^12(|Yk|+|Yk|2σ2)

que es simplemente la media aritmética de la observación ruidosa |Yk| y la estimación obtenida de la sustracción de potencia espectral.


EDITAR:

Sería bueno tener una aproximación como (3) que funciona en toda la gama x[0,). Un candidato para tal aproximación es la familia de funciones

(6)f(x)=xc1+c2x2

La elección teóricamente correcta de las constantes es c1=4 y c2=1, considerando las propiedades de f(x) alrededor x=0 y x. Sin embargo, para una gama realista dex, una mejor aproximación en ese rango podría lograrse ajustando un poco esas constantes.

Usando la aproximación (6) con c1=4 y c2=1 da como resultado la siguiente estimación:

(7)a^=m11m4

o equivalente,

(8)|X|k^=|Yk|1σ4|Yk|4


Edición de Olli:

ingrese la descripción de la imagen aquí
Figura 1. a^ML(naranja) y sus aproximaciones definidas por la ecuación. 4 (azul) y la ecuación. 7 (verde), en función dem. Enfoque de todas las curvas a=m como m (ver figura derecha para grande m) a^ML2 asintóticamente se acerca a su serie Laurent truncada m212 como m, lo que da el curioso resultado de que a pesar de las aproximaciones de a^ML asintóticamente abordarlo como m, el cuadrado de la ecuación. 7 tiene un error constante al aproximarsea^ML2 como mporque el término constante 0 de su serie Laurent difiere de12 de la serie Laurent de a^ML2(ver la respuesta del estimador ML de Olli) y la serie Laurent del cuadrado de la ecuación. 4. Este error constantec desaparece en la estimación de a^ML Debido al hecho de que limm(m2+cm)=0.

Script de Python para la Fig. 1

Este script requiere el script de la pregunta para las importaciones de módulos y para la función de trazado plot_est, y la definición de la función de est_a_MLla respuesta ML de Olli.

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)

@OlliNiemitalo: he adaptado mis fórmulas en consecuencia.
Matt L.

2

Estimadores anteriores uniformes inadecuados de amplitud transformada de error de cuadrado mínimo mínimo invariante de escala (MMSE)

Esta respuesta presenta estimadores invariantes de escala familiar, parametrizados por un único parámetro que controla tanto la distribución de amplitud previa bayesiana como la transformación de amplitud a otra escala. Los estimadores son estimadores de error cuadrado medio mínimo (MMSE) en la escala de amplitud transformada. Se supone un uniforme incorrecto antes de la amplitud transformada. Las transformaciones disponibles incluyen una escala lineal (sin transformación) y pueden acercarse a una escala logarítmica mediante la cual el estimador se aproxima a cero en todas partes. Los estimadores se pueden parametrizar para lograr una suma baja de error cuadrado a relaciones señal / ruido negativas (SNR).

Estimación bayesiana

El estimador de máxima verosimilitud (ML) en mi primera respuesta funcionó bastante mal. El estimador ML también puede entenderse como un estimador Bayesiano de máximo a posteriori (MAP) dada una distribución de probabilidad previa uniforme inadecuada. Aquí, incorrecto significa que lo anterior se extiende de cero a infinito con densidad infinitesimal. Debido a que la densidad no es un número real, el anterior no es una distribución adecuada, pero aún puede proporcionar una distribución posterior adecuada según el teorema de Bayes que luego puede usarse para obtener una estimación MAP o MMSE.

El teorema de Bayes en términos de funciones de densidad de probabilidad (PDF) es:

(1)PDF(unametro)=PDF(metrouna)PDF(una)PDF(metro)=PDF(metrouna)PDF(una)0 0PDF(metrouna)PDF(una)reuna.

Un estimador MAP una^MAPA es el argumento del PDF posterior que lo maximiza:

(2)una^MAPA=unarsolmetrounaXunaPDF(unametro).

Un estimador MMSE una^MMSE es la media posterior:

(3)una^MMSE=unarsolmetrounaXuna^mi[(una-una^)2metro]=mi[unametro]=0 0unaPDF(unametro)reuna.

Un prior uniforme incorrecto no es el único prior invariante de escala. Cualquier PDF anterior satisfactorio:

(4)PAGSreF(El |XkEl |)El |XkEl |ε-1,

con exponente real ε-1, y significado: "es proporcional a", es invariante de escala en el sentido de que el producto de Xky una constante positiva sigue la misma distribución (ver Lauwers et al. 2010 ).

Una familia de estimadores

Se presentará una familia de estimadores, con estas propiedades:

  1. Escala-invariancia: si el contenedor limpio y complejoXk, o equivalentemente la amplitud limpia El |XkEl |, y la desviación estándar de ruido σ cada uno se multiplica por la misma constante positiva, luego también la amplitud estimada El |XkEl |^ se multiplica por esa constante.
  2. Error mínimo medio de amplitud transformada transformada.
  3. Uniforme inadecuado antes de la amplitud transformada.

Usaremos notación normalizada:

(5)a=|Xk|σnormalized clean amplitude,m=|Yk|σnormalized noisy magnitude,1=(σσ)2normalized variance of noise,SNR=(|Xk|σ)2=a2signal-to-noise ratio (10log10(SNR) dB),

dónde |Xk| es la amplitud limpia que deseamos estimar a partir de la magnitud ruidosa |Yk| del valor bin Yk whicy es igual a la suma del valor del contenedor limpio Xk más ruido de varianza gaussiano complejo simétrico circularmente σ2. La escala invariante anterior de |Xk|dado en la ecuación. 4 se traslada a la notación normalizada como:

(6)PDF(a)aε1.

Dejar g(a) ser una función de transformación creciente de amplitud a. El uniforme incorrecto previo de amplitud transformada se denota por:

(7)PDF(g(a))1.

Eqs. 6 y 7 juntos determinan la familia de posibles transformaciones de amplitud. Están relacionados por un cambio de variables :

(8)sol(una)PDF(sol(una))=PDF(una)sol(una)unaε-1sol(una)unaε-1reuna=unaεε+Csol(una)=C1unaεε+C0 0.

Suponemos sin prueba que la elección de las constantes C0 0 y C1no afectará la estimación de amplitud. Por conveniencia establecemos:

(9)sol(1)=1ysol(1)=1C0 0=ε-1εyC1=1sol(una)=unaε+ε-1ε,

que tiene un caso lineal especial:

(10)sol(una)=unaSiε=1,

y un límite:

(11)limε0 0sol(una)=Iniciar sesión(una)+1)

La función de transformación puede representar convenientemente la escala de amplitud lineal (en ε=1) y puede acercarse a una escala de amplitud logarítmica (como ε0 0) Para positivoε, El soporte del PDF de amplitud transformada es:

(12)0 0<una<ε-1ε<sol(una)<,

La función de transformación inversa es:

(13)sol-1(sol(una))=(εsol(una)-ε+1)1/ /ε=una.

La estimación transformada es entonces, usando la ley del estadístico inconsciente :

(14)una^uni-MMSE-xform=unarsolmetroyonorteuna^mi[(sol(una)-sol(una^))2metro]=sol-1(mi[sol(una)metro])=sol-1(0 0sol(una)PDF(unametro)reuna)=sol-1(0 0sol(una)F(unametro)reuna0 0F(unametro)reuna),

dónde PDF(unasi) es el PDF posterior y F(unametro) es un PDF posterior no normalizado definido usando el teorema de Bayes (Ec. 1), el Rician PDF(metrouna)=2metromi-(metro2+una2)yo0 0(2metrouna)de la ecuación 3.2 de la respuesta de mi estimador de ML, y la ecuación. 6:

(15)PDF(unametro)PDF(metrouna)PDF(una)2metromi-(metro2+una2)yo0 0(2metrouna)×unaε-1mi-una2yo0 0(2metrouna)unaε-1=F(unametro),

a partir del cual PDF(metro) se eliminó de la fórmula de Bayes porque es constante durante una.Combinando Eqs. 14, 9 y 15, resolviendo las integrales en Mathematica y simplificando, da:

(dieciséis)una^uni-MMSE-xform=sol-1(0 0unaε+ε-1ε×mi-una2yo0 0(2metrouna)unaε-1reuna0 0mi-una2yo0 0(2metrouna)unaε-1reuna)=(ε12ε(Γ(ε)L-ε(metro2)+(ε-1)Γ(ε/ /2)L-ε/ /2(metro2))12Γ(ε/ /2)L-ε/ /2(metro2)-ε+1)1/ /ε=(Γ(ε)L-ε(metro2)+(ε-1)Γ(ε/ /2)L-ε/ /2(metro2)Γ(ε/ /2)L-ε/ /2(metro2)-ε+1)1/ /ε=(Γ(ε)L-ε(metro2)Γ(ε/ /2)L-ε/ /2(metro2))1/ /ε,

dónde Γes la función gamma yLes la función de Laguerre . El estimador colapsa a cero en todas partes a medida queε0 0, entonces no tiene sentido usar negativo ε, que enfatizaría pequeños valores de unaaún más y dar una distribución posterior inadecuada. Algunos casos especiales son:

(17)una^uni-MMSE-xform=metro2+1,Si ε=2,

(18)una^uni-MMSE=una^uni-MMSE-xform=mimetro2/ /2πyo0 0(metro2/ /2),Si ε=1,

aproximado en general metropor ( ver cálculo ) una serie truncada de Laurent:

(19)una^uni-MMSEmetro-14 4metro-7 732metro3-59128metro5 5,

Esta aproximación asintótica tiene un error de amplitud máxima absoluta de menos de 10-6 6 para metro>7.7.

Las curvas del estimador se muestran en la figura 1.

enter image description here
Figura 1. Estimador una^uni-MMSE-xform en función de metro para diferentes valores de ε, de arriba a abajo: azul: ε=2, que minimiza el error de potencia cuadrada media suponiendo un uniforme incorrecto antes de la potencia, naranja: ε=1, que minimiza el error de amplitud cuadrada media suponiendo un uniforme incorrecto antes de la amplitud, verde: ε=12, rojo: ε=14 4, y morado: ε=18.

A metro=0 0 las curvas son horizontales con valor:

(20)una^uni-MMSE-xform=21-1/ /ε(Γ(1+ε2))1/ /επ1/ /(2ε),Si metro=0.

En SNR negativo, el estimador uni-MMSE-xform se puede parametrizar usando baja ε para dar una suma menor de error cuadrado en comparación con el estimador de sustracción de potencia espectral sujeta, con una penalización correspondiente a valores intermedios de SNR cerca de 7 dB (Fig. 2).

enter image description here
enter image description here
enter image description here
Figura 2. Estimaciones de Monte Carlo con un tamaño de muestra de 105 5, de: Sólido: ganancia de la suma del error cuadrado en la estimación El |XkEl | por El |XkEl |^ en comparación con estimarlo con El |YkEl |, discontinuo: ganancia de la suma del error cuadrado en la estimación El |XkEl |2 por El |XkEl |2^ en comparación con estimarlo con El |YkEl |2, punteado: ganancia de la suma del error cuadrado en la estimación Xk por El |XkEl |^miyoarg(Yk) en comparación con estimarlo con Yk. Azul: estimador uni-MMSE-xform con ε=1 (parte superior), ε=12 (medio) y ε=14 4, naranja: sustracción de potencia espectral sujeta.

Script de Python para la Fig. 1

Este guión extiende el guión de la pregunta 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)

Script de Python para la Fig. 2

Este script extiende el script B de la pregunta. La función est_a_uni_MMSE_xform_fastpuede ser numéricamente inestable.

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])

Referencias

Lieve Lauwers, Kurt Barbe, Wendy Van Moer y Rik Pintelon, Analizando Rice, distribuyeron datos de resonancia magnética funcional: un enfoque bayesiano , Meas. Sci. Technol. 21 (2010) 115804 (12pp) DOI: 10.1088 / 0957-0233 / 21/11/115804 .


0

Estimadores mínimos de error de amplitud logarítmica cuadrática mínima

Esta respuesta presenta estimadores que minimizan el error medio de la amplitud logarítmica cuadrada, para una selección de antecedentes incorrectos de la amplitud limpia: uniforme y lineal.

Estimador de error de amplitud cuadrático medio mínimo previo uniforme incorrecto (uni-MMSE-log)

En la literatura, un nuevo desarrollo después de un estimador de amplitud MMSE ha sido un estimador de amplitud logarítmica MMSE, particularmente el estimador de (Ephraim y Malah 1985, gracias a @MattL. Por la referencia) que asume un Rician antes de la amplitud limpia. En un intento de mejorar el estimadoruna^uni-MMSE , aquí se derivará un estimador mínimo de error de amplitud logarítmica cuadrada mínima (uni-MMSE-log) para un uniforme incorrecto antes de la amplitud limpia.

Usando las variables normalizadas de mi respuesta "Mínimo invariante de escala mínimo medio cuadrado error estimadores anteriores uniformes de amplitud transformada" Ec. (5), el estimador uni-MMSE-log de la amplitud limpia es:

(1)una^uni-MMSE-log=unarsolmetroyonorteuna^mi[(Iniciar sesiónuna-Iniciar sesiónuna^)2metro]=Exp(mi[Iniciar sesiónunametro]).

Usando la ley del estadístico inconsciente , luego escribiendo la estimación en términos de un PDF no normalizadoF(unametro)=PDF(metrouna),y simplificando :

(2)a^uni-MMSE-log=exp(0log(a)PDF(am)da)=exp(0log(a)f(am)da0f(am)da)=exp(0log(a)PDF(ma)da0PDF(ma)da)=exp(0log(a)2me(m2+a2)I0(2ma)da02me(m2+a2)I0(2ma)da)=exp(2mem20log(a)ea2I0(2ma)damem2πem2/2I0(m2/2))=exp(20log(a)ea2I0(2ma)daπem2/2I0(m2/2))=exp(em2/2I0(m22)Ψ(12)+m2F201112(3/2;1;1,1/2;2,2;;3/2;m2,m2)2em2/2I0(m2/2))=exp(m2F201112(3/2;1;1,1/2;2,2;;3/2;m2,m2))2em2/2I0(m2/2)γ2log2),

where Ψ is the digamma function, γ is the Euler–Mascheroni constant, and F201112 is a Kampé de Fériet (-like) function. This special function form of the estimator can be evaluated in Python's mpmath (see script at the end of the answer). There is also a form using series that requires no special functions:

(3)=exp(L1/2(1,0)(m2)2em2/2I0(m2/2)+Ψ(12)2)=exp(k=0((1/2)km2k(1)kk!n=1k12n1)em2/2I0(m2/2)+Ψ(12)2)=exp(k=0((1/2)km2k(1)kk!n=1k12n1)k=0(1/2)km2k(1)kk!γ2log2),

where Ln(x) is Laguerre's L function and superscript (1,0) denotes differentiating it with respect to the subscript parameter, and (x)k is a Pochhammer symbol with special cases (1)k=k! and (1/2)k=(2k1)!!/2k. The numerator and denominator series can be truncated at tens of terms to obtain the estimator for low m. Better accuracy is obtained by approximating both series using the same length truncation, compared to using an exact special function for the other, or different length truncations. It is difficult to evaluate the series at large m because the largest terms appear around km2.

@user150203's original expression of the series related to the numerator integral gives another equivalent expression for the estimator:

(4)=exp(k=0m2kk!(k12k)Ψ(k+12)2em2/2I0(m2/2))=exp(k=0m2kk!(k12k)Ψ(k+12)2k=0m2kk!(k12k)),

where (ab) denotes a binomial coefficient.

The curve of the uni-MMSE-log estimator (Fig. 1, orange lower curve) is similar to that of the uni-MMSE estimator, but with a lower value at m=0:

(5)a^uni-MMSE-log=eγ20.374653,if m=0.

Improper linear prior minimum mean square log-amplitude error (lin-MMSE-log) estimator

A related estimator can be obtained if one takes the limit of the estimator of (Ephraim & Malah 1985) at infinite prior variance of the clean complex variable. Then, the Rayleigh prior probability density function of the clean amplitude becomes a linear ramp that is zero at zero magnitude and rises linearly with an infinitesimal slope. The resulting estimator (Fig. 1, blue upper curve) is:

(6)a^lin-MMSE-log=exp(12m2ettdt)m=exp(Ei(m2)2)m=exp(Γ(0,m2)2)m,
(7)limm0+a^lin-MMSE-log=eγ/20.749306,

where Ei(x) is the exponential integral, and Γ(0,x) is the upper incomplete gamma function.

enter image description here
Figure 1. Minimum mean square log-amplitude error estimators: blue, upper: a^lin-MMSE-log with an improper linear prior and orange, lower: a^uni-MMSE-log with an improper uniform prior. Estimated clean amplitude a^ as function of noisy magnitude m with unit-variance additive noise.

Python script for Fig. 1

This script extends the question's script A. The function est_a_uni_MMSE_log is numerically unstable at large m.

def est_a_uni_MMSE_log(m):
    m = mp.mpf(m)
    return mp.exp(m**2*mp.hyper2d({'m+n':[1.5], 'n':[1], 'm':[1, 0.5]}, {'m+n':[2, 2], 'm':[1.5]}, m**2, m**2)/(2*mp.exp(m**2/2)*mp.besseli(0, m**2/2))-mp.euler/2-mp.log(2))

def est_a_lin_MMSE_log(m):
    m = mp.mpf(m)
    if m == 0:
        return mp.exp(-mp.euler/2)
    else:
        return mp.exp(-mp.ei(-m**2)/2)*m

ms = np.arange(0, 6.0625, 0.0625)
est_as_MMSE_log = [[est_a_lin_MMSE_log(m) for m in ms], [est_a_uni_MMSE_log(m) for m in ms]];    
plot_est(ms, est_as_MMSE_log)

References

Y. Ephraim and D. Malah, Speech enhancement using a minimum mean-square error log-spectral amplitude estimator, IEEE Transactions on Acoustics Speech and Signal Processing, May 1985, DOI: 10.1109/TASSP.1985.1164550.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.