मैं FFT का उपयोग करते समय स्पाइक्स के प्रसार की उत्पत्ति की व्याख्या करने के लिए यह अतिरिक्त उत्तर लिखता हूं और विशेष रूप से scipy.fftpack ट्यूटोरियल पर चर्चा करता हूं जिसके साथ मैं कुछ बिंदु पर असहमत हूं।
इस उदाहरण में, रिकॉर्डिंग समय tmax=N*T=0.75
। संकेत है sin(50*2*pi*x) + 0.5*sin(80*2*pi*x)
। आवृत्ति संकेत में आवृत्तियों पर 50
और 80
एम्पलीट्यूड के साथ दो स्पाइक्स होने चाहिए 1
और 0.5
। हालाँकि, यदि विश्लेषण किए गए सिग्नल में पूर्णांक संख्या नहीं है, तो संकेत की छंटनी के कारण प्रसार की अवधि दिखाई दे सकती है:
- पाईक 1:
50*tmax=37.5
=> आवृत्ति इस आवृत्ति पर संकेत छंटनी के कारण प्रसार50
का एक 1/tmax
= = प्रसार की उपस्थिति नहीं है ।
- पाईक 2:
80*tmax=60
=> आवृत्ति इस आवृत्ति पर सिग्नल ट्रंकेशन के कारण 80
बहुविध 1/tmax
=> कोई प्रसार नहीं है ।
यहां एक कोड है जो ट्यूटोरियल में उसी सिग्नल का विश्लेषण करता है ( sin(50*2*pi*x) + 0.5*sin(80*2*pi*x)
), लेकिन थोड़े अंतर के साथ:
- मूल scipy.fftpack उदाहरण।
- सिग्नल अवधि की पूर्णांक संख्या (
tmax=1.0
इसके बजाय) के साथ मूल scipy.fftpack उदाहरण0.75
प्रसार से बचने लिए) के ।
- मूल scipy.fftpack उदाहरण काल की पूर्णांक संख्या के साथ उदाहरण और जहां दिनांक और आवृत्तियों को एफएफटी सिद्धांत से लिया जाता है।
कोड:
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack
N = 600
tmax = 3/4
T = tmax / N
x1 = np.linspace(0.0, N*T, N)
y1 = np.sin(50.0 * 2.0*np.pi*x1) + 0.5*np.sin(80.0 * 2.0*np.pi*x1)
yf1 = scipy.fftpack.fft(y1)
xf1 = np.linspace(0.0, 1.0/(2.0*T), N//2)
tmax = 1
T = tmax / N
x2 = np.linspace(0.0, N*T, N)
y2 = np.sin(50.0 * 2.0*np.pi*x2) + 0.5*np.sin(80.0 * 2.0*np.pi*x2)
yf2 = scipy.fftpack.fft(y2)
xf2 = np.linspace(0.0, 1.0/(2.0*T), N//2)
tmax = 1
T = tmax / N
x3 = T * np.arange(N)
y3 = np.sin(50.0 * 2.0*np.pi*x3) + 0.5*np.sin(80.0 * 2.0*np.pi*x3)
yf3 = scipy.fftpack.fft(y3)
xf3 = 1/(N*T) * np.arange(N)[:N//2]
fig, ax = plt.subplots()
ax.plot(xf1, 2.0/N * np.abs(yf1[:N//2]), label='fftpack tutorial')
ax.plot(xf2, 2.0/N * np.abs(yf2[:N//2]), label='Integer number of periods')
ax.plot(xf3, 2.0/N * np.abs(yf3[:N//2]), label='Correct positioning of dates')
plt.legend()
plt.grid()
plt.show()
आउटपुट:
जैसा कि यह यहां हो सकता है, यहां तक कि पूर्णांक संख्याओं का उपयोग करके कुछ प्रसार अभी भी बना हुआ है। यह व्यवहार scipy.fftpack ट्यूटोरियल में दिनांक और आवृत्तियों की खराब स्थिति के कारण है। इसलिए, असतत फूरियर रूपांतरण के सिद्धांत में:
- सिग्नल का मूल्यांकन उन तिथियों पर किया जाना चाहिए
t=0,T,...,(N-1)*T
जहां T नमूना अवधि है और संकेत की कुल अवधि है tmax=N*T
। ध्यान दें कि हम पर रोक tmax-T
।
- संबंधित आवृत्तियाँ नमूने की आवृत्ति
f=0,df,...,(N-1)*df
कहाँ df=1/tmax=1/(N*T)
है। संकेत के सभी हार्मोनिक्स विसरण से बचने के लिए नमूना आवृत्ति के कई होने चाहिए।
ऊपर दिए गए उदाहरण में, आप देख सकते हैं कि आवृत्ति स्पेक्ट्रम में अतिरिक्त प्रसार से बचने के लिए सक्षम के arange
बजाय का उपयोग linspace
। इसके अलावा, का उपयोग करlinspace
संस्करण भी स्पाइक्स की भरपाई होती है, जो कि जितनी होनी चाहिए, उससे थोड़ी अधिक आवृत्तियों पर स्थित होती हैं, यह पहली तस्वीर में देखा जा सकता है, जहां स्पाइक्स आवृत्तियों के दाईं ओर थोड़ा सा होते हैं 50
और80
।
मैं केवल यह निष्कर्ष निकालता हूं कि उपयोग का उदाहरण निम्नलिखित कोड द्वारा प्रतिस्थापित किया जाना चाहिए (जो मेरी राय में कम भ्रामक है):
import numpy as np
from scipy.fftpack import fft
N = 600
T = 1.0 / 800.0
x = T*np.arange(N)
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = fft(y)
xf = 1/(N*T)*np.arange(N//2)
import matplotlib.pyplot as plt
plt.plot(xf, 2.0/N * np.abs(yf[0:N//2]))
plt.grid()
plt.show()
आउटपुट (दूसरा स्पाइक अब विसरित नहीं है):
मुझे लगता है कि यह उत्तर अभी भी सही ढंग से असतत फूरियर रूपांतरण को लागू करने के बारे में कुछ अतिरिक्त स्पष्टीकरण लाता है। जाहिर है, मेरा जवाब बहुत लंबा है और कहने के लिए हमेशा अतिरिक्त चीजें होती हैं ( उदाहरण के लिए एलियासिंग के बारे में संक्षेप में बात की गई है और बहुत कुछ कहा जा सकता है विंडोइंग ), इसलिए मैं रुक ।
मुझे लगता है कि इसे लागू करते समय असतत फूरियर रूपांतरण के सिद्धांतों को गहराई से समझना बहुत महत्वपूर्ण है क्योंकि हम सभी जानते हैं कि यहां बहुत सारे लोग कारकों को जोड़ रहे हैं और इसे लागू करने के लिए कि वे क्या चाहते हैं।