Eu quero implementar a Transformação rápida de cosseno. Eu li na wikipedia , que existe uma versão rápida do DCT que é similarmente calculada à FFT. Tentei ler o artigo Makhoul * citado , para as implementações FTPACK e FFTW que também são usadas no Scipy , mas não consegui extrair o algoritmo realmente. Isto é o que eu tenho até agora:
Código FFT:
def fft(x):
if x.size ==1:
return x
N = x.size
x0 = my_fft(x[0:N:2])
x1 = my_fft(x[0+1:N:2])
k = numpy.arange(N/2)
e = numpy.exp(-2j*numpy.pi*k/N)
l = x0 + x1 * e
r = x0 - x1 * e
return numpy.hstack([l,r])
Código DCT:
def dct(x):
k = 0
N = x.size
xk = numpy.zeros(N)
for k in range(N):
for n in range(N):
xn = x[n]
xk[k] += xn*numpy.cos(numpy.pi/N*(n+1/2.0)*k)
return xk
Julgamento da FCT:
def my_fct(x):
if x.size ==1:
return x
N = x.size
x0 = my_fct(x[0:N:2]) # have to be set to zero?
x1 = my_fct(x[0+1:N:2])
k = numpy.arange(N/2)
n = # ???
c = numpy.cos(numpy.pi/N*(n+1/2.0)*k)
l = x0 #???
r = x0 #???
return numpy.hstack([l,r])
* J. Makhoul, "Uma transformação rápida de cosseno em uma e duas dimensões", IEEE Trans. Acoust. Speech Sig. Proc. 28 (1), 27-34 (1980).
Respostas:
N
x
k
arange(N)
Tipo 2 DCT usando 4N FFT e sem turnos
O sinal
[a, b, c, d]
se torna[0, a, 0, b, 0, c, 0, d, 0, d, 0, c, 0, b, 0, a]
.Em seguida, pegue a FFT para obter o espectro
[A, B, C, D, 0, -D, -C, -B, -A, -B, -C, -D, 0, D, C, B]
jogue fora tudo, menos o primeiro
[A, B, C, D]
, e pronto:Tipo 2 DCT usando 2N FFT espelhado (Makhoul)
[a, b, c, d]
[a, b, c, d, d, c, b, a]
[A, B, C, D, 0, D*, C*, B*]
[A, B, C, D]
Tipo 2 DCT usando 2N FFT acolchoado (Makhoul)
[a, b, c, d]
[a, b, c, d, 0, 0, 0, 0]
[A, B, C, D, E, D*, C*, B*]
[A, B, C, D]
DCT tipo 2 usando N FFT (Makhoul)
[a, b, c, d, e, f]
[a, c, e, f, d, b]
[A, B, C, D, C*, B*]
Na minha máquina, todas elas têm aproximadamente a mesma velocidade, pois a geração
exp(-1j*pi*k/(2*N))
leva mais tempo que a FFT. : Dfonte
exp(-1j*pi*k/(2*N))
ou existe um atalho para essa etapa?exp(-1j*pi*k/(2*N))
no meu código , porque é necessário um deslocamento de quarto de amostra para fazer o mapeamento do DCT para o DFT. O que faz você perguntar?deixei
O DCT é então dado por
Aqui está o código no MATLAB.
Editar:
Nota: A fórmula DCT que está usando é:
Existem várias maneiras de dimensionar a soma para que ela não corresponda exatamente a outras implementações. Por exemplo, o MATLAB usa:
Você pode explicar isso dimensionando corretamente a saída.
fonte
Para uma verdadeira computação científica, a quantidade de uso de memória também é importante. Portanto, o ponto N FFT é mais atraente para mim. Isso só é possível devido à simetria hermitiana do sinal. A referência Makhoul é dada aqui. E, na verdade, possui o algoritmo para calcular DCT e IDCT ou DCT10 e DCT01.
http://ieeexplore.ieee.org/abstract/document/1163351/
fonte