2
votes

I am new to FFT and I am trying to understand the Python code by manually trying to test. The reason i am testing is to understand FFT step by step.

import numpy as np
import matplotlib.pyplot as plt
from numpy.fft import fft, fftfreq

n = 1000 #Number of samples on x axis
Lx = 100 #Time period in seconds
omg = 2.0*np.pi/Lx #Frequency is in cycles per second. Multiplying by 2π gives the frequency in radians

x = np.linspace(0, Lx, n)# np.linspace(start = val, stop = val, num = val), here 0 to 100 with 1000 numbers

#A Sine wave with 1 wave with 1 amplitude
y = (1.0*np.sin(1.0*omg*x))

freqs = fftfreq(n)
#print('FFT Values freqs ',freqs[mask])

# Used to ignore half the values
mask = freqs > 0

# fft values
fft_vals = fft(y)

#Theoritical FFT
fft_theo = 2.0*np.abs(fft_vals/n)
#print('FFT Amplitude ',fft_theo[mask])
plt.figure(1)
plt.title('Original Signal')
plt.plot(x, y)
plt.xlabel('Time in seconds')
plt.ylabel('Amplitude')
plt.legend()

plt.figure(2)
plt.title('FFT values using Mask')
plt.plot(freqs[mask], fft_theo[mask], color='xkcd:salmon')
plt.xlabel('Frequency in Hz')
plt.ylabel('Amplitude')
plt.legend()

plt.show

Following is my understanding of the program The input is a single sine wave with 1 as amplitude and the x axis is time in periods which is 100s Now a single wave's length is 2 PI which is divided by 1000 I understood the input of sending a single sine wave with time on x axis and amplitude on y axis

To convert this time to frequency fftfreq function is used. Here is where i dont understand how does this function convert. To ignore the negative values mask variable is assigned to contain only the frequencies which are greater than 0. Again i didnt understand how or why we have to call fft function to convert amplitude because amplitude should remain the same and only time should be converted to frequency.

Then the theoriticaly value is calculated fft_theo = 2.0*np.abs(fft_vals/n) so that the output is as expected

enter image description here

enter image description here

Also in the output i didnt understand why amplitude is 1 at 0 frequency.

Please help me in understanding FFT in layman terms.

Thanks, Asha

1
You're looking for a peak at bin index = 1 = 0.01 Hz. As a sanity check try printing the (absolute) values of the first few FFT bins and/or reduce the X axis range for the freq plot (it may just be that you can't distinguish 0 Hz from 0.01 Hz in the above plot). - Paul R
You are using the same variable to describe the period of your wave as well as the length of the interval. Make them separate. Then check what happens when you change your period. Half it. your main peak will move to the right by one step (frequency '2'). Note that for the FFT the spectral resolution (in Hz) is the inverse of the overall width of your time vector (so 100 secs --> 0.01 Hz). The width of your spectrum is the inverse of your timestep (so 0.1 sec --> 10 Hz (-5 Hz ... 5 Hz). You got that wrong because you didn't pass your timestep to fftfreq. - roadrunner66
Watch youtu.be/spUNpyF58BY and youtu.be/r6sGWTCMz2k. I can't think of a more layman-y explaination that goes into full (reproducible) detail. - Mark Jeronimus

1 Answers

0
votes

An FFT magnitude doesn't convert time to frequency for a single sinusoid.

Instead it decomposes possibly far more interesting waveforms.

It converts a waveform assumed to possibly consist of the sum of a vast number of sinusoids, into an array containing the amount of each frequency as correlated against a set of N/2 different frequency sinusoids.

The peak you see near the bottom of your graph indicates a single strong correlation against a extremely low frequency (compared to the X range of your graph). With the vast number of correlations against higher frequencies all zero.