gpt4 book ai didi

python - 将量化函数转换为python

转载 作者:行者123 更新时间:2023-12-02 05:07:56 25 4
gpt4 key购买 nike

如何转换 MATLAB's quantiz function(其中 xd 是 desimated 信号)到 python/scipy?

我正在尝试将我在 MATLAB 中开发的用于语音处理的算法实现到一个软件包中,使用 python 和 scipy、numpy、pygtk 和 matplotlib 等库,以便将该算法转换为一个完整的包。

我正在使用 scipy 进行算法开发,但我找不到合适的函数来在 python 中“量化信号”:

[I,xq] = quantiz(xd,1:step:1-step, -1:step:1);

我如何用 python 编写它?

最佳答案

查看文档,这是一个非常简单的函数,很容易用 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,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15983986/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com