{ "cells": [ { "cell_type": "markdown", "metadata": { "nbsphinx": "hidden" }, "source": [ "# The Discrete Fourier Transform\n", "\n", "*This Jupyter notebook is part of a [collection of notebooks](../index.ipynb) in the bachelors module Signals and Systems, Comunications Engineering, Universität Rostock. Please direct questions and suggestions to [Sascha.Spors@uni-rostock.de](mailto:Sascha.Spors@uni-rostock.de).*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Fast Convolution\n", "\n", "The linear convolution of signals is a basic building block in many practical applications. The straightforward convolution of two finite-length signals $x[k]$ and $h[k]$ has considerable numerical complexity. This has led to the development of various algorithms that realize the convolution with lower complexity. The basic concept of the *fast convolution* is to exploit the [convolution theorem](theorems.ipynb#Convolution-Theorem) of the discrete Fourier transform (DFT). This theorem states that the periodic convolution of two signals is equal to a scalar multiplication of their spectra. The scalar multiplication has considerably less numerical operations that the convolution. The transformation of the signals can be performed efficiently by the [fast Fourier transform](fast_fourier_transform.ipynb) (FFT). \n", "\n", "Since the scalar multiplication of the spectra realizes a periodic convolution, special care has to be taken to realize a linear convolution in the spectral domain. The equivalence between linear and periodic convolution is discussed in the following." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Equivalence of Linear and Periodic Convolution\n", "\n", "The [linear convolution](../discrete_systems/linear_convolution.ipynb#Finite-Length-Signals) of a causal signal $x_L[k]$ of length $L$ with a causal signal $h_N[k]$ of length $N$ reads\n", "\n", "\\begin{equation}\n", "y[k] = x_L[k] * h_N[k] = \\sum_{\\kappa = 0}^{L-1} x_L[\\kappa] \\; h_N[k - \\kappa] = \\sum_{\\kappa = 0}^{N-1} h_N[\\kappa] \\; x_L[k - \\kappa]\n", "\\end{equation}\n", "\n", "The resulting signal $y[k]$ is of finite length $M = N+L-1$. Without loss of generality it is assumed in the following that $N \\leq L$. The computation of $y[k]$ for $k=0,1, \\dots, M-1$ requires $M \\cdot N$ multiplications and $M \\cdot (N-1)$ additions. The computational complexity of the convolution is consequently [on the order of](https://en.wikipedia.org/wiki/Big_O_notation) $\\mathcal{O}(M \\cdot N)$.\n", "\n", "The [periodic (or circular/cyclic) convolution](https://en.wikipedia.org/wiki/Circular_convolution) of two signals $x_L[k]$ and $h_N[k]$ is defined as\n", "\n", "\\begin{equation}\n", "x_L[k] \\circledast_P h_N[k] = \\sum_{\\kappa=0}^{P-1} \\tilde{x}_P[k - \\kappa] \\; \\tilde{h}_P[\\kappa]\n", "\\end{equation}\n", "\n", "where $\\circledast_P$ denotes the periodic convolution with period $P$. The periodic summations $\\tilde{x}_P[k]$ of $x[k]$ and $\\tilde{h}_P[k]$ of $h[k]$ with period $P$ are defined as\n", "\n", "\\begin{align}\n", "\\tilde{x}_P[k] &= \\sum_{\\nu = -\\infty}^{\\infty} x_L[\\nu \\cdot P + k] \\\\\n", "\\tilde{h}_P[k] &= \\sum_{\\nu = -\\infty}^{\\infty} h_N[\\nu \\cdot P + k]\n", "\\end{align}\n", "\n", "The result of the circular convolution has a period of $P$.\n", "\n", "\n", "To compute the linear convolution by a periodic convolution, one has to take care that the result of the linear convolution fits into one period of the periodic convolution. Hence, the periodicity has to be chosen as $P \\geq M$ where $M = N+L-1$. This can be achieved by zero-padding of $x_L[k]$ to the total length $M$ resulting in the signal $x_M[k]$ of length $M$ which is defined as\n", "\n", "\\begin{equation}\n", "x_M[k] = \\begin{cases} \n", "x_L[k] & \\text{for } 0 \\leq k < L \\\\\n", "0 & \\text{for } L \\leq k < M\n", "\\end{cases}\n", "\\end{equation}\n", "\n", "and similar for $h_N[k]$ resulting in the zero-padded signal $h_M[k]$ which is defined as\n", "\n", "\\begin{equation}\n", "h_M[k] = \\begin{cases} \n", "h_N[k] & \\text{for } 0 \\leq k < N \\\\\n", "0 & \\text{for } N \\leq k < M\n", "\\end{cases}\n", "\\end{equation}\n", "\n", "Using these signals, the linear and periodic convolution are equivalent for the first $M$ samples $k = 0,1,\\dots, M-1$\n", "\n", "\\begin{equation}\n", "x_L[k] * h_N[k] = x_M[k] \\circledast_M h_M[k]\n", "\\end{equation}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Example\n", "\n", "The following example computes the linear, periodic and linear by periodic convolution of two signals $x[k] = \\text{rect}_L[k]$ and $h[k] = \\text{rect}_N[k]$." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAA90AAAMVCAYAAABqdZdfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAACXMklEQVR4nOzdfVhUdf7/8dcIwqAhiopAImJaimje573ZjVlIVtqNhXlTW5rdqGVqm6LuJtmNX7cbaa1NtyXbdrcsqSRNzWpTMQlNcXMrSjOUQgOzQGU+vz9c5ucIKHfDGWaej+ua62I+85lz3mfOnJsX58w5NmOMEQAAAAAAqHUNrC4AAAAAAABvRegGAAAAAMBNCN0AAAAAALgJoRsAAAAAADchdAMAAAAA4CaEbgAAAAAA3ITQDQAAAACAmxC6AQAAAABwE0I3AAAAAABuQugGAHiFFStWyGaz6bPPPquwz7fffiubzaYVK1bUXWEoY968ebLZbNV6b3Z2tubNm6dvv/22zGvjx49X27Zta1YcAAC1jNANAPAZERER2rx5s+Lj460uBdWUnZ2t+fPnlxu658yZo1WrVtV9UQAAnIW/1QUAAFBXAgMD1bdvX6vLOKtff/1VjRo1srqMeumCCy6wugQAAMrgSDcAwGeUd3p56anOu3fv1pgxYxQSEqJWrVpp4sSJKigocHm/MUZLly5Vt27dFBQUpGbNmmn06NH65ptvXPqtW7dOI0eOVOvWrWW329W+fXvdfffd+umnn1z6lY47MzNTo0ePVrNmzc4ZHA8cOKC77rpLUVFRCggIUGRkpEaPHq1Dhw45++zbt0+JiYkKCwtTYGCgOnXqpKeffloOh6PMZ/HUU09p8eLFiomJ0Xnnnad+/fppy5Ytzn5LliyRzWbTV199VaaWmTNnKiAgwGW6Xn75ZV188cWy2+0KDQ3V9ddfrz179px1miTJZrNp3rx5Zdrbtm2r8ePHSzr1E4Ibb7xRkjR06FDZbDaX+Vne6eVFRUWaPXu2YmJiFBAQoPPPP19TpkzRzz//XGY8I0aMUHp6unr06KGgoCB17NhRL7/88jlrBwDgbAjdAABIGjVqlC688EK98cYbmjVrllauXKlp06a59Ln77rs1depUXXHFFXrrrbe0dOlS7d69W/3793cJvV9//bX69eunlJQUrV27VnPnztXWrVs1cOBAnThxosy4b7jhBrVv317//Oc/9cILL1RY44EDB9S7d2+tWrVK06dP15o1a7RkyRKFhIToyJEjkqQff/xR/fv319q1a/WHP/xBq1ev1hVXXKGHHnpI9957b5lhPv/881q3bp2WLFmiV199VceOHdM111zj/IdDYmKiAgICyvwOvqSkRKmpqUpISFCLFi0kScnJybrjjjvUuXNnvfnmm/rTn/6knTt3ql+/fvrvf/9buRlxFvHx8Vq4cKGz7s2bN5/15wLGGF133XV66qmnNHbsWL377ruaPn26/vrXv+qyyy5TcXGxS/8dO3bowQcf1LRp0/T222+ra9euuuOOO/TRRx/VuHYAgA8zAAB4geXLlxtJZtu2bRX2ycnJMZLM8uXLnW1JSUlGknniiSdc+t5zzz3Gbrcbh8NhjDFm8+bNRpJ5+umnXfrt37/fBAUFmYcffrjccTocDnPixAnz3XffGUnm7bffLjPuuXPnVmoaJ06caBo2bGiys7Mr7DNr1iwjyWzdutWlffLkycZms5kvv/zSGPP/P4suXbqYkydPOvtlZGQYSea1115ztt1www2mdevWpqSkxNn23nvvGUkmLS3NGGPMkSNHTFBQkLnmmmtcxrtv3z4TGBhobr311jLTfTpJJikpqcz0REdHm3Hjxjmf//Of/zSSzMaNG8v0HTdunImOjnY+T09PL3fevv7660aSWbZsmct47Ha7+e6775xtv/32mwkNDTV33313mXEBAFBZHOkGAEDStdde6/K8a9euKioqUl5eniTpnXfekc1mU2Jiok6ePOl8hIeH6+KLL9aHH37ofG9eXp4mTZqkqKgo+fv7q2HDhoqOjpakck+1HjVqVKVqXLNmjYYOHapOnTpV2GfDhg2KjY1Vnz59XNrHjx8vY4w2bNjg0h4fHy8/Pz+X6Zak7777ztk2YcIEff/99/rggw+cbcuXL1d4eLiuvvpqSdLmzZv122+/OU8FLxUVFaXLLrtM69evr9Q01qbSaT2zphtvvFGNGzcuU1O3bt3Upk0b53O73a4LL7zQ5bMAAKCquJAaAACSmjdv7vI8MDBQkvTbb79Jkg4dOiRjjFq1alXu+9u1aydJcjgcGjZsmH744QfNmTNHXbp0UePGjeVwONS3b1/n8E4XERFRqRp//PFHtW7d+qx98vPzy71tVmRkpPP1051ruiXp6quv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lVdesbo0nzZz5kyNGTNGHTt2VMOGDdW9e3dNnTpVY8aMsbo0/E/pdp59AM9WVFSkWbNm6dZbb1WTJk2sLsfnLVq0SP7+/rr//vutLgX/k5eXp19++UWPP/64hg8frrVr1+r666/XDTfcoE2bNlldnk975plnFBsbq9atWysgIEDDhw/X0qVLNXDgwEoPw9+N9dU5m83m8twYU6YN1rj33nu1c+dOffLJJ1aX4vP279+vBx54QGvXruU3Qh7E4XCoV69eWrhwoSSpe/fu2r17t1JSUnT77bdbXJ3vev3115WamqqVK1eqc+fOysrK0tSpUxUZGalx48ZZXR5Owz6A5zpx4oRuueUWORwOLV261OpyfN727dv1pz/9SZmZmSwjHqT0Ap0jR47UtGnTJEndunXTp59+qhdeeEFDhgyxsjyf9swzz2jLli1avXq1oqOj9dFHH+mee+5RREREpc8Y9YrQ3aJFC/n5+ZX5j3ZeXl6Z/3yj7t13331avXq1PvroI7Vu3drqcnze9u3blZeXp549ezrbSkpK9NFHH+m5555TcXGx/Pz8LKzQN0VERCg2NtalrVOnTnrjjTcsqgiSNGPGDM2aNUu33HKLJKlLly767rvvlJycTOj2EOHh4ZJOHfGOiIhwtrMP4BlOnDihm266STk5OdqwYQNHuT3Axx9/rLy8PLVp08bZVlJSogcffFBLlizRt99+a11xPqxFixby9/cvd1+Ag1bW+e233/TII49o1apVio+PlyR17dpVWVlZeuqppyodur3i9PKAgAD17NlT69atc2lft26d+vfvb1FVMMbo3nvv1ZtvvqkNGzYoJibG6pIg6fLLL9cXX3yhrKws56NXr1667bbblJWVReC2yIABA8rcUm/v3r2Kjo62qCJIp67A3KCB66bSz8+PW4Z5kJiYGIWHh7vsAxw/flybNm1iH8BipYH7v//9rz744AM1b97c6pIgaezYsdq5c6fLfkBkZKRmzJih999/3+ryfFZAQIB69+7NvoCHOXHihE6cOFHjfQGvONItSdOnT9fYsWPVq1cv9evXT8uWLdO+ffs0adIkq0vzWVOmTNHKlSv19ttvKzg42HkmQkhIiIKCgiyuzncFBweX+V1948aN1bx5c35vb6Fp06apf//+WrhwoW666SZlZGRo2bJlWrZsmdWl+bSEhAQ99thjatOm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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from tools import cconv\n", "%matplotlib inline\n", "\n", "L = 8 # length of signal x[k]\n", "N = 10 # length of signal h[k]\n", "P = 14 # periodicity of periodic convolution\n", "\n", "# generate signals\n", "x = np.ones(L)\n", "h = np.ones(N)\n", "\n", "# linear convolution\n", "y1 = np.convolve(x, h, 'full')\n", "# periodic convolution\n", "y2 = cconv(x, h, int(P))\n", "# linear convolution via periodic convolution\n", "xp = np.append(x, np.zeros(N-1))\n", "hp = np.append(h, np.zeros(L-1))\n", "y3 = cconv(xp, hp, L+N-1)\n", "\n", "# plot results\n", "def plot_signal(x):\n", " plt.stem(x)\n", " plt.xlabel('$k$')\n", " plt.ylabel('$y[k]$')\n", " plt.xlim([0, N+L])\n", " plt.gca().margins(y=0.1)\n", "\n", "plt.figure(figsize = (10, 8))\n", "plt.subplot(3,1,1)\n", "plot_signal(y1)\n", "plt.title('Linear convolution')\n", "\n", "plt.subplot(3,1,2)\n", "plot_signal(y2)\n", "plt.title('Periodic convolution with period $P=%d$'%P)\n", "\n", "plt.subplot(3,1,3)\n", "plot_signal(y3)\n", "plt.title('Linear convolution as periodic convolution')\n", "plt.tight_layout()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise**\n", "\n", "* Change the lengths `L`, `N` and `P` and check how the results for the different convolutions change." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The Fast Convolution Algorithm\n", "\n", "Using the above derived equality of the linear and periodic convolution one can express the linear convolution $y[k] = x_L[k] * h_N[k]$ by the DFT as\n", "\n", "$$ y[k] = \\text{IDFT}_M \\{ \\; \\text{DFT}_M\\{ x_M[k] \\} \\cdot \\text{DFT}_M\\{ h_M[k] \\} \\; \\} $$\n", "\n", "The resulting algorithm is composed of the following steps\n", "\n", "1. Zero-padding of the two input signals $x_L[k]$ and $h_N[k]$ to at least a total length of $M \\geq N+L-1$\n", "\n", "2. Computation of the DFTs $X[\\mu]$ and $H[\\mu]$ using a FFT of length $M$\n", "\n", "3. Multiplication of the spectra $Y[\\mu] = X[\\mu] \\cdot H[\\mu]$\n", "\n", "4. Inverse DFT of $Y[\\mu]$ using an inverse FFT of length $M$\n", "\n", "The algorithm requires two DFTs of length $M$, $M$ complex multiplications and one IDFT of length $M$. On first sight this does not seem to be an improvement, since one DFT/IDFT requires $M^2$ complex multiplications and $M \\cdot (M-1)$ complex additions. The overall numerical complexity is hence in the order of $\\mathcal{O}(M^2)$. The DFT can be realized efficiently by the [fast Fourier transformation](fast_fourier_transform.ipynb) (FFT), which lowers the number of numerical operations for each DFT/IDFT significantly. The actual gain depends on the particular implementation of the FFT. Many FFTs are most efficient for lengths which are a power of two. It therefore can make sense, in terms of the number of numerical operations, to choose $M$ as a power of two instead of the shortest possible length $N+L-1$. In this case, the numerical complexity of the radix-2 algorithm is on the order of $\\mathcal{O}(M \\log_2 M)$.\n", "\n", "The introduced algorithm is known as *fast convolution* due to its computational efficiency when realized by the FFT. For real valued signals $x[k] \\in \\mathbb{R}$ and $h[k] \\in \\mathbb{R}$ the number of numerical operations can be reduced further by using a real valued FFT." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Example\n", "\n", "The implementation of the fast convolution algorithm is straightforward. In the following example the fast convolution of two real-valued signals $x[k] = \\text{rect}_L[k]$ and $h[k] = \\text{rect}_N[k]$ is shown. The real valued FFT/IFFT is consequently used. Most implementations of the FFT include the zero-padding to a given length $M$, e.g as in `numpy` by `numpy.fft.rfft(x, M)`." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Text(0, 0.5, 'y[k]')" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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E3T66acrJSVFCxYs0OHDh80FtomuzvfWbrnlFrlcLm3atCli+ZyEEtQHtmzZohUrVuj222/X/v37NX36dF166aU6ePCg6Wi2VVpaqiVLluitt97Srl27dOLECc2ePVtffvml6WiOsXfvXhUWFurcc881HcX2Pv/8c02dOlWnnXaaXnzxRVVVVenuu+/W0KFDTUeztY0bN+rhhx/Wgw8+qH/84x+666679Oc//1kPPPCA6Wi28uWXX+oHP/iBHnzwwQ7//a677tI999yjBx98UHv37lVycrIuvvhi1dfXRzipvZzquH/11VcqLy/X73//e5WXl+vZZ5/VgQMHdMUVVxhIai9dne/Nnn/+eb399ttKSUmJUDIHstBrmZmZ1qJFi9psGzdunLVmzRpDiZyntrbWkmSVlpaajuII9fX11tixY61du3ZZM2bMsJYvX246kq2tXr3amjZtmukYjjNnzhzrxhtvbLPtpz/9qZWTk2Mokf1Jsp577rmW56FQyEpOTrb+9Kc/tWxraGiwvF6v9fDDDxtIaE/fPu4dKSsrsyRZn376aWRCOUBnx/1f//qX9d3vfteqrKy0Ro8ebd17770Rz+YEzAT10tdff619+/Zp9uzZbbbPnj1bf//73w2lcp5gMChJSkxMNJzEGZYsWaI5c+booosuMh3FEXbs2KHJkyfrmmuuUVJSks477zw98sgjpmPZ3rRp0/TKK6/owIEDkqR3331Xe/bs0WWXXWY4mXNUV1fryJEjba6xbrdbM2bM4BobYcFgUC6XixnofhYKhTR//nzddtttGj9+vOk4thZnOkC0++yzz9TU1KQzzjijzfYzzjhDR44cMZTKWSzL0qpVqzRt2jSlp6ebjmN7zzzzjMrLy7V3717TURzjk08+UUFBgVatWqXf/e53Kisr06233iq3260FCxaYjmdbq1evVjAY1Lhx4xQbG6umpiatX79e1113nelojtF8He3oGvvpp5+aiORIDQ0NWrNmja6//nolJCSYjmNrGzduVFxcnG699VbTUWyPEtRHXC5Xm+eWZbXbhv6xdOlSvffee9qzZ4/pKLZXU1Oj5cuXa+fOnfJ4PKbjOEYoFNLkyZO1YcMGSdJ5552nDz74QAUFBZSgfrRlyxYVFRXpqaee0vjx41VRUaEVK1YoJSVFN9xwg+l4jsI11pzjx4/r2muvVSgU0kMPPWQ6jq3t27dP9913n8rLyzm/I4Db4Xpp+PDhio2NbTfrU1tb227kCn1v2bJl2rFjh3bv3q2RI0eajmN7+/btU21trSZNmqS4uDjFxcWptLRU999/v+Li4tTU1GQ6oi35fD6lpaW12XbOOeew+Eo/u+2227RmzRpde+21mjBhgubPn6+VK1cqPz/fdDTHSE5OliSusYYcP35cc+fOVXV1tXbt2sUsUD974403VFtbq1GjRrVcYz/99FP9+te/1plnnmk6nu1Qgnpp0KBBmjRpknbt2tVm+65du3TBBRcYSmV/lmVp6dKlevbZZ/Xqq6/K7/ebjuQIs2bN0vvvv6+KioqWx+TJkzVv3jxVVFQoNjbWdERbmjp1arsl4A8cOKDRo0cbSuQMX331lWJi2l4mY2NjWSI7gvx+v5KTk9tcY7/++muVlpZyje1nzQXoo48+0ssvv6xhw4aZjmR78+fP13vvvdfmGpuSkqLbbrtNL730kul4tsPtcH1g1apVmj9/viZPnqzzzz9fhYWFOnjwoBYtWmQ6mm0tWbJETz31lLZv3674+PiWUUKv16vBgwcbTmdf8fHx7T53dfrpp2vYsGF8HqsfrVy5UhdccIE2bNiguXPnqqysTIWFhSosLDQdzdays7O1fv16jRo1SuPHj9f+/ft1zz336MYbbzQdzVa++OIL/fOf/2x5Xl1drYqKCiUmJmrUqFFasWKFNmzYoLFjx2rs2LHasGGDhgwZouuvv95g6uh3quOekpKiq6++WuXl5frb3/6mpqamlutsYmKiBg0aZCp21OvqfP922TzttNOUnJyss88+O9JR7c/s4nT28de//tUaPXq0NWjQICsjI4OlmvuZpA4fmzdvNh3NcVgiOzKKi4ut9PR0y+12W+PGjbMKCwtNR7K9uro6a/ny5daoUaMsj8djnXXWWdbtt99uNTY2mo5mK7t37+7w9fyGG26wLOvkMtm5ublWcnKy5Xa7rQsvvNB6//33zYa2gVMd9+rq6k6vs7t37zYdPap1db5/G0tk9x+XZVlWhPoWAAAAABjHZ4IAAAAAOAolCAAAAICjUIIAAAAAOAolCAAAAICjUIIAAAAAOAolCAAAAICjUIIAAAAAOAolCAAQtWbOnKkVK1aYjgEAiDKUIAAAAACOQgkCAAAA4CiUIACAbZSUlMjr9eqJJ54wHQUAMIBRggAAtvDMM89o7ty5euKJJ7RgwQLTcQAAAxglCAAQ9R566CEtWrRI27dv15VXXmk6DgBggIszHQAAgN7Ytm2b/v3vf2vPnj3KzMw0HQcAEAWYCQIARLWJEydqxIgR2rx5syzLMh0HABAFKEEAgKj2ve99T7t379b27du1bNky03EAAFGA2+EAAFHv+9//vnbv3q2ZM2cqLi5OmzZtMh0JADCAUYIAALZw9tln69VXX9XMmTMVGxuru+++23QkAMAA5bK4gRoAAACAg/CZIAAAAACOQgkCAAAA4CiUIAAAAACOQgkCAAAA4CiUIAAAAACOQgkCAAAA4CiUIAAAAACOQgkCAAAA4CiUIAAAAACOQgkCAAAA4CiUIAAAAACOQgkCAAAA4Cj/H6iDj22D3v5eAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "L = 8 # length of signal x[k]\n", "N = 10 # length of signal h[k]\n", "\n", "# generate signals\n", "x = np.ones(L)\n", "h = np.ones(N)\n", "\n", "# fast convolution\n", "M = N+L-1\n", "y = np.fft.irfft(np.fft.rfft(x, M)*np.fft.rfft(h, M))\n", "\n", "# show result\n", "plt.figure(figsize=(10, 3))\n", "plt.stem(y)\n", "plt.xlabel('k')\n", "plt.ylabel('y[k]')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Benchmark\n", "\n", "It was already argued that the numerical complexity of the fast convolution is considerably lower due to the usage of the FFT. As measure, the gain in terms of execution time with respect to the linear convolution is evaluated in the following. Both algorithms are executed for the convolution of two real-valued signals $x_L[k]$ and $h_N[k]$ of length $L=N=2^n$ for $n \\in \\mathbb{N}$. The length of the FFTs/IFFT was chosen as $M=2^{n+1}$. The results depend heavily on the implementation of the FFT and the hardware used. Note that the execution of the following cell may take some time." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnAAAAHJCAYAAAAFPgSDAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB9OElEQVR4nO3dd1gUV9sG8HtZlmVBOiogCHbF3msUNKjYNdFYYs1rjL0k9iigUWwxJho1pqB+saCxRA2iKGKJDUU0GktU0EQlWEFBYFnO9wcycQWU1cVl9P5dl5c7Z8/MPDN7dvbhzJwZhRBCgIiIiIhkw8zUARARERGRYZjAEREREckMEzgiIiIimWECR0RERCQzTOCIiIiIZIYJHBEREZHMMIEjIiIikhkmcEREREQywwSOiIiISGbeuATuzJkzGDhwIMqUKQNLS0sUK1YMderUwbx583Dv3j1Th1foBgwYAC8vL1OH8cpOnTqFFi1awM7ODgqFAosWLTJ1SIVq6dKlWLlyZa7y+Ph4KBSKPN8rbGFhYQgMDMzzPS8vLwwYMOC1xvOqfHx8UK1aNaMuM7/P7U23cuVKKBQKxMfHS2U+Pj7w8fF57bHcvHkTgYGBiI2Nfe3rfpGCHo8zMjLwySefwNXVFUqlErVq1TJ6LLNnz8bWrVuNvtyiLCoqCgqFAlFRUQbPm5qaisDAwDznzav9m4K5SdduZN9//z2GDRuGSpUqYfz48fD29oZWq8WJEyewfPlyHDlyBFu2bDF1mIVq2rRpGD16tKnDeGWDBg1CSkoK1q9fDwcHhzciKX2epUuXwtnZOVdS5OrqiiNHjqBcuXKvPaawsDB8++23eSZxW7Zsga2t7WuPqajJ73N7Gy1dutQk67158yaCgoLg5eVVKInP67Bs2TJ89913WLx4MerWrYtixYoZfR2zZ8/G+++/jy5duhh92W+i1NRUBAUFAUCuP0zat2+PI0eOwNXV1QSR/eeNSeCOHDmCoUOHws/PD1u3boVarZbe8/Pzw6efforw8HATRli4UlNTYWVlZZIf+sJw9uxZDB48GP7+/qYOxaTUajUaNWpk6jByqV27tqlDoCLG29v7hXV0Oh0yMzP1js+UfbzTaDQYMWKEqUOhAihevDiKFy9u6jAA8Ybo0KGDMDc3F9evXy9QfZ1OJ+bOnSsqVaokLCwsRPHixUXfvn3F33//rVevRYsWomrVquLw4cOicePGwtLSUnh6eoqffvpJCCHEjh07RO3atYVGoxHVqlUTO3fu1Js/ICBAABAxMTGia9euwsbGRtja2oo+ffqIxMREvbrr168Xfn5+wsXFRVhaWorKlSuLiRMnikePHunV69+/v7C2thZnzpwRfn5+olixYqJRo0bSe56ennr1N2zYIBo0aCBsbW2FRqMRZcqUEQMHDtSrc+3aNdGnTx9RvHhxYWFhISpXriwWLFggdDqdVCcuLk4AEPPnzxdffvml8PLyEtbW1qJRo0biyJEjBdrvf/zxh+jUqZOwt7cXarVa1KxZU6xcuVJ6PyQkRADI9e950tPTxcyZM6XP0tnZWQwYMEBv/wYHBwuFQiG2bduWa19qNBpx5swZqSwiIkK0bNlS2NjYCI1GI5o0aSL27NmTa73nz58XPXv2FCVKlBAWFhbCw8ND9O3bV6SlpQkh/vvsn5WzjXFxcUIIITw9PXNtb85nmLPPQ0JC9JZx8OBB0bJlS1GsWDGh0WhE48aNxY4dO/JcT2RkpPjkk0+Ek5OTcHR0FF27dhU3btx47j7t379/np/D0zH3799fqr9v3z4BQKxZs0ZMmDBBuLi4CGtra9GhQweRkJAgkpOTxeDBg4WTk5NwcnISAwYMEA8fPtRbZ1ZWlvj2229FzZo1haWlpbC3txfvvfeeuHLlil69mJgY0b59e6mturq6inbt2uX67j4r57t84MAB0bBhQ2FpaSnc3NzE559/LjIzM/XqFqRN5fe5ZWVliRIlSohhw4ZJdTMzM4W9vb1QKBQiISFBKv/yyy+FUqkU9+/fl8qio6NFx44dhYODg1Cr1aJWrVoiNDQ01/bcunVLfPzxx6JUqVJCpVIJLy8vERgYKLRarVTHGN/ZI0eOiCZNmgi1Wi1cXV3FpEmTxIoVK/TaQ87+bdGiRa51z507V8ycOVN4eXkJpVIpHSMLup3//POPGDx4sHB3dxcqlUq4urqK9957TyQkJEjt7tl/AQEB+W5PYmKiGDp0qKhSpYqwtrYWxYsXF76+vuLAgQN69QzddyEhIaJixYrS8XPVqlV5Ho+flVf8Od/3JUuWiHfeeUcUL15cWFlZiWrVqom5c+eKjIwMvWW86DuR1zqe/qzykpaWJoKCgkTlypWFWq0Wjo6OwsfHR/z+++9SncePH4tJkyYJLy8voVKphJubmxg2bJheexYi+7vSvn17sXPnTlG7dm1haWkpKlWqJH788UepTmxsrAAgfvjhh1yxhIWFCQDi119/lcoKcgzMaR/79u2Typ5tpzme/qxyPvtn/+Uc8549huf48ccfRY0aNYRarRYODg6iS5cu4s8//8y1Hmtra/HXX38Jf39/YW1tLdzd3cW4ceOk346CeiMSuMzMTGFlZSUaNmxY4Hk+/vhjAUCMGDFChIeHi+XLl4vixYsLDw8Pcfv2baleixYthJOTk9TYdu3aJTp06CAAiKCgIFG9enWxbt06ERYWJho1aiTUarXej2POj7inp6cYP3682LVrl1i4cKGwtrYWtWvX1vsizpw5U3z11Vfit99+E1FRUWL58uWiTJkywtfXVy/2/v37Swfs4OBgsXfvXrFr1y7pvacPGIcPHxYKhUL07NlThIWFicjISBESEiL69u0r1UlMTBSlSpUSxYsXF8uXLxfh4eFixIgRAoAYOnSoVC+nUXt5eYm2bduKrVu3iq1bt4rq1asLBwcH8eDBg+fu8wsXLggbGxtRrlw5sXr1avHbb7+JXr16SQf5nFiOHDkiAIj3339fHDly5Lk/NDqdTrRt21ZYW1uLoKAgERERIX744QdRqlQp4e3tLVJTU4UQ2clBu3bthIODg4iPjxdCCPHTTz/lOmD83//9n1AoFKJLly5i8+bNYvv27aJDhw5CqVTqJXGxsbGiWLFiwsvLSyxfvlzs3btX/Pzzz6JHjx4iOTlZ77N/1rNf/piYGFG2bFlRu3ZtaXtjYmL09vnTCVxUVJRQqVSibt26IjQ0VGzdulW0bt1aKBQKsX79+lzrKVu2rBg5cqTYtWuX+OGHH4SDg0OuNvWsy5cvi/fff18AkGI6cuSIdIDJL4Hz9PQUAwYMkL5TxYoVE76+vsLPz0989tlnYvfu3WLu3LlCqVSKkSNH6q1z8ODBQqVSiU8//VSEh4eLtWvXisqVK4uSJUtKSc+jR4+Ek5OTqFevntiwYYPYv3+/CA0NFZ988kmuA+Wzcr7Lbm5u4ptvvhG7du0So0aNEgDE8OHDpXoFbVPP+9x69uwpKlasKC3z6NGjAoDQaDRizZo1Urm/v79o0KCBNB0ZGSksLCzEO++8I0JDQ0V4eLgYMGBArjZw69Yt4eHhITw9PcV3330n9uzZI2bOnCnUarUYMGCAVO9Vv7Pnzp0TVlZWwtvbW6xbt078+uuvok2bNqJ06dIFTuBKlSolfH19xS+//CJ2794t4uLiCryd//zzj3B1dRXOzs5i4cKFYs+ePSI0NFQMGjRInD9/XiQlJUnt/PPPP5c+h+cl8xcuXBBDhw4V69evF1FRUWLHjh3io48+EmZmZno/9Ibsu5wYOnfuLLZv3y5+/vlnUb58eekzep4jR46Idu3aCY1GI8Wf84fC2LFjxbJly0R4eLiIjIwUX331lXB2dtb7A7wg34kjR44IjUYj2rVrJ63j3Llz+cak1WqFr6+vMDc3F5999pkICwsT27ZtE1OmTBHr1q0TQmQfU9u0aSPMzc3FtGnTxO7du8WCBQuk37ankxFPT0/h7u4uvL29xerVq8WuXbtE9+7dBQCxf/9+qV7t2rVF06ZNc8XTo0cPUaJECemPk4IeA182gUtLSxPh4eECgPjoo4+kfXb58mUhRN4J3OzZswUA0atXL/Hbb7+J1atXi7Jlywo7Oztx6dIlvfVYWFiIKlWqiAULFog9e/aI6dOnC4VCIYKCgvL9TPLyRiRwCQkJAoDo2bNngeqfP39eAND7C1kIIY4dOyYAiClTpkhlLVq0EADEiRMnpLK7d+8KpVIpNBqNXrKW8xfEN998I5Xl/IiPHTtWb11r1qwRAMTPP/+cZ4xZWVlCq9WK/fv3CwDi9OnT0ns5vSM5vYBPezaBW7BggQDw3AP1pEmTBABx7NgxvfKhQ4cKhUIhLl68KIT474BWvXp1vR6L48ePCwDSFzs/PXv2FGq1Olcvqb+/v7CystKL8dkf1fysW7dOABCbNm3SK4+OjhYAxNKlS6WyO3fuCHd3d9GgQQMRExMjrKysxIcffii9n5KSIhwdHUXHjh31lqXT6UTNmjX1fmhbtmwp7O3tc/WiPq2gCZwQQlStWjXPg0peCVyjRo1EiRIl9HqwMjMzRbVq1YS7u7vIysrSW8+z7XzevHkCgLh161a+sQshxPDhw/Pt/cwvgXt2340ZM0YAEKNGjdIr79Kli3B0dJSmc5L2L7/8Uq/e33//LTQajZgwYYIQQogTJ04IAGLr1q3PjT0vOd/lp/+KFyI7cTQzMxPXrl0TQhjWpvL73H744QcBQGrrX3zxhahcubLo1KmT9OObkZEhrK2t9Y43lStXFrVr19brRRMi+wyDq6ur1CM+ZMgQUaxYMSnmHDnf95wf51f9zn7wwQdCo9Ho9RpmZmaKypUrFziBK1euXK4eo4Ju56BBg4RKpXpucp7zuTzbS11QmZmZQqvVilatWomuXbvmiv9F+06n0wk3NzdRp04d6bsnhBDx8fFCpVK9MIET4r9emefR6XRCq9WK1atXC6VSKe7duyeEKPh3wtraWu87+zyrV68WAMT333+fb52cBGfevHl65aGhoQKAWLFihVTm6ekpLC0t9drr48ePhaOjoxgyZIhU9s033wgA0m+OEELcu3dPqNVq8emnn0plBT0GvmwCJ4QQt2/fzrc399lj+P3796UE+WnXr18XarVa9O7dW289AMSGDRv06rZr105UqlQp17qe540bhVoQ+/btA4BcFx43aNAAVapUwd69e/XKXV1dUbduXWna0dERJUqUQK1ateDm5iaVV6lSBQBw7dq1XOvs06eP3nSPHj1gbm4uxQIAV69eRe/eveHi4gKlUgmVSoUWLVoAAM6fP59rme+9994Lt7V+/frS+jZs2IAbN27kqhMZGQlvb280aNBAr3zAgAEQQiAyMlKvvH379lAqldJ0jRo1AOS93c+up1WrVvDw8Mi1ntTUVBw5cuSF2/OsHTt2wN7eHh07dkRmZqb0r1atWnBxcdEbQeTk5ITQ0FDExMSgSZMmKF26NJYvXy69f/jwYdy7dw/9+/fXW1ZWVhbatm2L6OhopKSkIDU1Ffv370ePHj1e+3UQKSkpOHbsGN5//329C52VSiX69u2Lf/75BxcvXtSbp1OnTnrTBf28XkaHDh30pnO+E+3bt89Vfu/ePTx69AhA9ueoUCjw4Ycf6u17FxcX1KxZU/ocy5cvDwcHB0ycOBHLly/Hn3/+aVB8NjY2ufZH7969kZWVhQMHDkixFLRN5efdd98FAOzZswcAEBERAT8/P7z77ruIiIgAkH3dbkpKilT38uXLuHDhgnSseHrd7dq1w61bt6TPdseOHfD19YWbm5tevZxrRvfv368Xz8t+Z/ft24dWrVqhZMmSUplSqcQHH3zwwn2Qo1OnTlCpVNK0Idu5c+dO+Pr6Su3IWJYvX446derA0tIS5ubmUKlU2Lt3b57H2Rftu4sXL+LmzZvo3bs3FAqFVM/T0xNNmjR5pThPnTqFTp06wcnJSfpN6NevH3Q6HS5dugTg1b8Tedm5cycsLS0xaNCgfOvk/C48+zvavXt3WFtb5/odrVWrFkqXLi1NW1paomLFinptsE+fPlCr1Xoju9etW4f09HQMHDgQwMsdAwvbkSNH8Pjx41z7wsPDAy1btsy1LxQKBTp27KhXVqNGDYOPyW9EAufs7AwrKyvExcUVqP7du3cBIM8RJG5ubtL7ORwdHXPVs7CwyFVuYWEBAEhLS8tV38XFRW/a3NwcTk5O0roePXqEd955B8eOHcMXX3yBqKgoREdHY/PmzQCAx48f681vZWVVoFGAzZs3x9atW5GZmYl+/frB3d0d1apVw7p166Q6d+/ezXdf5Lz/NCcnJ73pnAuSn43xWYaupyD+/fdfPHjwABYWFlCpVHr/EhIScOfOHb36DRs2RNWqVZGWloahQ4fC2tpab1kA8P777+da1ty5cyGEwL1793D//n3odDq4u7sbHO+run//PoQQr+Xzehn5fSde9F35999/IYRAyZIlc+37o0ePSp+jnZ0d9u/fj1q1amHKlCmoWrUq3NzcEBAQAK1W+8L4nk5EcuR8N3P2m6FtKi+enp4oV64c9uzZI/1xkpPA5fzA7NmzBxqNRvqRz2l/n332Wa71Dhs2DACkdf/777/Yvn17rnpVq1bVq5fjVb6zzx67nt5nBfFsWzVkO2/fvm3079nChQsxdOhQNGzYEJs2bcLRo0cRHR2Ntm3b5rk/XrTvctrNq+6nZ12/fh3vvPMObty4ga+//hoHDx5EdHQ0vv32W731v+p3Ii+3b9+Gm5sbzMzyTxHu3r0Lc3PzXH/EKhQKuLi4vPA4BGTvy6f3uaOjIzp16oTVq1dDp9MByL5lR4MGDaS2/TLHwMJmaE5hZWUFS0tLvTK1Wp1n7vA8b8QoVKVSiVatWmHnzp34559/XviFz2lIt27dylX35s2bcHZ2NnqMCQkJKFWqlDSdmZmJu3fvSrFERkbi5s2biIqKknrdAODBgwd5Lu/pv/RepHPnzujcuTPS09Nx9OhRBAcHo3fv3vDy8kLjxo3h5OSEW7du5Zrv5s2bAGC0/VEY63F2doaTk1O+I4xtbGz0pgMCAvDHH3+gbt26mD59Ojp06ICyZcvqrX/x4sX5jvwsWbIkdDodlEol/vnnn+fGlvMFTU9P1xt1V5AEID8ODg4wMzN7LZ/X6+Ts7AyFQoGDBw/mOULx6bLq1atj/fr1EELgzJkzWLlyJWbMmAGNRoNJkyY9dz05ycPTEhISAPx3XDC0TeWnVatW+PXXX7F//35kZWXBx8cHNjY2cHNzQ0REBPbs2YN33nlH2racz23y5Mno1q1bnsusVKmSVLdGjRqYNWtWnvWePjPwKpycnKT987S8yvLz7LHKkO0sXrz4C79nhvr555/h4+ODZcuW6ZU/fPjwpZaX025edT89a+vWrUhJScHmzZvh6ekpled1v7tX+U7kpXjx4jh06BCysrLyTeKcnJyQmZmJ27dv6yVxQggkJCRIZ38MNXDgQGzcuBEREREoXbo0oqOj9T6rVz0GWlpaIikpKVf5qxyXn84p8oqpsI7Jb0QPHJB9MBBCYPDgwcjIyMj1vlarxfbt2wEALVu2BJD9RX5adHQ0zp8/j1atWhk9vjVr1uhNb9iwAZmZmdL9ZXIOcs/+eH333XdGi0GtVqNFixaYO3cugOzueSD7h+bPP/9ETEyMXv3Vq1dDoVDA19fXKOtv1aqVlKg+ux4rK6uXul1Ghw4dcPfuXeh0OtSrVy/Xv5wfAiD7NFZwcDA+//xzREREwM7ODh988IHUXpo2bQp7e3v8+eefeS6rXr16sLCwgEajQYsWLbBx48bnfulz7l135swZvfKcdvi0Z/8SzY+1tTUaNmyIzZs369XPysrCzz//DHd3d1SsWPGFyymIwuype1aHDh0ghMCNGzfy3O/Vq1fPNY9CoUDNmjXx1Vdfwd7ePlf7zcvDhw+xbds2vbK1a9fCzMwMzZs3l2IpaJt63uf27rvv4t9//8WiRYvQqFEjKfFr1aoVtmzZgujoaOn0KZCdtFSoUAGnT5/Ot/3lLKNDhw44e/YsypUrl2c9YyVwvr6+2Lt3r17iq9PpEBoa+tLLNGQ7/f39sW/fvueeEjO0nSoUilzH2TNnzrzUJRw52+Pq6op169ZBCCGVX7t2DYcPH36pZebECej/Jggh8P333z93nvy+EwU9xgDZ+z0tLe25N6nO+Z189nd006ZNSElJeenf0datW6NUqVIICQlBSEgILC0t0atXL+n9Vz0Genl54dKlS0hPT5fK7t69m+uzMqRdNW7cGBqNJte++Oeff6RLhwrDG9EDB2TvwGXLlmHYsGGoW7cuhg4diqpVq0Kr1eLUqVNYsWIFqlWrho4dO6JSpUr4+OOPsXjxYpiZmcHf3x/x8fGYNm0aPDw8MHbsWKPHt3nzZpibm8PPzw/nzp3DtGnTULNmTfTo0QMA0KRJEzg4OOCTTz5BQEAAVCoV1qxZg9OnT7/SeqdPn45//vkHrVq1gru7Ox48eICvv/5a7/q6sWPHYvXq1Wjfvj1mzJgBT09P/Pbbb1i6dCmGDh1qtIQgICBAunZn+vTpcHR0xJo1a/Dbb79h3rx5sLOzM3iZPXv2xJo1a9CuXTuMHj0aDRo0gEqlwj///IN9+/ahc+fO6Nq1K27duoUPP/wQLVq0QEBAAMzMzBAaGormzZtjwoQJWLRoEYoVK4bFixejf//+uHfvHt5//32UKFECt2/fxunTp3H79m3pL8GFCxeiWbNmaNiwISZNmoTy5cvj33//xbZt2/Ddd9/BxsYG7dq1g6OjIz766CPMmDED5ubmWLlyJf7+++9c25HzF3RoaCjKli0LS0vLPJMWAAgODoafnx98fX3x2WefwcLCAkuXLsXZs2exbt06g3pnnydn/XPnzoW/vz+USiVq1Kghnf40pqZNm+Ljjz/GwIEDceLECTRv3hzW1ta4desWDh06hOrVq2Po0KHYsWMHli5dii5duqBs2bIQQmDz5s148OAB/Pz8XrgeJycnDB06FNevX0fFihURFhaG77//HkOHDpWuzylom8rZR/l9bi1btoRCocDu3bulG4IC2Yld//79pddP++677+Dv7482bdpgwIABKFWqFO7du4fz588jJiYGGzduBADMmDEDERERaNKkCUaNGoVKlSohLS0N8fHxCAsLw/Lly41y6vHzzz/Htm3b0LJlS0yfPh1WVlb49ttvkZKS8krLNWQ7d+7ciebNm2PKlCmoXr06Hjx4gPDwcIwbNw6VK1dGuXLloNFosGbNGlSpUgXFihWDm5tbvklshw4dMHPmTAQEBKBFixa4ePEiZsyYgTJlyiAzM9PgbTEzM8PMmTPxv//9D127dsXgwYPx4MEDBAYGvtIpVD8/P1hYWKBXr16YMGEC0tLSsGzZMty/f1+vXkG/E9WrV0dUVBS2b98OV1dX2NjY6P0x8rRevXohJCQEn3zyCS5evAhfX19kZWXh2LFjqFKlCnr27Ak/Pz+0adMGEydORHJyMpo2bYozZ84gICAAtWvXRt++fV9qu5VKJfr164eFCxfC1tYW3bp1y/Xb8CrHwL59++K7777Dhx9+iMGDB+Pu3buYN29erkuSbGxs4OnpiV9//RWtWrWCo6MjnJ2d87ypvL29PaZNm4YpU6agX79+6NWrF+7evYugoCBYWloiICDgpfbFCxk05EEGYmNjRf/+/UXp0qWFhYWFNKR5+vTpeiMGc+4DV7FiRaFSqYSzs7P48MMP870P3LNy7mvzLDwzejJnJOLJkydFx44dRbFixYSNjY3o1auX+Pfff/XmzbnXnJWVlShevLj43//+J2JiYnKNsHreiKVnR9Ls2LFD+Pv7i1KlSgkLCwtRokQJ0a5dO3Hw4EG9+a5duyZ69+4tnJychEqlEpUqVRLz58/P9z5weW338+69lOOPP/4QHTt2FHZ2dsLCwkLUrFkzz9Fjz+7H59FqtWLBggXS/cOKFSsmKleuLIYMGSL++usvkZmZKVq0aCFKliyZa+Tl/PnzBQCxZcsWqWz//v2iffv2wtHRUahUKlGqVCnRvn17sXHjRr15//zzT9G9e3fh5OQkLCwsROnSpcWAAQP0hs8fP35cNGnSRFhbW4tSpUqJgIAAaYTi0yP44uPjRevWrYWNjY10Ow4hXnwfOGtra6HRaESjRo3E9u3b9erkjJSKjo7WK89rZFZe0tPTxf/+9z9RvHhxoVAo9GLObxTqs/sovxhyvhdP37JHiOxbuzRs2FDarnLlyol+/fpJo8AvXLggevXqJcqVKyc0Go2ws7MTDRo00LuXYH5yvstRUVGiXr160n3NpkyZkms05IvaVI78PrcctWvXFgD07p1148YNAUA4OTnpjVrMcfr0aem2CSqVSri4uIiWLVuK5cuX69W7ffu2GDVqlChTpoxQqVTC0dFR1K1bV0ydOlW6d6QxvrO///67dIskFxcXMX78eIPuA5fXug3Zzr///lsMGjRIuLi4SPca69Gjh97xc926daJy5cpCpVK9cLvS09PFZ599JkqVKiUsLS1FnTp1xNatW3MdOw3ddz/88IOoUKGCsLCwEBUrVhQ//fRTge4DJ0T+x/Tt27dLbbBUqVJi/PjxYufOnXrf34J+J2JjY0XTpk2FlZVVge4D9/jxYzF9+nRpm5ycnETLli3F4cOH9epMnDhReHp6SvfoGzp0aL73gXtWfiNCL126JN17LSIiIs/4CnIMzO9Yt2rVKlGlShVhaWkpvL29RWhoaJ6f1Z49e0Tt2rWFWq0u0H3gfvjhB1GjRg1hYWEh7OzsROfOnXPdriW/zzq/uxY8j0KIp/p8yegCAwMRFBSE27dvy/LaJCIiIip63phr4IiIiIjeFkzgiIiIiGSGp1CJiIiIZIY9cEREREQywwSOiIiISGaYwBERERHJzBtzI9+iICsrCzdv3oSNjY3RbqZKREREhUsIgYcPH77wGbBFCRM4I7p58yY8PDxMHQYRERG9hL///tsoTzF5HZjAGVHO8/v+/vvvXI/lIHpZWq0Wu3fvRuvWraFSqUwdDlGBsN2SnCQnJ8PDw0P6HZcDJnBGlHPa1NbWlgkcGY1Wq4WVlRVsbW35Q0iywXZLciSny5/kcaKXiIiIiCRM4IiIiIhkhgkcERERkcwwgSMiIiKSGSZwRERERDLDBI6IiIhIZpjAEREREckMEzgiIiIimWECR0RERCQzTOCIiIiIZIYJHBEREZHMMIEjKsqEAFJSoExLy35NREQEPsyeqGhLTYXKwQEdAGjv3wcsLEwdERERFQHsgSMiIiKSGSZwRERERDLDBI6IiIhIZpjAEREREckMEzgiIiIimWECR0RERCQzTOCIiIiIZIYJHBEREZHMMIEjIiIikhkmcEREREQywwSOiIiISGaYwBERERHJDB9mXwiqBeyCmdrK1GHQG0CTkYbzT17Xn7UHD5Qak8ZDVFBqpcC8BkC1wF1I1ylMHQ69IeLntDd1CEUGe+CIiIiIZIYJHBEREZHMmDyBu3HjBj788EM4OTnBysoKtWrVwsmTJ6X3BwwYAIVCofevUaNGesvw8fHJVadnz556dTp16oTSpUvD0tISrq6u6Nu3L27evJkrnpUrV6JGjRqwtLSEi4sLRowYUTgbTkRERPSSTHoN3P3799G0aVP4+vpi586dKFGiBK5cuQJ7e3u9em3btkVISIg0bWFhkWtZgwcPxowZM6RpjUb/WiFfX19MmTIFrq6uuHHjBj777DO8//77OHz4sFRn4cKF+PLLLzF//nw0bNgQaWlpuHr1qpG2loiIiMg4TJrAzZ07Fx4eHnrJmZeXV656arUaLi4uz12WlZXVc+uMHTtWeu3p6YlJkyahS5cu0Gq1UKlUuH//Pj7//HNs374drVq1kupWrVrVgC0iIiIiKnwmTeC2bduGNm3aoHv37ti/fz9KlSqFYcOGYfDgwXr1oqKiUKJECdjb26NFixaYNWsWSpQooVdnzZo1+Pnnn1GyZEn4+/sjICAANjY2ea733r17WLNmDZo0aQKVSgUAiIiIQFZWFm7cuIEqVarg4cOHaNKkCb788kt4eHjkuZz09HSkp6dL08nJyQAAC6WAUileer8Q5VA/1Y7UZkJvmqgoU5sJvf+JjEGr1cpquYXJpAnc1atXsWzZMowbNw5TpkzB8ePHMWrUKKjVavTr1w8A4O/vj+7du8PT0xNxcXGYNm0aWrZsiZMnT0KtVgMA+vTpgzJlysDFxQVnz57F5MmTcfr0aUREROitb+LEiViyZAlSU1PRqFEj7NixQy+WrKwszJ49G19//TXs7Ozw+eefw8/PD2fOnMnztG1wcDCCgoJylc+sq4OVlc6Yu4reUsq0/9rRtDpZ0FmyXZG8zKyXZeoQ6A0SFhZWKMtNTU0tlOUWJoUQwmR/HllYWKBevXp616GNGjUK0dHROHLkSJ7z3Lp1C56enli/fj26deuWZ52TJ0+iXr16OHnyJOrUqSOV37lzB/fu3cO1a9cQFBQEOzs77NixAwqFArNnz8bUqVOxa9cutG7dGgBw+/ZtuLi4ICwsDG3atMm1nrx64Dw8PFDu01AoeR84MgJNRhpiF3QHADScsAEPzHkfOJIHtZnAzHpZmHbCDOlZvA8cGcfZwNy/xcaQnJwMZ2dnJCUlwdbWtlDWYWwm7YFzdXWFt7e3XlmVKlWwadOm587j6emJv/76K986derUgUqlwl9//aWXwDk7O8PZ2RkVK1ZElSpV4OHhgaNHj6Jx48ZwdXUFAL14ihcvDmdnZ1y/fj3P9ajVaqkX8GkZOgXMeONKMoKn21F6loI3RCXZYbslY8q57Ekuyy1MJr2NSNOmTXHx4kW9skuXLsHT0zPfee7evYu///5bSrjycu7cOWi12ufWyel4zOlBa9q0KQDoxXPv3j3cuXPnufEQERERvW4mTeDGjh2Lo0ePYvbs2bh8+TLWrl2LFStWYPjw4QCAR48e4bPPPsORI0cQHx+PqKgodOzYEc7OzujatSsA4MqVK5gxYwZOnDiB+Ph4hIWFoXv37qhdu7aUlB0/fhxLlixBbGwsrl27hn379qF3794oV64cGjduDACoWLEiOnfujNGjR+Pw4cM4e/Ys+vfvj8qVK8PX19c0O4iIiIgoDyZN4OrXr48tW7Zg3bp1qFatGmbOnIlFixahT58+AAClUok//vgDnTt3RsWKFdG/f39UrFgRR44ckUaYWlhYYO/evWjTpg0qVaqEUaNGoXXr1tizZw+USiWA7HvCbd68Ga1atUKlSpUwaNAgVKtWDfv379c7Bbp69Wo0bNgQ7du3R4sWLaBSqRAeHi7LrlUiIiJ6c5l0EMObJjk5GXZ2dvAYs4EPsyej0GSk4fxX7wMAan22kQ+zJ9nIfpi9DhOOK3kNHBlNYT3MPuf3W06DGJjAGZEcGwAVcSkpQLFiAADt/ftQPfOUEqKiSqvVIiwsDO3ateNZDCry5Pj7bfJnoRIRERGRYZjAEREREckMEzgiIiIimTHpjXzfVNUCdnEQAxmFJiMN55+8rj9rDwcxkGxkD2IAqgXu4iCGN1BhDSaggmMPHBEREZHMMIEjIiIikhkmcEREREQyY9IEbtmyZahRowZsbW1ha2uLxo0bY+fOnQCy7yE0ceJEVK9eHdbW1nBzc0O/fv1w8+ZNaf74+HgoFIo8/23cuFFvXb/99hsaNmwIjUYDZ2dndOvWTe/96OhotGrVCvb29nBwcEDr1q0RGxtb6PuAiIiIyFAmTeDc3d0xZ84cnDhxAidOnEDLli3RuXNnnDt3DqmpqYiJicG0adMQExODzZs349KlS+jUqZM0v4eHB27duqX3LygoCNbW1vD395fqbdq0CX379sXAgQNx+vRp/P777+jdu7f0/sOHD9GmTRuULl0ax44dw6FDh2Bra4s2bdpAq9W+1n1CRERE9CJF7kkMjo6OmD9/Pj766KNc70VHR6NBgwa4du0aSpcunef8tWvXRp06dfDjjz8CADIzM+Hl5YWgoKA8lwkAJ06cQP369XH9+nV4eHgAAP744w/UqFEDly9fRrly5QoUOx+lRcbGR2mRXPFRWm+2N20UqhyfxFBkbiOi0+mwceNGpKSkoHHjxnnWSUpKgkKhgH0+jxM6efIkYmNj8e2330plMTExuHHjBszMzFC7dm0kJCSgVq1aWLBgAapWrQoAqFSpEpydnfHjjz9iypQp0Ol0+PHHH1G1alV4enrmG3N6ejrS09Ol6eTkZACAhVJAqSxSeTHJlPqpdqQ2E3rTREWZ2kzo/U9vljft7JQct8fkCdwff/yBxo0bIy0tDcWKFcOWLVvg7e2dq15aWhomTZqE3r1755sd//jjj6hSpQqaNGkilV29ehUAEBgYiIULF8LLywtffvklWrRogUuXLsHR0RE2NjaIiopC586dMXPmTABAxYoVsWvXLpib57+LgoODERQUlKt8Zl0drKx0Bu0Horwo0/5rR9PqZEFnyXZF8jKzXpapQ6BCEBYWZuoQjCo1NdXUIRjM5KdQMzIycP36dTx48ACbNm3CDz/8gP379+slcVqtFt27d8f169cRFRWVZwL3+PFjuLq6Ytq0afj000+l8rVr16JPnz747rvv8PHHHwPI7jlzd3fHF198gSFDhuDx48fw8fFB5cqVMWLECOh0OixYsAAXLlxAdHQ0NJq8T1vl1QPn4eGBcp+GQslTqGQEmow0xC7oDgBoOGEDHpjzFCrJg9pMYGa9LEw7YYb0LJ5CfdOcDWxj6hCMKjk5Gc7OzjyFaggLCwuUL18eAFCvXj1ER0fj66+/xnfffQcgO3nr0aMH4uLiEBkZme+O/eWXX5Camop+/frplbu6ugKAXkKoVqtRtmxZXL9+HUB2khcfH48jR47AzMxMKnNwcMCvv/6Knj175rlOtVoNtVqdqzxDp4AZr/kgI3i6HaVnKXgtEckO2+2bSaVSmToEo5Lj9hS5+8AJIaRerZzk7a+//sKePXvg5OSU73w//vgjOnXqhOLFi+uV161bF2q1GhcvXpTKtFot4uPjpevbUlNTYWZmBoXiv4NMznRWFrv/iYiIqGgxaQ/clClT4O/vDw8PDzx8+BDr169HVFQUwsPDkZmZiffffx8xMTHYsWMHdDodEhISAGSPVLWwsJCWc/nyZRw4cCDPc/K2trb45JNPEBAQAA8PD3h6emL+/PkAgO7ds09N+fn5Yfz48Rg+fDhGjhyJrKwszJkzB+bm5vD19X0Ne4KIiIio4EyawP3777/o27cvbt26BTs7O9SoUQPh4eHw8/NDfHw8tm3bBgCoVauW3nz79u2Dj4+PNP3TTz+hVKlSaN26dZ7rmT9/PszNzdG3b188fvwYDRs2RGRkJBwcHAAAlStXxvbt2xEUFITGjRtLI1bDw8OlU7BERERERYXJBzG8SXgfODI23geO5Ir3gXuz8T5wpscEzojk2ACoiEtJAYoVAwBo79+HKp97IBIVNVqtFmFhYWjXrp0sLxCnt4scf7+L3CAGIiIiIno+JnBEREREMsMEjoiIiEhmTH4j3zdRtYBdHMRARqHJSMP5J6/rz9rDQQwkG9mDGIBqgbs4iMFI3rSBA/Rq2ANHREREJDNM4IiIiIhkhgkcERERkcyYNIE7cOAAOnbsCDc3NygUCmzdujVXnfPnz6NTp06ws7ODjY0NGjVqJD2EHgCGDBmCcuXKQaPRoHjx4ujcuTMuXLigt4xLly6hc+fOcHZ2hq2tLZo2bYp9+/blGdPdu3fh7u4OhUKBBw8eGHNziYiIiIzCpAlcSkoKatasiSVLluT5/pUrV9CsWTNUrlwZUVFROH36NKZNmwZLS0upTt26dRESEoLz589j165dEEKgdevW0Ol0Up327dsjMzMTkZGROHnyJGrVqoUOHTpIz1Z92kcffYQaNWoYf2OJiIiIjMSko1D9/f3h7++f7/tTp05Fu3btMG/ePKmsbNmyenU+/vhj6bWXlxe++OIL1KxZE/Hx8ShXrhzu3LmDy5cv46effpISszlz5mDp0qU4d+4cXFxcpPmXLVuGBw8eYPr06di5c+cL409PT0d6ero0nZycDACwUAoolXzABb069VPtSG0m9KaJijK1mdD7n16dVqs1dQhvLDnu2yJ7G5GsrCz89ttvmDBhAtq0aYNTp06hTJkymDx5Mrp06ZLnPCkpKQgJCUGZMmXg4eEBAHByckKVKlWwevVq1KlTB2q1Gt999x1KliyJunXrSvP++eefmDFjBo4dO4arV68WKMbg4GAEBQXlKp9ZVwcrK10ecxAZRpn2XzuaVicLOku2K5KXmfWyTB3CGyMsLMzUIbyxUlNTTR2CwYpsApeYmIhHjx5hzpw5+OKLLzB37lyEh4ejW7du2LdvH1q0aCHVXbp0KSZMmICUlBRUrlwZERERsLCwAAAoFApERESgc+fOsLGxgZmZGUqWLInw8HDYP3muZHp6Onr16oX58+ejdOnSBU7gJk+ejHHjxknTycnJ8PDwwLSTSijVSuPtDHpraTKU6PDk9cwYMzwwZ7sieVCbCcysl4VpJ8yQnsX7wBnD2cA2pg7hjZVzBk1OimwCl5WV/Vdb586dMXbsWABArVq1cPjwYSxfvlwvgevTpw/8/Pxw69YtLFiwAD169MDvv/8OS0tLCCEwbNgwlChRAgcPHoRGo8EPP/yADh06IDo6Gq6urpg8eTKqVKmCDz/80KAY1Wo11Gp1rvIMnQJmvHElGcHT7Sg9S8EbopLssN0aj0qlMnUIbyw57tsiexsRZ2dnmJubw9vbW6+8SpUqeqNQAcDOzg4VKlRA8+bN8csvv+DChQvYsmULACAyMhI7duzA+vXr0bRpU9SpUwdLly6FRqPBqlWrpDobN26Eubk5zM3N0apVKymGgICA17C1RERERAVXZHvgLCwsUL9+fVy8eFGv/NKlS/D09HzuvEIIaXBBznltMzP9XNXMzEzq5du0aRMeP34svRcdHY1Bgwbh4MGDKFeu3CtvCxEREZExmTSBe/ToES5fvixNx8XFITY2Fo6OjihdujTGjx+PDz74AM2bN4evry/Cw8Oxfft2REVFAQCuXr2K0NBQtG7dGsWLF8eNGzcwd+5caDQatGvXDgDQuHFjODg4oH///pg+fTo0Gg2+//57xMXFoX377OfKPZuk3blzB0B2b1/OdXJERERERYVJT6GeOHECtWvXRu3atQEA48aNQ+3atTF9+nQAQNeuXbF8+XLMmzcP1atXxw8//IBNmzahWbNmAABLS0scPHgQ7dq1Q/ny5dGjRw9YW1vj8OHDKFGiBIDs06Dh4eF49OgRWrZsiXr16uHQoUP49ddfUbNmTdNsOBEREdErMGkPnI+PD4R4/j2CBg0ahEGDBuX5npubW4GGVderVw+7du0yalxEREREpqIQzFSMJjk5GXZ2dkhKSoKtra2pw6E3QUoKUKwYAEB7/z5UPKVPMqHVahEWFoZ27drJcoQfvV3k+PtdZEehEhEREVHemMARERERyQwTOCIiIiKZKbL3gZOzagG7YKa2MnUY9AbQZKTh/JPX9WftwQOlxqTxEBWUWikwrwFQLXAXn8TwEuLntDd1CFTEsQeOiIiISGaYwBERERHJTJFO4DIzM/H555+jTJky0Gg0KFu2LGbMmCE9AgsANm/ejDZt2sDZ2RkKhQKxsbG5lnPlyhV07doVxYsXh62tLXr06IF///1Xej8+Ph4fffSRtJ5y5cohICAAGRkZr2MziYiIiAxSpBO4uXPnYvny5ViyZAnOnz+PefPmYf78+Vi8eLFUJyUlBU2bNsWcOXPyXEZKSgpat24NhUKByMhI/P7778jIyEDHjh2lRPDChQvIysrCd999h3PnzuGrr77C8uXLMWXKlNeynURERESGKNKDGI4cOYLOnTtLzyz18vLCunXrcOLECalO3759AWT3ouXl999/R3x8PE6dOiXdnC8kJASOjo6IjIzEu+++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L14cCQkJenE9e2+3gmy/sbaPiF4eEziit8DSpUuRmZmJevXqITQ0FOfPn8fFixfx888/48KFC1LSVK5cOWRmZmLx4sW4evUq/u///g/Lly83ejyffvop9u7di5kzZ+LSpUtYtWoVlixZgs8+++yVl12+fHls3rwZsbGxOH36NHr37q3X67Njxw588803iI2NxbVr17B69WpkZWWhUqVKALJPBx87dgzx8fG4c+dOnj1GXl5e6N+/PwYNGoStW7ciLi4OUVFR2LBhAwBg2LBh+PvvvzFy5EhcuHABv/76KwICAjBu3DiYmRX8sKtQKNC7d28sX74cERER+PDDD6X3rK2tMXToUIwfPx7h4eH4888/MXjwYKSmpuKjjz7Kc3k+Pj64ffs25s2bhytXruDbb7/Fzp07c23bmTNncPHiRdy5cyfPHjpjbR8RvQLTXHpHRK/bzZs3xYgRI0SZMmWESqUSxYoVEw0aNBDz588XKSkpUr2FCxcKV1dXodFoRJs2bcTq1av1LoTP7zYiT3v2wvi85NxGRKVSidKlS4v58+frvf+ygxji4uKEr6+v0Gg0wsPDQyxZskRvYMLBgwdFixYthIODg9BoNKJGjRoiNDRUmv/ixYuiUaNGQqPRPHeAxOPHj8XYsWOFq6urdBuRnNt7CFGw22w8O1iic+fOon///npl586dEwCEp6en3qCBnBhGjhwpnJ2dC3QbESGEWLZsmfDw8BDW1taiX79+YtasWXqfVWJiovDz8xPFihV75duIFGT7iOjlKIQw0oUnRERERPRasK+biIiISGaYwBERERHJDBM4IiIiIplhAkdEREQkM0zgiIiIiGSGCRwRERGRzDCBIyIiIpIZJnBEREREMsMEjoiIiEhmmMARERERyQwTOCIiIiKZ+X9LMER4DP+pTAAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import timeit\n", "\n", "n = np.arange(17) # lengths = 2**n to evaluate\n", "reps = 100 # number of repetitions for timeit\n", "\n", "gain = np.zeros(len(n))\n", "for N in n:\n", " length = 2**N\n", " # setup environment for timeit\n", " tsetup = 'import numpy as np; from numpy.fft import rfft, irfft; \\\n", " x=np.random.randn(%d); h=np.random.randn(%d)' % (length, length)\n", " # direct convolution\n", " tc = timeit.timeit('np.convolve(x, x, \"full\")', setup=tsetup, number=reps)\n", " # fast convolution\n", " tf = timeit.timeit('irfft(rfft(x, %d) * rfft(h, %d))' % (2*length, 2*length), setup=tsetup, number=reps)\n", " # speedup by using the fast convolution\n", " gain[N] = tc/tf\n", "\n", "# show the results\n", "plt.barh(n, gain, log=True)\n", "plt.plot([1, 1], [-1, n[-1]+1], 'r-')\n", "plt.yticks(n, 2**n)\n", "plt.xlabel('Gain of fast convolution')\n", "plt.ylabel('Length of signals')\n", "plt.title('Comparison of execution times between direct and fast convolution')\n", "plt.grid()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Exercise**\n", "\n", "* For which lengths is the fast convolution faster than the linear convolution? \n", "* Why is it slower below a given signal length?\n", "* Is the trend of the gain as expected from above considerations?" ] }, { "cell_type": "markdown", "metadata": { "nbsphinx": "hidden" }, "source": [ "**Copyright**\n", "\n", "This notebook is provided as [Open Educational Resource](https://en.wikipedia.org/wiki/Open_educational_resources). Feel free to use the notebook for your own purposes. The text is licensed under [Creative Commons Attribution 4.0](https://creativecommons.org/licenses/by/4.0/), the code of the IPython examples under the [MIT license](https://opensource.org/licenses/MIT). Please attribute the work as follows: *Sascha Spors, Continuous- and Discrete-Time Signals and Systems - Theory and Computational Examples*." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.9.13" } }, "nbformat": 4, "nbformat_minor": 1 }