`mdwtdec()` в Matlab против `wavedec()` в Python

Я пытаюсь преобразовать код Matlab в Python. Для разложения мультисигнального одномерного вейвлета я использую mdwtdec() в Matlab. Самая близкая функция, которую я нашел в python, находится в pywt lib, wavedec().

В то время как функция Matlab принимает 4 аргумента mdwtdec(DIRDEC,X,LEV,WNAME): здесь X — сигнал, LEV — уровень, WNAME — имя вейвлета, а DIRDEC — индикатор направления: r (строка) или c (столбец).

mdwtdec(DIRDEC,X,LEV,WNAME) возвращает вейвлет-разложение на уровне LEV каждой строки (если DIRDEC = r) или каждого столбца (если DIRDEC = c) матрицы X, используя вейвлет WNAME.

В pywavelets wavedec(X,LEV,WNAME) принимает X, LEV и WNAME аналогично Matlab. Варианта направления нет, поэтому по умолчанию установлено значение «r». Мне тоже нужен «c» в качестве опции. Как мне добиться этого в Python?


person Prashanth    schedule 01.02.2016    source источник


Ответы (1)


pywt wavedec предполагает, что сигнал представляет собой массив. Если сигнал не является массивом, то результаты менее убедительны (для квадратных матриц результат кажется соответствующим построчной операции, но этого нельзя сказать о неквадратных матрицах).

К счастью, вы можете запустить wavedec для каждой строки или столбца, используя apply_along_axis numpy. С небольшой дополнительной оберткой вы можете определить приближение Matlab (версия Matlab, вероятно, имеет лучшую обработку ошибок) для mdwtdec, например:

import pywt
import numpy as np
def mdwtdec(dirdec,x,lev,wavelet):
    """
    Multisignal 1D Discrete Wavelet decomposition.

    Parameters
    ----------
    dirdec  : char
        Direction indicator: 'r' (row) or 'c' (column)
    x       : matrix
        Input matrix
    wavelet : Wavelet object or name string
        Wavelet to use
    lev     : int
        Decomposition level (must be >= 0). If level is None then it
        will be calculated using the ``dwt_max_level`` function.
    """
    return np.apply_along_axis(
        lambda y: np.concatenate(pywt.wavedec(y, wavelet, level=lev)),
        axis={'c':0, 'r':1}[dirdec], arr=x)

в котором я использовал:

  • np.concatenate, чтобы коэффициенты аппроксимации и детализации сохранялись в виде плотного вектора строки/столбца.
  • выражение lambda для указания выполняемой функции вместе с отображением входных аргументов
person SleuthEye    schedule 04.02.2016
comment
Спасибо за Ваш ответ. Я попробовал это с 2D-матрицами, это работает для dirdec = 'r', но для dirdec = 'c' это повышает ValueError: axis must be less than arr.ndim; axis=0, rank=0. - person Prashanth; 04.02.2016
comment
Что я сделал, так это транспонировал ввод x в wavedec для обработки dirdec = 'c'. Он работает прилично, но выходные данные различаются как по размеру (иногда), так и по значениям от mdwtdec() Matlab, что заставляет меня сомневаться, делаю ли я это неправильно. - person Prashanth; 04.02.2016
comment
Результаты моих тестов выглядели нормально для dirdec='c' с np.matrix входами. Не могли бы вы предоставить пример тестового примера, с которым у вас возникли проблемы? - person SleuthEye; 04.02.2016
comment
Я пробовал p = np.random.rand(512, 7608) q = mswpd.mdwtdec('c', p, 1, 'db4') - person Prashanth; 04.02.2016
comment
Извините, но я не могу воспроизвести эту ошибку (кроме тривиального скалярного ввода, который действительно имеет нулевой ранг). Обратите внимание, как вы получите матрицу 0-ранга (с входными данными 512x7608) в mdwtdec из моего поста. - person SleuthEye; 05.02.2016