将quantiz函数转换为python

2024-09-29 23:15:35 发布

您现在位置:Python中文网/ 问答频道 /正文

如何转换MATLAB's ^{} function (其中xd是终止信号)到python/scipy中?在

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

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

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

我如何用python编写这个呢?在


Tags: 函数numpy算法信号matplotlibstepfunction语音
1条回答
网友
1楼 · 发布于 2024-09-29 23:15:35

看一下文档,它是一个非常简单的函数,很容易用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

用文档中的示例进行尝试:

^{pr2}$

对于效率稍高但不太灵活的版本,我们可以绕过范围,只使用数学:

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

对于kicks,我尝试使用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解决方案的性能(我缺少编译结果所需的头文件)。在

相关问题 更多 >

    热门问题