GDET3 Fourier-Transformation.ipynb 7.96 KB
Newer Older
Christian Rohlfing's avatar
Christian Rohlfing committed
1
2
3
4
5
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
6
7
8
9
10
   "metadata": {
    "jupyter": {
     "source_hidden": true
    }
   },
Christian Rohlfing's avatar
Christian Rohlfing committed
11
12
   "outputs": [],
   "source": [
13
    "# Copyright 2020 Institut für Nachrichtentechnik, RWTH Aachen University\n",
14
    "%matplotlib widget\n",
Christian Rohlfing's avatar
Christian Rohlfing committed
15
16
    "\n",
    "import ipywidgets as widgets\n",
17
18
    "from ipywidgets import interact, interactive, fixed, Layout\n",
    "from IPython.display import clear_output, display, HTML\n",
Christian Rohlfing's avatar
Christian Rohlfing committed
19
    "\n",
20
    "from scipy import signal # convolution\n",
Christian Rohlfing's avatar
Christian Rohlfing committed
21
22
    "\n",
    "from ient_nb.ient_plots import *\n",
23
24
    "from ient_nb.ient_signals import *\n",
    "from ient_nb.ient_transforms import *\n",
Christian Rohlfing's avatar
Christian Rohlfing committed
25
    "\n",
26
    "eps = np.finfo(float).eps"
Christian Rohlfing's avatar
Christian Rohlfing committed
27
28
   ]
  },
29
30
31
32
33
34
35
36
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div>\n",
    "    <img src=\"ient_nb/figures/rwth_ient_logo@2x.png\" style=\"float: right;height: 5em;\">\n",
    "</div>\n",
    "\n",
37
    "# Demonstrator Fourier-Transformation\n",
Christian Rohlfing's avatar
Christian Rohlfing committed
38
39
    "\n",
    "\n",
40
41
42
43
44
45
46
47
48
    "Zum Starten: Im Menü: Run <span class=\"fa-chevron-right fa\"></span> Run All Cells auswählen.\n",
    " \n",
    "Die Fouriertransformierte eines Signals $s(t)$ ist definiert als \n",
    "$$\n",
    "\\displaystyle S(f)=\\int\\limits_{-\\infty}^{\\infty}s(t)\\mathrm{e}^{-j2\\pi ft}\\mathrm{d}t\n",
    "$$\n",
    "Im Allgemeinen kann angenommen werden, dass $S(f)$ komplexwertig ist. Es lässt sich somit in den Betrag der Übertragungsfunktion $|S(f)|$ und die Phase $\\varphi(f)$ zerlegen.\n",
    "Dieser Demonstrator veranschaulicht, wie sich die Fouriertransformierte eines Signals $s(t)$ in Betrag und Phase verhält.\n",
    "\n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
49
    "Im Drop-Down Menü für $s(t)$ kann zwischen fünf verschiedenen Funktionen ausgewählt werden. Die zur Verfügung stehenden Funktionen sind\n",
50
51
52
53
54
55
56
    "* Rechteck\n",
    "* Dreieck\n",
    "* Dirac\n",
    "* si-Funktion\n",
    "* Gauß-Signal\n",
    "\n",
    "Über den Slider für die Dehnung $T_0$ des Signals kann die Breite des Signals angepasst werden, über die Verschiebung $t_0$ kann die Position des Signals geändert werden. \n"
Christian Rohlfing's avatar
Christian Rohlfing committed
57
58
59
60
61
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
62
63
64
65
66
   "metadata": {
    "jupyter": {
     "source_hidden": true
    }
   },
Christian Rohlfing's avatar
Christian Rohlfing committed
67
68
   "outputs": [],
   "source": [
69
70
    "(t,deltat) = np.linspace(-20, 20, 50001, retstep=True) # t Achse\n",
    "f = t; deltaf=deltat;\n",
Christian Rohlfing's avatar
Christian Rohlfing committed
71
    "\n",
72
73
    "signal_types_t = {'Rechteck'           : rect,  \n",
    "                  'Dreieck'            : tri, \n",
74
    "                  'Dirac'              : lambda t: [1],\n",
75
76
    "                  'si-Funktion'        : lambda t: si(2*np.pi*t),\n",
    "                  'Gauß-Signal'        : gauss}\n",
Christian Rohlfing's avatar
Christian Rohlfing committed
77
    "\n",
78
79
    "signal_types_f = {'Rechteck'           : lambda f,T: np.abs(T)*si(np.pi*T*f),\n",
    "                  'Dreieck'            : lambda f,T: np.abs(T)*si(np.pi*T*f)**2, \n",
80
    "                  'Dirac'              : lambda f,T: np.abs(T),\n",
81
82
    "                  'si-Funktion'        : lambda f,T: np.abs(T)/2*rect(f*T/2),\n",
    "                  'Gauß-Signal'        : lambda f,T: np.abs(T)*gauss(f*T)}\n",
83
    "\n",
84
    "# Plot\n",
85
    "plt.close(); fig, axs = plt.subplots(3, 1); plt.tight_layout();\n",
86
87
88
89
90
91
92
93
94
95
96
97
    "@widgets.interact(s_type=widgets.Dropdown(options=list(signal_types_t.keys()), description=r'Wähle $s(t)$:'),\n",
    "                  T=widgets.FloatSlider(min=0.5, max=4, value=1, step=.1, description=r'Dehnung T', style=ient_wdgtl_style), \n",
    "                  t0=widgets.FloatSlider(min=-2, max=2, value=0, step=.1, description=r'Verschiebung $t_0$', style=ient_wdgtl_style))\n",
    "def update_signals(s_type, T, t0):\n",
    "    s = lambda t: signal_types_t[s_type]((t-t0)/T);\n",
    "    S = lambda f: signal_types_f[s_type](f, T)*np.exp(-2j*np.pi*f*t0)\n",
    "\n",
    "    Sabs = np.abs(S(f));\n",
    "    Sangle = np.angle(S(f)); Sangle[Sabs < eps] = 0;\n",
    "    \n",
    "    if not axs[0].lines: # plot s(t)\n",
    "        ax = axs[0]; ax.plot(t, s(t), 'rwth');\n",
98
99
    "        ient_plot_dirac(axs[0], [], [])\n",
    "        ient_dirac_weights(axs[0],0,1,2);axs[0].texts[0].set_text('');\n",
100
101
102
103
104
105
106
107
108
109
110
    "        ax.set_xlabel(r'$\\rightarrow t$'); ax.set_ylabel(r'$\\uparrow s(t)$')\n",
    "        ax.set_xlim([-2.9, 2.9]); ax.set_ylim([-1.19, 1.19]);  ient_axis(ax); ient_grid(ax);\n",
    "        \n",
    "        ax = axs[1]; ax.plot(f, Sabs, 'rwth');\n",
    "        ax.set_xlabel(r'$\\rightarrow f$'); ax.set_ylabel(r'$\\uparrow |S(f)|$')\n",
    "        ax.set_xlim([-20,20]); ient_axis(ax); ient_grid(ax);\n",
    "        \n",
    "        ax = axs[2]; ax.plot(f, Sangle, 'rwth');\n",
    "        ax.set_xlabel(r'$\\rightarrow f$'); ax.set_ylabel(r'$\\uparrow \\angle S(f)$')\n",
    "        ax.set_xlim([-20,20]); ax.set_ylim([-4, 4]); ient_axis(ax); ient_grid(ax); ax.set_yticks([-np.pi, np.pi]); ax.yaxis.set_ticklabels([r'$-\\pi$', r'$\\pi$'])\n",
    "    else: # update lines\n",
111
112
113
114
115
116
117
118
119
120
121
122
123
    "        if s_type == 'Dirac':\n",
    "            axs[0].lines[0].set_ydata(0)\n",
    "            ient_dirac_set_data(axs[0].containers, [t0], [np.abs(T)])\n",
    "            axs[1].lines[0].set_ydata(Sabs)\n",
    "            axs[0].set_ylim(0, np.abs(T)*1.5); axs[1].set_ylim(0, np.abs(T)*1.5)\n",
    "            axs[0].texts[0].set_text('({})'.format(np.abs(T))); axs[0].texts[0].set_x(t0); axs[0].texts[0].set_y(np.abs(T))\n",
    "        else:\n",
    "            ient_dirac_set_data(axs[0].containers, [], [])\n",
    "            axs[0].lines[0].set_ydata(s(t)); \n",
    "            axs[1].lines[0].set_ydata(Sabs)\n",
    "            ient_update_ylim(axs[0], s(t), 0.19, np.max(s(t)));  ient_update_ylim(axs[1], Sabs, 0.19, np.max(Sabs));\n",
    "            axs[0].texts[0].set_text('')\n",
    "        axs[2].lines[0].set_ydata(Sangle)"
124
125
   ]
  },
126
  {
127
   "cell_type": "markdown",
128
129
130
   "metadata": {},
   "source": [
    "## Aufgaben\n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
131
132
133
134
    "Wähle für $s(t)$ ein Rechteck aus. \n",
    "* Variiere die Breite $T$, während die Verschiebung konstant gehalten wird. Was passiert mit Betrag und Phase des Spektrums? Wo sind die Sprünge in der Phase zu finden?\n",
    "* Betrachte ein Rechteck der Breite $T=1$. Variiere die Verschiebung $t_0$ und beobachte, was sich ändert. Wieso passiert das?\n",
    "* Betrachte die Phase für $t_0=0.5$ und $t_0=-0.5$. Was macht die Phase?\n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
135
    "\n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
136
137
138
    "Wähle nun ein Dreieck für $s(t)$.\n",
    "* Wie sieht der Betrag der Phase nun aus im Vergleich? Warum?\n",
    "* Wie ändert sich die Phase, wenn das Dreieck verschoben wird?\n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
139
    "\n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
140
141
142
    "Wähle nun einen Dirac als Funktion aus. \n",
    "* Ändere die Verschiebung $t_0$. Was passiert mit Betrag und Phase des Spektrums?\n",
    "* Ändere die Dehnung $T$. Was passiert nun? \n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
143
    "\n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
144
145
146
    "Wähle nun die si-Funktion aus. \n",
    "* Vergleiche mit dem Ergebnis für das Rechteck. Wieso ist das so? \n",
    "* Ändere $T$. Was passiert mit der Phase?\n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
147
    "\n",
Iris Heisterklaus's avatar
Iris Heisterklaus committed
148
149
    "Wähle nun ein Gauß-Signal. \n",
    "* Was passiert hier mit der Phase, wenn $T$ und $t_0$ geändert werden?"
150
151
152
153
   ]
  },
  {
   "cell_type": "markdown",
154
155
   "metadata": {},
   "source": [
156
    "___\n",
157
158
159
    "This notebook is provided as [Open Educational Resource](https://en.wikipedia.org/wiki/Open_educational_resources) (OER). Feel free to use the notebook for your own purposes. The code is licensed under the [MIT license](https://opensource.org/licenses/MIT). \n",
    "\n",
    "Please attribute the work as follows: \n",
160
    "*Christian Rohlfing, Übungsbeispiele zur Vorlesung \"Grundgebiete der Elektrotechnik 3 - Signale und Systeme\"*, gehalten von Jens-Rainer Ohm, 2020, Institut für Nachrichtentechnik, RWTH Aachen University."
Christian Rohlfing's avatar
Christian Rohlfing committed
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
   ]
  }
 ],
 "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",
180
   "version": "3.8.1"
Christian Rohlfing's avatar
Christian Rohlfing committed
181
182
183
  }
 },
 "nbformat": 4,
184
 "nbformat_minor": 4
Christian Rohlfing's avatar
Christian Rohlfing committed
185
}