-
Notifications
You must be signed in to change notification settings - Fork 14
/
LevinsonDurbanRecursion.py
109 lines (87 loc) · 2.57 KB
/
LevinsonDurbanRecursion.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import numpy as np
import pylab as pl
from numpy.fft import fft, ifft
def LPC(x, ncoeffs):
dims = np.shape(x)
nrows = dims[0]
if len(dims) == 1:
ncols = 1
x = (x*np.ones((1,nrows))).T
else:
ncols = dims[1]
# Autocorrelation
#R = np.zeros((ncols,ncoeffs+1))
R = np.real(ifft(np.abs(fft(x.T, n=len(x)) ** 2)))
R = R[:,:ncoeffs+1]
# Least-squares minimisation of a Toeplitz matrix
# by Levinson-Durban recursion
A = np.zeros((ncols,ncoeffs+1))
A[:,0] = np.ones(ncols)
#print(A)
E = np.zeros(ncols)
for col in range(ncols):
# Crapper autocorrelation
#for i in range(ncoeffs+1):
#for j in range(nrows-i):
#R[col,i] += x[j,col] * x[j+i,col]
e = R[col,0]
for k in range(ncoeffs):
l = 0
for j in range(k+1):
l -= A[col,j]*R[col,k+1-j]
l /= e
for n in range((k+1)//2 + 1):
temp = A[col,k+1-n] + l*A[col,n]
A[col,n] += l * A[col,k+1-n]
A[col,k+1-n] = temp
e *= 1 - l*l
E[col] = e
return A, E, R
def test(ncoeffs=4):
o = np.zeros(128)
for i in range(1,129):
o[i-1] = np.sin(0.01*i) + 0.75*np.sin(0.03*i) + 0.5*np.sin(0.05*i) + 0.25 * np.sin(0.11*i)
#print(o)
A, E, R = LPC(o,ncoeffs)
#print(np.shape(A))
p = np.zeros(128)
for i in range(ncoeffs,len(o)):
for j in range(ncoeffs):
p[i] -= A[0,j+1] * o[i-1-j]
e = 0
for i in range(ncoeffs,len(o)):
delta = o[i] - p[i]
e += delta*delta
print(e)
print(np.shape(A))
A = np.squeeze(A)
roots = np.roots(A)
roots = [r for r in roots if np.imag(r) >= 0]
angles = np.arctan2(np.imag(roots), np.real(roots))
freqs = []
freqs.append(sorted(angles * (128 / (2 * np.pi))))
print(freqs)
def test2(ncoeffs=4):
o = np.zeros((128,2))
for i in range(1,129):
o[i-1,0] = np.sin(0.01*i) + 0.75*np.sin(0.03*i) + 0.5*np.sin(0.05*i) + 0.25 * np.sin(0.11*i)
o[i-1,1] = np.sin(0.01*i) + 0.75*np.sin(0.03*i) + 0.5*np.sin(0.05*i) + 0.25 * np.sin(0.11*i)
#print(o)
A, E, R = LPC(o,ncoeffs)
print(np.shape(A))
print(A)
p = np.zeros(128)
for i in range(ncoeffs,len(o)):
for j in range(ncoeffs):
p[i] -= A[0,j+1] * o[i-1-j,0]
e = 0
for i in range(ncoeffs,len(o)):
delta = o[i] - p[i]
e += delta*delta
print(e)
pl.ion()
pl.plot(o,'ro')
pl.plot(p,'k+')
pl.show()
#test(4)
#test2(4)