Python與Matlab實(shí)現(xiàn)快速傅里葉變化的區(qū)別
注:兩種語言的fft算法是有區(qū)別的,最后細(xì)聊!
Matlab的fftlw函數(shù)
輸入是信號序列、對應(yīng)的時(shí)間序列、以及是否作圖,輸出可以得到單邊歸一化之后的頻率與對應(yīng)的振幅,通過輸出可以直接畫出常用的頻譜圖!
function [ F,M ] = fftlw( x,y,draw ) %FFTLW 快速傅里葉變化2021.10.26 %輸入x--時(shí)間 y--信號 draw--1為畫頻譜圖,0為不畫 %輸出F--頻率 M--幅值 N=length(y); %采樣點(diǎn)數(shù) if(mod(N,2)>0) N=N-1; end Fs=(N-1)/(x(N)-x(1)); %采樣頻率 F=(N/2:N-1)*Fs/N-Fs/2 ;%頻率 y2=abs(fftshift(fft(y(1:N)))); %快速傅里葉變化 M=2*y2(N/2+1:N)/N; %歸一化 M(1)=M(1)/2; %常量除以2 if draw==1 %可視化 figure plot(F,M) xlabel('f/HZ') ylabel('amplitude') title('頻譜圖') end end
Python的fftlw函數(shù)
輸入與matlab的略有點(diǎn)不同,分別是采樣頻率、信號序列、是否作圖,輸出與matlab的函數(shù)一致。
import numpy as np from scipy.fftpack import fft,ifft import matplotlib.pyplot as plt def fftlw(Fs,y,draw): ''' Parameters ---------- Fs : 采樣頻率 y : 信號序列 draw :1為畫頻譜圖,0為不畫 Returns ------- f : 頻率 M : 幅值 ''' L=len(y) #采樣點(diǎn)數(shù) f = np.arange(int(L / 2)) * Fs / L #頻率 #M = np.abs(np.fft.fft(y))*2/L#采用numpy.fft.fft()函數(shù)并歸一化 M = np.abs((fft(y))) *2/L #采用scipy.fftpack.fft()函數(shù)并歸一化 M = M[0:int(L / 2)] #取單邊譜 M[0]=M[0]/2#常量除以2 if draw==1:#可視化 plt.figure() plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus'] = False plt.plot(f,M) plt.xlabel('f/HZ') plt.ylabel('amplitude') plt.title('頻譜圖') return f,M
構(gòu)造簡單的信號對比兩種語言fftlw效果
舉個(gè)例子,構(gòu)造如下信號驗(yàn)證所寫函數(shù)的正確性:
y=3+t⋅sin(2πt⋅100)+3⋅sin(2πt⋅200)
其中,包括常數(shù)項(xiàng),周期項(xiàng)和趨勢項(xiàng),理論上該信號的頻率應(yīng)該為0Hz、100Hz、200Hz(具體怎么算的補(bǔ)一補(bǔ)書知識(shí))。在這里,我設(shè)置采樣頻率 fs=10000,產(chǎn)生10000個(gè)數(shù)據(jù)點(diǎn),時(shí)域圖如下:
Matlab調(diào)用fftlw函數(shù)的主函數(shù)
fs=10000;%采樣頻率 x=0:1/fs:(10000-1)/fs;%時(shí)間序列 y=sin(2*pi*x*100).*x+3*sin(2*pi*x*200)+3; %信號序列 figure%畫時(shí)域圖 plot(x,y) title('時(shí)域圖') xlabel('t/s') ylabel('amplitude') [f,m]=fftlw(x,y,1);%快速傅里葉變化并畫頻譜圖
得到的頻譜圖如下:發(fā)現(xiàn)0Hz、100Hz、200Hz處的幅值分別為3,0.5,3。0Hz與200Hz處的幅值完美對應(yīng)時(shí)域中常數(shù)項(xiàng)與s i n ( 2 π t ⋅ 200 ) 的系數(shù);而100Hz項(xiàng)sin(2πt⋅200)的系數(shù)不是常數(shù)而是t,且時(shí)間是0-1s,該項(xiàng)傅里葉變化得到的是該段時(shí)間內(nèi)的平均幅值,也就是0.5。
Python調(diào)用fftlw函數(shù)的主函數(shù)
直接加在def fftlw()的后文調(diào)用他就行。
Fs=10000 #采用頻率 L=10000 #采樣點(diǎn)數(shù) t=np.arange(0,L/Fs,1/Fs)#時(shí)間序列 y=np.sin(2*np.pi*t*100)*t+3*np.sin(2*np.pi*t*200)+3 #信號序列 f,M=fftlw(Fs,y,1)#快速傅里葉變化并畫頻譜圖
圖和matlab的一模一樣!但是!
采用實(shí)際的振動(dòng)信號對比兩種語言fftlw效果
數(shù)據(jù)來源于西儲(chǔ)大學(xué)轉(zhuǎn)子實(shí)驗(yàn)臺(tái)振動(dòng)信號,采樣頻率為12000Hz,現(xiàn)取正常狀態(tài)下、轉(zhuǎn)速1796 rpm軸承振動(dòng)信號1000個(gè)點(diǎn)如下。粗略的觀察,有一個(gè)低頻信號大概周期為0.035 s,頻率大概 29Hz。
Matlab畫頻譜圖
Python畫頻譜圖
python的頻譜圖的幅值與原始數(shù)據(jù)量級差別較大,與matlab的頻譜圖也毫不相關(guān),可能是底層傅里葉變換的算法不同所致,具體哪個(gè)正確還帶進(jìn)一步考證?。。?/p>
到此這篇關(guān)于Python與Matlab實(shí)現(xiàn)快速傅里葉變化的區(qū)別的文章就介紹到這了,更多相關(guān)Python 傅里葉變化內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。