एफएफटी के माध्यम से फास्ट कोसाइन ट्रांसफॉर्म


15

मैं तेज कोसाइन ट्रांसफॉर्म को लागू करना चाहता हूं। मैंने विकिपीडिया पर पढ़ा , कि डीसीटी का एक तेज़ संस्करण है जो एफएफटी के समान है। मैं उद्धृत पढ़ने के लिए करने की कोशिश की Makhoul * कागज, FTPACK और FFTW कार्यान्वयन कि भी उपयोग किया जाता है के लिए SciPy , लेकिन मैं वास्तव में एल्गोरिथ्म निकालने में सक्षम नहीं थे। अभी तक मेरे पास इतना ही है:

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])

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 

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])

*जे। माखौल, "एक और दो आयामों में एक तेज कोसाइन ट्रांसफॉर्म होता है," आईईईई ट्रांस। Acoust। भाषण सिग। प्रोक। 28 (1), 27-34 (1980)।


2
क्या आप पूछ रहे हैं कि आपका DCT कोड सही है या कुछ और?
जिम क्ले

आपकी टिप्पणीयों के लिए धन्यवाद। मैंने शुरुआत में एक और वाक्य जोड़ा। मेरा उद्देश्य एफएफटी को एफएफटी के आधार पर लागू करना है।
Framester

जवाबों:


18

मैं, इस बारे में पढ़ रहा था और वहाँ यह करने के लिए कई तरीके, का उपयोग कर विभिन्न आकार एन मेरे मैटलैब जंग लगी है इसलिए यहाँ वे अजगर (में हैं Nइनपुट संकेत की लंबाई है x, kहै arange(N)= ):[0,1,2,,एन-1]

4N FFT और कोई बदलाव का उपयोग करके टाइप 2 DCT

सिग्नल [a, b, c, d]बन जाता है

[0, a, 0, b, 0, c, 0, d, 0, d, 0, c, 0, b, 0, a]

फिर स्पेक्ट्रम पाने के लिए एफएफटी लें

[A, B, C, D, 0, -D, -C, -B, -A, -B, -C, -D, 0, D, C, B]

फिर सब कुछ फेंक दो लेकिन पहले [A, B, C, D], और तुम हो गए:

u = zeros(4 * N)
u[1:2*N:2] = x
u[2*N+1::2] = x[::-1]

U = fft(u)[:N]
return U.real

2N FFT (Makhoul) का उपयोग करके टाइप 2 DCT

[a, b, c, d][a, b, c, d, d, c, b, a][A, B, C, D, 0, D*, C*, B*][A, B, C, D]-जेπ2एन

y = empty(2*N)
y[:N] = x
y[N:] = x[::-1]

Y = fft(y)[:N]

Y *= exp(-1j*pi*k/(2*N))
return Y.real

2N FFT गद्देदार (मखौल) का उपयोग करके टाइप 2 DCT

[a, b, c, d][a, b, c, d, 0, 0, 0, 0][A, B, C, D, E, D*, C*, B*][A, B, C, D]2-जेπ2एन

y = zeros(2*N)
y[:N] = x

Y = fft(y)[:N]

Y *= 2 * exp(-1j*pi*k/(2*N))
return Y.real

N FFT (मखौल) का उपयोग करके टाइप 2 DCT

[a, b, c, d, e, f][a, c, e, f, d, b][A, B, C, D, C*, B*]2-जेπ2एन

v = empty_like(x)
v[:(N-1)//2+1] = x[::2]

if N % 2: # odd length
    v[(N-1)//2+1:] = x[-2::-2]
else: # even length
    v[(N-1)//2+1:] = x[::-2]

V = fft(v)

V *= 2 * exp(-1j*pi*k/(2*N))
return V.real

मेरी मशीन पर, ये सभी लगभग एक ही गति हैं, क्योंकि उत्पन्न exp(-1j*pi*k/(2*N))होने में एफएफटी से अधिक समय लगता है। : डी

In [99]: timeit dct2_4nfft(a)
10 loops, best of 3: 23.6 ms per loop

In [100]: timeit dct2_2nfft_1(a)
10 loops, best of 3: 20.1 ms per loop

In [101]: timeit dct2_2nfft_2(a)
10 loops, best of 3: 20.8 ms per loop

In [102]: timeit dct2_nfft(a)
100 loops, best of 3: 16.4 ms per loop

In [103]: timeit scipy.fftpack.dct(a, 2)
100 loops, best of 3: 3 ms per loop

2
महान जवाब, मेरे कार्यान्वयन में बहुत मदद की! अतिरिक्त नोट: अंतिम विधि "टाइप 2 डीसीटी एन एफएफटी का उपयोग करना" अभी भी ठीक से काम करता है अगर सिग्नल की लंबाई विषम है; अंतिम तत्व मध्य तत्व पर जाता है। मैंने इस तथ्य के लिए गणित और कोड को सत्यापित किया है।
नायुकी

1
@Nayuki आप पैदा exp(-1j*pi*k/(2*N))कर रहे हैं या उस कदम का कोई शॉर्टकट है?
एंडोलिथ

मैं exp(-1j*pi*k/(2*N))अपने कोड में उत्पन्न कर रहा हूं , क्योंकि DCT-to-DFT मैपिंग कार्य करने के लिए एक तिमाही-नमूना शिफ्ट आवश्यक है। तुम क्या पूछते हो?
नायुकी

नमस्ते, DCT-II के व्युत्क्रम की गणना करने के लिए, टाइप III DCT के लिए यह कैसे काम करेगा?
जैक एच

8

एक्स(n)

चलो

y(n)={एक्स(n),n=0,1,,एन-1एक्स(2एन-1-n),n=एन,एन+1,,2एन-1

उसके बाद DCT द्वारा दिया जाता है

सी()=आर{-जेπ2एनएफएफटी{y(n)}}

2एनy(n)एक्स(n)एक्स(n)

यहाँ MATLAB में कोड है।

function C = fdct(x)
    N = length(x);
    y = zeros(1,2*N);
    y(1:N) = x;
    y(N+1:2*N) = fliplr(x);
    Y = fft(y);
    k=0:N-1;
    C = real(exp(-j.* pi.*k./(2*N)).*Y(1:N));

संपादित करें:

नोट: DCT सूत्र जो इसका उपयोग कर रहा है:

सी()=2Σn=0एन-1एक्स(n)क्योंकि(π2एन(2n+1))

योग को स्केल करने के कई तरीके हैं, इसलिए यह अन्य कार्यान्वयन के साथ बिल्कुल मेल नहीं खा सकता है। उदाहरण के लिए, MATLAB का उपयोग करता है:

सी()=w()Σn=0एन-1एक्स(n)क्योंकि(π2एन(2n+1))

w(0)=1एनw(1 ...एन-1)=2एन

आउटपुट को ठीक से स्केल करके आप इसके लिए जिम्मेदार हो सकते हैं।


1
y (n) को N-लंबाई माना जाता है, 2N-लंबाई नहीं। यही कारण है कि 2N FFT के बजाय N-length सिग्नल से N-length DCT की गणना करके आपको 4x कम्प्यूटेशन गति मिलती है। fourier.eng.hmc.edu/e161/lectures/dct/node2.html www-ee.uta.edu/dip/Courses/EE5355/Discrete%20class%201.pdf
एंडोलिथ

0

सही वैज्ञानिक कंप्यूटिंग के लिए, स्मृति उपयोग की मात्रा भी महत्वपूर्ण है। इसलिए एन पॉइंट एफएफटी मेरे लिए अधिक आकर्षक है। यह संकेत के हरमिटियन समरूपता के कारण ही संभव है। संदर्भ मखौल यहां दिया गया है। और वास्तव में DCT और IDCT या DCT10 और DCT01 की गणना के लिए एल्गोरिथ्म है।
http://ieeexplore.ieee.org/abstract/document/1163351/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.