Как расширить pyWavelets для работы с N-мерными данными?
Это может быть вопрос для другого форума, если да, пожалуйста, дайте мне знать. Я заметил, что только 14 человек следуют вейвлет-тегу.
У меня здесь элегантный способ расширения вейвлет-декомпозиции в pywt (pywavelets package) до нескольких измерений. Это должно закончиться из коробки, если pywt установлен. Тест 1 показывает декомпозицию и перекомпозицию 3D-массива. Все, что нужно сделать, это увеличить количество измерений, и код будет работать при разложении / перекомпозиции с 4, 6 или даже 18 размеры данных.
Я заменил pywt.wavedec и pywt.здесь функционирует waverec. Кроме того, в fn_dec я показываю, как новая функция wavedec работает так же, как и старая.
есть один улов: он представляет вейвлет-коэффициенты в виде массива той же формы, что и данные. Как следствие, с моими ограниченными знаниями вейвлетов, я смог использовать его только для вейвлетов Хаара. Другие подобные ДБ4 например стравить коэффициентов по краям этих строгих границ (не проблема с текущим представлением коэффициентов в виде списка массивов [CA, CD1 ... CDN]. Еще одна загвоздка в том, что я работал только с 2^N реберными кубоидами данных.
теоретически, я думаю, что должно быть возможно убедиться, что" кровотечение " не происходит. Алгоритм для такого рода вейвлет-декомпозиции и рекомпозиции обсуждается в "численные рецепты в C" - Уильям брюк, Саул в teukolsky, Уильям Т. Vetterling и Брайан П. Фланнери (Второе Издание). Хотя этот алгоритм предполагает отражение на ребрах, а не другие формы расширений ребер (например, zpd), метод достаточно общий для работы с другими формами расширения.
любые предложения о том, как распространить эту работу на другие вейвлеты?
Примечание: этот запрос также размещен наhttp://groups.google.com/group/pywavelets
спасибо, 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
1 ответов
прежде всего, я хотел бы указать вам на функцию, которая уже реализует одноуровневое многомерное преобразование (источник). Он возвращает словарь массивов n-мерных коэффициентов. Коэффициенты адресуются ключами, описывающими тип преобразования (аппроксимация / детали), применяемого к каждому из измерений.
например, для 2D-случая результатом является словарь с коэффициентами аппроксимации и подробностей массивы:
>>> pywt.dwtn([[1,2,3,4],[3,4,5,6],[5,6,7,8],[7,8,9,10]], 'db1')
{'aa': [[5.0, 9.0], [13.0, 17.0]],
'ad': [[-1.0, -1.0], [-1.0, -1.0]],
'da': [[-2.0, -2.0], [-2.0, -2.0]],
'dd': [[0.0, 0.0], [0.0, -0.0]]}
здесь aa
- массив коэффициентов с аппроксимационным преобразованием, примененным к обоим измерениям (LL) и da
- массив коэффициентов с преобразованием деталей, примененным к первому измерению, и преобразованием аппроксимации, примененным ко второму (HL) (сравните с выход dwt2).
на основе этого должно быть довольно легко расширить его до многоуровневого случая.
вот мой взгляд на часть разложения: https://gist.github.com/934166.
Я также хотел бы затронуть один вопрос, Вы упомянули в своем вопросе:
есть один улов, хотя: это представляет вейвлет-коэффициенты как массив той же формы, что и данные.
подход представления результатов в виде массива той же формы/размера, что и входные данные, на мой взгляд, вреден. Это делает все это излишне сложным для понимания и работы поскольку в любом случае вы должны делать предположения или поддерживать вторичную структуру данных с индексами, чтобы иметь доступ к коэффициенту в выходном массиве и выполнять обратное преобразование (см. документацию Matlab для wavedec/waverec).
кроме того, хотя он отлично работает на бумаге, он не всегда подходит для реальных приложений из-за проблем, о которых вы упомянули: в большинстве случаев размер входных данных не 2^n и уничтоженный результат свертки сигнала с вейвлет-фильтром больше "пространства хранения", что в свою очередь может привести к потере данных и не совершенной реконструкции.
чтобы избежать этих проблем, я бы рекомендовал использовать более естественные структуры данных для представления иерархии данных результата, такие как списки Python, словари и кортежи (если они доступны).