Phần đầu tiên của mã tạo ra 30 chu kỳ của sóng vuông trong một thời gian tăng/giảm nhất định [tính theo% của chu kỳ]. Sau đó, FFT của sóng vuông được tính. Biểu đồ đầu tiên hiển thị một chu kỳ của sóng vuông và biểu đồ thứ hai hiển thị FFT của sóng vuông. Tôi đã sử dụng một tiện ích để có thể nhanh chóng vẽ đồ thị và xem ảnh hưởng của thời gian tăng/giảm đối với phổ tần số của sóng vuông
Trọng tâm. Tìm hiểu cách vẽ biểu đồ FFT của sóng hình sin và sóng cosine bằng Python. Hiểu FFTshift. Vẽ phổ một mặt, hai mặt và chuẩn hóa bằng FFT
Giới thiệu
Nhiều văn bản có sẵn để giải thích những điều cơ bản của Biến đổi Fourier rời rạc và cách triển khai rất hiệu quả của nó – Biến đổi Fourier nhanh [FFT]. Thông thường, chúng ta phải đối mặt với nhu cầu tạo ra các tín hiệu chuẩn, đơn giản [sin, cosin, xung Gaussian, sóng vuông, xung chữ nhật cô lập, phân rã hàm mũ, tín hiệu chirp] cho mục đích mô phỏng. Tôi dự định trình bày [trong một loạt bài viết] cách tạo ra các tín hiệu cơ bản này bằng Python và cách biểu diễn chúng trong miền tần số bằng FFT. Nếu bạn thiên về lập trình Matlab, hãy truy cập tại đây
Bài viết này là một phần của cuốn sách Digital Modulations using Python, ISBN. 978-1712321638 có sẵn ở định dạng sách điện tử [PDF] và Bìa mềm [bản cứng]
Sóng hình sin
Để tạo sóng hình sin, bước đầu tiên là cố định tần số f của sóng hình sin. Ví dụ, chúng ta muốn tạo ra một
Đối với các tín hiệu băng cơ sở, quá trình lấy mẫu diễn ra đơn giản. Theo định lý lấy mẫu Nyquist Shannon, để tái tạo trung thực tín hiệu liên tục trong miền rời rạc, người ta phải lấy mẫu tín hiệu ở tốc độ
Để triển khai Python, chúng ta hãy viết một hàm để tạo tín hiệu hình sin bằng thư viện Numpy của Python. Numpy là một thư viện cơ bản cho các tính toán khoa học trong Python. Để sử dụng gói numpy, nó cần được nhập. Ở đây, chúng tôi đang nhập gói numpy và đổi tên nó thành bí danh ngắn hơn np
import numpy as np
Tiếp theo, chúng tôi xác định hàm tạo tín hiệu sóng hình sin với các tham số cần thiết
def sine_wave[f,overSampRate,phase,nCyl]: """ Generate sine wave signal with the following parameters Parameters: f : frequency of sine wave in Hertz overSampRate : oversampling rate [integer] phase : desired phase shift in radians nCyl : number of cycles of sine wave to generate Returns: [t,g] : time base [t] and the signal g[t] as tuple Example: f=10; overSampRate=30; phase = 1/3*np.pi;nCyl = 5; [t,g] = sine_wave[f,overSampRate,phase,nCyl] """ fs = overSampRate*f # sampling frequency t = np.arange[0,nCyl*1/f-1/fs,1/fs] # time base g = np.sin[2*np.pi*f*t+phase] # replace with cos if a cosine wave is desired return [t,g] # return time base and signal g[t] as tuple
Chúng tôi lưu ý rằng sóng hình sin được xác định bên trong một tệp có tên signalgen. py. Chúng tôi sẽ thêm nhiều chức năng tương tự như vậy trong cùng một tệp. Mục đích là để giữ tất cả các chức năng tạo tín hiệu liên quan, trong một tệp duy nhất. Cách tiếp cận này có thể được mở rộng sang lập trình hướng đối tượng. Bây giờ chúng ta đã xác định hàm sóng hình sin trong signalgen. py, tất cả những gì chúng ta cần làm là gọi nó với các tham số cần thiết và vẽ kết quả đầu ra
""" Simulate a sinusoidal signal with given sampling rate """ import numpy as np import matplotlib.pyplot as plt # library for plotting from signalgen import sine_wave # import the function f = 10 #frequency = 10 Hz overSampRate = 30 #oversammpling rate fs = f*overSampRate #sampling frequency phase = 1/3*np.pi #phase shift in radians nCyl = 5 # desired number of cycles of the sine wave [t,x] = sine_wave[f,overSampRate,phase,nCyl] #function call plt.plot[t,x] # plot using pyplot library from matplotlib package plt.title['Sine wave f='+str[f]+' Hz'] # plot title plt.xlabel['Time [s]'] # x-axis label plt.ylabel['Amplitude'] # y-axis label plt.show[] # display the figure
Python là ngôn ngữ phần mềm dựa trên trình thông dịch xử lý mọi thứ ở dạng kỹ thuật số. Để có được sóng hình sin mượt mà, tốc độ lấy mẫu phải cao hơn nhiều so với tốc độ lấy mẫu tối thiểu được yêu cầu theo quy định, tức là ít nhất gấp đôi tần số
Hệ số lấy mẫu quá mức
Các đại diện khác nhau của FFT
Vì FFT chỉ là phép tính số của
J. W. Tuckey để tính toán hiệu quả DFT.
Các hàm SciPy triển khai FFT và IFFT có thể được gọi như sau
from scipy.fftpack import fft, ifft X = fft[x,N] #compute X[k] x = ifft[X,N] #compute x[n]
1. Vẽ các giá trị thô của DFT
Trục x chạy từ đến
import numpy as np import matplotlib.pyplot as plt from scipy.fftpack import fft NFFT=1024 #NFFT-point DFT X=fft[x,NFFT] #compute DFT using FFT fig1, ax = plt.subplots[nrows=1, ncols=1] #create figure handle nVals = np.arange[start = 0,stop = NFFT] # raw index for FFT plot ax.plot[nVals,np.abs[X]] ax.set_title['Double Sided FFT - without FFTShift'] ax.set_xlabel['Sample points [N-point DFT]'] ax.set_ylabel['DFT Values'] fig1.show[]
2. Âm mưu FFT – vẽ các giá trị thô theo trục tần số chuẩn hóa
Trong phiên bản tiếp theo của biểu đồ, trục tần số [trục x] được chuẩn hóa thành đơn vị. Chỉ cần chia chỉ mục mẫu trên trục x cho chiều dài của FFT. Điều này chuẩn hóa trục x theo tốc độ lấy mẫu . Tuy nhiên, chúng ta không thể tìm ra tần số của hình sin từ biểu đồ.
import numpy as np import matplotlib.pyplot as plt from scipy.fftpack import fft NFFT=1024 #NFFT-point DFT X=fft[x,NFFT] #compute DFT using FFT fig2, ax = plt.subplots[nrows=1, ncols=1] #create figure handle nVals=np.arange[start = 0,stop = NFFT]/NFFT #Normalized DFT Sample points ax.plot[nVals,np.abs[X]] ax.set_title['Double Sided FFT - without FFTShift'] ax.set_xlabel['Normalized Frequency'] ax.set_ylabel['DFT Values'] fig2.show[]
3. Biểu đồ FFT – vẽ các giá trị thô theo tần số chuẩn hóa [tần số dương và âm]
Như các bạn đã biết, trong miền tần số, các giá trị chiếm cả trục tần số dương và âm. Để vẽ các giá trị DFT trên một trục tần số có cả giá trị dương và âm, giá trị DFT tại chỉ số mẫu phải được căn giữa ở giữa mảng. Điều này được thực hiện bằng cách sử dụng chức năng FFTshift trong Scipy Python. Trục x chạy từ
import numpy as np import matplotlib.pyplot as plt from scipy.fftpack import fft,fftshift NFFT=1024 #NFFT-point DFT X=fftshift[fft[x,NFFT]] #compute DFT using FFT fig3, ax = plt.subplots[nrows=1, ncols=1] #create figure handle fVals=np.arange[start = -NFFT/2,stop = NFFT/2]/NFFT #DFT Sample points ax.plot[fVals,np.abs[X]] ax.set_title['Double Sided FFT - with FFTShift'] ax.set_xlabel['Normalized Frequency'] ax.set_ylabel['DFT Values']; ax.autoscale[enable=True, axis='x', tight=True] ax.set_xticks[np.arange[-0.5, 0.5+0.1,0.1]] fig.show[]
4. Đồ thị FFT – Tần số tuyệt đối trên trục x so với. độ lớn trên trục y
Ở đây, trục tần số chuẩn hóa chỉ được nhân với tốc độ lấy mẫu. Từ biểu đồ bên dưới, chúng ta có thể xác định rằng giá trị tuyệt đối của FFT đạt cực đại tại
import numpy as np import matplotlib.pyplot as plt from scipy.fftpack import fft,fftshift NFFT=1024 X=fftshift[fft[x,NFFT]] fig4, ax = plt.subplots[nrows=1, ncols=1] #create figure handle fVals=np.arange[start = -NFFT/2,stop = NFFT/2]*fs/NFFT ax.plot[fVals,np.abs[X],'b'] ax.set_title['Double Sided FFT - with FFTShift'] ax.set_xlabel['Frequency [Hz]'] ax.set_ylabel['|DFT Values|'] ax.set_xlim[-50,50] ax.set_xticks[np.arange[-50, 50+10,10]] fig4.show[]
5. Phổ công suất – Tần số tuyệt đối trên trục x so với. nguồn trên trục y
Sau đây là đại diện quan trọng nhất của FFT. Nó vẽ đồ thị công suất của từng thành phần tần số trên trục y và tần số trên trục x. Công suất có thể được vẽ theo tỷ lệ tuyến tính hoặc theo tỷ lệ log. Công suất của từng thành phần tần số được tính như
Ở đâu
Vẽ biểu đồ PSD với trục y trên thang log, tạo ra loại biểu đồ PSD gặp nhiều nhất trong xử lý tín hiệu