Commit 6acd1dba authored by Hafiz Emin Kosar's avatar Hafiz Emin Kosar
Browse files

- added custom signal to Diskrete Faltung

parent 85246835
......@@ -56,7 +56,18 @@
"* Exponentialimpuls $\\epsilon(n)\\cdot\\mathrm{b}^{n}$\n",
"* Rechteckfunktion $rect(n) = \\epsilon(n+M)-\\epsilon(n-M-1)$\n",
"\n",
"Unter der folgenden Abbildungen können diese Funktionen ausgewählt werden und, falls gewünscht, eine Verschiebung um $n_0$ eingestellt werden. Für den Exponentialimpuls ist ebenfalls der Faktor $b$ variierbar, für die Rechteckfunktion ist die Breite $M$ wählbar. In der Abbildung können dann die gewählten Funktionen mit ihren Parametern betrachtet werden."
"Unter der folgenden Abbildungen können diese Funktionen ausgewählt werden und, falls gewünscht, eine Verschiebung um $n_0$ eingestellt werden. Für den Exponentialimpuls ist ebenfalls der Faktor $b$ variierbar, für die Rechteckfunktion ist die Breite $M$ wählbar. In der Abbildung können dann die gewählten Funktionen mit ihren Parametern betrachtet werden.\n",
"\n",
"Zusätzlich zu Elementarsignalen kann auch eine frei definierbare Funktion $s_0(t)$ zur Faltung verwendet werden."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"s_0 = lambda n: 0.5 * (unitstep(n-2) + unitstep(-(n+2)))"
]
},
{
......@@ -82,7 +93,8 @@
"signal_types = {'Dirac-Impuls' : lambda n, b, M: np.where(n==0, 1, 0),\n",
" 'Sprungfunktion' : lambda n, b, M: np.where(n>=0, 1, 0),\n",
" 'Exponentialimpuls' : lambda n, b, M: unitstep(n)*b**n,\n",
" 'Rechteck' : lambda n, b, M: unitstep(n+M) - unitstep(n-M-1)\n",
" 'Rechteck' : lambda n, b, M: unitstep(n+M) - unitstep(n-M-1),\n",
" 'Eigene Kreation s0(n)' : lambda n, b, M: s_0(n)\n",
" }\n",
"\n",
"fig0, axs0 = plt.subplots(1, 2, figsize=(ient_fig_width, ient_fig_width/4));\n",
......
%% Cell type:code id: tags:
``` python
# Copyright 2019 Institut für Nachrichtentechnik, RWTH Aachen University
%matplotlib widget
import ipywidgets as widgets
from ipywidgets import interact, interactive, fixed, Layout, HBox, VBox
from IPython.display import clear_output, display, HTML
from scipy import signal # convolution
from ient_nb.ient_plots import *
from ient_nb.ient_signals import *
```
%% Cell type:markdown id: tags:
<div>
<img src="ient_nb/figures/rwth_ient_logo@2x.png" style="float: right;height: 5em;">
</div>
# Demonstrator Diskrete Faltung
Zum Starten: Im Menü: Run <span class="fa-chevron-right fa"></span> Run All Cells auswählen.
%% Cell type:markdown id: tags:
## Einleitung
Ein diskretes Signal ist ein Signal, welches nur für ganzzahlige Werte $n$ einen Wert annimmt und sonst Null ist. Auch für die Elementarsignale existieren jeweils zeitdiskrete Versionen. Diese Demonstration nutzt einige davon.
Diskrete Signale können genau wie kontinuierliche Signale gefaltet werden.
Im Folgenden wird die diskrete Faltung
$$g(n)=s(n)\ast h(n)=\sum_{m=-\infty}^{\infty}s(m)h(n-m)$$
betrachtet und veranschaulicht.
## Demo
In der Demonstration stehen verschiedene Signale für $s(n)$ und $h(n)$ zur Verfügung.
$s(n)$ und $h(n)$ können gewählt werden als zeitdiskrete Varianten von:
* Dirac-Impuls $\delta(n)$
* Sprungfunktion $\epsilon(n)$
* Exponentialimpuls $\epsilon(n)\cdot\mathrm{b}^{n}$
* Rechteckfunktion $rect(n) = \epsilon(n+M)-\epsilon(n-M-1)$
Unter der folgenden Abbildungen können diese Funktionen ausgewählt werden und, falls gewünscht, eine Verschiebung um $n_0$ eingestellt werden. Für den Exponentialimpuls ist ebenfalls der Faktor $b$ variierbar, für die Rechteckfunktion ist die Breite $M$ wählbar. In der Abbildung können dann die gewählten Funktionen mit ihren Parametern betrachtet werden.
Zusätzlich zu Elementarsignalen kann auch eine frei definierbare Funktion $s_0(t)$ zur Faltung verwendet werden.
%% Cell type:code id: tags:
``` python
s_0 = lambda n: 0.5 * (unitstep(n-2) + unitstep(-(n+2)))
```
%% Cell type:code id: tags:
``` python
n = np.linspace(-10, 10, 21)
m = np.linspace(-40, 40, 81) # m Achse
n0 = -2
container_s = container_h = None
def convolution(s, h):
# Convolve s and h numerically
return signal.convolve(s(m), h(m), mode='same')
signal_types = {'Dirac-Impuls' : lambda n, b, M: np.where(n==0, 1, 0),
'Sprungfunktion' : lambda n, b, M: np.where(n>=0, 1, 0),
'Exponentialimpuls' : lambda n, b, M: unitstep(n)*b**n,
'Rechteck' : lambda n, b, M: unitstep(n+M) - unitstep(n-M-1)
'Rechteck' : lambda n, b, M: unitstep(n+M) - unitstep(n-M-1),
'Eigene Kreation s0(n)' : lambda n, b, M: s_0(n)
}
fig0, axs0 = plt.subplots(1, 2, figsize=(ient_fig_width, ient_fig_width/4));
def update_signals(s_type, s_n0, h_type, h_n0, b_s, b_h, M_s, M_h):
# show widgets according to chosen s and h
w_b_s.layout.visibility = 'visible' if s_type == 'Exponentialimpuls' else 'hidden'; w_M_s.layout.visibility = 'visible' if s_type == 'Rechteck' else 'hidden'
w_b_h.layout.visibility = 'visible' if h_type == 'Exponentialimpuls' else 'hidden'; w_M_h.layout.visibility = 'visible' if h_type == 'Rechteck' else 'hidden'
# calculate s(m-n0) and h(m-n0)
global s, h, gn, container_s, container_h # reused in second interactive plot
s = lambda m: signal_types[s_type]((m-s_n0), b_s, M_s); # s(m-n0)
h = lambda m: signal_types[h_type]((m-h_n0), b_h, M_h); # h(m-n0)
gn = convolution(s, h) # numerical convolution
# update second plot if existing
try:
global n0
update_plot(n0)
except NameError:
pass
# display s and h plots
if container_s is None:
ax = axs0[0];
container_s = ient_stem(ax, m, s(m), 'rwth')
ax.set_xticks(np.arange(-10, 11, step=2))
ax.set_xlabel(r'$\rightarrow n$'); ax.set_ylabel(r'$\uparrow s(n)$')
ax.set_xlim([-10.9, 10.9]); ax.set_ylim([-.19, 1.19]); ient_axis(ax); ient_grid(ax);
ax = axs0[1];
container_h = ient_stem(ax, m, h(m), 'rwth')
ax.set_xticks(np.arange(-10, 11, step=2))
ax.set_xlabel(r'$\rightarrow n$'); ax.set_ylabel(r'$\uparrow h(n)$')
ax.set_xlim(axs0[0].get_xlim()); ax.set_ylim(axs0[0].get_ylim()); ient_axis(ax); ient_grid(ax);
else:
ient_stem_set_ydata(container_s, s(m))
ient_stem_set_ydata(container_h, h(m))
# Widgets
w_s_type=widgets.Dropdown(options=list(signal_types.keys()), description=r'Wähle $s(n)$:', style=ient_wdgtl_style)
w_s_n0=widgets.FloatSlider(min=-5, max=5, value=0, step=1, description=r'Verschiebung $n_0$', style=ient_wdgtl_style)
w_h_type=widgets.Dropdown(options=list(signal_types.keys()), description=r'Wähle $h(n)$:', style=ient_wdgtl_style)
w_h_n0=widgets.FloatSlider(min=-5, max=5, value=0, step=1, description=r'Verschiebung $n_0$', style=ient_wdgtl_style)
w_b_s=widgets.FloatSlider(min=.1, max=1, value=.5, step=.1, description=r'$b_s$', style=ient_wdgtl_style)
w_b_h=widgets.FloatSlider(min=.1, max=1, value=.5, step=.1, description=r'$b_h$', style=ient_wdgtl_style)
w_M_s=widgets.FloatSlider(min=0, max=5, value=1, step=1, description=r'$M_s$', style=ient_wdgtl_style)
w_M_h=widgets.FloatSlider(min=0, max=5, value=1, step=1, description=r'$M_h$', style=ient_wdgtl_style)
w = widgets.interactive(update_signals, s_type=w_s_type, s_n0=w_s_n0, h_type=w_h_type, h_n0 =w_h_n0, b_s=w_b_s, b_h=w_b_h, M_s=w_M_s, M_h=w_M_h)
display(widgets.HBox((widgets.VBox((w_s_type, w_s_n0, w_b_s, w_M_s)), widgets.VBox((w_h_type, w_h_n0, w_b_h, w_M_h), layout=Layout(margin='0 0 0 100px'))))); w.update();
```
%% Cell type:markdown id: tags:
Anschließend kann hier die Faltung $g(n)=s(n)\ast h(n)$ der zuvor eingestellten Funktionen betrachtet werden.
Über den Schieberegler kann der Wert für $n$ verändert werden und die Funktion $h(n-m)$ bewegt sich in der oberen Grafik. In der unteren Grafik ist das resultierende Ausgangssignal $g(n)$ zu sehen.
%% Cell type:code id: tags:
``` python
fig, axs = plt.subplots(2, 1, **ient_landscape)
global n0
container_ss = container_hh = container_gg = None
@widgets.interact(n=widgets.FloatSlider(min=-10, max=10, value=n0, step=1, description='Verschiebung $n$', style=ient_wdgtl_style))
def update_plot(n):
global container_ss, container_hh, container_gg
global n0
n0 = n
n_ind = np.where(m>=n); n_ind = n_ind[0][0]; g_plot = gn.copy(); g_plot[n_ind+1:] = 0; # hide g(n') with n'>n
if container_gg is None:
ax = axs[1]
container_gg = ient_stem(ax, m, g_plot)
if container_ss is not None:
ient_stem_set_ydata(container_ss, s(m))
ient_stem_set_ydata(container_hh, h(n-m))
ient_stem_set_ydata(container_gg, g_plot)
ax = axs[0]
ax.texts[0].set_x(n); ax.lines[3].set_xdata([n,n]) # update labels
ax = axs[1]
ient_update_ylim(ax, gn, 0.19, 20);
else:
ax = axs[0];
container_ss = ient_stem(ax, m, s(m), 'grun', label=r'$s(m)$')
container_ss[0].set_markerfacecolor('none');
container_ss[0].set_markersize(8);
container_ss[0].set_markeredgewidth(2);
container_hh = ient_stem(ax, m, h(n-m), 'rwth', label=r'$h(n-m)$')
ient_annotate_xtick(ax, r'$n$', n, -0.1, 'rwth', 15); # mark n on m axis
ax.set_xlabel(r'$\rightarrow m$');
ax.set_xlim([-10.2,10.2]); ient_update_ylim(ax, np.concatenate((h(m), s(m))), 0.19, 5);
ax.set_xticks(np.arange(-10, 11, step=2))
ax.legend(); ient_grid(ax); ient_axis(ax);
ax = axs[1]
ax.set_xlabel(r'$\rightarrow n$'); ax.set_ylabel(r'$\uparrow g(n)=s(n)\ast h(n)$');
ax.set_xlim(axs[0].get_xlim()); ient_update_ylim(ax, gn, 0.19, 20);
ax.set_xticks(np.arange(-10, 11, step=2))
ient_grid(ax); ient_axis(ax);
```
%% Cell type:markdown id: tags:
## Aufgaben
Wähle zunächst für $s(n)$ den Dirac-Impuls und für $h(n)$ verschiedene Funktionen aus.
* Beobachte das Faltungsergebnis. Ab welchem $n$ ist ein Ergebnis zu sehen? Was passiert, wenn du eine der Funktionen verschiebst?
* Wie sieht das Ergebnis für zwei Rechteckfunktionen aus? Wie für zwei Sprungfunktionen?
Wähle nun zwei Rechteckfunktionen mit $M>2$.
* Bewege den Schieberegler langsam von links nach rechts. An welcher Stelle tritt der erste Wert des Faltungsergebnisses auf? Wie hoch ist dieser Wert?
* Bewege den Schieberegler eins weiter nach rechts. Nun überlagern sich die beiden Signalen an zwei Positionen. Wie hoch ist der Wert des Faltungsergebnisses nun?
* Bewege den Schieberegler weiter, bis die beiden Funktionen sich vollständig überlagern. Was passiert, wenn nun der Schieberegler weiter nach rechts geschoben wird? Wie hoch ist der Wert des Faltungsergebnisses? Wie berechnen sich die Höhen des Faltungsergebnisses?
%% Cell type:markdown id: tags:
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).
Please attribute the work as follows:
*Christian Rohlfing, Emin Kosar, Übungsbeispiele zur Vorlesung "Grundgebiete der Elektrotechnik 3 - Signale und Systeme"*, gehalten von Jens-Rainer Ohm, 2019, Institut für Nachrichtentechnik, RWTH Aachen University.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment