Stimatori per una migliore sottrazione spettrale del rumore


8

Il rumore bianco gaussiano a media zero reale, indipendente da un segnale pulito e di varianza nota viene aggiunto a producendo un segnale rumorosoTrasformata discreta di Fourier (DFT) del segnale rumoroso viene calcolata da:xxy.Y

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

Questo è solo per il contesto e definiremo la varianza del rumore nel dominio della frequenza, quindi la normalizzazione (o la sua mancanza) non è importante. Il rumore bianco gaussiano nel dominio del tempo è il rumore bianco gaussiano nel dominio della frequenza, vedi domanda: " Qual è la statistica della trasformata discreta di Fourier del rumore gaussiano bianco? ". Pertanto possiamo scrivere:

Yk=Xk+Zk,

dove e sono i DFT del segnale pulito e del rumore, e il del rumore che segue una distribuzione gaussiana complessa simmetrica circolare della varianza . Ciascuna parte reale e immaginaria di segue indipendentemente una distribuzione gaussiana della varianza . Definiamo il rapporto segnale-rumore (SNR) del bin come:XZZkσ2Zk12σ2Yk

SNR=σ2|Xk|2.

Un tentativo di ridurre il rumore viene quindi effettuato mediante sottrazione spettrale, per cui l'entità di ciascun contenitore viene ridotta indipendentemente mantenendo la fase originale (a meno che il valore del contenitore non vada a zero nella riduzione dell'ampiezza). La riduzione forma una stima del quadrato del valore assoluto di ogni bin del DFT del segnale pulito:Yk|Xk|2^|Xk|2

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

dove è la varianza nota del rumore in ciascun cestino DFT. Per semplicità, non stiamo prendendo in considerazione o per , che sono casi speciali per realeCon un SNR basso, la formulazione in (2) a volte potrebbe risultare inPossiamo rimuovere questo problema bloccando la stima a zero dal basso, ridefinendo:σ2k=0,k=N/2Nx.|Xk|2^.

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

inserisci qui la descrizione dell'immagine
Figura 1. Stime Monte Carlo con una dimensione del campione di di: Solido: guadagno della somma dell'errore quadrato nella stimadi rispetto alla stima con tratteggiato: guadagno della somma dell'errore quadrato nella stima di rispetto alla stima con punteggiato: guadagno della somma dell'errore quadrato nella stima di di rispetto alla stima conViene utilizzata la definizione di da (3).105,|Xk||Xk|^|Yk|,|Xk|2|Xk|2^|Yk|2,Xk|Xk|^eiarg(Yk)Yk.|Xk|2^

Domanda: esiste un'altra stima dio che migliora su (2) e (3) senza fare affidamento sulla distribuzione di ?|Xk||Xk|2Yk

Penso che il problema sia equivalente alla stima del quadrato del parametro di una distribuzione Rice (Fig. 2) con parametro noto data una singola osservazione.νRiceσRice=22σ,

inserisci qui la descrizione dell'immagine
Figura 2. La distribuzione del riso è la distribuzione della distanza dall'origine da un punto che segue una distribuzione normale simmetrica circolare bivariata con un valore assoluto della media varianza e varianza dei componentiRνRice,2σRice2=σ2σRice2=12σ2.

Ho trovato della letteratura che sembra rilevante:

  • Jan Sijbers, Arnold J. den Dekker, Paul Scheunders e Dirk Van Dyck, "Stima della massima verosimiglianza dei parametri di distribuzione Rician" , Transazioni IEEE sull'imaging medico (Volume: 17, Numero: 3, Giugno 1998) ( doi , pdf ).

Python script A per curve di stima

Questo script può essere esteso per tracciare curve di stima nelle risposte.

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

Script Python B per Fig. 1

Questo script può essere esteso per curve di guadagno di errore nelle risposte.

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
Accidenti, una domanda di chiarimento: "Questo è solo per il contesto, quindi la normalizzazione non è importante. Il rumore viene quindi ridotto dalla sottrazione spettrale, per cui l'entità di ciascun contenitore Yk viene ridotta in modo indipendente mantenendo la fase originale (a meno che il valore del contenitore non vada a zero nella riduzione dell'ampiezza). "Cosa ti dice che si tratta di un'operazione di riduzione del rumore? Se il rumore può andare in qualsiasi direzione, mi sembra che ciò amplifichi altrettanto facilmente qualsiasi rumore quanto lo è per attenuarlo.
Cedron Dawg,


2
@CedronDawg: se assumiamo l'indipendenza del segnale e del rumore, i loro poteri si sommeranno, quindi il segnale (potenza) si ottiene sottraendo la potenza del rumore stimata. Quindi, in termini di potenza, il rumore può andare solo in una direzione.
Matt L.

1
@OlliNiemitalo: conosci questo articolo fondamentale di Ephraim e Malah? Derivano uno stimatore ottimale per l'ampiezza del segnale, che è un miglioramento rispetto alla semplice sottrazione spettrale.
Matt L.

1
@OlliNiemitalo: si presume che i coefficienti DFT siano gaussiani (sia per il segnale desiderato che per il rumore), quindi le ampiezze hanno una distribuzione di Rayleigh. Cf. Eq (5) e (6) nel documento.
Matt L.

Risposte:


7

Stimatore di massima verosimiglianza (ML)

Qui verrà derivato uno stimatore della massima probabilità della potenza del segnale pulito, ma non sembra migliorare le cose in termini di errore quadratico medio radice, per qualsiasi SNR, rispetto alla sottrazione di potenza spettrale.

introduzione

Introduciamo l'ampiezza normalizzata pulita e normalizzato magnitudo rumoroso normalizzato per la deviazione standard di rumoreamσ:

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

Lo stimatore in Eq. 3 della domanda fornisce una stima di as:a^a

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

Stima della massima verosimiglianza

Per fare uno stimatore forse migliore di di Eq. 2, seguiamo la procedura di Sijbers et al. 1998. (vedi domanda) per costruire uno stimatore di massima verosimiglianza (ML)Fornisce il valore di che massimizza la probabilità del valore dato diaa^ML.am.

Il PDF diè riciano con il parametroe parametro (da sostituire in seguito per maggiore chiarezza)|Yk|νRice=|Xk|σRice=12σ:

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

dove è una funzione di Bessel modificata del primo tipo . Sostituzione eIα|Xk|=σa, |Yk|=σm,σRice2=12σ2:

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

e trasformando:

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

Il PDF riciano di parametrizzato da è indipendente dalla varianza del rumoreLo stimatore di massima verosimiglianza del parametro è il valore di che massimizza . È una soluzione di:maσ2.a^MLaaPDF(m)

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

La soluzione all'Eq. 4 ha la proprietà che:

(5)a^ML=0 if m1.

Altrimenti deve essere risolto numericamente.

enter image description here
Figura 1. blu, in alto: lo stimatore di massima probabilità e arancione, in basso: lo stimatore di sottrazione spettrale di potenza della domanda di ampiezza pulita normalizzata , in funzione della magnitudine rumorosa normalizzataa^MLa^am.

σa^ML è lo stimatore della massima verosimiglianza di e per invarianza funzionale della stima della massima verosimiglianza, è lo stimatore della verosimiglianza massima di|Xk|,σ2a^ML2|Xk|2.

Serie empirica di Laurent dello stimatore ML

Ho provato a calcolare numericamente (vedi lo script più avanti) la serie Laurent di ma non sembra convergere per l'intervallo di necessario. Ecco un troncamento della serie Laurent per quanto l'ho calcolato:a^ML2,m

(6)a^ML2m2121m0123m2325m41227m65729m8309211m101884213m1212864215m1498301217m16839919219m187999311221m20

Non sono riuscito a trovare le sequenze di numeri interi o denominatori nell'Enciclopedia in linea delle sequenze di numeri interi (OEIS). Solo per i primi cinque termini di potenza negativa, i coefficienti numeratori corrispondono a A027710 . Tuttavia, dopo aver inviato la sequenza calcolata ( ) a Superseeker OEIS , ho ottenuto questo nella risposta (da cui ho confermato i tre numeri suggeriti successivi con un calcolo esteso):1,1,1,3,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]

Guadagno approssimativo tabulato e errore di stima

Una tabella interpolata linearmente (vedere gli script seguenti) contenente campioni distribuiti in modo non uniforme di fornisce un'approssimazione con un errore massimo di circa124071a^ML2m26×1011.

Approssimazione dei minimi quadrati dello stimatore ML

È stata creata un'approssimazione dei minimi quadrati (con un peso extra a ) dei campioni della curva dello stimatore, in forma ispirata agli esperimenti della serie Laurent (vedere lo script di Octave più in basso). Il termine costante è stato modificato per rimuovere la possibilità di negativo at L'approssimazione è valida per e presenta un errore massimo di circa (Fig 3) in approssimazionem2=1- 0.5- 0.49999998237308493999a2m2=1.m212×105a^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

enter image description here
Figura 3. Errore dell'approssimazione dei minimi quadrati dia^ML2.

Lo script sembra in grado di gestire l'aumento del numero di potenze negative di fornendo costantemente errori sempre più piccoli, con il numero di errori estremi in aumento, ma con un decadimento dell'errore massimo piuttosto lento. L'approssimazione è quasi equiripple, ma trarrebbe comunque beneficio dall'affinamento dello scambio di Remez .m2,

Utilizzando l'approssimazione, sono state ottenute le seguenti curve di guadagno di errore previste:

enter image description here
Figura 2. Stime Monte Carlo con una dimensione del campione di di: Solido: guadagno della somma dell'errore quadrato nella stimadi rispetto alla stima con tratteggiato: guadagno della somma dell'errore quadrato nella stima di rispetto alla stima con punteggiato: guadagno della somma dell'errore quadrato nella stima di di rispetto alla stima conBlu: stimatore ML, arancione: sottrazione di potenza spettrale bloccata.105,|Xk||Xk|^|Yk|,|Xk|2|Xk|2^|Yk|2,Xk|Xk|^eiarg(Yk)Yk.

Sorprendentemente, lo stimatore ML è peggio della sottrazione di potenza spettrale bloccata in quasi tutti gli aspetti, tranne per essere leggermente migliore per la stima del segnale a SNR> circa 5 dB e la stima di ampiezza a SNR> circa 3 dB. A quei SNR, i due stimatori sono peggio del semplice uso del segnale rumoroso come stima.

Script Python A per Fig. 1

Questo script estende lo script della domanda 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 Python per il calcolo numerico della serie Laurent

Questo script calcola numericamente i primi termini della serie Laurent diSi basa sullo script in questa risposta .a^ML2m2.

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 Python per tabulazione dello stimatore ML

Questo script crea una tabella campionata in modo non uniforme delle coppie adatte per l'interpolazione lineare, fornendo approssimativamente l'errore di interpolazione lineare assoluta massima definita di approssimazione per l'intervalloLa dimensione della tabella viene automaticamente aumentata aggiungendo campioni alle parti difficili, fino a quando l'errore di picco è abbastanza piccolo. Se pari a più una potenza intera di poi tutti gli intervalli di campionamento sarà poteri di Al termine del tavolo ci sarà una transizione senza discontinuità ad una larga approssimazione[m2,a^ML2]a^ML2m=0mmax.mmax22,2.ma^ML2=m212.Se è necessario, la mia ipotesi è che sia meglio interpolare la tabella così com'è e quindi fare la conversionea^MLa^ML=a^ML2.

Per l'uso in combinazione con lo script successivo, convogliare l'output > 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('];')

Script Python B per Fig. 2

Questo script estende lo script della domanda 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 di ottava per i minimi quadrati

Questo script di Octave (un adattamento di questa risposta ) fa almeno un quadrato di poteri di in . Gli esempi sono stati preparati dallo script Python un po 'sopra.m2a^ML2(m212)

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}")

Script Python A2 per approssimazione usando polinomi di Chebyshev

Questo script estende lo script A e fornisce un'approssimazione alternativa dello stimatore ML usando i polinomi di Chebyshev. Il primo nodo di Chebyshev è a e il numero di polinomi di Chebyshev è tale che l'approssimazione non è negativa.m=1

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

Aggiornare:

Mi dispiace dover dire che i test mostrano che il seguente argomento sembra guastarsi sotto un forte rumore. Non è quello che mi aspettavo, quindi ho sicuramente imparato qualcosa di nuovo. I miei test precedenti erano stati tutti nella gamma SNR elevata poiché il mio obiettivo era quello di trovare soluzioni esatte nel caso silenzioso.


Olli,

Se il tuo obiettivo è trovare i parametri di un tono puro in un segnale rumoroso, avresti dovuto dirlo. Questo problema, ho molta esperienza e competenza in.

Dici che stai cercando l'ampiezza (e la fase ne deriva), quindi scommetto che stai allineando il tuo DFT per avere un numero intero di cicli. Questa è la peggior configurazione per questa situazione, dato che hai a che fare con il tuo segnale in un solo bin contro il rumore in quel singolo bin.

Come hai mostrato sopra, maggiore è il SNR, peggiore sarà il tuo trucco, al punto di essere dannoso o oltre. Bene, il tuo cestino di interesse sarà quello con il più alto SNR.

Quello che vuoi fare è allineare la cornice DFT su un intero più un mezzo ciclo. Questo diffonderà il tuo segnale su più bin possibili. Quindi puoi trovare la fase e l'ampiezza come descritto nel mio articolo di blog sull'argomento Calcolo di fase e ampiezza per un tono reale puro in un DFT: Metodo 1 .

In breve, trattate l'insieme di bidoni vicino al picco come uno spazio vettoriale complesso. Quindi conoscendo la frequenza, costruisci un insieme di vettori di base per il tuo segnale. I coefficienti dei vettori agiscono come un bidone virtuale che ti dirà l'ampiezza del segnale e la fase. Trovando il vettore che si adatta meglio tra più bin, la tecnica non consente al rumore in un dato bidone di essere troppo dominante e in qualche modo fornisce una "leva" su cui il rumore deve bilanciarsi. Gli effetti di riduzione del rumore sono simili a quando le variabili casuali vengono calcolate in media insieme.

Costruire i vettori di base significa prendere il DFT di un seno e un coseno alla tua frequenza. Ho una formula per il loro calcolo diretto che evita di dover fare una somma. L'articolo per questo è collegato dall'articolo sopra.

Sarei interessato a scoprire se la tua tecnica migliora i risultati di questo metodo. Sono abituato a lavorare con SNR superiori >> 1, quindi non ho mai testato realmente i livelli di rumore con cui hai a che fare.

Sinossi dell'approccio:

x[n]=acos(ωn)+bsin(ωn)+wgn[n]

Perché il DFT è un operatore lineare:

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

In notazione vettoriale:

Z=aA+bB+W

Siete semplicemente risolvendo per e usando l'algebra lineare standard per darvi una migliore vestibilità. Un vantaggio è che ottieni anche una stima di W. Pertanto, puoi provare un approccio "buttare il culo fuori", ed eliminare completamente il rumore stimato nel cestino peggiore e quindi ricalcolare. Risciacqua, ripeti. Oppure riduci il rumore in ogni cestino con un'altra formula. Se lo fai in modo proporzionale, i tuoi risultati rimarranno gli stessi di W ortogonale ad A e B. Ma una costante sottrazione lungo W, piuttosto che Z (come fa il tuo metodo) dovrebbe migliorare anche i risultati.ab

Normalmente, faccio i quattro bin attorno al picco, ma potresti voler estenderlo a 6 o addirittura 8. Ad un certo punto, più bin rende risultati peggiori poiché stai producendo più rumore del segnale.

Devi solo calcolare i bin di interesse DFT.


Penso che ci dovrebbe essere un'altra domanda in cui il tuo e altri metodi potrebbero essere confrontati.
Olli Niemitalo,

@OlliNiemitalo, facciamolo entrambi e pubblichiamo i risultati qui. Qual è un valore equo per il numero di campioni per ciclo? Del resto, quanti cicli per frame?
Cedron Dawg,

Non qui per favore, in un'altra domanda.
Olli Niemitalo,

@OlliNiemitalo, Ok, se insisti, ma non sarà davvero una domanda. Per curiosità, è questo un problema che stai cercando di risolvere davvero, o è più un esercizio accademico?
Cedron Dawg,

Penso che il risultato possa essere utile in senso generale, quindi mi interessa lavorarci su.
Olli Niemitalo,

2

Un'interessante soluzione approssimativa del problema di stima della massima verosimiglianza (ML) si ottiene usando la formula asintotica

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

Utilizzando la notazione e le formule della risposta di Olli , la stima ML ottimale dell'ampiezza del segnale pulito normalizzato soddisfa

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

Usando e notando che , otteniamo l'approssimazione(1)I1(x)=I0(x)

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

Questa approssimazione ha un errore relativo inferiore % per .1x>4.5

Inserendo in ottiene la soluzione approssimativa(3)(2)

(4)a^12(m+m21)

Con e otteniamom=|Yk|/σa=|Xk|/σ

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

che è semplicemente la media aritmetica dell'osservazione rumorosae la stima ottenuta dalla sottrazione di potenza spettrale.|Yk|


MODIFICARE:

Sarebbe bello avere un'approssimazione come che funzioni su tutto l'intervallo . Un candidato per tale approssimazione è la famiglia di funzioni(3)x[0,)

(6)f(x)=xc1+c2x2

La scelta teoricamente corretta delle costanti è e , considerando le proprietà di attorno a e . Tuttavia, per un intervallo realistico di , è possibile ottenere una migliore approssimazione in quell'intervallo modificando un po 'quelle costanti.c1=4c2=1f(x)x=0xx

Utilizzando l'approssimazione con e ottiene la seguente stima:(6)c1=4c2=1

(7)a^=m11m4

o, equivalentemente,

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


Modifica di Olli:

enter image description here
Figura 1. (arancione) e le sue approssimazioni definite dall'Eq. 4 (blu) ed Eq. 7 (verde), in funzione diTutte le curve si avvicinano come (vedere la figura a destra per la grande ). avvicina asintoticamente alla sua serie troncata di Laurent come che dà il risultato curioso che nonostante le approssimazioni di avvicina asintoticamente come , il quadrato dell'Eq. 7 presenta un errore costante nell'approssimazione di comea^MLm.a=mmma^ML2m212m,a^MLma^ML2mperché il termine costante 0 della sua serie Laurent differisce da della serie Laurent di (vedi la risposta dello stimatore ML di Olli) e la serie Laurent del quadrato di Eq. 4. Questo errore costante scompare nella stima di causa del fatto che12a^ML2ca^MLlimm(m2+cm)=0.

Script Python per Fig. 1

Questo script richiede lo script della domanda per l'importazione dei moduli e per la funzione di stampa plot_este la definizione della funzione est_a_MLdalla risposta ML di 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: ho adattato le mie formule di conseguenza.
Matt L.

2

Stima precedente uniforme impropria errata di scala quadrata media invariante (MMSE) impropria di ampiezza trasformata

Questa risposta presenta uno stimatore invariante su scala familiare, parametrizzato da un singolo parametro che controlla sia la precedente distribuzione bayesiana dell'ampiezza sia la trasformazione dell'ampiezza in un'altra scala. Gli stimatori sono stimatori dell'errore quadrato medio minimo (MMSE) nella scala di ampiezza trasformata. Si presuppone un'uniforme uniforme impropria di ampiezza trasformata. Le trasformazioni disponibili includono una scala lineare (nessuna trasformazione) e possono avvicinarsi a una scala logaritmica per cui lo stimatore si avvicina allo zero ovunque. Gli stimatori possono essere parametrizzati per ottenere una bassa somma di errori quadrati con rapporti segnale-rumore negativi (SNR).

Stima bayesiana

Lo stimatore della massima verosimiglianza (ML) nella mia prima risposta ha funzionato piuttosto male. Lo stimatore ML può anche essere inteso come uno stimatore bayesiano massimo a posteriori (MAP) data una distribuzione di probabilità precedente uniforme impropria. Qui, improprio significa che il precedente si estende da zero a infinito con densità infinitesimale. Poiché la densità non è un numero reale, il precedente non è una distribuzione corretta, ma può comunque fornire una corretta distribuzione posteriore mediante il teorema di Bayes che può quindi essere utilizzato per ottenere una stima MAP o MMSE.

Il teorema di They Bayes in termini di funzioni di densità di probabilità (PDF) è:

(1)PDF(am)=PDF(ma)PDF(a)PDF(m)=PDF(ma)PDF(a)0PDF(ma)PDF(a)da.

Uno stimatore MAP a^MAP è l'argomento del PDF posteriore che lo massimizza:

(2)a^MAP=argmaxaPDF(am).

Uno stimatore MMSE a^MMSE è la media posteriore:

(3)a^MMSE=argmaxa^E[(aa^)2m]=E[am]=0aPDF(am)da.

Un priore uniforme improprio non è l'unico precedente invariante alla scala. Qualsiasi PDF precedente soddisfacente:

(4)PDF(|Xk|)|Xk|ε1,

con vero esponente ε1, e significato: "è proporzionale a", è invariante alla scala nel senso che il prodotto di Xke una costante positiva segue ancora la stessa distribuzione (vedi Lauwers et al. 2010 ).

Una famiglia di stimatori

Deve essere presentata una famiglia di stimatori, con queste proprietà:

  1. Invarianza di scala: se il contenitore pulito complessoXk, o equivalentemente l'ampiezza pulita |Xk|, e la deviazione standard del rumore σ sono moltiplicati per la stessa costante positiva, quindi anche per l'ampiezza stimata |Xk|^ viene moltiplicato per quella costante.
  2. Errore di ampiezza trasformata quadrata media minima.
  3. Priore uniforme improprio di ampiezza trasformata.

Useremo la notazione normalizzata:

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

dove |Xk| è l'ampiezza pulita che desideriamo stimare dalla grandezza rumorosa |Yk| di valore bin Yk whicy è uguale alla somma del valore del cestino pulito Xk più rumore di varianza gaussiana complesso a simmetria circolare σ2. Il precedente invariante di scala di |Xk|dato in Eq. 4 viene riportato alla notazione normalizzata come:

(6)PDF(a)aε1.

Permettere g(a) essere una crescente funzione di trasformazione dell'ampiezza a. Il priore uniforme improprio dell'ampiezza trasformata è indicato da:

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

Eq. 6 e 7 determinano insieme la famiglia delle possibili trasformazioni di ampiezza. Sono correlati da un cambiamento di variabili :

(8)g(a)PDF(g(a))=PDF(a)g(a)aε1g(a)aε1da=aεε+cg(a)=c1aεε+c0.

Assumiamo senza prove che la scelta delle costanti c0 e c1non influirà sulla stima dell'ampiezza. Per comodità impostiamo:

(9)g(1)=1andg(1)=1c0=ε1εandc1=1g(a)=aε+ε1ε,

che ha un caso lineare speciale:

(10)g(a)=aifε=1,

e un limite:

(11)limε0g(a)=log(a)+1.

La funzione di trasformazione può rappresentare convenientemente la scala dell'ampiezza lineare (a ε=1) e può avvicinarsi a una scala di ampiezza logaritmica (come ε0). Per positivoε, il supporto del PDF di ampiezza trasformata è:

(12)0<a<ε1ε<g(a)<,

La funzione di trasformazione inversa è:

(13)g1(g(a))=(εg(a)ε+1)1/ε=a.

La stima trasformata è quindi, usando la legge dello statistico inconscio :

(14)a^uni-MMSE-xform=argmina^E[(g(a)g(a^))2m]=g1(E[g(a)m])=g1(0g(a)PDF(am)da)=g1(0g(a)f(am)da0f(am)da),

dove PDF(ab) è il PDF posteriore e f(am) è un PDF posteriore non normalizzato definito usando il teorema di Bayes (Eq. 1), il Riciano PDF(ma)=2me(m2+a2)I0(2ma)dall'eq. 3.2 della mia risposta dello stimatore ML ed Eq. 6:

(15)PDF(am)PDF(ma)PDF(a)2me(m2+a2)I0(2ma)×aε1ea2I0(2ma)aε1=f(am),

da cui PDF(m) è stato abbandonato dalla formula di Bayes perché è costante a.Combinazione di Eq. 14, 9 e 15, risolvendo gli integrali in Mathematica e semplificando, dà:

(16)a^uni-MMSE-xform=g1(0aε+ε1ε×ea2I0(2ma)aε1da0ea2I0(2ma)aε1da)=(ε12ε(Γ(ε)Lε(m2)+(ε1)Γ(ε/2)Lε/2(m2))12Γ(ε/2)Lε/2(m2)ε+1)1/ε=(Γ(ε)Lε(m2)+(ε1)Γ(ε/2)Lε/2(m2)Γ(ε/2)Lε/2(m2)ε+1)1/ε=(Γ(ε)Lε(m2)Γ(ε/2)Lε/2(m2))1/ε,

where Γ is the gamma function and L is the Laguerre function. The estimator collapses to zero everywhere as ε0, so it does not make sense to use negative ε, which would emphasis small values of a even further and give an improper posterior distribution. Some special cases are:

(17)a^uni-MMSE-xform=m2+1,if ε=2,

(18)a^uni-MMSE=a^uni-MMSE-xform=em2/2πI0(m2/2),if ε=1,

approximated at large m by (see calculation) a truncated Laurent series:

(19)a^uni-MMSEm14m732m359128m5,

This asymptotic approximation has an absolute maximum amplitude error of less than 106 for m>7.7.

The estimator curves are shown in Fig. 1.

enter image description here
Figure 1. Estimator a^uni-MMSE-xform as function of m for different values of ε, from top to bottom: blue: ε=2, which minimizes the mean square power error assuming an improper uniform prior of power, orange: ε=1, which minimizes the mean square amplitude error assuming an improper uniform prior of amplitude, green: ε=12, red: ε=14, and purple: ε=18.

At m=0 the curves are horizontal with value:

(20)a^uni-MMSE-xform=211/ε(Γ(1+ε2))1/επ1/(2ε),if m=0.

At negative SNR, the uni-MMSE-xform estimator can be parameterized using low ε to give a lower sum of square error compared to the clamped spectral power subtraction estimator, with a corresponding penalty at intermediate SNR values near 7 dB (Fig. 2).

enter image description here
enter image description here
enter image description here
Figure 2. Monte Carlo estimations with a sample size of 105, of: Solid: gain of sum of square error in estimating |Xk| by |Xk|^ as compared to estimating it with |Yk|, dashed: gain of sum of square error in estimating |Xk|2 by |Xk|2^ as compared to estimating it with |Yk|2, dotted: gain of sum of square error in estimating Xk by |Xk|^eiarg(Yk) as compared to estimating it with Yk. Blue: uni-MMSE-xform estimator with ε=1 (top), ε=12 (middle), and ε=14, orange: clamped spectral power subtraction.

Python script for Fig. 1

This script extends the question's script 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)

Python script for Fig. 2

This script extends the question's script B. The function est_a_uni_MMSE_xform_fast may be numerically unstable.

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

References

Lieve Lauwers, Kurt Barbe, Wendy Van Moer and Rik Pintelon, Analyzing Rice distributed functional magnetic resonance imaging data: A Bayesian approach, Meas. Sci. Technol. 21 (2010) 115804 (12pp) DOI: 10.1088/0957-0233/21/11/115804.


0

Minimum mean square log-amplitude error estimators of amplitude

This answer presents estimators that minimize the mean square log-amplitude error, for a selection of improper priors of the clean amplitude: uniform and linear.

Improper uniform prior minimum mean square log-amplitude error (uni-MMSE-log) estimator

In literature, a next development after a MMSE amplitude estimator has been a MMSE log-amplitude estimator, particularly the estimator of (Ephraim & Malah 1985, thanks to @MattL. for the reference) which assumes a Rician prior of the clean amplitude. In an attempt to improve upon the estimator a^uni-MMSE , here will be derived a minimum mean square log-amplitude error (uni-MMSE-log) estimator for an improper uniform prior of the clean amplitude.

Using the normalized variables of my answer "Scale-invariant minimum mean square error uniform prior estimators of transformed amplitude" Eq. (5), the uni-MMSE-log estimator of the clean amplitude is:

(1)a^uni-MMSE-log=argmina^E[(logaloga^)2m]=exp(E[logam]).

Using the law of the unconscious statistician, then writing the estimate in terms of an unnormalized PDF f(am)=PDF(ma), and simplifying:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.