m-thesis-introduction/01_fourier.ipynb

800 lines
799 KiB
Text
Raw Normal View History

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Fourier Transforms"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"import numpy as np\n",
"import scipy.fft as ft\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib.gridspec as gridspec\n",
"import matplotlib.ticker as tck\n",
"rng = np.random.default_rng()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Fourier transform (FT) of a quantity $t$ is defined as\n",
"\n",
"$$\n",
2021-11-25 18:49:42 +01:00
"\\hat{f}(\\omega) = F(f(t)) = \\frac{1}{\\sqrt{2\\pi}} \\int_{-\\infty}^{\\infty} \\mathrm{d}t\\, f(t)\\, \\exp{ \\left(-i \\omega t \\right)}\n",
".\n",
"$$\n",
"\n",
"In signal processing, taking the integral from $t = -\\infty$ to $t = \\infty$ is not practical. Together with a finite sample space $t$, the integral can be turned into a (discrete) sum, giving a Discrete Fourier Transform (DFT)\n",
"\n",
"$$\n",
2021-11-25 18:49:42 +01:00
"F(t) = \\frac{1}{\\sqrt{2\\pi}} \\sum_{k=0}^{N-1} f(t_k)\\, \\exp{ \\left(-i \\omega t_k \\right)}\n",
"\\label{eq:DFT} \\tag{1}\n",
",\n",
"$$\n",
"where the sum iterates over each sample $t_k$ up to the end ($k=N-1$) of the signal."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Interdependence $\\Delta t$, $T$, $\\Delta f$, $f_{min}$, $f_{max}$"
]
},
{
2021-11-25 18:49:42 +01:00
"cell_type": "markdown",
"metadata": {},
2021-11-25 18:49:42 +01:00
"source": [
"The highest frequency $f_\\mathrm{max}$ (also known as the Nyquist frequency) that can be (reliably) measured within a signal is dependent only on the sampling rate ($1/\\Delta t$) of the signal with\n",
"$$\n",
" f_\\mathrm{max} = \\frac{1}{2} f_\\mathrm{sampling} = \\frac{1}{2} \\frac{1}{\\Delta t}\n",
" .\n",
"$$\n",
2021-11-30 15:35:09 +01:00
"Higher frequencies will fall in between two adjacent samples. This means that these frequencies are then 'measured\\` with differing phases in such a way that they are 'folded' around the Nyquist frequency and appear as aliased frequencies below it.\n",
2021-11-25 18:49:42 +01:00
"\n",
"Likewise, the lowest frequency depends on the length of the signal $T$, such that over the whole signal one oscillation can be found\n",
"$$\n",
" f_\\mathrm{min} \\sim \\frac{1}{T}\n",
" .\n",
"$$\n",
"Even lower frequencies will no longer be detected as a frequency. Instead, they will introduce a bias for the $0 Hz$ component in the spectrum."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# FTs of ideal signals"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def ft_spectrum( signal, sample_rate, fft=None, freq=None, mask_bias=False):\n",
" \"\"\"Return a FT of $signal$, with corresponding frequencies\"\"\"\n",
" n_samples = len(signal)\n",
2021-11-30 15:35:09 +01:00
" real_signal = np.isrealobj(signal)\n",
" \n",
2021-11-25 18:49:42 +01:00
" if fft is None:\n",
" if real_signal:\n",
" fft = ft.rfft\n",
" freq = ft.rfftfreq\n",
" else:\n",
" fft = ft.fft\n",
" freq = ft.fftfreq\n",
"\n",
" if freq is None:\n",
" freq = ft.fftfreq\n",
" \n",
2021-11-25 18:49:42 +01:00
" spectrum = fft(signal) / sample_rate\n",
" freqs = freq(n_samples, 1/sample_rate)\n",
" \n",
2021-11-25 18:49:42 +01:00
" if not mask_bias:\n",
" return spectrum, freqs\n",
" else:\n",
" return spectrum[1:], freqs[1:]\n",
"\n",
" \n",
"def plot_spectrum( ax, spectrum, freqs, plot_complex=False, plot_power=False, plot_amplitude=None):\n",
" \"\"\" Plot a signal's spectrum on an Axis object\"\"\"\n",
" plot_amplitude = plot_amplitude or (not plot_power and not plot_complex)\n",
2021-11-25 18:49:42 +01:00
" alpha = 1\n",
" \n",
" ax.set_title(\"Spectrum\")\n",
" ax.set_xlabel(\"f (Hz)\")\n",
" ylabel = \"\"\n",
2021-11-30 15:35:09 +01:00
" if plot_amplitude or plot_complex:\n",
" ylabel = \"Amplitude\"\n",
" if plot_power:\n",
" if ylabel:\n",
" ylabel += \"|\"\n",
" ylabel += \"Power\"\n",
" ax.set_ylabel(ylabel)\n",
"\n",
2021-11-25 18:49:42 +01:00
" if plot_complex:\n",
" alpha = 0.5\n",
" ax.plot(freqs, np.real(spectrum), '.-', label='Real', alpha=alpha)\n",
" ax.plot(freqs, np.imag(spectrum), '.-', label='Imag', alpha=alpha)\n",
"\n",
" if plot_power:\n",
" ax.plot(freqs, np.abs(spectrum)**2, '.-', label='Power', alpha=alpha)\n",
2021-11-25 18:49:42 +01:00
" \n",
" if plot_amplitude:\n",
" ax.plot(freqs, np.abs(spectrum), '.-', label='Abs', alpha=alpha)\n",
2021-11-25 18:49:42 +01:00
"\n",
2021-11-30 15:35:09 +01:00
" ax.legend()\n",
"\n",
" return ax\n",
"\n",
"\n",
"def plot_phase( ax, spectrum, freqs):\n",
" ax.set_ylabel(\"Phase\")\n",
" ax.set_xlabel(\"f (Hz)\")\n",
"\n",
" ax.plot(freqs, np.angle(spectrum), '.-')\n",
" ax.set_ylim(-1*np.pi, np.pi)\n",
" \n",
" return ax\n",
"\n",
"\n",
"def plot_combined_spectrum(spectrum, freqs, \n",
" spectrum_kwargs={}, fig=None, gs=None):\n",
" \"\"\"Plot both the frequencies and phase in one figure.\"\"\"\n",
" \n",
" # configure plotting layout\n",
" if fig is None:\n",
" fig = plt.figure(figsize=(8, 16))\n",
"\n",
" if gs is None:\n",
" gs = gridspec.GridSpec(2, 1, figure=fig, height_ratios=[2,1])\n",
"\n",
" ax1 = fig.add_subplot(gs[:-1, -1])\n",
" ax2 = fig.add_subplot(gs[-1, -1], sharex=ax1)\n",
"\n",
" axes = np.array([ax1, ax2])\n",
" \n",
" # plot the spectrum \n",
" plot_spectrum(ax1, spectrum, freqs, **spectrum_kwargs)\n",
" \n",
" # plot the phase\n",
" plot_phase(ax2, spectrum, freqs)\n",
" \n",
" return fig, axes\n",
" \n",
"\n",
"def plot_signal( ax, signal, sample_rate = 1):\n",
" ax.set_title(\"Signal\")\n",
" ax.set_xlabel(\"t (s)\")\n",
" ax.set_ylabel(\"A(t)\")\n",
"\n",
" ax.plot(np.arange(len(signal)) / sample_rate, signal)\n",
" \n",
" return ax\n",
"\n",
"\n",
"def plot_signal_and_spectrum( signal, sample_rate, title=None,\n",
" ft_kwargs = {}, spectrum_kwargs = {}):\n",
" \"\"\"Plot a signal and its spectrum in one go.\"\"\"\n",
" fig = plt.figure(figsize=(16, 4))\n",
" \n",
" if title:\n",
" fig.suptitle(title)\n",
"\n",
" # setup plot layout\n",
" gs0 = gridspec.GridSpec(1, 2, figure=fig)\n",
" gs00 = gs0[0].subgridspec(1, 1)\n",
" gs01 = gs0[1].subgridspec(2, 1)\n",
" \n",
" # plot the signal\n",
" ax1 = fig.add_subplot(gs00[0, 0])\n",
" plot_signal(ax1, signal)\n",
" \n",
" # plot spectrum\n",
" signal_fft, freqs = ft_spectrum(signal, sample_rate, **ft_kwargs)\n",
" _, (ax2, ax3) = plot_combined_spectrum(signal_fft, freqs, spectrum_kwargs = spectrum_kwargs, fig=fig, gs=gs01)\n",
"\n",
" # return the axes\n",
" axes = np.array([ax1, ax2, ax3])\n",
" \n",
" return (fig, axes)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"sample_rate = 1/1e-3 # s\n",
"n_samples = int(1e3)\n",
"t = np.arange(n_samples) / sample_rate"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2021-11-25 18:49:42 +01:00
"### FTs: constant signal\n",
"\n",
"A constant signal (also termed offset or bias) results in only a single component in the Fourier transform, at the zero frequency.\n",
"\n",
"Since often such a component is included in a signal (for example when a signal is not on average zero), it can help to mask out the zero frequency when plotting the spectrum.\n",
"Doing this for a constant signal, we get a totally flat spectrum."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
2021-11-25 18:49:42 +01:00
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
2021-11-25 18:49:42 +01:00
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"signal_constant = np.ones(int(n_samples))\n",
2021-11-25 18:49:42 +01:00
"\n",
"fig, axes = plot_signal_and_spectrum(signal_constant, sample_rate, \"Constant signal\")\n",
"axes.flat[1].set_xlim(0,10);\n",
"\n",
"fig, axes = plot_signal_and_spectrum(signal_constant, sample_rate, \"Constant signal (masked zero)\", ft_kwargs={'mask_bias':True})\n",
"axes.flat[1].set_xlim(0,10);\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2021-11-25 18:49:42 +01:00
"### FTs: noise (normal distributed)\n",
"\n",
"A FT of normal distributed noise will not have easily identifiable peaks in the spectrum.\n",
"Instead, the spectrum is on average a bit flat, with only low power in any individual peak."
2021-11-25 18:49:42 +01:00
]
},
{
"cell_type": "code",
"execution_count": 5,
2021-11-25 18:49:42 +01:00
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
2021-11-25 18:49:42 +01:00
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
2021-11-25 18:49:42 +01:00
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"signal_normal_noise = rng.normal(size=n_samples)\n",
"\n",
"plot_signal_and_spectrum(signal_normal_noise, sample_rate, \"Noise (normal distributed)\");"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### FTs: sine wave"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA74AAAEjCAYAAAAVGd21AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzdeXxU9b3/8dcnC4uyL+ICElBQESsiWrx6FbW1Lrgg1YJal1a5bbXWW5eqtWq9+qttrWutdde2FKiI1oW6ArYuYQmiIItiIBJR1rBvSebz++OcCZPJTDJZJpPl/Xw88sicc77nnM+czGTmc76buTsiIiIiIiIiLVVWpgMQERERERERSSclviIiIiIiItKiKfEVERERERGRFk2Jr4iIiIiIiLRoSnxFRERERESkRVPiKyIiIiIiIi2aEl8RERERERFp0ZT4ioiIiIiISIumxFdERGpkZp+Y2YgGOtZyM/tWHfY7yMw+NLPNZnZ1Q8TS2phZTzN708xKzOzJTMcjIiLSWJT4iogIAGZ2nJm9b2YbzWy9mb1nZkcBuPuh7j4jwyHeAMxw947u/mCGY2lyUryhcBPwmbt3dfcf1uNc3czsBTPbamZFZnZBXcvXdKwUtl9lZnPMbKeZPRO3bbmZ7TKzHnHr55mZm1leXNlvxZW71MzeTfGyiIhIE6bEV0REMLNOwCvAQ0A3YD/g18DOTMYVpy/wSaINZpbTyLE0V98CnmuA4zwM7AJ6ARcCj5jZoXUsX9Oxatq+ErgTeCrJuZcBY6MLZnYY0D6F5ygiIi2IEl8REQEYCODuE9y93N23u/sb7v4xVK4NCx9fZ2Yfh7XDk8ysXfRAZjY0pknyc+H2OxOd1Mz2NbPnzWyNmS1L1oTZzKYBJwJ/NLMtZjYwjOMXZvYxsNXMcmo6npkdYWZzw9gmmdnEaGxhDeCBMWWfiY27umOncE36mNmUcN91ZvbHcP31ZvZ8XIwPmdn9Ca7BjWb2eRj7QjMbFbPtr8D+wMvh9bkhbt82ZrYROCwsMz/RdU6Fme0JjAZ+5e5b3P1d4CXg+7UtX9OxUjmXu09x9xeBdUlC/itwcczyJcBf6vC8vxde2+jPTjObUdvjiIhIZijxFRERgE+BcjN71sxOM7OuNZQ/HzgV6Ad8A7gUggQLeAF4hqDmeAIwKtEBzCwLeBn4iKCG+WTgGjP7TnxZdz8J+A9wlbt3cPdPw01jgTOALkCkuuOFsb1IkAh1I6j5HF3D86xNrMmuSTZBbXoRkBfuPzHc52/AqWbWJSybA3wvjDHe58B/A50JauP/Zmb7hNfn+8AXwJnh9fld3PXbBRwDrA63Hxb3/F4xsw1Jfl6Ji2MgUB7zNyC8LslqfKsrX9OxanuuRPKBTmZ2SPi3+B7Bda8Vd58UXrsOwL5AIcHrW0REmgElviIigrtvAo4DHHgcWGNmL5lZryS7POjuK919PUFCOCRcPxzICbeXuvsUYFaSYxwF9HT3O9x9l7sXhuceU4vQH3T3Fe6+PYXjDQdygfvD2CYDs1M8TyqxJrsmRxMkSte7+1Z33xHWXOLuXwH/Bs4Ly54KrHX3gvgA3P258PgRd58EfBYeO1VDCJLGKtx9pLt3SfIzMq54B2Bj3LqNQMck562ufE3Hqu25konW+n4bWAx8maTci7FJP/Cn+ALhTZC/E/Q3f7SWcYiISIaoT5SIiADg7ovYXUt5MEGt2P3E9I+M8XXM420EiR3h7y/d3WO2r0hyyr7AvmGCEZVNULObqthj13S8RLEVpXieVGJNdk36AEXuXpbk2M8CPyZIpC8icW0vZnYx8HOCWmMIksIeicomkTTxraUtQKe4dZ2AzXUoX9OxanuuZP5KcIOhH9U3cz7H3d+KLpjZpcDlcWXuIki8NbK4iEgzohpfERGpwt0XEzRXHlzLXb8C9jMzi1nXJ0nZFcCyuNrFju5+em1CrcXxEsW2f8zjbcAeMct7N1CsK4D9LfkAXC8C3zCzwcBIYHx8ATPrS5AYXwV0d/cuwAIg9rl4/H5xDidJ4mtm/4rrvxr786+44p8COWY2IO7YCQceq6F8Tceq7bkScvcigkGuTgem1GbfWGY2huBG0HfdvbSuxxERkcanxFdERDCzg83sWjPrHS73IfiCn1/LQ30AlANXhYNNnU3y5rizgE3hAFXtzSzbzAZbOIVSHdR0vA+AMuDqMLZz42KbB1wQ7ncqcEIDxTqLIOm+28z2NLN2ZnZsdKO77wAmEzSfneXuXyQ4xp4Eie0aADO7jKo3JVYB/auJI2ni6+6nRfuvJvg5La7sVoLk8Y7w+RwLnE2Smurqytd0rFTOFf4t2xHUwGeH1zfRTYYfAieFx6w1MzuCYNTzc9x9TV2OISIimaPEV0REIGg6+k1gppltJUh4FwDX1uYg4SBK5xIkGRsImu6+QoJpkdy9HDiToAnuMmAt8ATB4E21VtPxYmK7FCghGOQotvbvZ+H+GwimzXmxIWKN2fdAggGoisNzx3qWYMTlZMnjQuAPBMn7qrDse3HFfgPcEvZPvS52g5ntDXQl6N/aEH5CMCXQaoIBnn7s7hW1sGEN8s0plq/2WClsvwXYDtxI8HrbHq6rxN0/d/c5dX7GQcLdFXi3mtpwERFpoqxyVycREZGGZWYzgT+7+9OZjiWemT0DFLt7lUSpkePYnyAp3TscaExEREQakGp8RVoJM7vQzN5ohPOMMLPidJ9Hmi4zO8HM9g6boF5CMLXPa5mOq6kKRwn+OTBRSa+IiEh6KPEVaWHM7Dgze9/MNprZejN7z8yOcvfx7n5KpuOTVuEggr6kGwmaSn83nLZH4pjZnsAmgml2bstwOCJSC8k+b9N4vuVm9q10HV+kpdN0RiItiJl1IuhP+WPgH0Ab4L9J0L9SJF3c/THgsUzHkQp3vzTD599KMC2RiDQjTfHz1sxyqpk2TaTVU42vSMsyEMDdJ7h7ubtvd/c33P1jM7vUzN6NFjSzU8xsSXin+k9m9o6ZXR5uu9TM3jWze8ysxMyWmdlpMfteZmaLzGyzmRWa2f80/lMVERHJmJo+b98zs4fCz9jFZnZydEcz62xmT5rZV2b2pZndaWbZMduviPmMXWhmQ83srwTTr70cDqx2g5nlmZmb2Q/N7AtgWqLuRrE1xWZ2u5k9Z2Z/C48/38wGmtlNZrbazFaYmVqHSYukxFekZfkUKDezZ83sNDPrmqiQmfUgmD7lJqA7sAT4r7hi3wzX9wB+BzxpVjH/6WqC+UY7AZcB95nZ0IZ+MiIiIk1UTZ+33wQKCT5DbwOmmFm3cNuzBFOrHQgcAZwCRG88nwfcDlxM8Bl7FrDO3b9PMCr8meE0Y7+LOdcJwCHAd1KM/UyCEeS7Ah8CrxPkBPsBdwCPpngckWZFia9ICxIOjHMcwXyfjwNrzOwlM+sVV/R04BN3nxI2i3oQ+DquTJG7Px5OxfIssA/QKzzPq+HUIO7u7wBvEDTxEhERafFS+LxdDdzv7qXuPongRvIZ4fbTgGvcfau7rwbuA8aE+10O/M7dZ4efsUvdvaiGcG4Pj7U9xfD/4+6vh5//zwE9gbvdvRSYCOSZWZcUjyXSbCjxFWlh3H2Ru1/q7r2BwcC+wP1xxfYFVsTs4wRzi8b6Omb7tvBhB4Dw7nZ+OJjHBoJEukfDPhMREZGmq4bP2y+98pyhReH2vkAu8FU45/YGghrWvcJyfYDPaxnKipqLVLIq5vF2YG14kzu6DBp7QFogJb4iLZi7LwaeIfhAjvUV0Du6EDZh7k0KzKwt8DxwD9DL3bsAUwGrdkcREZEWKsHn7X4x3YMg6J+7kiBJ3Qn0cPcu4U8ndz80LLcCOCDZaVJYvxXYI7oQ9h3uWZvnItJSKfEVaUHM7GAzu9bMeofLfYCxQH5c0VeBw8zsHDPLAa4E9k7xNG2AtsAaoCwc9EoDYYiISKuRwuftXsDVZpYb9ts9BJgaTu32BvAHM+tkZllmdoCZnRDu9wRwnZkdaYEDzaxvuG0V0L+G0D4F2pnZGWaWC9xC8Jkt0uop8RVpWTYTDKgx08y2Enw
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
2021-11-25 18:49:42 +01:00
"f = 1e2 # Hz\n",
"if f > sample_rate/2:\n",
" print(\"Sampling a frequency above the sample_rate/2 gives problems\")\n",
"\n",
2021-11-25 18:49:42 +01:00
"signal_sine = np.sin( 2*np.pi*f*t )\n",
2021-11-30 15:35:09 +01:00
"\n",
2021-11-25 18:49:42 +01:00
"if False:\n",
" # aliased peak\n",
2021-11-30 15:35:09 +01:00
" f_alias = (1.1* sample_rate/2)\n",
" signal_sine += 1/2*np.sin( 2*np.pi* f_alias *t)\n",
2021-11-25 18:49:42 +01:00
"\n",
"fig, axes = plot_signal_and_spectrum(signal_sine, sample_rate, \"Single frequency at $f = {:g}$MHz\".format(f/10**6))\n",
"axes.flat[1].axvline(sample_rate/2, color='r', label='Nyquist Frequency');\n",
"axes.flat[1].legend();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A sine wave will give very clear peaks at the frequency of the sine wave."
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/software/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:30: RuntimeWarning: invalid value encountered in double_scalars\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.0 0.0 nan\n",
"0.7853981633974483 0.7071067811865475 1.2337005501361697\n",
"1.5707963267948966 1.0 2.4674011002723395\n",
"2.356194490192345 0.7071067811865476 11.103304951225525\n",
"3.141592653589793 1.2246467991473532e-16 6.580790147320947e+32\n",
"3.9269908169872414 -0.7071067811865475 30.842513753404255\n",
"4.71238898038469 -1.0 22.206609902451056\n",
"5.497787143782138 -0.7071067811865477 60.45132695667229\n"
]
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x576 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"if True:\n",
" sample_rate = 1/1e-3 # s\n",
" n_samples = 1e\n",
" t = np.arange(n_samples) / sample_rate\n",
"\n",
"f = 100 # Hz\n",
"if f > sample_rate/2:\n",
" print(\"Sampling a frequency above the sample_rate/2 gives problems\")\n",
"\n",
"offsets = np.linspace(0, 2*np.pi, 8, endpoint=False)\n",
"\n",
"signals_sine = np.sin( 2*np.pi*f*t )\n",
"\n",
"with_spectrum = True\n",
"\n",
"if with_spectrum:\n",
" fig, axes = plt.subplots(2,1, sharex=True, figsize=(16,8))\n",
"else:\n",
" fig, ax = plt.subplots(figsize=(16,4))\n",
" axes = np.array([None, ax])\n",
" \n",
"if with_spectrum:\n",
" axes[0].set_ylabel(\"Amplitude\")\n",
" axes[0].axvline(f, alpha=0.3, label='f = {:g}Hz'.format(f))\n",
"\n",
"axes[1].axvline(f, alpha=0.3, label='f = {:g}Hz'.format(f))\n",
"axes[1].set_ylabel(\"Phase\")\n",
"axes[1].set_xlabel(\"f\")\n",
"axes[1].set_xlim( f-5, f+5)\n",
"axes[1].set_ylim( -1*np.pi - 0.2, np.pi + 0.2)\n",
"\n",
"for phase in offsets:\n",
" signal = np.sin( 2*np.pi*f*t + phase )\n",
" \n",
" ft_signal, freqs = ft_spectrum(signal, sample_rate)\n",
" \n",
" if with_spectrum:\n",
" axes[0].plot(freqs, np.real(ft_signal), '.-', label='Re $\\\\varphi = {}\\\\pi$'.format(phase/np.pi))\n",
" \n",
" axes[1].plot(freqs, np.angle(ft_signal), '.-', label='$\\\\varphi = {}\\\\pi$'.format(phase/np.pi))\n",
"if with_spectrum:\n",
" axes[0].legend(loc='center right');\n",
"axes[1].legend(loc='center right');\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For a sine wave, the phase of the spectrum at it's frequency is $\\theta( \\varphi = 0 ) = - \\dfrac{\\pi}{2}$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### FTs: step function"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
2021-11-25 18:49:42 +01:00
"t_0 = t[n_samples//4]\n",
"signal_step = np.heaviside(t - t_0, 1)\n",
"fig, axes = plot_signal_and_spectrum(signal_step, sample_rate, \"Step function $t_0 = {:g}ns$\".format(t_0 * 10**9), ft_kwargs={'mask_bias':True});\n",
"axes.flat[1].set_xlim(0, 20);\n",
"\n",
"t_0 = t[n_samples//2]\n",
"signal_step = np.heaviside(t - t_0, 1)\n",
"fig, axes = plot_signal_and_spectrum(signal_step, sample_rate, \"Step function $t_0 = {:g}ns$\".format(t_0 * 10**9), ft_kwargs={'mask_bias':True});\n",
"axes.flat[1].set_xlim(0, 20);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### FTs: delta peak\n",
"\n",
"All frequencies are accounted for with the same amplitude, but the phase will change depending on the position of the delta peak within the signal.\n",
"\n",
"Still, the individual phases are linearly related to their corresponding frequencies."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"\n",
"for n in [4, 2, -4]:\n",
" index_t0 = n_samples//n\n",
"\n",
" t_0 = t[index_t0]\n",
" signal_step = np.zeros(n_samples)\n",
" signal_step[index_t0] = 1\n",
"\n",
" fig, axes = plot_signal_and_spectrum(signal_step, sample_rate, ft_kwargs={'mask_bias':True}, spectrum_kwargs={'plot_complex':True, 'plot_amplitude':True});\n",
" fig.suptitle(\"Delta function at ${}/{}$th of the sample\".format(np.sign(n), np.abs(n)))\n",
" axes.flat[1].set_xlim(0, 20);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### FTs: delta peak: group velocity"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the above plots, the phases follow"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Peculiarities $F^{-1}( F(A(t)) ) \\sim A(t)$"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1152x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"t_0 = t[n_samples//4]\n",
"signal_step = np.heaviside(t - t_0, 1)\n",
"\n",
"signal_fft = ft.rfft(signal_step) / sample_rate\n",
"signal_ifft = ft.irfft(signal_fft, len(signal_fft))\n",
"ft_freqs = ft.rfftfreq(n_samples, 1/sample_rate)\n",
"\n",
"\n",
"alpha = 0.8\n",
"fig, (ax1, ax2) = plt.subplots(1,2, figsize=(16,4))\n",
"ax1.set_title(\"Spectrum\")\n",
"ax1.set_xlabel(\"f (Hz)\")\n",
"ax1.set_ylabel(\"Amplitude\")\n",
"ax1.set_xlim(-1,20)\n",
"ax1.plot(ft_freqs, np.real(signal_fft), '.-', label='Real', alpha=alpha)\n",
"ax1.plot(ft_freqs, np.imag(signal_fft), '.-', label='Imag', alpha=alpha)\n",
"ax1.plot(ft_freqs, np.abs(signal_fft), '.-', label='Abs', alpha=alpha)\n",
"ax1.legend()\n",
"\n",
"# Signal and Inversed FFT\n",
"ax2.set_title(\"Signal and Inversed FFT\")\n",
"ax2.set_xlabel(\"t (s)\")\n",
"ax2.set_ylabel(\"A(t)\")\n",
"ax2.plot(np.arange(len(signal_step)) / sample_rate, signal_step, label=\"Original\")\n",
"ax2.plot(np.arange(len(signal_ifft)) / sample_rate, np.abs(signal_ifft) - 2, label=\"Inversed FFT (offset -2)\")\n",
"ax2.legend()\n",
"\n",
"plt.show();\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2021-11-25 18:49:42 +01:00
"# DFT\n",
"\n",
"A naive implementation of a DFT is simple to setup by implementing Eq. (1)\n",
"\n",
"$$\n",
"\\hat{f}(\\omega) = F(t) = \\frac{1}{\\sqrt{2\\pi}} \\sum_{k=0}^{N-1} f(t_k)\\, \\exp{ \\left(-i \\omega t_k \\right)}\n",
".\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 11,
2021-11-25 18:49:42 +01:00
"metadata": {},
"outputs": [],
"source": [
"def naive_DFT( signal ):\n",
" \"\"\"\n",
" Calculate DFT in a naive way, returns a complex DFT.\n",
" \"\"\"\n",
"\n",
" N = np.size(signal)\n",
"\n",
" x_k = 2*np.pi/N*np.arange(N)\n",
" ft = np.zeros(N, dtype=np.complex128)\n",
" for j in range(N):\n",
" ft[j] = np.dot(signal, np.exp(- 1j * j * x_k ))\n",
"\n",
" return ft"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### DFT: Cooley and Tukey (or Divide and Conquer)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2021-11-25 18:49:42 +01:00
"A smarter DFT (Cooley and Tukey) can be implemented by splitting the sum in Eq. (1) into two parts: $k$ even and $k$ odd.\n",
"\n",
2021-11-25 18:49:42 +01:00
"With a uniform sample space $t$, the label $t_k$ can be rewritten to $t_k = k \\Delta t = $.\n",
"\n",
"This gives\n",
"$$\n",
2021-11-25 18:49:42 +01:00
"F(t) = \n",
" \\frac{1}{\\sqrt{2\\pi}} \\sum_{k=0}^{N/2-1} f(t_{2k})\\, \\exp{ \\left(-i \\omega \\, t_{2k} \\right)}\n",
" +\n",
2021-11-25 18:49:42 +01:00
" \\frac{1}{\\sqrt{2\\pi}} \\sum_{k=0}^{N/2-1} f(t_{2k+1})\\, \\exp{ \\left(-i \\omega \\, t_{2k+1} \\right)}\n",
" \\\\\n",
" =\n",
" \\frac{1}{\\sqrt{2\\pi}} \\sum_{k=0}^{N/2-1} f(t_{2k})\\, \\exp{ \\left(-i \\omega \\, 2k \\Delta t \\right)}\n",
" +\n",
2021-11-25 18:49:42 +01:00
" \\frac{1}{\\sqrt{2\\pi}} \\sum_{k=0}^{N/2-1} f(t_{2k+1})\\, \\exp{ \\left(-i \\omega \\, 2k \\Delta t \\right)}\\exp{ \\left(-i \\omega \\, \\Delta t \\right)}\n",
" \\\\\n",
" =\n",
" \\frac{1}{\\sqrt{2\\pi}} \\sum_{k=0}^{N/2-1} f(t_{2k})\\, \\exp{ \\left(-i \\omega \\, 2k \\Delta t \\right)}\n",
" +\n",
2021-11-25 18:49:42 +01:00
" \\frac{\\exp{ \\left(-i \\omega \\, \\Delta t \\right)} }{\\sqrt{2\\pi}} \\sum_{k=0}^{N/2-1} f(t_{2k+1})\\, \\exp{ \\left(-i \\omega \\, 2k \\Delta t \\right)}\n",
" \\\\\n",
" =\n",
" F(t_{even}) + F(t_{odd}) \\exp{ \\left(-i \\omega \\, \\Delta t \\right)}\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
2021-11-25 18:49:42 +01:00
"def cooley_tukey_DFT( signal ):\n",
" \"\"\"\n",
" Calculate a DFT according to the Cooley and Tukey algorithm (radix-2)\n",
" also known as Divide and Conquer.\n",
" \n",
" It divides the terms into 2 streams with odd and even index.\n",
" \"\"\"\n",
" radix = 2\n",
"\n",
" N = np.size(signal)\n",
2021-11-25 18:49:42 +01:00
" \n",
" if N <= radix:\n",
" return naive_DFT(signal)\n",
" \n",
" if N % radix > 0:\n",
" raise ValueError(\"Provide a signal with N%{radix} == 0 values.\".format(radix=radix))\n",
" \n",
" # divide and conquer\n",
" DFT_even = cooley_tukey_DFT(signal[::radix])\n",
" DFT_odd = cooley_tukey_DFT(signal[1::radix])\n",
" \n",
" phase_terms = np.exp( -2j * np.pi * np.arange(0, N) / N )\n",
" \n",
" return np.tile(DFT_even, 2) + np.tile(DFT_odd,2) * phase_terms\n"
]
},
{
"cell_type": "code",
"execution_count": 13,
2021-11-25 18:49:42 +01:00
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
2021-11-25 18:49:42 +01:00
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
2021-11-25 18:49:42 +01:00
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"dft_sample_rate = 1/1e-3 # s\n",
"dft_n_samples = 2**10\n",
"dft_t = np.arange(dft_n_samples) / dft_sample_rate\n",
"\n",
2021-11-25 18:49:42 +01:00
"f = 1e2 # Hz\n",
"if f > dft_sample_rate/2:\n",
2021-11-25 18:49:42 +01:00
" print(\"Sampling a frequency above the sample_rate/2 gives problems\")\n",
"\n",
"signal_sine = np.sin( 2*np.pi*f*dft_t )\n",
"\n",
"fig, axes = plot_signal_and_spectrum(signal_sine, dft_sample_rate, \"Single frequency at $f = {:g}$MHz\".format(f/10**6), ft_kwargs={'fft': cooley_tukey_DFT})\n",
"axes.flat[1].axvline(dft_sample_rate/2, color='r', label='Nyquist Frequency');"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}