由於dft演算法太慢,fft是更加快速的演算法。
import numpy as np
f0,f1 = 0.5,2 # 最高頻率為f1
t = 1/f0 # 取樣時間為最低頻率對應的週期
fs = m*f1 # 取樣頻率為最高頻率的m倍
dt = 1/fs # 取樣間隔
# 生產取樣訊號
t = np.arange(0,t,dt)
y = 3 + 2*np.sin(2*np.pi*f0*t+np.pi/2) + np.sin(2*np.pi*f1*t+np.pi/3)
# 進行dft
n = len(y)
x_dft = np.zeros([n],dtype=complex) # 生成n個元素的向量
for k in range(n):
for n in range(n):
# 累加
x_dft[k] = x_dft[k] + y[n]*np.exp(-2j*np.pi*k*n/n)
# 捨去
x_dft = np.round(x_dft,4)
print(x_dft)
進行fft變換
x_fft = np.fft.fft(y)
x_fft = np.round(x_fft,4)
print(x_fft)
幅值
# 取模後,第乙個元素除以n,其餘元素除以n/2,才是幅值
x_fft_abs = abs(x_fft)/len(y)*2
x_fft_abs[0] = x_fft_abs[0]/2
x_fft_abs = np.round(x_fft_abs,4)
相位
# 結果加pi/2才是相位
x_fft_phase = np.angle(x_fft) + np.pi/2
x_fft_phase[0] = 0
頻率序列
freq = np.fft.fftfreq(len(y),dt)
我們所要的資訊是:
f=0,a=3
f=0.5,a=2,φ=1.5708
f=2,a=1,φ=1.0472
其他值不是我們關心的。
比如下面這行**沒啥意思,雖然在這沒啥意思,但如果要編寫程式自動找出幅值與之對應的相位以及頻率,這麼做會方便查詢。
x_fft_phase[0] = 0
第一組 m = 3,n=12
第二組 m = 4,n=16=2^4
因為時間太短不明顯,將取樣時間調長,t=1/f0*100
第一組,fft用時0.0019s,dft用時5s,第二組,fft用時0.0s,dft用時9s
這只是一次統計,但可以說明fft速度就是快,dft速度特別慢。因為速度太快,所以沒有顯示出變換序列是2的整數次方,fft會更快。
理論上對於fft演算法,變換序列是2的整數次方,會更快。
dft的快速演算法有好多種,有名的是庫利-圖基快速傅利葉變換演算法(cooley-tukey)即fft演算法。
快速傅利葉變換#其他演算法
混疊:取樣率低於最高頻率的2倍造成的(欠取樣造成的)
能量洩露:取樣時間過短造成的(用於fft的訊號過短造成的)
柵欄效應:雖然取樣率滿足最高頻率的2倍,但還是太低造成的
總之,取樣率盡量高、取樣時間盡量長、取樣時間盡量為各分量週期的倍數(整週期取樣),就不會發生這些,分解得到的幅值、相位越接近實際。
疑問:在此實驗中,取樣時間為1/f0,我的取樣率為2*f1時,就會出現混疊,導致f=2對應的幅值能量洩露,因此改為3*f1,不知道什麼問題?
蒙特卡洛的metropolis演算法
線性規劃中的單純形法
krylov子空間迭代法
矩陣計算的分解方法
fotran最優化編譯器
計算特徵值的qr演算法
用於排序的quicksort演算法
fft整數關係探測
快速多級子法
關於DFT與FFT的細節備忘
備忘內容 dft是將離散非週期訊號,如 做週期延拓之後,認為它是週期訊號,再做傅利葉變換的乙個過程。做完傅利葉變換之後,得到的仍然是乙個週期離散訊號,取其主值序列即可 所以,之前部落格裡的內容實際上有一點問題,因為做週期延拓的時候,如果原訊號是乙個週期訊號,但是截斷的位置並不是完整的週期,那麼實際上...
對於FFT和DFT的理解
此篇文章是對 ministm32f103實現家庭普通電路中的電流諧波檢測 一文的補充 本文參考 快速傅利葉變換學習及c語言實現 形象的介紹 什麼是傅利葉變換?手把手教你理解 fft fft是最重要,也是最難懂的。簡單說下原理 fft 快速傅利葉變換 是dft 離散傅利葉變換 的改進演算法,其將dft...
DFT插零FFT演算法理解
圖1 為什麼fft時域補0後,經fft變換就是頻域進行內插?應該這樣來理解這個問題 補0後的dft fft是dft的快速演算法 實際上公式並沒變,變化的只是頻域項 如 補0前fft計算得到的是m 2 pi m處的頻域值,而補0後得到的是n 2 pi n處的頻域值 m為原dft長度,n變成了補0後的長...