Преобразование функции квантизации в python
Как преобразовать функцию quantiz
MATLAB (где xd – затухающий сигнал) в python / scipy?
Я пытаюсь реализовать алгоритм, который я разработал в MATLAB для обработки речи в программном пакете с использованием python и библиотек, таких как scipy, numpy, pygtk и matplotlib, чтобы преобразовать алгоритм в полный пакет.
Я использую scipy для разработки алгоритмов, но я не могу найти подходящую функцию для «квантования сигнала» в python:
[I,xq] = quantiz(xd,1:step:1-step, -1:step:1);
Как я могу написать это в python?
- симулятор реалистичного сигнала ЭКГ из данных rr для matlab или python
- Создание спектрограммы в python (без рисования)
- вычисление завитка компонентов u и v ветра в спутниковых данных – Python
- Как создать матрицу с кругом единиц в numpy / scipy
- SciPy "lfilter" возвращает только NaNs
Глядя на документацию, это довольно простая функция, которую довольно легко написать в Python. Я переименовал функцию, чтобы добавить отсутствующий «e», потому что это меня раздражало. Так или иначе:
def quantize(signal, partitions, codebook): indices = [] quanta = [] for datum in signal: index = 0 while index < len(partitions) and datum > partitions[index]: index += 1 indices.append(index) quanta.append(codebook[index]) return indices, quanta
Попробуйте это с примером в документации:
>>> index, quants = quantize([3, 34, 84, 40, 23], range(10, 90, 10), range(10, 100, 10)) >>> index [0, 3, 8, 3, 2] >>> quants [10, 40, 90, 40, 30]
Для немного более эффективной, но менее гибкой версии мы можем обойти диапазоны и просто использовать математику:
from __future__ import division import math def opt_quantize(signal, num_quanta, partition_start, partition_step, codebook_start, codebook_step): indices = [] quanta = [] for datum in signal: index = int(math.floor((datum - partition_start) / partition_step + 1)) if index < 0: index = 0 if index >= num_quanta: index = num_quanta - 1 indices.append(index) quanta.append(codebook_start + codebook_step * index) return indices, quanta
Попробуйте это с примером в документации:
>>> index, quants = opt_quantize([3, 34, 84, 40, 23], 9, 10, 10, 10, 10) >>> index [0, 3, 8, 4, 2] >>> quants [10, 40, 90, 50, 30]
Таким образом, результаты представляют собой небольшую разницу в бит в том случае, когда базовая точка находится именно на разделе из-за ошибки с плавающей запятой, но она работает, если ничего нет в разделе.
Таким образом, сокращается время работы, где n – длина сигнала, а m – количество разделов от O (mn) до O (n). Это должно дать вам значительное повышение производительности. Мы можем сделать лучше?
Да. С помощью нашего нового подхода, основанного на математике, код легко векторизован, и мы можем заставить Numpy выполнять тяжелую работу:
import numpy as np def np_quantize(signal, num_quanta, partition_start, partition_step, codebook_start, codebook_step): signal = np.asarray(signal, dtype=float) indices = np.empty_like(signal, dtype=int) np.floor_divide((signal - partition_start + partition_step), \ partition_step, indices) np.clip(indices, 0, num_quanta - 1, indices) quanta = np.asarray(indices, dtype=float) * codebook_step + codebook_start return indices, quanta
Я случайно оценил это, и кажется, что каждая из моих оптимизаций сделала его медленнее , так что либо я делаю что-то ужасно неправильно, либо я не тестирую данные, достаточно большие, чтобы амортизировать константу.
~$ python -m timeit -s 'from quantize import orig_quantize' 'orig_quantize([-3, -2, -1, 0, 1, 2, 3], [-0.5, 0.5], [-1, 0, 1])' 100000 loops, best of 3: 8.58 usec per loop ~$ python -m timeit -s 'from quantize import opt_quantize' 'opt_quantize([-3, -2, -1, 0, 1, 2, 3], 3, -0.5, 1, -1, 1)' 100000 loops, best of 3: 10.8 usec per loop ~$ python -m timeit -s 'from quantize import np_quantize' 'np_quantize([-3, -2, -1, 0, 1, 2, 3], 3, -0.5, 1, -1, 1)' 10000 loops, best of 3: 57.4 usec per loop
Для ударов я пытался использовать Cython, а также Numpy:
cimport cython cimport numpy as np cdef extern from "math.h": float floorf(float) @cython.boundscheck(False) def cynp_quantize(np.ndarray[float, ndim=1] signal, int num_quanta, float partition_start, float partition_step, float codebook_start, float codebook_step): cdef int i cdef int index cdef np.ndarray[np.int_t, ndim=1] indices = np.empty_like(signal, dtype=int) cdef np.ndarray[float, ndim=1] quanta = np.empty_like(signal) for i in range(signal.shape[0]): index = <int>floorf((signal[i] - partition_start) / partition_step + 1.0) if index < 0: index = 0 if index >= num_quanta: index = num_quanta - 1 indices[i] = index quanta[i] = codebook_start + index * codebook_step return indices, quanta
Из того, что я собираю, Cython также экспериментально поддерживает OpenMP, который позволит ему делать все с несколькими потоками. Я не смог проверить производительность этого решения Cython, хотя, с или без потоков (мне не хватает файла заголовка, необходимого для компиляции результата).
- Получение определенного элемента набора в Python
- Более эффективные способы сохранения графа больших объектов и добавления к нему в python
- циклический кросс-корреляционный питон
- Удаление фонового шума из аудиосигналов с использованием FFT Python
- Анализ аудио с использованием быстрого преобразования Фурье
- Фильтр высоких частот Python
- Почему я получаю строки нулей в 2D 2D?
- Как улучшить изображение, а затем преобразовать его в двоичное изображение с помощью Python и OpenCV?
- sklearn – модель продолжает перерабатывать
- Записанный звук одной заметки создает несколько периодов начала
- Вычисление DCT с помощью OpenCV