<jupyter_start><jupyter_text>Source: https://gist.github.com/jedludlow/3919130 Create a Test Signal$f_s$ is the sampling frequency, while $f$ is a base frequency for the signal content. We create a signal that contains components at a couple of multiples of this base frequency. Note the amplitudes here since we will be trying to extract those correctly from the FFT later.<jupyter_code>f_s = 50.0 # Hz, sampling freq -> Nyquist sampling, try change this to see what happen. -> 2*maxfreq in data

time = np.arange(0.0, 3.0, 1/f_s)

f = 1.0 # Hz
# amplitude -> 5 and 2
# freq  -> 1 and 10
x = 5 * np.sin(2 * np.pi * f * time) + 2 * np.sin(10 * 2 * np.pi * f * time)
plt.plot(time, x)
plt.xlabel("Time (sec)")
plt.ylabel("x")<jupyter_output><empty_output><jupyter_text>Compute the FFT¶The FFT and a matching vector of frequencies<jupyter_code>fft_x = np.fft.fft(x)

n = len(fft_x)
freq = np.fft.fftfreq(n, 1/f_s)

print n
print freq
plt.plot(np.abs(fft_x))<jupyter_output><empty_output><jupyter_text>Swap Half SpacesNote that frequencies in the FFT and the freq vector go from zero to some larger positive number then from a large negative number back toward zero. We can swap that so that the DC component is in the center of the vector while maintaining a two-sided spectrum.<jupyter_code>fft_x_shifted = np.fft.fftshift(fft_x)
freq_shifted = np.fft.fftshift(freq)
plt.plot(freq_shifted, np.abs(fft_x_shifted))
plt.xlabel("Frequency (Hz)")<jupyter_output><empty_output><jupyter_text>Fold Negative Frequencies and ScaleIt's actually more common to look at just the first half of the unshifted FFT and frequency vectors and fold all the amplitude information into the positive frequencies. Furthermore, to get ampltude right, we must normalize by the length of the original FFT. Note the factor of $2/n$ in the following which accomplishes both the folding and scaling.<jupyter_code>half_n = int(np.ceil(n/2.0))
fft_x_half = (2.0 / n) * fft_x[:half_n]
freq_half = freq[:half_n]
plt.plot(freq_half, np.abs(fft_x_half))
plt.xlabel("Frequency (Hz)")
plt.ylabel("Amplitude")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1010004764173416, 'fraction_numerical': 0.016674606955693186, 'mean_word_length': 5.104651162790698, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '295774', 'license': 'MIT', 'n_tokens_mistral': 776, 'n_tokens_neox': 735, 'n_words': 250, 'path': 'uvfitting/FFTnumpy_1D.ipynb', 'repo_name': 'ridlo/radio_analysis', 'size': '2099'}