模块scikits.talkbox包含一些用于Levinson-Durbin递归的C代码。不幸的是,这段代码在最新版本的Python中不起作用,我想用纯Python实现替换它。 (速度不是问题,只要它有效。)
破坏的C函数的docstring读取:
Levinson-Durbin recursion, to efficiently solve symmetric linear systems
with toeplitz structure.
Parameters
----------
r : array-like
input array to invert (since the matrix is symmetric Toeplitz, the
corresponding pxp matrix is defined by p items only). Generally the
autocorrelation of the signal for linear prediction coefficients
estimation. The first item must be a non zero real, and corresponds
to the autocorelation at lag 0 for linear prediction.
order : int
order of the recursion. For order p, you will get p+1 coefficients.
axis : int, optional
axis over which the algorithm is applied. -1 by default.
Returns
-------
a : array-like
the solution of the inversion (see notes).
e : array-like
the prediction error.
k : array-like
reflection coefficients.
Notes
-----
Levinson is a well-known algorithm to solve the Hermitian toeplitz
equation: ::
_ _
-R[1] = R[0] R[1] ... R[p-1] a[1]
: : : : :
: : : _ * :
-R[p] = R[p-1] R[p-2] ... R[0] a[p]
with respect to a. Using the special symmetry in the matrix, the inversion
can be done in O(p^2) instead of O(p^3).
Only double argument are supported: float and long double are internally
converted to double, and complex input are not supported at all.
我看到有一个函数scipy.linalg.solve_toeplitz
看起来像我想要的。但是,它无法指定顺序,并将数组元组作为输入。
我承认我在这里有点偏离我的深度,并且不完全理解这段代码应该做什么。是否有一种简单的方法可以用Numpy的solve_toeplitz
替换对已损坏的C函数的调用?
答案 0 :(得分:0)
scikits.talkbox
包还包含一个名为py_lpc
的模块,其中包含LPC估计的纯Python实现。适应这一点并不困难。
def lpc2(signal, order):
"""Compute the Linear Prediction Coefficients.
Return the order + 1 LPC coefficients for the signal. c = lpc(x, k) will
find the k+1 coefficients of a k order linear filter:
xp[n] = -c[1] * x[n-2] - ... - c[k-1] * x[n-k-1]
Such as the sum of the squared-error e[i] = xp[i] - x[i] is minimized.
Parameters
----------
signal: array_like
input signal
order : int
LPC order (the output will have order + 1 items)"""
order = int(order)
if signal.ndim > 1:
raise ValueError("Array of rank > 1 not supported yet")
if order > signal.size:
raise ValueError("Input signal must have a lenght >= lpc order")
if order > 0:
p = order + 1
r = np.zeros(p, signal.dtype)
# Number of non zero values in autocorrelation one needs for p LPC
# coefficients
nx = np.min([p, signal.size])
x = np.correlate(signal, signal, 'full')
r[:nx] = x[signal.size-1:signal.size+order]
phi = np.dot(sp.linalg.inv(sp.linalg.toeplitz(r[:-1])), -r[1:])
return np.concatenate(([1.], phi)), None, None
else:
return np.ones(1, dtype = signal.dtype), None, None
这会在不使用任何特殊Toeplitz属性的情况下反转矩阵,使其显着变慢,但无需任何C代码即可工作。