PyWavelets CWT uygulaması
Anlıyorum etmeye PyWavelets' uygulaması Sürekli Dalgacık Dönüşümü ve daha kıyasla nasıl 'temel' sürümü ben kodlu ve burada sağladık. Özellikle:
- Entegre dalgacık nasıl olur, sonra kıvrım sonrası farklılaşır, int + diff olmadan kıvrılmaya eşdeğerdir?
- Artan çözünürlükte entegre dalgacık yeniden örnekleme ölçeğini değiştirmeye eşdeğerdir?
Naif uygulama :
def cwt(x, win_len=None, win='morlet', real=False):
N = len(x)
win_len = win_len or N // 8
scales = _scales(N, nv=32)
coef = np.zeros((len(scales), N), dtype='complex128')
kernel = morlet_kernel(win_len)
wl2 = win_len // 2
for i, scale in enumerate(scales):
coef[i, :] = np.convolve(x, kernel(scale)[::-1])[wl2:-(wl2 - 1)]
return coef
PyWavelets (ilgili bölümlere kırpılmış) :
def pywt_cwt(data, scales):
out = np.empty((np.size(scales),) + data.shape)
int_psi, x = integrate_wavelet(wavelet='morl', precision=10)
for i, scale in enumerate(scales):
step = x[1] - x[0]
j = np.arange(scale * (x[-1] - x[0]) + 1) / (scale * step)
j = j.astype(int) # floor
if j[-1] >= int_psi.size:
j = np.extract(j < int_psi.size, j)
int_psi_scale = int_psi[j][::-1]
conv = np.convolve(data, int_psi_scale)
coef = - np.sqrt(scale) * np.diff(conv, axis=-1)
d = (coef.shape[-1] - data.shape[-1]) / 2.
coef = coef[..., floor(d):-ceil(d)]
out[i, ...] = coef
return out
Karşılaştırma $f=1, 4$sinüzoidler :
Yanıtlar
Önce aşağıdaki bölümde "Naif Dağılım" konusuna bakın. PyWavelets üstüne: algoritma bulunmuştur Github eski MATLAB kaynaklandığı uygulanması , ancak dalgacık çekirdek kodlama üzerinde hiçbir ayrıntıları sağlar. Ben de keşfetmeye başladım; çeşitli görseller ve kod açıklamaları burada . Temel bulgular takip eder. - Tüm kod
Aşağıdaki "PyWavelets Dökümüne" bakın. Aşağıdakileri uygulamaktadır - yani Denklem 4:
(1) Entegre dalgacık nasıl olur, sonra kıvrım sonrası farklılaşır, int + diff olmadan evrişime eşdeğerdir?
Formülasyon sağdadır, soldan gelen denklemler; Sürekli olarak her şeye entegre olmak yerine$\mathcal{R}$integral, özetlenen bölümlere ayrılır. $k$. Girişin üzerinde sabit olduğu varsayılır$[k, k+1]$ (yine de olmamalı $)$?), ayrık olduğu için dalgacık sürekli tutulur. Bu, girişi integralin dışına taşımayı sağlar; görsel olarak:
Peki bunu nasıl kodlayacağız? Denklem 4'ten bir diffyere ihtiyacımız olduğu açık . pywtyapar np.diff(conv), ki bu temelde np.diff(coef); Naive'deki olasılık katsayısının farkını neden alıyor gibi görünüyor?
Denklem 4'te dalgacık ile çarpılmış k + 1eksi yukarı- yukarı entegre dalgacık var k. Bu eşdeğer de dalgacık ürüne b - 1ve bsırasıyla (eklenti t=k+1ve t=k, takmayı ile karşılaştırmak b=b-1ve b=binstead`).
Cevap daha sonra içeride conv; sadece dalgacık sinyalin en azından yarısında olduğunda olacak şekilde zaten kırpıldığını varsayın. O halde, her nokta conv, dalgacıkların farklı tau(veya daha doğrusu b) bir girdinin bir kısmıyla çarpımıdır . Dolayısıyla, bitişik iki nokta conv, bve konumunda dalgacıklara sahip ürünlerdir b + 1:
$$ \begin{align} \text{conv} &= [s \cdot \psi_{\text{int}}(t - 0),\ s \cdot \psi_{\text{int}}(t - 1),\ ...] \\ \Rightarrow \text{DIFF}(\text{conv}) &= [s \cdot (\psi_{\text{int}}(t - 1) - \psi_{\text{int}}(t - 0)),\ ...] \end{align} $$
Bununla birlikte, aralarında eksi aramak t=k+1ve tya da büyük bir tve alt tböylece PW Ayrıntılarında adım 7 açıklayan, yukarıda belirtilen negatif olduğu,.
(2) Tümleşik dalgacıkların artan çözünürlükte yeniden örneklenmesi ölçeğini değiştirmeye eşdeğerdir?
PW Dağılımı'nda (5) altındaki şekle bakın. pywtdalgacığı genişletilmiş bir argümanla yeniden hesaplamak yerine dalgacığı tanımlayan örneklerin sayısı yoluyla "ölçekleniyor" görünmektedir. ... gerçi, görsel, bu açıkça yeniden örnekleme yapar girişine o göreli germe, dalgacık dilate.
Yani gerçekten bir ölçeklendirme şekli; ama naif ile karşılaştırıldığında nasıl? Naive, sabit dalgacık uzunluğu kullanılarak ve ölçeklenmiş bir argüman iletilerek denklem başına daha sezgisel olarak yeniden hesaplanır. O zaman hangisi daha iyi? Tersi soruyu yanıtlamak daha nettir; daha yüksek ve daha düşük ölçeklerde neler olduğunu düşünün:
- Naif daha yüksek : dalgacık çok fazla genişler ve örnekleme çerçevesinden sıfır kuyruklarından çok önce çıkar.
- pywt daha yüksek : dalgacık gayet iyi; sorun ile
conv. Dalgacık uzunluğu 1024 olarak sabitlenmiştir, bu nedenle giriş daha kısaysa, daha yüksek ölçekli dalgacıklar hiçbir zaman sinyali tam olarak çarpamaz. Eşitsizlik ne kadar büyük olursa, dalgacık o kadar çok sinyal tarafından "Naif daha yüksek" e benzer şekilde "görülür"; bu, sorunun dikey kaymalarla farklılık gösteren ısı haritalarında görülebilir.- Maksimum dalgacık ölçeği de sınırsızdır;
len(j)ölçekle orantılı olarak büyür (ancak bir normalizasyon sorunu var, buraya bakın ).
- Maksimum dalgacık ölçeği de sınırsızdır;
- Naif alt : her şey yolunda .
- pywt daha düşük : dalgacık küçük çözünürlüğe sahiptir.
- Sabit ve değişken pencere uzunluğu : daha yüksek ölçekler , girdiye göre dalgacıkta daha fazla genişlemeye veya sıfırdan farklı olmaya karşılık gelmelidir . Naive'in daha yüksek ölçeklerde aniden sıfıra gitmemesi dışında her ikisi de bunu başarır.
Her ikisinde de daha yüksek ölçek sorunları, maksimum ölçek sınırlandırılarak çözülür; her ikisi de tamamen güvenli bölgelerindeyse, daha yüksek çözünürlük nedeniyle Naive uygulaması tercih edilebilir görünüyor. Bununla birlikte, Naive için bu "güvenli bölge", "güvenli" yi kuyruklarda sıfıra atlamamak olarak düşünecek olursak, engelleyici bir şekilde küçüktür.
Aksine, fermuar benzeri yapılardan kurtulmak için önerilenpywt maksimum dalgacık uzunluğunun artırılmasıyla sorunu daha kolay çözülür (ki bu sorunun grafiklerinde de görülebilmektedir). Ancak bu, kısa girdiler için daha yüksek ölçekli performansı kötüleştirdi - ancak pratikte 1024'ten daha kısa olması pek olası değil.
PyWavelets Dağılımı :
- Dalgacık, entegrasyondan önce, gösterilen kod blobuyla tam olarak eşleşir; bu, tam gerçek Morlet'in (Naive tarafından kullanılır) varsayımıyla $\sigma > 5$içinde Wiki .
pywtnp.cumsum(psi) * stepfarklı adım boyutunu hesaba katarak gerçek Morlet aracılığıyla entegre eder- Entegre dalgacık,
int_psiherkes için yeniden kullanılırscales - Her biri için
scale, aynıint_psiolan yeniden örneklenmiş olan, artan çözünürlük dejbir tamsayıdır, aynı dakika ve (neredeyse) tüm maks arasında doğrusal değişken olarakscales:
- Naifle
scaleyan yana artmak için ortaya çıkan dalgacık (sonrası için):
- Evrişim sonucu önce
diff'd, - olumsuz,
- çarpılarak
sqrt(scale), - daha sonra (a) dalgacık "sinyalin içinde" en azından yarı yolda olan kısımları içerecek veya (b) uzunluğunu zorlayacak şekilde her iki taraftan kırpılır
len(x).
Naive Breakdown : CWT / STFT'ye aşina değilseniz, burada 1-3 . Bölümleri şiddetle tavsiye ederim .
(1) dalgacık tipine ihtiyacımız var; (2) dalgacık uzunluğu; (3) dalgacık artışı / örtüşmesi. Gerçek Morlet , 96 örnek kullanacağız ve 20 artıracağız .
win_len = 96 # "win" == window == wavelet
win_inc = 20
n_wins = (len(x) - win_len) // win_inc + 1
coef = np.zeros((n_wins, len(scales)), dtype='complex128')
kernel = morlet_kernel(win_len)
for tau in range(n_wins):
start = tau * win_inc
end = start + win_len
coef[tau, :] = _transform(x[start:end], kernel, scales)
def _transform(x, kernel, scales):
coef = np.zeros(len(scales), dtype='complex128')
for i, scale in enumerate(scales):
psi = np.conj(kernel(scale))
coef[i] = np.sum(x * psi / np.sqrt(scale))
return coef
Şunun için görselleştirildi scale=2:
Bu ve sorudaki naif uygulama arasındaki fark, ikinci kullanımlar win_inc=1, ters çevrilmiş bir dalgacıkla kıvrılmaya eşdeğerdir ve sonucu, yalnızca dalgacık tamamen "sinyalin içinde" olan parçaları içerecek şekilde kırpmaktır. Ayrıca, burada taudış döngüde ("artış") var, orada ölçek var, ancak ikisi eşdeğer.
Son olarak, zaman kayması sönüklüğü boyunca şekiller farklıdır; sorunun gerçeklenmesi, dalgacıkların en azından "girdinin içinde" en azından yarısında olduğu evrişim parçalarını içerecek şekilde kırpar; bu, tam dalgacıkların dahil edildiği yere daha da kırpar .
ÇÖZÜLMÜŞ :
NedenÇözüldü .* sqrt(scale)(8. adım pywt)? Denklem 4 gösterir1 / sqrt(scale). Ben kabul* scalesayısal olarak dalgacık entegre ettik hariç ..., zincir kuralı başına başına ölçekli tedavi mantıklı geldi; Ölçek başına dalgacık integral almamaktan kurtulabilir miyiz çünkü ölçek başına dalgacık ... aynı yeniden örneklenmiş dalgacıktır?