PyWavelets CWT: normalizacja? Vs Scipy?

Oct 01 2020

Powiązane . Realizowane równanie normalizuje się przez sqrt(1 / scale):

$$ C_{a, b} = \frac{1}{\sqrt{a}} \sum_k s(k)\left( \int_{-\infty}^{k+1} \overline{\psi \left(\frac{t-b}{a} \right) }dt - \int_{-\infty}^{k} \overline{\psi \left(\frac{t-b}{a} \right) }dt \right) $$

więc dlaczego nie pywt._cwtzrobić * sqrt (skala) ? Jak to normalizuje (L1, L2 itd.)?


Edycja : Po przejrzeniu cwt Scipy'ego zdałem sobie sprawę, że implementuje dokładnie to, co opisałem jako „idealne” w odpowiedzi, więc jest to to samo, co porównanie dwóch (z wyjątkiem kilku oczywistych szczegółów). Nie wiem, w których scenariuszach algorytm pywta jest lepszy, ale ogólnie - łatwe zwycięstwo dla Scipy . Otworzyłem PR, aby zająć się kluczową usterką pywt.

Edit2 : Znaleziono widoczną przewagę pywt's over scipy's w najmniej oczekiwanym miejscu: niskie skale . Adresowane tutaj .

Edycja 3 : po zamocowaniu niski precisionw pywt, faktycznie znalazłem pywtlepsze scipywe wszystkich różnych sygnałów syntetycznych, ale squeezepyzawsze jest pokonanie obu. Testy tutaj , a wkrótce więcej.

Odpowiedzi

3 OverLordGoldDragon Oct 01 2020 at 21:20

Prześledźmy matematykę od inkubacji do dostawy. Zaczyna się psiod przeskalowania morlet2(jak pokazano wcześniej ) w skali$a=64$, i $\sigma=5$:

$$ \psi = \psi_{\sigma}(t/a) = e^{j\sigma (t/a)} e^{-(t/a)^2/2} \tag{2} $$

zostaje zintegrowany i znormalizowany L1 : - (patrz zastrzeżenie 2 poniżej)

$$ \psi = \psi_{\text{int}}(t) = \frac{1}{a} \int \psi_{\sigma}(t/a)\ dt \tag{3} $$

Norma jest odchylona przez współczynnik skalarny, ale ważne jest to, że dla różnych jest to samo$a$; możesz zweryfikować, że tak jest (dla dużych plików$a$zwiększyć limity integracji). Zauważ, że to falka jest znormalizowana L1, a nie zintegrowana falka$\psi_\text{int}(t)$; rozróżnienie jest niezbędne, jak zobaczymy.

$\psi$ jest następnie spleciona z sygnałem $s$i skończone zróżnicowane i zanegowane; od tutaj , to jest:

$$ -\text{DIFF}(\text{conv}) = [s \cdot (\psi_{\text{int}}(t - 0) - \psi_{\text{int}}(t - 1)),\ ...] \tag{4} $$

Dokładna analiza jest równoznaczna z cofnięciem poprzedniej integracji, z pewnymi różnicami liczbowymi (omówionymi później), więc pozostaje nam

$$ \psi = \frac{1}{a} \psi_{\sigma}(t/a) \tag{5} $$

Wreszcie * sqrt(scale):

$$ \boxed{\psi = \frac{1}{\sqrt{a}} \psi_{\sigma}(t/a)} \tag{6} $$

który jest zatem ostatecznie znormalizowany L2 . Możemy to zweryfikować na podstawie sygnału testowego; L2 jest przesunięty w reprezentacji amplitudy / mocy w kierunku niższych częstotliwości, tłumiąc wysokie częstotliwości. Jeśli powyższe ma rację, nie tylko możemy to zobaczyć, ale zastosować poprawkę, usuwając * sqrt(scale)z kodu:

Zastrzeżenia specyficzne dla implementacji omówione poniżej.


Jak wiarygodna jest normalizacja w różnych skalach? - Niezbyt dobre (- code2 ):

Po prawej stronie widzimy najlepszy przypadek przy użyciu ograniczonej liczby próbek, po lewej stronie widzimy implementację resamplingu. Najwyraźniej z powodu nieodłącznej słabej rozdzielczości niewielkiej liczby próbek nasze normy nie sprawdzają się dobrze dla niskich skal - ale przeliczony wariant przynajmniej utrzymuje średnią normę w przybliżeniu na stałym poziomie.

Co ciekawsze, ponownie próbkowany nagle pojawia się po $\log_2(a)=6$; o co chodzi? Przypomnijmy: „Zaczyna się… na dużą skalę$a=64$"; to jest, gdy ponownie próbujemy z większą liczbą próbek niż w oryginale ( int_psi):

czyj diffjest

  • W 1LR widzimy int_psico scale=256jest resampling te same wartości z int_psiwielu razy, co przejawia się w zerami diff(2LR).
  • Następnie podnosimy wartości do kwadratu, aby uzyskać pojęcie o normie L2 i porównujemy je ze znormalizowanymi wartościami L2 w 3LR; znajdujemy znormalizowane wartości wydmuchujące nienormalne wartości z wody. Czy to jest przesadne czy właściwe?
  • Porównaj z przeliczonymi w tej samej skali; w 4LR przynajmniej widzimy przeliczony kształt - nie jest już nieistotny. Sugeruje to, że ponowne próbkowanie jest zawyżeniem amplitudy falki, a ponieważ w obliczeniach normalnych jest to znacznie przesunięte o połowę wartości równej zeru diff, to przeszacowanie musi być duże.

Jak wielkie? Możemy porównać szczytowe amplitudy falki w skalach nienormowanego ponownego próbkowania diff(int_psi_256)i przeliczenia w( morlet2/scale); normowanie zmian obu tym samym współczynnikiem ( *sqrt(scale)) nie zrobi różnicy.

Z pewnością znowu o godz $a=64$widzimy krytyczne zachowanie; Amplituda piku resamplingowi nasyconych do minimum, podczas gdy przeliczane nadal zmniejszać. Różnica w$a=256$jest więcej niż wystarczająco duży (~ 12db = 4x, jeśli do kwadratu -> 16x), aby zrównoważyć zera w diff, stąd rośnie norma L2.

Ale zauważ, że norma L1 pozostaje dobrze zachowana w wyższych skalach. Aby dowiedzieć się, dlaczego, musimy dokładnie porównać proporcję zer ze współczynnikiem przeszacowania. Wiemy już, że to ostatnie jest 4x; dla pierwszego wziąłem obszar niepłaski (w przeciwnym razie i tak są to zera) i znalazłem stosunek zer do liczby próbek: 0,75 . Oznacza to, że 1 na 4 wartości jest niezerowe, a każda z nich jest 4x większa ... dokładna proporcja potrzebna do zachowania normy L1.

Ta proporcja zer nie jest zbyt wyraźna z powyższych wykresów - zamiast tego kropki:


Jeśli diffcofnie się cumsum, dlaczego w ogóle to zrobisz?

Dobre pytanie. W rzeczywistości, pozbywając się obu, stwierdziłem, że efekt degradacji jakości (zamek błyskawiczny) zniknął:

Ale znika też coś innego - skale wysokich częstotliwości (po lewej), a znak odwraca się (rozwiązałem to usuwając minus na coef = -). I to częściowo skompensowane przez zastąpienie * sqrt(scale)przez 1 / sqrt(scale)(po prawej), ale że robi nam L2 unormowane sprawy ( 1 / scalejest przesadą), i jest bezpodstawne modyfikacji w świetle wszystkiego znaleziono do tej pory. Czy można to zrobić? Jasne, można to zrealizować bez int-difftańca, ale nie będę tego tutaj badał.


Zastrzeżenie: skuteczna norma

Przypomnijmy, convzostaje przycięty do len(x), więc cała falka może nie uczestniczyć w obliczeniach, podczas gdy powyższe obliczenia zakładają inaczej. Założenie jest prawdziwsze, im dłuższe xjest - ale oto, co się dzieje, jeśli len(x) == 512z tą samą falką precision=10(2 ^ 10 = 1024 int_psi), porównamy z przeliczoną falką:

Bałagan! Oba zniekształcają się znacznie, prawdopodobnie sugerując, że jest to nieodłączne dla wystarczająco dużych skal przypiętych do krótkich sygnałów. Prostym obejściem jest wypełnienie sygnału przez zero, ale nie ręczyłbym za to bez zrozumienia zastrzeżeń (czego nie robię dla falek, ale robię dla DFT ).

Ponadto zwróć uwagę, że norma dotyczy nie tylko skali, ale także zmiany ($b$); mniej falki znajduje się w sygnale, gdy właśnie wchodzi, w przeciwieństwie do tego, gdy jej środek znajduje się w środku sygnału.

Ale zachowując to według skali, przyznaję, że oszukiwałem w poprzednim przykładzie $f=4$; początkowo wybrałem$f=1$, ale wykres normy L1 nie wyglądał ładnie i nie rozumiałem dlaczego. Od teraz mam, tutaj są zarówno L1, jak i L2 na skalę dla$f=1,64$:

Porównaj z wcześniejszą fabułą; Zwróć uwagę, że lewe mody (niskie skale) obu norm pozostają niezmienione, tylko te o wysokiej skali (o niskiej częstotliwości) są teraz znacznie większe (L2) i niższe (L1), tak jak oczekiwano.


Zastrzeżenie 2: * stepnie normalizuje L1

Zamiast tego, wynika to z diffponownego próbkowania zintegrowanej falki; * steptylko ustawia właściwą skalę początkowego i może zostać pominięta bez utraty normę. To jest nie stało się ponowne obliczenie falki lub resampling niezintegrowanych falki.

(Zwróć uwagę, że przeliczony scipy.signal.morlet2jest znormalizowany L2, ale tylko dlatego, że jest jawnie znormalizowany; diff-próbka- intjest „ samonormalizowana ”).