#!/usr/bin/env python
# coding: utf-8
# In[19]:
# Graphing helper function
def setup_graph(title='', x_label='', y_label='', fig_size=None):
fig = plt.figure()
if fig_size != None:
fig.set_size_inches(fig_size[0], fig_size[1])
ax = fig.add_subplot(111)
ax.set_title(title)
ax.set_xlabel(x_label)
ax.set_ylabel(y_label)
# ---
# # Fourier Transform
#
# ![Time to Frequency Domain](files/images/time_freq_domain.png)
#
# ## The Fourier Transform is like a prism (not the NSA one)
#
# ![Prism](files/images/prism.png)
#
#
# ---
#
#
# ## Fourier Transform Definition
#
# $$G(f) = \int_{-\infty}^\infty g(t) e^{-i 2 \pi f t} dt$$
#
#
# For our purposes, we will just be using the discrete version...
#
#
# ## Discrete Fourier Transform (DFT) Definition
# $$G(\frac{n}{N}) = \sum_{k=0}^{N-1} g(k) e^{-i 2 \pi k \frac{n}{N} }$$
#
# **Meaning**:
#
# * $N$ is the total number of samples
# * $g(k)$ is the kth sample for the time-domain function (i.e. the DFT input)
# * $G(\frac{n}{N})$ is the output of the DFT for the frequency that is $\frac{n}{N}$ cycles per sample; so to get the frequency, you have to multiply $n/N$ by the sample rate.
# # How to represent waves
# In[20]:
get_ipython().run_line_magic('matplotlib', 'inline')
import matplotlib.pyplot as plt
import numpy as np
import scipy
freq = 1 #hz - cycles per second
amplitude = 3
time_to_plot = 2 # second
sample_rate = 100 # samples per second
num_samples = sample_rate * time_to_plot
t = np.linspace(0, time_to_plot, num_samples)
signal = [amplitude * np.sin(freq * i * 2*np.pi) for i in t] # Explain the 2*pi
# ### Why the 2*pi?
#
# * If we want a wave which completes 1 cycle per second, so sine must come back to the same position on a circle as the starting point
# * So one full rotation about a circle - $2 \pi$ (in radians)
#
# ![sine_curve](files/images/Sine_curve_drawing_animation.gif)
# # Plot the wave
# In[21]:
setup_graph(x_label='time (in seconds)', y_label='amplitude', title='time domain')
plt.plot(t, signal)
# # Convert to the Frequency Domain
#
#
# In[22]:
fft_output = np.fft.rfft(signal)
magnitude_only = [np.sqrt(i.real**2 + i.imag**2)/len(fft_output) for i in fft_output]
frequencies = [(i*1.0/num_samples)*sample_rate for i in range(num_samples//2+1)]
# In[23]:
setup_graph(x_label='frequency (in Hz)', y_label='amplitude', title='frequency domain')
plt.plot(frequencies, magnitude_only, 'r')
# ## Question: So what does the Fourier Transform give us?
#
# * The amplitudes of simple sine waves
# * Their starting position - phase (we won't get into this part much)
#
# ## Question: what sine wave frequencies are used?
#
# * Answer: This is determined by how many samples are provided to the Fourier Transform
# * Frequencies range from 0 to (number of samples) / 2
# * **Example: If your sample rate is 100Hz, and you give the FFT 100 samples, the FFT will return the amplitude of the components with frequencies 0 to 50Hz.**
# In[ ]: