Esto puede ser una pregunta para un foro diferente, de ser así, hágamelo saber. Noté que solo 14 personas siguen la etiqueta wavelet.¿Cómo extender pyWavelets para trabajar con datos N-dimensionales?
He aquí una forma elegante de extender la descomposición wavelet en pywt (paquete pyWavelets) a múltiples dimensiones. Esto debería ejecutarse fuera de la caja si pywt está instalado. La prueba 1 muestra la descomposición y recomposición de una matriz 3D. Todo, uno tiene que hacer es aumentar el número de dimensiones y el código funcionará en descomposición/recomposición con 4, 6 o incluso 18 dimensiones de datos.
He sustituido las funciones pywt.wavedec y pywt.waverec aquí. Además, en fn_dec, muestro cómo la nueva función wavedec funciona igual que la anterior.
Sin embargo, hay una trampa: representa los coeficientes wavelet como una matriz de la misma forma que los datos. Como consecuencia, con mi conocimiento limitado de wavelets, solo he podido usarlo para Haar wavelets. Otros como DB4, por ejemplo, coeficientes de sangrado sobre los límites de estos límites estrictos (no es un problema con la representación actual de los coeficientes como lista de matrices [CA, CD1 ... CDN]. Otra pega es que solo he trabajado esto con 2^N borde cuboids de datos
Teóricamente, creo que debería ser posible asegurarse de que el "sangrado" no se produce. Un algoritmo para este tipo de descomposición wavelet y recomposición se discute en "recetas numéricas en C" - por William Press, Saul A teukolsky, William T. Vetterling y Brian P. Flannery (Segunda edición). Aunque este algoritmo asume la reflexión en los bordes en lugar de las otras formas de extensiones de borde (como zpd), el método es lo suficientemente general como para trabajo para otras formas de extensión.
Cualquier sugerencia ión sobre cómo extender este trabajo a otras wavelets?
NOTA: Esta consulta también está publicada en http://groups.google.com/group/pywavelets
Gracias, Ajo
import pywt
import sys
import numpy as np
def waveFn(wavelet):
if not isinstance(wavelet, pywt.Wavelet):
return pywt.Wavelet(wavelet)
else:
return wavelet
# given a single dimensional array ... returns the coefficients.
def wavedec(data, wavelet, mode='sym'):
wavelet = waveFn(wavelet)
dLen = len(data)
coeffs = np.zeros_like(data)
level = pywt.dwt_max_level(dLen, wavelet.dec_len)
a = data
end_idx = dLen
for idx in xrange(level):
a, d = pywt.dwt(a, wavelet, mode)
begin_idx = end_idx/2
coeffs[begin_idx:end_idx] = d
end_idx = begin_idx
coeffs[:end_idx] = a
return coeffs
def waverec(data, wavelet, mode='sym'):
wavelet = waveFn(wavelet)
dLen = len(data)
level = pywt.dwt_max_level(dLen, wavelet.dec_len)
end_idx = 1
a = data[:end_idx] # approximation ... also the original data
d = data[end_idx:end_idx*2]
for idx in xrange(level):
a = pywt.idwt(a, d, wavelet, mode)
end_idx *= 2
d = data[end_idx:end_idx*2]
return a
def fn_dec(arr):
return np.array(map(lambda row: reduce(lambda x,y : np.hstack((x,y)), pywt.wavedec(row, 'haar', 'zpd')), arr))
# return np.array(map(lambda row: row*2, arr))
if __name__ == '__main__':
test = 1
np.random.seed(10)
wavelet = waveFn('haar')
if test==0:
# SIngle dimensional test.
a = np.random.randn(1,8)
print "original values A"
print a
print "decomposition of A by method in pywt"
print fn_dec(a)
print " decomposition of A by my method"
coeffs = wavedec(a[0], 'haar', 'zpd')
print coeffs
print "recomposition of A by my method"
print waverec(coeffs, 'haar', 'zpd')
sys.exit()
if test==1:
a = np.random.randn(4,4,4)
# 2 D test
print "original value of A"
print a
# decompose the signal into wavelet coefficients.
dimensions = a.shape
for dim in dimensions:
a = np.rollaxis(a, 0, a.ndim)
ndim = a.shape
#a = fn_dec(a.reshape(-1, dim))
a = np.array(map(lambda row: wavedec(row, wavelet), a.reshape(-1, dim)))
a = a.reshape(ndim)
print " decomposition of signal into coefficients"
print a
# re-composition of the coefficients into original signal
for dim in dimensions:
a = np.rollaxis(a, 0, a.ndim)
ndim = a.shape
a = np.array(map(lambda row: waverec(row, wavelet), a.reshape(-1, dim)))
a = a.reshape(ndim)
print "recomposition of coefficients to signal"
print a
En su ejemplo de github ... la recomposición fue la parte más difícil. Además, me resulta mucho más fácil manipular una matriz ND de coeficientes (... como clasificar magnitudes de coeficientes y restar una función de rango de las magnitudes de los coeficientes). Finalmente, las magnitudes cuadradas de los coeficientes son los mismos que los de la muestra datos si uno usa el cubo ND de coeficientes. – fodon