Ich möchte die schnelle Kosinustransformation implementieren. Ich habe auf Wikipedia gelesen , dass es eine schnelle Version der DCT gibt, die ähnlich wie die FFT berechnet wird. Ich habe versucht, das zitierte Makhoul * -Papier für die FTPACK- und FFTW-Implementierungen zu lesen , die auch in Scipy verwendet werden , aber ich konnte den tatsächlichen Algorithmus nicht extrahieren. Das habe ich bisher:
FFT-Code:
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])
DCT-Code:
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
FCT-Studie:
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, "Eine schnelle Cosinustransformation in einer und zwei Dimensionen", IEEE Trans. Akust. Speech Sig. Proc. 28 (1), 27 & ndash; 34 (1980).
Antworten:
N
x
k
arange(N)
Typ 2 DCT mit 4N FFT und ohne Schichten
Signal
[a, b, c, d]
wird[0, a, 0, b, 0, c, 0, d, 0, d, 0, c, 0, b, 0, a]
.Nehmen Sie dann die FFT, um das Spektrum zu erhalten
[A, B, C, D, 0, -D, -C, -B, -A, -B, -C, -D, 0, D, C, B]
dann wirf alles weg, bis auf das erste
[A, B, C, D]
, und du bist fertig:Typ 2 DCT mit gespiegelter 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]
Typ 2 DCT mit 2N FFT gepolstert (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]
Typ 2 DCT mit N FFT (Makhoul)
Signal2 e- j πk2 N
[a, b, c, d, e, f]
wird[a, c, e, f, d, b]
, dann nimm die FFT um zu bekommen[A, B, C, D, C*, B*]
. Mit multiplizierenAuf meinem Computer sind diese ungefähr gleich schnell, da das Generieren
exp(-1j*pi*k/(2*N))
länger dauert als die FFT. : Dquelle
exp(-1j*pi*k/(2*N))
oder gibt es eine Verknüpfung zu diesem Schritt?exp(-1j*pi*k/(2*N))
in meinem Code , weil eine Viertelstichprobenverschiebung erforderlich ist, damit das DCT-zu-DFT-Mapping funktioniert. Warum fragst du?Lassen
Die DCT wird dann von gegeben
Hier ist der Code in MATLAB.
Bearbeiten:
Hinweis: Die verwendete DCT-Formel lautet:
Es gibt verschiedene Möglichkeiten, die Summe zu skalieren, sodass sie möglicherweise nicht genau mit anderen Implementierungen übereinstimmt. Zum Beispiel verwendet MATLAB:
Sie können dies berücksichtigen, indem Sie die Ausgabe richtig skalieren.
quelle
Für echtes wissenschaftliches Rechnen ist auch der Umfang der Speichernutzung wichtig. Daher ist die N-Punkt-FFT für mich attraktiver. Dies ist nur aufgrund der hermitischen Symmetrie des Signals möglich. Die Referenz Makhoul ist hier angegeben. Und tatsächlich hat der Algorithmus zur Berechnung von DCT und IDCT oder DCT10 und DCT01.
http://ieeexplore.ieee.org/abstract/document/1163351/
quelle