Próbkowanie w dół sygnału z dziesiętną

12

Eksperymentuję z zdziesiątkowaniem sygnału, w tym przypadku impulsu jednostkowego.

Używam Pythona z pylab. Najpierw tworzę impuls jednostkowy i zliczam go o 5.

x = r_[zeros(0), 1, zeros(100)]
N = 2 ** 14
q = 5

y = decimate(x, q, ftype="fir")
subplot(211)
title("Original")
stem(range(len(x)), x)
subplot(212)
title("Decimated - FIR")
stem(range(len(y)), y)

figure()
subplot(211)
semilogx(log(abs(fft(x, N))))
subplot(212)
y = decimate(x, q, ftype="fir")
semilogx(log(abs(fft(y, N))))

Wynika to z następujących wykresów

Impuls jednostkowy z zerowym opóźnieniem i wynikowy zdziesiątkowany sygnał

Następnie dodaję kilka próbek opóźnienia przed impulsem, zmieniając x na:

x = r_[zeros(3), 1, zeros(100)]

Powoduje to następujące wykresy

Impuls jednostkowy z opóźnieniem 3 próbek i powstały zdziesiątkowany sygnał

W drugim zestawie wykresów uzyskany zdziesiątkowany sygnał nie jest już pojedynczą próbką, ale został zniekształcony.

Jeśli opóźnię sygnał o 5 - i dowolną wielokrotność q - próbek, ponownie otrzymam pierwszy zestaw wykresów.

Kod źródłowy funkcji dziesiętnej to https://github.com/scipy/scipy/blob/master/scipy/signal/signaltools.py#L1570

def decimate(x, q, n=None, ftype='iir', axis=-1):
    if not isinstance(q, int):
        raise TypeError("q must be an integer")

    if n is None:
        if ftype == 'fir':
            n = 30
        else:
            n = 8

    if ftype == 'fir':
        b = firwin(n + 1, 1. / q, window='hamming')
        a = 1.
    else:
        b, a = cheby1(n, 0.05, 0.8 / q)

    y = lfilter(b, a, x, axis=axis)

    sl = [slice(None)] * y.ndim
    sl[axis] = slice(None, None, q)
    return y[sl]

Używam jodłowego filtra dolnoprzepustowego przed zdziesiątkowaniem, odpowiedź impulsowa filtra to

odpowiedź impulsowa filtra dolnoprzepustowego

To wyjaśnia, dlaczego impuls jest zniekształcony, gdy występuje opóźnienie, decymacja wybiera części odpowiedzi impulsowej, gdy opóźnienie jest wielokrotnością decymacji, wybiera tylko zero odpowiedzi impulsowej i jedną niezerową próbkę przy szczyt.

Czy istnieje sposób na zdziesiątkowanie próbki jednostkowej z dowolnym opóźnieniem, co skutkuje skalowaniem wyjściowej próbki jednostkowej?

Lanca
źródło
Rozumiesz, że impuls „pojedynczej próbki” faktycznie reprezentuje funkcję sinusa, prawda? Ponieważ przed próbkowaniem musisz filtrować filtr antyaliasowy, a Twoja idealna funkcja impulsu matematycznego zmienia się w funkcję sinc po przefiltrowaniu. Zdarza się, że próbki spadają dokładnie na zera cynku, więc nie wygląda to tak, ale gdyby cynk został przesunięty mniej niż o jedną próbkę w czasie, zobaczyłbyś to.
endolith

Odpowiedzi:

11

Wydaje się, że rozumiesz poprawnie, co się dzieje. Nie jestem jednak pewien, czego oczekujesz. Weź swój początkowy przykład. Niech twój sygnał wejściowy będzie :x[n]

x[n]=δ[n]

Pierwszym krokiem w procesie decymacji jest to, że sygnał wejściowy jest splatany z odpowiedzią impulsową filtra antyaliasingu :h[n]

xf[n]=x[n]h[n]=δ[n]h[n]=h[n]

Następnie filtrowany sygnał jest próbkowany w dół o współczynnik ( w twoim przykładzie).q5

xd[n]=xf[qn]=h[qn]

Jak zauważono, w przypadku filtrów FIR, których zamówienia są wielokrotnością (w rzeczywistości, ponieważ filtr ma fazę liniową, kolejność musi być tylko wielokrotnością ), zaczepy w opóźnieniach są zero dla wszystkich . Dlatego jest niezerowe tylko przy , jak stwierdzono.qq2qnq0xd[n]n=0

Kiedy zastosujesz opóźnienie czasowe do impulsu wejściowego , wówczas filtrowane wyjście jest tylko opóźnione o tę samą wartość, ponieważ filtr jest liniowy i niezmienny w czasie (LTI) :x[n]

xf[n]=h[nD]

xd[n]=xf[qn]=h[qnD]

Ponownie, jak zauważyłeś, ma to efekt wyciągania innego zestawu zaczepów z odpowiedzi filtra, tak że zdziesiątkowany sygnał wyjściowy nie jest już zerowy dla wszystkich prócz jednej próbki (tj. Nie wygląda już jak impuls ). Tego można było się spodziewać. Dlaczego?

Pamiętaj, że dyskretna transformata Fouriera (DTFT) dyskretnego impulsu jest płaska (pod względem wielkości) w dziedzinie częstotliwości. Jeśli ma być równoważny opóźnionemu impulsowi, musi on również mieć płaską wielkość w dziedzinie częstotliwości. Jednak jego DTFT jest po prostu skalowaną kopią odpowiedzi częstotliwościowej filtra:xd[n]

xd[n]=h[qnD]ejωDH(ωq)

gdzie jest odpowiedzią częstotliwościową filtra. Aby zdziesiątkowana moc wyjściowa była równa opóźnionemu impulsowi, filtr musi mieć ceglaną ścianę, która jest idealnie płaska w całym paśmie (do częstotliwości po zdziesiątkowaniu Nyquista) i zero wszędzie indziej (więc brak aliasingu wycieka z powrotem po próbkowaniu w dół, co powoduje, że wynik nie jest płaski). Nie jest to możliwe, chyba że masz nieskończoną ilość czasu i zasobów.H(ω)xd[n]

Ponieważ filtr jest źródłem „zniekształceń”, których nie chcesz, możesz rozważyć ponowne uruchomienie procesu bez filtra. Ale zastanów się, co byś wtedy otrzymał:

xf[n]=x[n]=δ[nD]

xd[n]=xf[qn]=δ[qnD]

Jeśli nie jest wielokrotnością , to , co prawdopodobnie nie jest tym, czego byś chciał.qDxd[n]=0  n

Jason R.
źródło