【发布时间】:2010-11-15 01:24:25
【问题描述】:
我在我的 python 程序中使用 cython 进行相关性计算。我有两个音频数据集,我需要知道它们之间的时间差。第二组根据开始时间进行切割,然后滑过第一组。有两个 for 循环:一个滑动集合,内部循环计算该点的相关性。这种方法效果很好,也够准确。
问题在于,对于纯 python,这需要超过一分钟。使用我的 cython 代码,大约需要 17 秒。这还是太多了。你有任何提示如何加速这段代码:
import numpy as np
cimport numpy as np
cimport cython
FTYPE = np.float
ctypedef np.float_t FTYPE_t
@cython.boundscheck(False)
def delay(np.ndarray[FTYPE_t, ndim=1] f, np.ndarray[FTYPE_t, ndim=1] g):
cdef int size1 = f.shape[0]
cdef int size2 = g.shape[0]
cdef int max_correlation = 0
cdef int delay = 0
cdef int current_correlation, i, j
# Move second data set frame by frame
for i in range(0, size1 - size2):
current_correlation = 0
# Calculate correlation at that point
for j in range(size2):
current_correlation += f[<unsigned int>(i+j)] * g[j]
# Check if current correlation is highest so far
if current_correlation > max_correlation:
max_correlation = current_correlation
delay = i
return delay
【问题讨论】:
-
只是出于好奇,每个音频信号中的样本数是多少?
-
大约 10.000 个样本被切割用于延迟计算。这意味着窗口滑动 10k 步。
-
啊。直接相关性为 O(n^2),因此对于 n = 10,000,大约需要 100,000,000 次操作。基于 FFT 的相关性为 O(n lg n),因此对于 n = 10,000,大约有 132,877 次操作。