diff --git a/05_DFT/imgs/Faltung.png b/05_DFT/imgs/Faltung.png new file mode 100644 index 0000000000000000000000000000000000000000..a282515d264ac335928dafc0c92452faedd436ba Binary files /dev/null and b/05_DFT/imgs/Faltung.png differ diff --git a/05_DFT/imgs/Faltung2.gif b/05_DFT/imgs/Faltung2.gif new file mode 100644 index 0000000000000000000000000000000000000000..5c0a18eac0cb4c27c9486496ca8da55333ce2d65 Binary files /dev/null and b/05_DFT/imgs/Faltung2.gif differ diff --git a/05_DFT/imgs/complex1.png b/05_DFT/imgs/complex1.png new file mode 100644 index 0000000000000000000000000000000000000000..98bc27e9809ad513562bf5350cf91d1b813763f0 Binary files /dev/null and b/05_DFT/imgs/complex1.png differ diff --git a/05_DFT/imgs/complexabs.png b/05_DFT/imgs/complexabs.png new file mode 100644 index 0000000000000000000000000000000000000000..2056b4f7000c78125d5b08c1f50c4843cf245ff8 Binary files /dev/null and b/05_DFT/imgs/complexabs.png differ diff --git a/05_DFT/imgs/complexexp2.jpg b/05_DFT/imgs/complexexp2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..048b7a19b46d27d6b89b5ebf8dc0637cedaeb294 Binary files /dev/null and b/05_DFT/imgs/complexexp2.jpg differ diff --git a/05_DFT/imgs/complexkon.png b/05_DFT/imgs/complexkon.png new file mode 100644 index 0000000000000000000000000000000000000000..04822c8592e11b2e131d97a2202ec76bbd07043a Binary files /dev/null and b/05_DFT/imgs/complexkon.png differ diff --git a/05_DFT/imgs/complexphase2.jpg b/05_DFT/imgs/complexphase2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3b7f3c4dead7f41a2c04c450b4ff4b8c6a0dc2a1 Binary files /dev/null and b/05_DFT/imgs/complexphase2.jpg differ diff --git a/05_DFT/imgs/dft1.png b/05_DFT/imgs/dft1.png new file mode 100644 index 0000000000000000000000000000000000000000..8034c3046416995f1a8ed4faf7fa56ee4858489f Binary files /dev/null and b/05_DFT/imgs/dft1.png differ diff --git a/05_DFT/imgs/dip_lowpass.png b/05_DFT/imgs/dip_lowpass.png new file mode 100644 index 0000000000000000000000000000000000000000..ef0ab053ab970dd28ae80f163fa11dda58346419 Binary files /dev/null and b/05_DFT/imgs/dip_lowpass.png differ diff --git a/05_DFT/imgs/fft-combine.png b/05_DFT/imgs/fft-combine.png new file mode 100644 index 0000000000000000000000000000000000000000..508ee61360fef0d455a651dd727e061252d140ab Binary files /dev/null and b/05_DFT/imgs/fft-combine.png differ diff --git a/05_DFT/imgs/fft-reverse_bits.png b/05_DFT/imgs/fft-reverse_bits.png new file mode 100644 index 0000000000000000000000000000000000000000..a5b5e1f69d21071c585f9d99da6df3b6292bd4bd Binary files /dev/null and b/05_DFT/imgs/fft-reverse_bits.png differ diff --git a/05_DFT/imgs/fft-shuffle.png b/05_DFT/imgs/fft-shuffle.png new file mode 100644 index 0000000000000000000000000000000000000000..a454d2af265cd3e029bf8f68259f0632a7e336e4 Binary files /dev/null and b/05_DFT/imgs/fft-shuffle.png differ diff --git a/05_DFT/imgs/fouriertransform.gif b/05_DFT/imgs/fouriertransform.gif new file mode 100644 index 0000000000000000000000000000000000000000..8dec60f679416bce291cd85719cd007ab1828477 Binary files /dev/null and b/05_DFT/imgs/fouriertransform.gif differ diff --git a/05_DFT/tutorial_5_part1_fourier_motivation.ipynb b/05_DFT/tutorial_5_part1_fourier_motivation.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..36fe622f49f278b3b06305107614950ea138ad41 --- /dev/null +++ b/05_DFT/tutorial_5_part1_fourier_motivation.ipynb @@ -0,0 +1,192 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Motivation: Discrete Fouriertransform" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## DFT\n", + "Ortsraum $\\rightarrow$ Frequenzraum<br>\n", + "$\\mathcal{F}: f \\mapsto \\mathcal{F}[f]$\n", + "<img src=\"imgs/dft1.png\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "Eigenfaces\n", + "<ul>\n", + " <li>Basiswechsel in Eigenbasis aus den Daten</li>\n", + " <li>Entfernung unwichtiger Dimensionen</li>\n", + "</ul>\n", + "<br></br>\n", + "DFT<br>\n", + "<ul>\n", + " <li>Basiswechsel in Eigenbasis eines LTI Operators/Faltung </li>\n", + " <li>Entfernung unwichtiger Frequenzen</li>\n", + "</ul>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "Interpolation\n", + "<ul>\n", + " <li>Interpolation einer Datenverteilung </li>\n", + " <li>Basiswechsel: Datenwerte $\\rightarrow$ Polynome </li>\n", + "</ul>\n", + "<br></br>\n", + "DFT\n", + "<ul>\n", + " <li>Interpolation eines diskreten Signals </li>\n", + " <li>Basiswechsel: Sin/Cos Basisfunktionen aus unterschiedlichen Frequenzen </li>\n", + "</ul>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "<img src=\"imgs/fouriertransform.gif\" width=\"500\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Historischer Sidefact\n", + "<img src=\"imgs/gauss.jpg\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Anwendungen\n", + "<ul>\n", + " <li>Audio- (mp3), Bild- (jpeg) und Videokompression</li>\n", + " <li>Signalverarbeitung/Filterung, z.B. Autotune</li>\n", + " <li>Lösung von Differentialgleichungen</li>\n", + " <li>Faltung </li>\n", + "</ul>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "<img src=\"imgs/dip_lowpass.png\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Faltung (Convolution)\n", + "Die Faltung $f * g$ zweier Funtionen/Signale $f,g:\\mathbb{R}^{n}\\rightarrow\\mathbb{C}$ ist definiert durch<br>\n", + "$$ (f*g)(x) := \\int f(\\tau)g(x-\\tau)d\\tau$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "$$ (f*g)(x) := \\int f(\\tau)g(x-\\tau)d\\tau$$\n", + "<img src=\"imgs/Faltung.png\" width=\"600\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "<img src=\"imgs/Faltung2.gif\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Faltungstheorem\n", + "Faltung in Ortsraum = Multiplikation in Frequenzraum\n", + "$$ f * g = \\mathcal{F}[ f ] \\cdot \\mathcal{F} [ g] $$" + ] + } + ], + "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.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/05_DFT/tutorial_5_part2_komplexe_zahlen.ipynb b/05_DFT/tutorial_5_part2_komplexe_zahlen.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..12d2559a3c41f29f694b538519b6781e3c87509f --- /dev/null +++ b/05_DFT/tutorial_5_part2_komplexe_zahlen.ipynb @@ -0,0 +1,266 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Komplexe Zahlen" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Komplexe Zahlen $\\mathbb{C}: z = a + bi$<br>\n", + "<ul>\n", + " <li>$a\\in\\mathbb{R}$ Realteil </li>\n", + " <li>$b\\in\\mathbb{R}$ Imaginärteil</li>\n", + " <li>$i=\\sqrt{-1}$ imaginäre Einheit</li>\n", + "</ul>\n", + "<img src=\"imgs/complex1.png\" width=\"500\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Operationen" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "#### Komplex Konjugierte\n", + "$z = a + bi$ \n", + "<ul>\n", + " <li>$\\overline{z} = a - bi$ </li>\n", + " <li>Reflexion an der reelen Achse</li>\n", + "</ul>\n", + "<img src=\"imgs/complexkon.png\" width=\"300\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "#### Betrag\n", + "$z = a + bi$ \n", + "<ul>\n", + " <li>$|z| = \\sqrt{a^{2}+b^{2}} = \\sqrt{z\\cdot\\overline{z}} $ </li>\n", + "</ul>\n", + "<img src=\"imgs/complexabs.png\" width=\"300\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "#### Winkel\n", + "$z = a + bi$\n", + "<ul>\n", + " <li>$ tan(\\phi) =\\frac{b}{a}$</li>\n", + " <li>$\\phi = arctan(\\frac{b}{a})$</li>\n", + "</ul>\n", + "<img src=\"imgs/complexphase2.jpg\" width=\"400\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Polardarstellung" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "$z = a + bi$\n", + "<ul>\n", + " <li>$ a =|z|cos\\phi$</li>\n", + " <li>$ b =|z|sin\\phi$</li>\n", + " <li>$ z = |z|cos\\phi + i\\cdot |z|sin\\phi = |z| (cos\\phi + i\\cdot sin\\phi)$</li>\n", + "</ul>\n", + "<img src=\"imgs/complexphase2.jpg\" width=\"400\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Eulersche Formel: $ e^{ix} = cosx + i\\cdot sinx$\n", + "<ul>\n", + " <li>$ z = |z| (cos\\phi + i\\cdot sin\\phi) = |z|e^{i\\phi}$</li>\n", + "</ul>\n", + "<img src=\"imgs/complexexp2.jpg\" width=\"800\">" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Multiplikation komplexer Zahlen\n", + "$$ z_{1} \\cdot z_{2} = |z_{1}|e^{i\\phi_{1}} \\cdot |z_{2}|e^{i\\phi_{2}} $$<br>\n", + "$$ z_{1} \\cdot z_{2} = |z_{1}||z_{2}|e^{i(\\phi_{1}+\\phi_{2})} $$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Wurzel einer komplexen Zahl\n", + "Gegeben sind \n", + "<ul>\n", + " <li>$w \\in \\mathbb{C}$</li>\n", + " <li>$n \\in \\mathbb{Z}^{+}$</li>\n", + "</ul><br>\n", + "Gesucht ist alle möglichen Werte von z, sodass <br>\n", + "$$z^{n} = w$$\n", + "$$\\Leftrightarrow z_{k} = \\sqrt[n]{w} $$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Idee: \n", + "$$ z^{n} = w \\Leftrightarrow r^{n}e^{in\\phi} = se^{i\\psi} $$<br>\n", + "$$\\text{1) } r^{n} = s \\Leftrightarrow r = \\sqrt[n]{s}$$<br>\n", + "$$\\text{2) } in\\phi = i\\psi = i(\\psi + 2\\pi k) \\text{ , } k \\in \\mathbb{Z} $$<br>\n", + "$$\\Leftrightarrow n\\phi = \\psi + 2\\pi k\\text{ , } k \\in \\mathbb{Z} $$<br>\n", + "$$\\Leftrightarrow \\phi = \\frac{\\psi}{n} + \\frac{2\\pi k}{n} \\text{ , } k \\in \\mathbb{Z} $$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Wie viele solcher k gibt es?\n", + "$$ \\phi_{k} = \\frac{\\psi}{n} + \\frac{2\\pi k}{n} \\text{ , } k \\in \\mathbb{Z} $$<br>\n", + "$$ \\phi_{0} = \\frac{\\psi}{n} \\text{ , } \\phi_{1} = \\frac{\\psi}{n}+ \\frac{2\\pi}{n} \\text{ , ... , } \\phi_{n-1} = \\frac{\\psi}{n}+ \\frac{2\\pi(n-1)}{n}$$<br>\n", + "$$ \\phi_{n} = \\frac{\\psi}{n}+\\frac{2\\pi n}{n} = \\frac{\\psi}{n}+2\\pi = \\frac{\\psi}{n} = \\phi_{0} $$<br>\n", + "$$\\Rightarrow k = 0,...,n-1$$\n", + "$$\\Rightarrow z^{n} = w \\text{ hat n Lösungen}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "$ z^{n} = w \\Leftrightarrow r^{n}e^{in\\phi} = se^{i\\psi} $<br>\n", + "<ul>\n", + "<li>$\\text{1) } r = \\sqrt[n]{s}$<br>\n", + "<li>$\\text{2) } \\phi_{k} = \\frac{\\psi}{n} + \\frac{2\\pi k}{n} \\text{ , } k \\in \\{0,...,n-1\\} $\n", + "</ul>\n", + "$$\\Rightarrow z_{k}= \\sqrt[n]{s} \\cdot e^{i(\\frac{\\psi}{n} + \\frac{2\\pi k}{n})} $$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Einheitswurzeln\n", + "<ul>\n", + " <li>$z^{n} = 1$</li>\n", + " <li>$w = 1$</li>\n", + " <li>$\\psi = 0$</li>\n", + "</ul>\n", + "$$ w^{k}_{n} = e^{\\frac{2\\pi ik}{n}} \\text{ , } k=0,...,n-1$$<br>" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "Beispiel $z^{5} = 1$\n", + "<img src=\"imgs/rootsofun.png\" width=500>" + ] + } + ], + "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.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/05_DFT/tutorial_5_part3_diskrete_fourier_transf.ipynb b/05_DFT/tutorial_5_part3_diskrete_fourier_transf.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..a0c694c170eaa1dc2b099ffcfed04999b2d9ec83 --- /dev/null +++ b/05_DFT/tutorial_5_part3_diskrete_fourier_transf.ipynb @@ -0,0 +1,688 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Diskrete Fourier-Transformation" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "# Übersicht" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "* Diskrete Faltung\n", + "* Zirkuläre Matrizen\n", + "* Diskrete Fourier-Transformation über Eigenbasis von ZM\n", + "* Inverse diskrete Fouriertransformation\n", + "* Faltungstheorem und weitere Eigenschaften" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Diskrete Faltung" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "* Betrachte ein diskretisiertes Zeitsignal $\\vec{v} \\in \\mathbb{R}^n$ und einen Vektor $\\vec{a}\\in \\mathbb{R}^n$\n", + "$$\\vec{v}\\ast \\vec{a} = \\vec{v}'$$\n", + "* Lineare Operation $\\rightarrow$ ein Element des gefalteten Signals ergibt sich aus dem Skalarprodukt mit einem Vektor gleicher Länge\n", + "* Zeitunabhängige Operation $\\rightarrow$ es wird zu jedem Zeitpunkt der gleiche Filter (Vektor) angewandt\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "Die diskrete Faltung eines Signals $\\vec{v} \\in \\mathbb{R}^n$ mit einem Vektor $\\vec{a} \\in \\mathbb{R}^n$ ist dann: \n", + "\n", + "$$\\vec{v}\\ast \\vec{a} = \\vec{v}'$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "$$\\vec{v}'_0 = a_0 v_0 + a_1 v_1 + \\dots + a_{n-1} v_{n-1}$$\n", + "\n", + "$$\\vec{v}'_1 = a_0 v_1 + a_1 v_2 + \\dots + a_{n-1} v_0$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "$\\Rightarrow$ Diese lineare Abbildung kann als Matrix $A \\in \\mathbb{R}^{n \\times n}$ aufgefasst werden:\n", + "\n", + "\n", + "\\begin{equation}\n", + " \\vec{v}' = A\\vec{v} = \n", + " \\begin{pmatrix}\n", + " a_0 & a_{n-1} & a_{n-2} & \\dots & a_1\\\\ \n", + " a_1 & a_0 & a_{n-1} & \\dots & a_2\\\\ \n", + " a_2 & a_1 & a_0 & \\dots & a_3\\\\ \n", + " \\vdots & \\vdots & \\vdots & \\ddots & \\vdots\\\\\n", + " a_{n-1} & a_{n-2} & a_{n-3} & \\dots & a_0\n", + " \\end{pmatrix}\n", + " \\vec{v}\n", + "\\end{equation}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "\\begin{equation}\n", + " \\vec{v}' = A\\vec{v} = \n", + " \\begin{pmatrix}\n", + " a_0 & a_{n-1} & a_{n-2} & \\dots & a_1\\\\ \n", + " a_1 & a_0 & a_{n-1} & \\dots & a_2\\\\ \n", + " a_2 & a_1 & a_0 & \\dots & a_3\\\\ \n", + " \\vdots & \\vdots & \\vdots & \\ddots & \\vdots\\\\\n", + " a_{n-1} & a_{n-2} & a_{n-3} & \\dots & a_0\n", + " \\end{pmatrix}\n", + " \\vec{v}\n", + "\\end{equation}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "$A$ ist eine **zirkuläre Matrix** und hängt nur von den Einträgen von $\\vec{a}$ ab.\n", + "\n", + "$\\vec{a}$ nennt man auch **Kern** des Faltungsoperators ($A$)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Eigenwerte und Eigenvektoren von zirkulären Matrizen\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Eine Matrix mit solcher Struktur hat, unabhängig von den konkreten Einträgen von $\\vec{a}$ immer folgende Eigenwerte:\n", + "\n", + "$$\n", + "\\lambda_k=a_0 + a_{n-1} \\omega_n^k + a_{n-2} \\omega_n^{2k} + \\dots + a_1 \\omega_n^{(n-1)k},\\quad k = 0, \\dots, n-1\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "\n", + "\n", + "Mit den komplexen Einheitswurzeln\n", + "\n", + "$$\\omega_n^k = e^{\\frac{2\\pi i k}{n}},\\quad k = 0, \\dots, n-1$$\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Eigenwerte und Eigenvektoren von zirkulären Matrizen\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "Die entsprechenden normierten Eigenvektoren sind dann gegeben durch:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "source": [ + "$$\n", + "v_k = \\frac{1}{\\sqrt{n}} (1, \\omega_n^k, \\omega_n^{2k}, \\omega_n^{3k}, \\dots, \\omega_n^{(n-1)k})^T,\\quad k = 0, \\dots, n-1\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Beispiel Eigenvektoren in Numpy" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "scrolled": false, + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[ 0.57735027+0.j -0.28867513+0.5j -0.28867513-0.5j]\n", + " [ 0.57735027+0.j 0.57735027+0.j 0.57735027-0.j ]\n", + " [ 0.57735027+0.j -0.28867513-0.5j -0.28867513+0.5j]]\n", + "\n", + "\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from scipy.linalg import circulant\n", + "\n", + "a = np.array([10,25,5])\n", + "A = circulant(a)\n", + "\n", + "eigenvalues, eigenvectors = np.linalg.eig(A)\n", + "print(eigenvectors)\n", + "print('\\n')" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$\\Rightarrow$ Egal wie der Kern des Faltungsoperators konkret aussieht: die normierten Eigenvektoren identisch (bei gleicher Dimension)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# DFT-Matrix\n", + "Nun kann, wie in der Vorlesung gezeigt, mit dieser Menge an Vektoren $\n", + "v_k = \\frac{1}{\\sqrt{n}} (1, \\omega_n^k, \\omega_n^{2k}, \\omega_n^{3k}, \\dots, \\omega_n^{(n-1)k})^T$ die DFT-Matrix aufgestellt werden." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "\n", + "\\begin{equation}\n", + "\\Omega_n\n", + "= \\frac{1}{\\sqrt{n}}\n", + "\\begin{pmatrix}\n", + "1 & 1 & 1 & 1 & \\dots & 1\\\\\n", + "1 & \\omega_n & \\omega_n^2 & \\omega_n^3 & \\dots & \\omega_n^{n-1}\\\\\n", + "1 & \\omega_n^2 & \\omega_n^4 & \\omega_n^6 & \\dots & \\omega_n^{2(n-1)}\\\\\n", + "1 & \\omega_n^3 & \\omega_n^6 & \\omega_n^9 & \\dots & \\omega_n^{3(n-1)}\\\\\n", + "\\vdots & \\vdots & \\vdots & \\vdots & \\ddots & \\vdots\\\\\n", + "1 & \\omega_n^{n-1} & \\omega_n^{2(n-1)} & \\omega_n^{3(n-1)} & \\dots & \\omega_n^{(n-1)(n-1)}\n", + "\\end{pmatrix} \n", + "\\end{equation}\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "Es handelt sich hierbei um eine symmetrische und unitäre (komplex orthogonale) Matrix:\n", + "\n", + "$$\\Omega_n^{-1} = \\bar{\\Omega_n}^T$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Die Matrix $\\Omega_n$ transformiert ein Signal in die Eigenbasis der zirkulären Matrizen." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Das Produkt eines Vektors (Signals) $\\hat{v}$ mit der DFT-Matrix $\\Omega_n$ heißt diskrete Fouriertransformation:\n", + "\n", + "$$\\hat{v} = \\Omega_n \\vec{v}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Die DFT ist also $O(n^2)$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "# Beispiel Euler Formula für\n", + "\n", + "\\begin{equation}\n", + "\\Omega_n\n", + "= \\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 & 1 \\\\\n", + "1 & \\omega_n \n", + "\\end{pmatrix} \n", + "= \\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 & 1 \\\\\n", + "1 & -1\n", + "\\end{pmatrix} \n", + "\\end{equation}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "$z = a + bi = |z| e^{i\\phi} = |z| \\cos{\\phi} + |z| i \\sin{\\phi} \n", + "$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "\\begin{equation}\n", + "\\Omega_n\n", + "= \\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "e^0 & e^0 \\\\\n", + "e^0 & e^{i \\pi}\n", + "\\end{pmatrix}\n", + "= \\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "cos(0) & cos(0) \\\\\n", + "cos(0) & cos(\\pi)\n", + "\\end{pmatrix}\n", + "\\end{equation}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Inverse der DFT\n", + "Nun wollen wir die Rücktransformation oder Inverse der DFT finden.\n", + "Es gilt $$\\Omega_n^{-1} = \\bar{\\Omega_n}^T$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Also kann direkt die Inverse bestimmt werden!\n", + "Dadurch wird wieder vom Frequenzraum in den Zeit oder Ortsraum transponiert. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Inverse der DFT\n", + "$$\n", + "\\Omega_n^{-1} = \n", + "\\bar{\\Omega_n}^T = \n", + "\\frac{1}{\\sqrt{n}}\n", + "\\begin{pmatrix}\n", + " 1 & 1 & 1 & 1 & \\dots & 1\\\\\n", + " 1 & \\bar{\\omega}_n & \\bar{\\omega}_n^2 & \\bar{\\omega}_n^3 &\\dots & \\bar{\\omega}_n^{n-1}\\\\\n", + " 1 & \\bar{\\omega}_n^2 & \\bar{\\omega}_n^4 & \\bar{\\omega}_n^6 & \\dots & \\bar{\\omega}_n^{2(n-1)}\\\\\n", + " \\vdots & \\vdots & \\vdots & \\vdots & \\dots & \\vdots\\\\\n", + " 1 & \\bar{\\omega}_n^{n-1} & \\bar{\\omega}_n^{2(n-1)} & \\bar{\\omega}_n^{3(n-1)} &\\dots & \\bar{\\omega}_n^{(n-1)(n-1)}\n", + "\\end{pmatrix}$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Faltungsstheorem\n", + "* Besagt, dass $\\widehat{v\\ast a} = \\hat{v}\\cdot \\hat{a}$, also dass Faltung im Ortsraum der Produktbildung im Frequenzraum entspricht.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "* Analog entspricht Produktbildung im Ortsraum entspricht Faltung im Frequenzraum\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "scrolled": true, + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[5 8 2 9 4]\n", + " [4 5 8 2 9]\n", + " [9 4 5 8 2]\n", + " [2 9 4 5 8]\n", + " [8 2 9 4 5]]\n", + "True\n" + ] + } + ], + "source": [ + "from numpy import fft\n", + "\n", + "s = np.random.rand(5) # Signal\n", + "f = np.array([5, 4, 9, 2, 8 ]) # Filter/Kern der Faltung\n", + "F = circulant(f) # Zirkuläre Faltungsmatrix\n", + "\n", + "fs = F.dot(s) # Resultat der Faltung: O(n^2)\n", + "fs1 = fft.ifft(fft.fft(f) * fft.fft(s)) # Schnelle Faltung mittels FFT: O(nlog n)\n", + "print(F)\n", + "print(np.allclose(fs, fs1))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Fouriertransformation eines reellen Signals\n", + "Die DFT eines reellen Signals ist komplex und weist folgende Symmetrien auf:" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "Realer Anteil symmetrisch:\n", + "\n", + "$$\\text{Re}\\left\\{DFT(-f)\\right\\} = \\text{Re} \\left\\{DFT(f)\\right\\}$$\n", + "\n", + "Imaginärer Anteil antisymmetrisch:\n", + "\n", + " $$\\text{Im}\\left\\{DFT(-f)\\right\\} = -\\text{Im}\\left\\{DFT(f)\\right\\}$$\n", + " \n", + "Amplitude symmetrisch:\n", + "\n", + "$$\\vert DFT(-f)\\vert = \\vert DFT(f)\\vert$$\n", + "\n", + "Phase antisymmetrisch:\n", + "\n", + "$$ \\angle DFT(-f) = - \\angle DFT(f)$$" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "time = np.arange(100) \n", + "\n", + "s = np.sin(time) + np.random.normal(scale=0.1, size=len(time))# Signal\n", + "\n", + "s_hat = fft.fft(s) # Berechne FFT des Signals\n", + "freq = fft.fftfreq(s.size) # Berechne frequenzen\n", + "s_hat = fft.fftshift(s_hat) # FFT und freq zum plotten umsortieren\n", + "freq = fft.fftshift(freq)\n", + "\n", + "magnitude = np.abs(s_hat)\n", + "phase = np.angle(s_hat)\n", + "plt.plot(time, s)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [], + "source": [ + "def plot_symmetries(freq, s_hat, magnitude, phase):\n", + " import matplotlib.pyplot as plt\n", + " fig,(ax1, ax2) = plt.subplots(2,2)\n", + " ax1[0].plot(freq,s_hat.real)\n", + " ax1[0].set_xticks([])\n", + " ax1[0].set_title(\"Reeller Anteil\")\n", + " ax1[1].plot(freq,s_hat.imag)\n", + " ax1[1].set_title(\"Imaginäre Anteil\")\n", + " \n", + " ax2[0].plot(freq,magnitude)\n", + " ax1[1].set_xticks([])\n", + " ax2[0].set_title(\"Amplitude\")\n", + " ax2[1].plot(freq,phase)\n", + " ax2[1].set_title(\"Phase\")\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 4 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot_symmetries(freq, s_hat, magnitude, phase)" + ] + } + ], + "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.9.1" + }, + "rise": { + "enable_chalkboard": true + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/05_DFT/tutorial_5_part4_fft.ipynb b/05_DFT/tutorial_5_part4_fft.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..97eea9ee75ec8520ecf5b7577fb22912e4f1f82b --- /dev/null +++ b/05_DFT/tutorial_5_part4_fft.ipynb @@ -0,0 +1,531 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Fast Fourier Transformation (FFT)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "* **Grundidee:** Eine DFT der Länge $2n$ kann durch 2 kleinere DFTs der Länge $n$ berechnet werden " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "* \"**Divide and Conquer**\"-Prinzip: Reduktion der Komplexität $O(n^2) \\to O(n \\text{log}n)$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "* Hier: Algorithmus von Cooley und Tukey (1965), **nur** für Signale der Länge $2^n$ anwendbar" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Grundidee" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$\\Omega_{n=2}\n", + "= \\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "\\omega_2^0 & \\omega_2^0\\\\\n", + "\\omega_2^0 & \\omega_2^1\n", + "\\end{pmatrix} \n", + "= \\frac{1}{\\sqrt{2}}\n", + "\\begin{pmatrix}\n", + "1 & 1\\\\\n", + "1 & -1\n", + "\\end{pmatrix} \n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$\\Omega_{2n=4}\n", + "= \\frac{1}{\\sqrt{4}}\n", + "\\begin{pmatrix}\n", + "\\omega_4^0 & \\omega_4^0 & \\omega_4^0 & \\omega_4^0\\\\\n", + "\\omega_4^0 & \\omega_4^1 & \\omega_4^2 & \\omega_4^3\\\\\n", + "\\omega_4^0 & \\omega_4^2 & \\omega_4^4 & \\omega_4^6\\\\\n", + "\\omega_4^0 & \\omega_4^3 & \\omega_4^6 & \\omega_4^9\n", + "\\end{pmatrix} \n", + "= \\frac{1}{\\sqrt{4}}\n", + "\\begin{pmatrix}\n", + "1 & 1 & 1 & 1\\\\\n", + "1 & i & -1 & -i\\\\\n", + "1 & -1 & 1 & -1\\\\\n", + "1 & -i & -1 & i\\\\\n", + "\\end{pmatrix} \n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$\\Omega_{2n=4} \\textbf{P}^\\top\n", + "= \\frac{1}{\\sqrt{4}}\n", + "\\begin{pmatrix}\n", + "1 & 1 & 1 & 1\\\\\n", + "1 & -1 & i & -i\\\\\n", + "1 & 1 & -1 & -1\\\\\n", + "1 & -1 & -i & i\\\\\n", + "\\end{pmatrix} \n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$\\textbf{F} = \\text{diag}(\\omega_{2n}^0,\\omega_{2n}, \\omega_{2n}^2, ..., \\omega_{2n}^{n-1})\n", + "\\stackrel{n=2}{=}\\begin{pmatrix}\n", + "1 & 0 \\\\\n", + "0 & i \\\\\n", + "\\end{pmatrix}\n", + "$$\n", + "<br>\n", + "$$ \\textbf{F} \\Omega'_2 =\n", + "\\begin{pmatrix}\n", + "1 & 0 \\\\\n", + "0 & i \\\\\n", + "\\end{pmatrix}\n", + "\\begin{pmatrix}\n", + "1 & 1\\\\\n", + "1 & -1\\\\\n", + "\\end{pmatrix}\n", + "=\n", + "\\begin{pmatrix}\n", + "1 & 1\\\\\n", + "i & -i\\\\\n", + "\\end{pmatrix}\n", + "$$ " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$ \\Omega_{4} \\textbf{P}^\\top\n", + "= \\frac{1}{\\sqrt{4}}\n", + "\\begin{pmatrix}\n", + "\\Omega'_2 & \\textbf{F} \\Omega'_2\\\\\n", + "\\Omega'_2 & -\\textbf{F} \\Omega'_2\n", + "\\end{pmatrix} \n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Rekursive FFT" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 1.14423775e-17+0.00000000e+00j -2.22044605e-16-4.00000000e+00j\n", + " 1.22464680e-16-1.11022302e-16j 5.32226757e-16+0.00000000e+00j\n", + " 2.33486982e-16+0.00000000e+00j 2.22044605e-16+0.00000000e+00j\n", + " 1.22464680e-16+1.11022302e-16j -1.02208548e-15+4.00000000e+00j]\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "\n", + "def dft_recursive(c):\n", + " n = len(c)\n", + " if n == 1:\n", + " return c\n", + " else:\n", + " m = n // 2\n", + " z1 = dft_recursive(c[0::2])\n", + " z2 = dft_recursive(c[1::2])\n", + " omega = np.exp(-2j * np.pi / n)\n", + " z = np.empty((n,), dtype=np.complex)\n", + " for i in range(m):\n", + " z[i] = z1[i] + (omega ** i) * z2[i]\n", + " z[i+m] = z1[i] - (omega ** i) * z2[i]\n", + " return z\n", + "\n", + "def idft_recursive(c):\n", + " n = len(c)\n", + " return 1.0/n * np.conjugate(dft_recursive(np.conjugate(c)))\n", + " \n", + " \n", + "\n", + "t = np.linspace(0,2*np.pi,9)\n", + "t = t[0:8]\n", + "c = np.sin(t)\n", + "\n", + "print(dft_recursive(c))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ True True True True True True True True]\n", + "[ True True True True True True True True]\n" + ] + } + ], + "source": [ + "c_new = idft_recursive(dft_recursive(c))\n", + "\n", + "print(np.isclose(c, c_new,rtol=1e-15))\n", + "print(np.isclose(dft_recursive(c), np.fft.fft(c),rtol=1e-15))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "### Iterative FFT" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "### Beispiel" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$c= \\begin{pmatrix} 4 \\\\ 2 \\\\ 3 \\\\ 1 \\end{pmatrix}$$ " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "$$c= \\begin{pmatrix} 4 \\\\ 2 \\\\ 3 \\\\ 1 \\end{pmatrix}\n", + "\\quad \\stackrel{Umordnung}{\\to} \\quad\n", + "\\begin{pmatrix} 4 \\\\ 3 \\\\ 2 \\\\ 1 \\end{pmatrix}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "$$\\omega_2^0 = (-1)^0 = 1$$ \n", + "<br>\n", + "<br>\n", + "$$\n", + "\\begin{pmatrix} 4 \\\\ 3 \\\\ 2 \\\\ 1 \\end{pmatrix}\n", + "\\quad \\stackrel{l=0}{\\to} \\quad\n", + "\\begin{pmatrix} 4+ 1\\cdot3 \\\\ 4- 1\\cdot3 \\\\ 2+ 1\\cdot1 \\\\ 2- 1\\cdot1 \\end{pmatrix}\n", + "=\n", + "\\begin{pmatrix} 7 \\\\ 1 \\\\ 3 \\\\ 1 \\end{pmatrix}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$\\omega_4 = i$$ \n", + "<br>\n", + "<br>\n", + "$$\\begin{pmatrix} 7 \\\\ 1 \\\\ 3 \\\\ 1 \\end{pmatrix}\n", + "\\quad \\stackrel{l=1}{\\to} \\quad\n", + "\\begin{pmatrix} 7+ 1\\cdot3 \\\\ 1 +i\\cdot1 \\\\ 7- 1\\cdot3 \\\\ 1 -i\\cdot1 \\end{pmatrix}\n", + "=\n", + "\\begin{pmatrix} 10 \\\\ 1+ i \\\\ 4\\\\ 1-i \\end{pmatrix}\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(0.25+2.4492935982947064e-16j)\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "m = 1 \n", + "n = 1\n", + "k = 3\n", + "N = 4\n", + "v = np.exp(-2*np.pi*1j*m*(n+k))/N\n", + "print(v)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 432x288 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "num = 200\n", + "f = 5\n", + "x = np.linspace(0.0, 2.0 * np.pi, num)\n", + "y = np.sin(f * x) + 0.1\n", + "fy = np.fft.fft(y)\n", + "ify = np.fft.ifft(fy)\n", + "#print(fy[190:210])\n", + "#print(ify)\n", + "plt.plot(y,\"r\", fy.imag, \"g\", ify.imag, \"b\")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "$$\n", + "\\begin{pmatrix}\n", + "\\begin{array}{c|c}\n", + " 1 & 2 \\\\ \n", + " \\hline\n", + " 3 & 4\n", + " \\end{array}\n", + " \\end{pmatrix}\n", + "$$\n", + "$$\n", + "\\begin{pmatrix}\n", + " 1 & 2 \\\\ \n", + " \\hline\n", + " 3 & 4\n", + " \\end{pmatrix}\n", + "$$\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "* Umsortieren der Spalten: \"Spalten mit geradem Spaltenindex nach vorne, die anderen nach hinten\" <br>\n", + " Ebenso: Zeilen des Signalvektors $\\textbf{s}$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "* Im Skript (S. 87f) Multiplikation mit Permutationsmatrix $\\textbf{P}$ " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "$ \\quad \\Omega_4 \\textbf{P} \\quad$ mit $\\textbf{P} = \n", + "\\begin{pmatrix} \n", + "1 & 0 & 0 & 0 \\\\\n", + "0 & 0 & 1 & 0 \\\\\n", + "0 & 1 & 0 & 0 \\\\\n", + "0 & 0 & 0 & 1 \\\\\n", + "\\end{pmatrix}$" + ] + } + ], + "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.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/05_DFT/tutorial_5_part5_fft_herleitung.ipynb b/05_DFT/tutorial_5_part5_fft_herleitung.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..deeb6d3e51431bde7389699c98c38557d2dd3a88 --- /dev/null +++ b/05_DFT/tutorial_5_part5_fft_herleitung.ipynb @@ -0,0 +1,269 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "## Fast Fourier Transformation (FFT) - Zusatz\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$ \\Omega_{4} \\textbf{P}^\\top\n", + "= \\frac{1}{\\sqrt{4}}\n", + "\\begin{pmatrix}\n", + "\\Omega'_2 & \\textbf{F} \\Omega'_2\\\\\n", + "\\Omega'_2 & -\\textbf{F} \\Omega'_2\n", + "\\end{pmatrix} \n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "* Signalvektor $ \\textbf{c} $:\n", + "$$ \\Omega_{4} \\textbf{P}^\\top \\textbf{P} \\textbf{c}\n", + "= \\frac{1}{\\sqrt{4}}\n", + "\\begin{pmatrix}\n", + "\\begin{array}{c:c}\n", + "\\Omega'_2 & \\textbf{F} \\Omega'_2\\\\\n", + "\\hdashline\n", + "\\Omega'_2 & -\\textbf{F} \\Omega'_2\n", + "\\end{array}\n", + "\\end{pmatrix} \n", + "\\begin{pmatrix}\n", + "c_0 \\\\\n", + "c_2 \\\\\n", + "\\hdashline\n", + "c_1 \\\\\n", + "c_3 \\\\ \n", + "\\end{pmatrix}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$ \\Omega'_{2} = \\Omega'_{2} \\textbf{P}^\\top = \n", + "\\begin{pmatrix}\n", + "\\Omega'_1 & \\text{F} \\Omega'_1\\\\\n", + "\\Omega'_1 & -\\text{F} \\Omega'_1\n", + "\\end{pmatrix} \n", + "= \n", + "\\begin{pmatrix}\n", + "1 & \\omega_2^0 \\cdot 1\\\\\n", + "1 &-\\omega_2^0 \\cdot 1\n", + "\\end{pmatrix}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$ \\Omega'_{2} \\begin{pmatrix} c_0 \\\\ c_2 \\\\ \\end{pmatrix}\n", + "= \\begin{pmatrix}\n", + "1 & \\omega_2^0\\\\\n", + "1 & -\\omega_2^0\n", + "\\end{pmatrix} \n", + "\\begin{pmatrix} c_0 \\\\ c_2 \\\\ \\end{pmatrix}\n", + "= \\begin{pmatrix}\n", + "c_0 + \\omega_2^0 c_2 \\\\\n", + "c_0 - \\omega_2^0 c_2 \n", + "\\end{pmatrix}\n", + "=: \n", + "\\begin{pmatrix}\n", + "z_1\\left[ 0\\right] \\\\\n", + "z_1\\left[ 1\\right]\n", + "\\end{pmatrix}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$ \\Omega'_{2} \\begin{pmatrix} c_1 \\\\ c_3 \\\\ \\end{pmatrix}\n", + "=: \n", + "\\begin{pmatrix}\n", + "z_2\\left[ 0\\right] \\\\\n", + "z_2\\left[ 1\\right]\n", + "\\end{pmatrix}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "$$\n", + "\\begin{pmatrix}\n", + "\\begin{array}{c:c}\n", + "\\Omega'_2 & \\textbf{F} \\Omega'_2\\\\\n", + "\\hdashline\n", + "\\Omega'_2 & -\\textbf{F} \\Omega'_2\n", + "\\end{array}\n", + "\\end{pmatrix} \n", + "\\begin{pmatrix}\n", + "c_0 \\\\\n", + "c_2 \\\\\n", + "\\hdashline\n", + "c_1 \\\\\n", + "c_3 \\\\ \n", + "\\end{pmatrix}\n", + "= \n", + "\\begin{pmatrix}\n", + "\\begin{pmatrix}\n", + "z_1\\left[ 0\\right] \\\\\n", + "z_1\\left[ 1\\right]\n", + "\\end{pmatrix}\n", + "+ \\textbf{F}\n", + "\\begin{pmatrix}\n", + "z_2\\left[ 0\\right] \\\\\n", + "z_2\\left[ 1\\right]\n", + "\\end{pmatrix}\\\\\n", + "\\hdashline\n", + "\\begin{pmatrix}\n", + "z_1\\left[ 0\\right] \\\\\n", + "z_1\\left[ 1\\right]\n", + "\\end{pmatrix}\n", + "- \\textbf{F}\n", + "\\begin{pmatrix}\n", + "z_2\\left[ 0\\right] \\\\\n", + "z_2\\left[ 1\\right]\n", + "\\end{pmatrix}\\\\\n", + "\\end{pmatrix}\n", + "$$\n", + "<br>\n", + "<br>\n", + "$$\n", + "\\textbf{F} \n", + "\\begin{pmatrix}\n", + "z_2\\left[ 0\\right] \\\\\n", + "z_2\\left[ 1\\right]\n", + "\\end{pmatrix}\n", + "= \\begin{pmatrix}\n", + "\\omega_{4}^0 & 0 \\\\\n", + "0 & \\omega_{4}^1 \\\\\n", + "\\end{pmatrix}\n", + "\\begin{pmatrix}\n", + "z_2\\left[ 0\\right] \\\\\n", + "z_2\\left[ 1\\right]\n", + "\\end{pmatrix}\n", + "=\n", + "\\begin{pmatrix}\n", + "\\omega_{4}^0 z_2\\left[ 0\\right] \\\\\n", + "\\omega_{4}^1 z_2\\left[ 1\\right]\n", + "\\end{pmatrix}\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "source": [ + "$$=\n", + "\\begin{pmatrix}\n", + "z_1\\left[ 0\\right] + \\omega_{4}^0 z_2\\left[ 0\\right] \\\\\n", + "z_1\\left[ 1\\right] + \\omega_{4}^1 z_2\\left[ 1\\right] \\\\\n", + "\\hdashline\n", + "z_1\\left[ 0\\right] - \\omega_{4}^0 z_2\\left[ 0\\right] \\\\\n", + "z_1\\left[ 1\\right] - \\omega_{4}^1 z_2\\left[ 1\\right] \n", + "\\end{pmatrix}\n", + "$$\n", + "Vgl. Ergbenis für $n=2$: \n", + "$$ \\Omega'_{2} \\begin{pmatrix} c_0 \\\\ c_2 \\\\ \\end{pmatrix}\n", + "= \\begin{pmatrix}\n", + "c_0 + \\omega_2^0 c_2 \\\\\n", + "c_0 - \\omega_2^0 c_2 \n", + "\\end{pmatrix}\n", + "$$" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "def dft_recursive(c):\n", + " n = len(c)\n", + " if n == 1:\n", + " return c\n", + " else:\n", + " m = n // 2\n", + " z1 = dft_recursive(c[0::2])\n", + " z2 = dft_recursive(c[1::2])\n", + " omega = np.exp(-2j * np.pi / n)\n", + " z = np.empty((n,), dtype=np.complex)\n", + " for i in range(m):\n", + " z[i] = z1[i] + (omega ** i) * z2[i]\n", + " z[i+m] = z1[i] - (omega ** i) * z2[i]\n", + " return z" + ] + } + ], + "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.9.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}