Estimateurs pour une meilleure soustraction spectrale du bruit


8

Bruit blanc gaussien à moyenne nulle, indépendant d'un signal propre x et de variance connue est ajoutée à x produire un signal bruyant y. Transformée de Fourier discrète (DFT) Y du signal bruyant est calculé par:

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

C'est juste pour le contexte, et nous définirons la variance du bruit dans le domaine fréquentiel, donc la normalisation (ou son absence) n'est pas importante. Le bruit blanc gaussien dans le domaine temporel est du bruit blanc gaussien dans le domaine fréquentiel, voir la question: " Quelles sont les statistiques de la transformée de Fourier discrète du bruit blanc gaussien? ". On peut donc écrire:

Yk=Xk+Zk,

X et Z sont les DFT du signal propre et du bruit, et Zk le bruit bin qui suit une distribution gaussienne complexe de symétrie circulaire σ2. Chacun de la partie réelle et imaginaire deZk suit indépendamment une distribution de variance gaussienne 12σ2. Nous définissons le rapport signal / bruit (SNR) de binYk comme:

SNR=σ2|Xk|2.

Une tentative de réduction du bruit est ensuite effectuée par soustraction spectrale, moyennant quoi l'amplitude de chaque bac Ykest indépendamment réduit tout en conservant la phase d'origine (à moins que la valeur de la corbeille ne passe à zéro dans la réduction d'amplitude). La réduction constitue une estimation|Xk|2^ du carré |Xk|2 de la valeur absolue de chaque bin de la DFT du signal propre:

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

σ2est la variance connue du bruit dans chaque bac DFT. Pour simplifier, nous n'envisageons pask=0, ou k=N/2 même pour N, qui sont des cas particuliers pour de x. À un SNR faible, la formulation en (2) pourrait parfois entraîner des |Xk|2^. Nous pouvons supprimer ce problème en fixant l'estimation à zéro par le bas, en redéfinissant:

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

entrez la description de l'image ici
Figure 1. Estimations de Monte Carlo avec un échantillon de de: Solide: gain de la somme des erreurs carrées dans l'estimation depar par rapport à son estimation avec pointillés: gain de somme d'erreur quadratique dans l'estimation de par par rapport à son estimation avec pointillé: gain de la somme de l'erreur carrée dans l'estimation de par par rapport à son estimation avecLa définition de de (3) est utilisée.105,|Xk||Xk|^|Yk|,|Xk|2|Xk|2^|Yk|2,Xk|Xk|^eiarg(Yk)Yk.|Xk|2^

Question: Y a - t-il une autre estimation deou qui s'améliore sur (2) et (3) sans compter sur la distribution de ?|Xk||Xk|2Yk

Je pense que le problème équivaut à estimer le carré du paramètre d'une distribution de Rice (Fig. 2) avec le paramètre connu étant donné une seule observation.νRiceσRice=22σ,

entrez la description de l'image ici
Figure 2. La distribution du riz est la distribution de la distance à l'origine à partir d'un point qui suit une distribution normale symétrique circulaire bivariée avec une valeur absolue de la moyenne variance et variance des composantsRνRice,2σRice2=σ2σRice2=12σ2.

J'ai trouvé de la littérature qui semble pertinente:

  • Jan Sijbers, Arnold J. den Dekker, Paul Scheunders et Dirk Van Dyck, "Maximum Likelihood estimation of Rician distribution parameters" , IEEE Transactions on Medical Imaging (Volume: 17, Issue: 3, June 1998) ( doi , pdf ).

Script Python A pour les courbes d'estimateur

Ce script peut être étendu pour tracer des courbes d'estimateur dans les réponses.

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 pour la figure 1

Ce script peut être étendu pour les courbes de gain d'erreur dans les réponses.

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, une question de clarification: "Ceci est juste pour le contexte, donc la normalisation n'est pas importante. Le bruit est ensuite réduit par soustraction spectrale, grâce à quoi l'amplitude de chaque bin Yk est indépendamment réduite tout en conservant la phase d'origine (à moins que la valeur du bin ne disparaisse à zéro dans la réduction de magnitude). "Qu'est-ce qui vous fait dire qu'il s'agit d'une opération de réduction du bruit? Si le bruit peut aller dans n'importe quelle direction, il me semble que cela amplifiera tout aussi probablement le bruit qu'il l'est pour l'atténuer.
Cedron Dawg


2
@CedronDawg: Si nous supposons l'indépendance du signal et du bruit, leurs puissances s'ajouteront, de sorte que le signal (puissance) est obtenu en soustrayant la puissance de bruit estimée. Donc en termes de puissance, le bruit ne peut aller que dans une seule direction.
Matt L.

1
@OlliNiemitalo: Connaissez-vous cet article fondamental d'Ephraim et Malah? Ils dérivent un estimateur optimal pour l'amplitude du signal, ce qui est une amélioration par rapport à la simple soustraction spectrale.
Matt L.

1
@OlliNiemitalo: Les coefficients DFT sont supposés être gaussiens (pour le signal souhaité ainsi que pour le bruit), donc les amplitudes ont une distribution de Rayleigh. Cf. Eqs (5) et (6) dans le papier.
Matt L.

Réponses:


7

Estimateur du maximum de vraisemblance (ML)

Ici sera dérivé un estimateur à maximum de vraisemblance de la puissance du signal propre, mais il ne semble pas améliorer les choses en termes d'erreur quadratique moyenne, pour tout SNR, par rapport à la soustraction de puissance spectrale.

introduction

Introduisons l'amplitude propre normalisée et l' amplitude de bruit normalisé normalisé par l'écart - type bruitamσ:

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

L'estimateur de l'équation. 3 de la question donne une estimation d' comme:a^a

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

Estimateur du maximum de vraisemblance

Pour faire un estimateur éventuellement meilleur de que Eq. 2, nous suivons la procédure de Sijbers et al. 1998. (voir question) pour construire un estimateur à maximum de vraisemblance (ML)Il donne la valeur de qui maximise la probabilité de la valeur donnée deaa^ML.am.

Le PDF deest ricain avec le paramètreet paramètre (à remplacer plus tard pour plus de clarté)|Yk|νRice=|Xk|σRice=12σ:

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

où est une fonction de Bessel modifiée du premier type . Substitution etIα|Xk|=σa, |Yk|=σm,σRjece2=12σ2:

(3.1)=PF(σm)=2mσe-(m2+une2)je0(2mune),

et transformer:

(3.2)PF(m)=σPF(σm)=2me-(m2+une2)je0(2mune).

Le PDF ricain de paramétré par est indépendant de la variance du bruitL'estimateur du maximum de vraisemblance du paramètre est la valeur de qui maximise . C'est une solution de:muneσ2.a^MLaaPDF(m)

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

La solution à l'Eq. 4 a la propriété:

(5)a^ML=0 if m1.

Sinon, il doit être résolu numériquement.

entrez la description de l'image ici
Figure 1. bleu, en haut: l'estimateur du maximum de vraisemblance et orange, en bas: l'estimateur de soustraction spectrale de puissance de la question d'amplitude propre normalisée , en fonction de l'amplitude bruyante normaliséea^MLa^am.

σa^ML est l'estimateur du maximum de vraisemblance de et par invariance fonctionnelle de l' estimation du maximum de vraisemblance, est l'estimateur du maximum de vraisemblance de|Xk|,σ2a^ML2|Xk|2.

Série empirique Laurent de l'estimateur ML

J'ai essayé de calculer numériquement (voir script plus loin) la série Laurent de mais elle ne semble pas converger pour la plage de nécessaire. Voici une troncature de la série Laurent pour autant que je l'ai calculée:a^ML2,m

(6)a^ML2m2121m0123m2325m41227m65729m8309211m101884213m1212864215m1498301217m16839919219m187999311221m20

Je n'ai pas pu trouver les séquences entières de numérateur ou de dénominateur dans l'Encyclopédie en ligne des séquences entières (OEIS). Uniquement pour les cinq premiers termes de puissance négative, les coefficients du numérateur correspondent à A027710 . Cependant, après avoir soumis la séquence calculée ( ) à OEIS Superseeker , je l'ai obtenu dans la réponse (à partir de laquelle j'ai confirmé les trois prochains numéros suggérés par un calcul étendu):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]

Approximation tabulée et gain d'erreur d'estimation

Un tableau interpolé linéairement (voir les scripts ci-dessous) contenant non uniformément répartis de donne une approximation avec une erreur maximale d'environ124071a^ML2m26×1011.

Approximation par moindres carrés de l'estimateur ML

Une approximation des moindres carrés (avec un poids supplémentaire à ) des échantillons de la courbe de l'estimateur a été créée, sous une forme inspirée des expériences de la série Laurent (voir le script Octave plus bas). Le terme constant a été modifié pour supprimer la possibilité d' négatif à L'approximation est valable pour et a une erreur maximale d'environ (Fig . 3) en approximantm2=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

entrez la description de l'image ici
Figure 3. Erreur de l'approximation des moindres carrés dea^ML2.

Le script semble capable de gérer l'augmentation du nombre de puissances négatives de donne constamment des erreurs de plus en plus petites, avec un nombre d'extrema d'erreur croissant, mais avec une décroissance d'erreur maximale assez lente. L'approximation est presque équiripple, mais bénéficierait encore un peu du raffinement de l' échange Remez .m2,

En utilisant l'approximation, les courbes de gain d'erreur attendues suivantes ont été obtenues:

entrez la description de l'image ici
Figure 2. Estimations de Monte Carlo avec un échantillon de de: Solide: gain de la somme de l'erreur carrée dans l'estimation depar par rapport à son estimation avec pointillés: gain de somme d'erreur quadratique dans l'estimation de par par rapport à son estimation avec pointillé: gain de la somme de l'erreur carrée dans l'estimation de par par rapport à son estimation avecBleu: estimateur ML, orange: soustraction de puissance spectrale bloquée.105,|Xk||Xk|^|Yk|,|Xk|2|Xk|2^|Yk|2,Xk|Xk|^eiarg(Yk)Yk.

Étonnamment, l'estimateur ML est pire que la soustraction de puissance spectrale bloquée dans presque tous les aspects, sauf qu'il est légèrement meilleur pour l'estimation du signal à SNR> environ 5 dB et l'estimation de l'amplitude à SNR> environ 3 dB. À ces SNR, les deux estimateurs sont pires que de simplement utiliser le signal bruyant comme estimation.

Script Python A pour Fig.1

Ce script prolonge le script de la question 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 pour le calcul numérique de la série Laurent

Ce script calcule numériquement les premiers termes de la série Laurent deIl est basé sur le script de cette réponse .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 pour la tabulation de l'estimateur ML

Ce script crée une table échantillonnée de manière inégale de paires adaptées à l'interpolation linéaire, donnant approximativement l'erreur d'interpolation linéaire absolue maximale définie d'approximation pour la plageLa taille du tableau est automatiquement augmentée en ajoutant des échantillons aux parties difficiles, jusqu'à ce que l'erreur de crête soit suffisamment petite. Si est égal à plus une puissance entière de alors tous les intervalles d'échantillonnage seront des puissances de À la fin du tableau, il y aura une transition sans discontinuité vers une approximation grande[m2,a^ML2]a^ML2m=0mmax.mmax22,2.ma^ML2=m212.Si est nécessaire, je suppose qu'il vaut mieux interpoler la table telle quelle, puis faire la conversiona^MLa^ML=a^ML2.

Pour une utilisation en conjonction avec le script suivant, canalisez la sortie > 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 pour la figure 2

Ce script étend le script B. de la question

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 d'octave pour les moindres carrés

Ce script Octave (une adaptation de cette réponse ) fait un ajustement des moindres carrés des puissances de dans . Les exemples ont été préparés par le script Python un peu plus haut.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 pour l'approximation à l'aide des polynômes de Chebyshev

Ce script étend le script A et donne une approximation alternative de l'estimateur ML à l'aide des polynômes de Chebyshev. Le premier nœud de Chebyshev est à et le nombre de polynômes de Chebyshev est tel que l'approximation est non négative.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

Mise à jour:

Je suis désolé de devoir dire que les tests montrent que l'argument suivant semble s'effondrer sous un bruit intense. Ce n'est pas ce à quoi je m'attendais, j'ai donc définitivement appris quelque chose de nouveau. Mes tests antérieurs étaient tous dans la gamme SNR élevée car mon objectif était de trouver des solutions exactes dans le cas silencieux.


Olli,

Si votre objectif est de trouver les paramètres d'une tonalité pure dans un signal bruyant, vous auriez dû le dire. Cette question, j'ai beaucoup d'expérience et d'expertise dans.

Vous dites que vous recherchez l'amplitude (et la phase l'accompagne), donc je parie que vous alignez votre DFT pour avoir un nombre entier de cycles. Il s'agit de la pire configuration pour cette situation car vous traitez alors votre signal dans un seul bac contre le bruit dans ce bac unique.

Comme vous l'avez montré ci-dessus, plus le SNR est élevé, plus votre astuce est mauvaise, au point de nuire ou au-delà. Eh bien, votre bac d'intérêt sera celui avec le SNR le plus élevé.

Ce que vous voulez faire, c'est aligner votre cadre DFT sur un ensemble plus un demi-cycle. Cela répartira votre signal sur autant de cases que possible. Ensuite, vous pouvez trouver la phase et l'amplitude comme décrit dans mon article de blog sur le thème Calcul de phase et d'amplitude pour un ton réel pur dans un DFT: Méthode 1 .

En bref, vous traitez l'ensemble de casiers près du pic comme un espace vectoriel complexe. Connaissant ensuite la fréquence, vous construisez un ensemble de vecteurs de base pour votre signal. Les coefficients des vecteurs agissent comme un bac virtuel qui vous indiquera l'amplitude du signal ainsi que la phase. En trouvant le meilleur vecteur d'ajustement sur plusieurs cases, la technique ne permet pas au bruit dans une case donnée d'être trop dominant et fournit en quelque sorte un "levier" que le bruit doit équilibrer. Les effets de réduction du bruit sont similaires à la moyenne des variables aléatoires.

Construire les vecteurs de base signifie prendre la DFT d'un sinus et d'un cosinus à votre fréquence. J'ai une formule pour leur calcul direct qui évite d'avoir à faire une sommation. L'article correspondant est lié à l'article ci-dessus.

J'aimerais savoir si votre technique améliore les résultats de cette méthode. Je suis habitué à travailler dans un SNR supérieur >> 1, donc je n'ai jamais vraiment testé les niveaux de bruit auxquels vous avez affaire.

Synopsis de l'approche:

X[n]=unecos(ωn)+bpéché(ωn)+wgn[n]

Parce que la DFT est un opérateur linéaire:

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

En notation vectorielle:

Z=aA+bB+W

Vous résolvez simplement pour et utilisant l'algèbre linéaire standard pour vous donner un meilleur ajustement. Un bonus est que vous obtenez également une estimation de W. Par conséquent, vous pouvez essayer une approche «jeter le clochard» et éliminer complètement le bruit estimé dans le bac le plus mal ajusté, puis recalculer. Rincez, répétez. Ou réduisez le bruit dans chaque bac par une autre formule. Si vous le faites proportionnellement, vos résultats resteront les mêmes car W est orthogonal à A et B. Mais une soustraction constante le long de W, plutôt que de Z (comme le fait votre méthode) devrait également améliorer les résultats.ab

Normalement, je fais les quatre bacs autour du pic, mais vous voudrez peut-être étendre cela à 6 ou même 8. À un moment donné, plus de bacs donnent de mauvais résultats car vous apportez plus de bruit que de signal.

Vous n'avez qu'à calculer les bacs DFT d'intérêt.


Je pense qu'il devrait y avoir une autre question où la vôtre et d'autres méthodes pourraient être comparées.
Olli Niemitalo

@OlliNiemitalo, Faisons-le tous les deux et publions les résultats ici. Quelle est la juste valeur du nombre d'échantillons par cycle? D'ailleurs, combien de cycles par image?
Cedron Dawg

Pas ici s'il vous plaît, dans une autre question.
Olli Niemitalo

@OlliNiemitalo, D'accord, si vous insistez, mais ce ne sera pas vraiment une question. Par curiosité, est-ce un problème que vous essayez de résoudre pour de vrai, ou s'agit-il plutôt d'un exercice académique?
Cedron Dawg

Je pense que le résultat pourrait être utile dans un sens général, donc cela m'intéresse de travailler dessus.
Olli Niemitalo

2

Une solution approximative intéressante du problème d'estimation du maximum de vraisemblance (ML) est obtenue en utilisant la formule asymptotique

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

En utilisant la notation et les formules de la réponse d' Olli , l'estimation ML optimale de l'amplitude du signal propre normalisé satisfait

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

En utilisant (1) et notant que I1(x)=I0(x), on obtient l'approximation

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

Cette approximation a une erreur relative inférieure à 1% pour x>4.5.

Bouchage (3) dans (2) donne la solution approximative

(4)a^12(m+m21)

Avec m=|Yk|/σ et a=|Xk|/σ on obtient

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

qui est simplement la moyenne arithmétique de l'observation bruyante |Yk| et l'estimation obtenue à partir de la soustraction de puissance spectrale.


ÉDITER:

Je serais bien d'avoir une approximation comme (3) qui fonctionne sur toute la gamme x[0,). Un candidat pour une telle approximation est la famille de fonctions

(6)f(x)=xc1+c2x2

Le choix théoriquement correct des constantes est c1=4 et c2=1, compte tenu des propriétés de f(x) environ x=0 et x. Cependant, pour une gamme réaliste dex, une meilleure approximation dans cette plage pourrait être obtenue en ajustant un peu ces constantes.

Utilisation de l'approximation (6) avec c1=4 et c2=1 donne l’estimation suivante:

(7)a^=m11m4

ou équivalent,

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


Le montage d'Olli:

entrez la description de l'image ici
Figure 1. a^ML(orange) et ses approximations définies par l'équation. 4 (bleu) et Eq. 7 (vert), en fonction dem. Approche toutes courbes a=m comme m (voir la figure de droite pour les grands m). a^ML2 s'approche asymptotiquement de sa série Laurent tronquée m212 comme m, ce qui donne le résultat curieux que même si les approximations de a^ML approcher asymptotiquement comme m, le carré de l'équ. 7 a une erreur constante d'approximationa^ML2 comme mparce que le terme constant 0 de sa série Laurent diffère de12 de la série Laurent de a^ML2(voir la réponse de l'estimateur ML d'Olli) et la série Laurent du carré de l'équation. 4. Cette erreur constantec disparaît dans l'estimation de a^ML à cause du fait que limm(m2+cm)=0.

Script Python pour la figure 1

Ce script nécessite le script de la question pour les importations de modules et pour la fonction de traçage plot_est, ainsi que la définition de fonction de est_a_MLla réponse ML d'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: J'ai adapté mes formules en conséquence.
Matt L.

2

Estimateurs antérieurs uniformes incorrects de l'erreur quadratique moyenne minimale (MMSE) invariants d'échelle

Cette réponse présente une famille d'estimateurs invariants à l'échelle, paramétrisés par un seul paramètre qui contrôle à la fois la distribution bayésienne antérieure de l'amplitude et la transformation de l'amplitude à une autre échelle. Les estimateurs sont des estimateurs d' erreur quadratique moyenne minimale (MMSE) dans l'échelle d'amplitude transformée. On suppose un avant uniforme incorrect d'amplitude transformée. Les transformations disponibles incluent une échelle linéaire (pas de transformation) et peuvent approcher une échelle logarithmique selon laquelle l'estimateur approche zéro partout. Les estimateurs peuvent être paramétrés pour atteindre une faible somme d'erreur quadratique à des rapports signal / bruit négatifs (SNR).

Estimation bayésienne

L'estimateur du maximum de vraisemblance (ML) dans ma première réponse s'est plutôt mal comporté. L'estimateur ML peut également être compris comme un estimateur bayésien du maximum a posteriori (MAP) étant donné une distribution de probabilité antérieure uniforme incorrecte. Ici, impropre signifie que le prieur s'étend de zéro à l'infini avec une densité infinitésimale. Parce que la densité n'est pas un nombre réel, l'a priori n'est pas une distribution correcte, mais il peut quand même donner une distribution postérieure appropriée par le théorème de Bayes qui peut ensuite être utilisée pour obtenir une MAP ou une estimation MMSE.

Le théorème de Bayes en termes de fonctions de densité de probabilité (PDF) est:

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

Un estimateur MAP a^MAP est l'argument du PDF postérieur qui le maximise:

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

Un estimateur MMSE a^MMSE est la moyenne postérieure:

(3)une^MMSE=unergmuneXune^E[(une-une^)2m]=E[unem]=0unePDF(unem)une.

Un a priori uniforme incorrect n'est pas le seul a priori invariant d'échelle. Tout PDF antérieur satisfaisant:

(4)PF(|Xk|)|Xk|ε-1,

avec un véritable exposant ε-1, et ce qui signifie: "est proportionnel à", est invariant d'échelle dans le sens où le produit de Xket une constante positive suit toujours la même distribution (voir Lauwers et al. 2010 ).

Une famille d'estimateurs

Une famille d'estimateurs doit être présentée, avec ces propriétés:

  1. Invariance d'échelle: si le bac propre complexeXk, ou de manière équivalente l'amplitude propre |Xk|, et l'écart type de bruit σ sont chacun multipliés par la même constante positive, puis aussi l'amplitude estimée |Xk|^ est multiplié par cette constante.
  2. Erreur d'amplitude transformée moyenne moyenne minimale.
  3. Uniform incorrect avant l'amplitude transformée.

Nous utiliserons la notation normalisée:

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

|Xk| est l'amplitude propre que nous souhaitons estimer à partir de l'amplitude bruyante |Yk| de valeur bin Yk whicy est égal à la somme de la valeur du bac propre Xk plus le bruit gaussien complexe de symétrie circulaire σ2. L'invariant d'échelle a priori de |Xk|donnée dans l'équation. 4 est reporté à la notation normalisée comme suit:

(6)PDF(a)aε1.

Laisser g(a) être une fonction de transformation croissante de l'amplitude a. L'antériorité uniforme incorrecte de l'amplitude transformée est indiquée par:

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

Eqs. 6 et 7 déterminent ensemble la famille des transformations d'amplitude possibles. Ils sont liés par un changement de variables :

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

On suppose sans preuve que le choix des constantes c0 et c1n'affectera pas l'estimation de l'amplitude. Pour plus de commodité, nous définissons:

(9)g(1)=1etg(1)=1c0=ε-1εetc1=1g(une)=uneε+ε-1ε,

qui a un cas linéaire spécial:

(dix)g(une)=unesiε=1,

et une limite:

(11)limε0g(une)=Journal(une)+1.

La fonction de transformation peut représenter commodément l'échelle d'amplitude linéaire (à ε=1) et peut approcher une échelle d'amplitude logarithmique (comme ε0). Pour positifε, le support du PDF d'amplitude transformée est:

(12)0<une<ε-1ε<g(une)<,

La fonction de transformation inverse est:

(13)g-1(g(une))=(εg(une)-ε+1)1/ε=une.

L'estimation transformée est alors, en utilisant la loi du statisticien inconscient :

(14)une^uni-MMSE-xform=unergmjenune^E[(g(une)-g(une^))2m]=g-1(E[g(une)m])=g-1(0g(une)PDF(unem)une)=g-1(0g(une)F(unem)une0F(unem)une),

PDF(uneb) est le PDF postérieur et F(unem) est un PDF postérieur non normalisé défini en utilisant le théorème de Bayes (Eq. 1), le PDF(mune)=2me-(m2+une2)je0(2mune)de l'Eq. 3.2 de ma réponse d'estimateur ML, et Eq. 6:

(15)PDF(unem)PDF(mune)PDF(une)2me-(m2+une2)je0(2mune)×uneε-1e-une2je0(2mune)uneε-1=F(unem),

à partir duquel PDF(m) a été supprimée de la formule de Bayes car elle est constante sur une.Combiner les égaliseurs. 14, 9 et 15, résoudre les intégrales dans Mathematica et simplifier, donne:

(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/ε,

Γest la fonction gamma etLest la fonction de Laguerre . L'estimateur s'effondre à zéro partout carε0, il n'est donc pas logique d'utiliser négatif ε, qui mettrait l'accent sur les petites valeurs de aencore plus loin et donner une mauvaise distribution postérieure. Certains cas particuliers sont:

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

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

approximé au sens large mpar ( voir calcul ) une série Laurent tronquée:

(19)a^uni-MMSEm14m732m359128m5,

Cette approximation asymptotique a une erreur d'amplitude maximale absolue inférieure à 106 pour m>7.7.

Les courbes de l'estimateur sont représentées sur la figure 1.

entrez la description de l'image ici
Figure 1. Estimateur a^uni-MMSE-xform en fonction de m pour différentes valeurs de ε, de haut en bas: bleu: ε=2, ce qui minimise l'erreur de puissance quadratique moyenne en supposant un avant uniforme incorrect de la puissance, orange: ε=1, ce qui minimise l'erreur d'amplitude carrée moyenne en supposant un avant uniforme incorrect d'amplitude, vert: ε=12, rouge: ε=14, et violet: ε=18.

À m=0 les courbes sont horizontales avec valeur:

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

À SNR négatif, l'estimateur uni-MMSE-xform peut être paramétré en utilisant ε pour donner une somme d'erreur quadratique inférieure par rapport à l'estimateur de soustraction de puissance spectrale bloquée, avec une pénalité correspondante à des valeurs SNR intermédiaires proches de 7 dB (Fig. 2).

entrez la description de l'image ici
entrez la description de l'image ici
entrez la description de l'image ici
Figure 2. Estimations de Monte Carlo avec un échantillon de 105, de: Solide: gain de la somme de l'erreur quadratique dans l'estimation |Xk| par |Xk|^ par rapport à son estimation avec |Yk|, en pointillés: gain de la somme de l'erreur quadratique dans l'estimation |Xk|2 par |Xk|2^ par rapport à son estimation avec |Yk|2, pointillé: gain de la somme de l'erreur quadratique dans l'estimation Xk par |Xk|^eiarg(Yk) par rapport à son estimation avec Yk. Bleu: estimateur uni-MMSE-xform avec ε=1 (Haut), ε=12 (milieu), et ε=14, orange: soustraction de puissance spectrale bloquée.

Script Python pour la figure 1

Ce script prolonge le script de la question 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 Python pour la figure 2

Ce script étend le script de la question B. La fonction est_a_uni_MMSE_xform_fastpeut être numériquement instable.

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

Références

Lieve Lauwers, Kurt Barbe, Wendy Van Moer et Rik Pintelon, Analyzing Rice distribué des données d'imagerie par résonance magnétique fonctionnelle: une approche bayésienne , Meas. Sci. Technol. 21 (2010) 115804 (12 pages) DOI: 10.1088 / 0957-0233 / 21/11/115804 .


0

Estimateurs d'erreur d'amplitude logarithmique moyenne minimale minimale

Cette réponse présente des estimateurs qui minimisent l'erreur quadratique moyenne d'amplitude logarithmique, pour une sélection de prieurs impropres de l'amplitude propre: uniforme et linéaire.

Estimateur d'erreur de l'amplitude logarithmique du carré moyen minimum antérieur incorrect et uniforme (log uni-MMSE)

Dans la littérature, un développement suivant après un estimateur d'amplitude MMSE a été un estimateur log-amplitude MMSE, en particulier l'estimateur de (Ephraim & Malah 1985, grâce à @MattL. Pour la référence) qui suppose un a priori ricain de l'amplitude propre. Pour tenter d'améliorer l'estimateurune^uni-MMSE , on dérivera ici un estimateur d'erreur log-amplitude quadratique moyenne minimum (uni-MMSE-log) pour un uniforme incorrect avant l'amplitude propre.

En utilisant les variables normalisées de ma réponse "Estimateurs a priori uniformes d'erreur quadratique moyenne minimale invariante d'échelle d'amplitude transformée" Eq. (5), l'estimateur uni-MMSE-log de l'amplitude propre est:

(1)une^journal uni-MMSE=unergmjenune^E[(Journalune-Journalune^)2m]=exp(E[Journalunem]).

Utiliser la loi du statisticien inconscient , puis écrire l'estimation en termes de PDF non normaliséF(unem)=PDF(mune),et simplifiant :

(2)une^journal uni-MMSE=exp(0Journal(une)PDF(unem)une)=exp(0Journal(une)F(unem)une0F(unem)une)=exp(0Journal(une)PDF(mune)une0PDF(mune)une)=exp(0Journal(une)2me-(m2+une2)je0(2mune)une02me-(m2+une2)je0(2mune)une)=exp(2me-m20Journal(une)e-une2je0(2mune)uneme-m2πem2/2je0(m2/2))=exp(20Journal(une)e-une2je0(2mune)uneπem2/2je0(m2/2))=exp(em2/2je0(m22)Ψ(12)+m2F201112(3/2;1;1,1/2;2,2;;3/2;m2,m2)2em2/2je0(m2/2))=exp(m2F201112(3/2;1;1,1/2;2,2;;3/2;m2,m2))2em2/2je0(m2/2)-γ2-Journal2),

Ψest la fonction digamma ,γest la constante d'Euler – Mascheroni , etF201112est une fonction de Kampé de Fériet (-like) . Cette forme de fonction spéciale de l'estimateur peut être évaluée dans mpmath de Python (voir le script à la fin de la réponse). Il existe également un formulaire utilisant des séries qui ne nécessite aucune fonction spéciale:

(3)=exp(-L-1/2(1,0)(m2)2em2/2je0(m2/2)+Ψ(12)2)=exp(k=0((1/2)km2k(1)kk!n=1k12n-1)em2/2je0(m2/2)+Ψ(12)2)=exp(k=0((1/2)km2k(1)kk!n=1k12n-1)k=0(1/2)km2k(1)kk!-γ2-Journal2),

Ln(X) est la fonction L de Laguerre et son exposant (1,0) signifie le différencier par rapport au paramètre d'indice, et (X)kest un symbole Pochhammer avec des cas spéciaux(1)k=k! et (1/2)k=(2k-1)!!/2k. Les séries du numérateur et du dénominateur peuvent être tronquées à des dizaines de termes pour obtenir l'estimateur m.Une meilleure précision est obtenue en approximant les deux séries en utilisant la même troncature de longueur, par rapport à l'utilisation d'une fonction spéciale exacte pour l'autre, ou des troncatures de longueur différente. Il est difficile d'évaluer la série dans son ensemblem parce que les termes les plus gros apparaissent autour km2.

L' expression originale de @ user150203 de la série liée à l'intégrale du numérateur donne une autre expression équivalente pour l'estimateur:

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

(uneb)désigne un coefficient binomial .

La courbe de l'estimateur uni-MMSE-log (Fig.1, courbe inférieure orange) est similaire à celle de l'estimateur uni-MMSE, mais avec une valeur inférieure àm=0:

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

Estimateur d'erreur de l'amplitude logarithmique moyenne linéaire minimale incorrecte (lin-MMSE-log)

Un estimateur connexe peut être obtenu si l'on prend la limite de l'estimateur de (Ephraim & Malah 1985) à une variance a priori infinie de la variable complexe propre. Ensuite, la fonction de densité de probabilité antérieure de Rayleigh de l'amplitude propre devient une rampe linéaire qui est nulle à une amplitude nulle et augmente linéairement avec une pente infinitésimale. L'estimateur résultant (Fig.1, courbe supérieure bleue) est:

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

Ei(x)est l' intégrale exponentielle , etΓ(0,x)est la fonction gamma incomplète supérieure .

entrez la description de l'image ici
Figure 1. Estimateurs d'erreur en amplitude logarithmique moyenne minimale: bleu, supérieur: a^lin-MMSE-log avec un avant linéaire incorrect et orange, inférieur: a^uni-MMSE-logavec un uniforme inapproprié au préalable. Amplitude propre estiméea^ en fonction de l'ampleur bruyante m avec bruit additif de variance unitaire.

Script Python pour la figure 1

Ce script étend le script de la question A. La fonction est_a_uni_MMSE_logest numériquement instable dans son ensemble 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)

Références

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.