2
from numpy import conj, dot, ogrid, pi, r_, sin, transpose, zeros
3
from scipy import linalg
6
__all__ = """dct idct dct2 idct2 dctn idctn dct2raw idct2raw
7
dst idst dst2 idst2 dstn idstn
8
digitrevorder bitrevorder wht
11
# fast discrete cosine transforms of real sequences (using the fft)
12
# These implement the DCT-II and inverse DCT-II (DCT-III)
13
# described at http://en.wikipedia.org/wiki/Discrete_cosine_transform
16
"""Discrete cosine transform based on the FFT.
18
For even-length signals it uses an N-point FFT
19
For odd-length signals it uses a 2N-point FFT.
28
slices[k].append(slice(None))
31
slices[0][axis] = slice(None,N/2)
32
slices[1][axis] = slice(None,None,2)
33
slices[2][axis] = slice(N/2,None)
34
slices[3][axis] = slice(N,None,-2)
36
newshape = list(x.shape)
38
xtilde = np.empty(newshape,np.float64)
39
slices[0][axis] = slice(None,N)
40
slices[2][axis] = slice(N,None)
41
slices[3][axis] = slice(None,None,-1)
44
slices[k] = tuple(slices[k])
45
xtilde[slices[0]] = x[slices[1]]
46
xtilde[slices[2]] = x[slices[3]]
47
Xt = np.fft(xtilde,axis=axis)
48
pk = np.exp(-1j*pi*np.arange(N)/(2*N))
68
slices[k].append(slice(None))
71
ak = np.r_[1.0,[2]*(N-1)]*np.exp(1j*pi*k/(2*N))
75
xhat = np.real(np.ifft(v*ak,axis=axis))
77
slices[0][axis] = slice(None,None,2)
78
slices[1][axis] = slice(None,N/2)
79
slices[2][axis] = slice(N,None,-2)
80
slices[3][axis] = slice(N/2,None)
82
slices[k] = tuple(slices[k])
83
x[slices[0]] = xhat[slices[1]]
84
x[slices[2]] = xhat[slices[3]]
87
ak = 2*np.exp(1j*pi*k/(2*N))
91
newshape = list(v.shape)
93
Y = zeros(newshape,np.complex128)
95
#Y[(N+1):] = conj(Y[N:0:-1])
96
slices[0][axis] = slice(None,N)
97
slices[1][axis] = slice(None,None)
98
slices[2][axis] = slice(N+1,None)
99
slices[3][axis] = slice((N-1),0,-1)
101
Y[slices[2]] = conj(Y[slices[3]])
102
x = np.real(np.ifft(Y,axis=axis))[slices[0]]
105
def dct2(x,axes=(-1,-2)):
106
return dct(dct(x,axis=axes[0]),axis=axes[1])
108
def idct2(v,axes=(-1,-2)):
109
return idct(idct(v,axis=axes[0]),axis=axes[1])
111
def dctn(x,axes=None):
113
axes = np.arange(len(x.shape))
116
res = dct(res,axis=k)
119
def idctn(v,axes=None):
121
axes = np.arange(len(v.shape))
124
res = idct(res,axis=k)
130
C = np.cos(pi*(2*n+1)*l/(2*N))
137
return dot(transpose(CM),dot(x,CN))
141
iCM = linalg.inv(makeC(M))
142
iCN = linalg.inv(makeC(N))
143
return dot(transpose(iCM),dot(v,iCN))
147
C = sin(pi*(k+1)*(n+1)/(N+1))
152
"""Discrete Sine Transform (DST-I)
154
Implemented using 2(N+1)-point FFT
155
xsym = r_[0,x,0,-x[::-1]]
156
DST = (-imag(fft(xsym))/2)[1:(N+1)]
158
adjusted to work over an arbitrary axis for entire n-dim array
166
slices[k].append(slice(None))
167
newshape = list(x.shape)
168
newshape[axis] = 2*(N+1)
169
xtilde = np.zeros(newshape,np.float64)
170
slices[0][axis] = slice(1,N+1)
171
slices[1][axis] = slice(N+2,None)
172
slices[2][axis] = slice(None,None,-1)
174
slices[k] = tuple(slices[k])
175
xtilde[slices[0]] = x
176
xtilde[slices[1]] = -x[slices[2]]
177
Xt = np.fft(xtilde,axis=axis)
178
return (-np.imag(Xt)/2)[slices[0]]
187
slices[k].append(slice(None))
188
newshape = list(v.shape)
189
newshape[axis] = 2*(N+1)
190
Xt = np.zeros(newshape,np.complex128)
191
slices[0][axis] = slice(1,N+1)
192
slices[1][axis] = slice(N+2,None)
193
slices[2][axis] = slice(None,None,-1)
196
slices[k] = tuple(slices[k])
198
Xt[slices[1]] = val[slices[2]]
199
xhat = np.real(np.ifft(Xt,axis=axis))
200
return xhat[slices[0]]
202
def dst2(x,axes=(-1,-2)):
203
return dst(dst(x,axis=axes[0]),axis=axes[1])
205
def idst2(v,axes=(-1,-2)):
206
return idst(idst(v,axis=axes[0]),axis=axes[1])
208
def dstn(x,axes=None):
210
axes = np.arange(len(x.shape))
213
res = dst(res,axis=k)
216
def idstn(v,axes=None):
218
axes = np.arange(len(v.shape))
221
res = idst(res,axis=k)
224
def digitrevorder(x,base):
233
raise ValueError, "Length of data must be power of base."
236
vec = r_[[base**n for n in range(L)]]
237
newx = x[np.newaxis,:]*vec[:,np.newaxis]
239
for k in range(L-1,-1,-1):
240
newx[k] = x // vec[k]
241
x = x - newx[k]*vec[k]
245
# construct new result from reversed digts
252
return digitrevorder(x,2)
257
"""Walsh-Hadamaard Transform (sequency ordered)
259
adapted from MATLAB algorithm published on the web by
260
Author: Gylson Thomas
261
e-mail: gylson_thomas@yahoo.com
262
Asst. Professor, Electrical and Electronics Engineering Dept.
263
MES College of Engineering Kuttippuram,
264
Kerala, India, February 2005.
266
Reference: N.Ahmed, K.R. Rao, "Orthogonal Transformations for
267
Digital Signal Processing" Spring Verlag, New York 1975. page-111.
271
if ((L-np.floor(L)) > 0.0):
272
raise ValueError, "Length must be power of 2"
276
for i1 in range(1,L+1): #Iteration stage
278
for i2 in range(1,k2+1):
279
for i3 in range(1,k3+1):
281
temp1= x[i-1]; temp2 = x[j-1];
283
x[i-1] = temp1 - temp2;
284
x[j-1] = temp1 + temp2;
285
x[i-1] = temp1 + temp2;
286
x[j-1] = temp1 - temp2;
288
k1 = k1/2; k2 = k2*2; k3 = k3/2;
289
x = x*1.0/N; # Delete this line for inverse wht