Saya ingin menerapkan Fast Cosine Transform. Saya membaca di wikipedia , bahwa ada versi cepat dari DCT yang juga dihitung untuk FFT. Saya mencoba membaca makalah yang dikutip Makhoul *, untuk implementasi FTPACK dan FFTW yang juga digunakan dalam Scipy , tetapi saya tidak dapat mengekstrak algoritma yang sebenarnya. Inilah yang saya miliki sejauh ini:
Kode 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])
Kode 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
Uji coba 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, "Transformasi kosinus cepat dalam satu dan dua dimensi," IEEE Trans. Acoust. Pidato Sig. Proc 28 (1), 27-34 (1980).
Jawaban:
Saya telah membaca tentang ini dan ada beberapa cara untuk melakukannya, menggunakan ukuran yang berbeda N. saya Matlab adalah berkarat, jadi di sini mereka berada di Python ([ 0 , 1 , 2 , . . . , N- 1 ]
N
adalah panjang sinyal inputx
,k
adalaharange(N)
= ):Tipe 2 DCT menggunakan 4N FFT dan tanpa shift
Sinyal
[a, b, c, d]
menjadi[0, a, 0, b, 0, c, 0, d, 0, d, 0, c, 0, b, 0, a]
.Kemudian ambil FFT untuk mendapatkan spektrum
[A, B, C, D, 0, -D, -C, -B, -A, -B, -C, -D, 0, D, C, B]
lalu buang semuanya kecuali yang pertama
[A, B, C, D]
, dan Anda selesai:Tipe 2 DCT menggunakan cermin 2N FFT (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]
Tipe 2 DCT menggunakan bantalan 2N FFT (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]
Tipe 2 DCT menggunakan N FFT (Makhoul)
[a, b, c, d, e, f]
[a, c, e, f, d, b]
[A, B, C, D, C*, B*]
Di mesin saya, ini semua kira-kira kecepatan yang sama, karena menghasilkan
exp(-1j*pi*k/(2*N))
membutuhkan waktu lebih lama daripada FFT. : Dsumber
exp(-1j*pi*k/(2*N))
atau apakah ada jalan pintas ke langkah itu?exp(-1j*pi*k/(2*N))
dalam kode saya , karena pergeseran seperempat sampel diperlukan untuk membuat pemetaan DCT-ke-DFT berfungsi. Apa yang membuatmu bertanya?membiarkan
DCT kemudian diberikan oleh
Berikut kode di MATLAB.
Edit:
Catatan: Formula DCT yang digunakan adalah:
Ada beberapa cara penskalaan penjumlahan sehingga mungkin tidak cocok persis dengan implementasi lainnya. Misalnya, MATLAB menggunakan:
Anda dapat menjelaskan ini dengan menskalakan output dengan benar.
sumber
Untuk komputasi ilmiah sejati, jumlah penggunaan memori juga penting. Oleh karena itu titik N FFT lebih menarik bagi saya. Ini hanya mungkin karena Simetri Hermit dari sinyal. Referensi Makhoul diberikan di sini. Dan sebenarnya memiliki algoritma untuk menghitung DCT dan IDCT atau DCT10 dan DCT01.
http://ieeexplore.ieee.org/abstract/document/1163351/
sumber