Commit e1f827da authored by Christian Rohlfing's avatar Christian Rohlfing
Browse files

Merge branch 'development-lab' of git.rwth-aachen.de:IENT/gdet3-demos into development-lab

parents 23285a50 40ea7565
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
}
},
"outputs": [],
"source": [
"# Copyright 2019 Institut für Nachrichtentechnik, RWTH Aachen University\n",
"%matplotlib widget\n",
"\n",
"import ipywidgets as widgets\n",
"from ipywidgets import interact, interactive, fixed, Layout, HBox, VBox\n",
"from IPython.display import clear_output, display, HTML\n",
"\n",
"from scipy import signal # convolution\n",
"\n",
"from ient_nb.ient_plots import *\n",
"from ient_nb.ient_signals import *"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Demonstrator Diskrete Faltung"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Im Folgenden wird die Faltung\n",
"$g(n)=s(n)\\ast h(n)$\n",
"betrachtet. <br>\n",
"$s(n)$ und $h(n)$ können gewählt werden als:\n",
"* $\\delta(n)$\n",
"* $\\epsilon(n)$\n",
"* $\\epsilon(n)\\cdot\\mathrm{b}^{n}$\n",
"* $rect(n) = \\epsilon(n+M)-\\epsilon(n-M-1)$"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
}
},
"outputs": [],
"source": [
"n = np.linspace(-10, 10, 21)\n",
"m = np.linspace(-40, 40, 81) # m Achse\n",
"s_type = h_type = ''; s_n0 = h_n0 = 0\n",
"M = 1\n",
"b = .5\n",
"\n",
"n0 = -2\n",
"\n",
"def convolution(s, h):\n",
" # Convolve s and h numerically\n",
" return signal.convolve(s(m), h(m), mode='same')\n",
"\n",
"signal_types = {'Dirac-Impuls' : lambda n: np.where(n==0, 1, 0),\n",
" 'Sprungfunktion' : unitstep,\n",
" 'Exponentialimpuls' : lambda n: unitstep(n)*b**n,\n",
" 'Rechteck' : lambda n: unitstep(n+M) - unitstep(n-M-1)\n",
" }\n",
"\n",
"def _update_b(_b):\n",
" global b\n",
" b = _b\n",
" update_signals(s_type, s_n0, h_type, h_n0)\n",
"\n",
"def _update_M(_M):\n",
" global M\n",
" M = _M\n",
" update_signals(s_type, s_n0, h_type, h_n0)\n",
"\n",
"# widgets for setting parameters b and M\n",
"w_b = interactive(_update_b, _b=widgets.FloatSlider(min=.1, max=1, value=.5, step=.1, description=r'$b$', style=ient_wdgtl_style))\n",
"w_M = interactive(_update_M, _M=widgets.FloatSlider(min=0, max=5, value=1, step=1, description=r'$M$', style=ient_wdgtl_style))\n",
"box = HBox([])\n",
"\n",
"fig0, axs0 = plt.subplots(1, 2, figsize=(8,2)); container_s = container_h = None\n",
"@widgets.interact(_s_type=widgets.Dropdown(options=list(signal_types.keys()), description=r'Wähle $s(n)$:'),\n",
" _s_n0=widgets.FloatSlider(min=-5, max=5, value=0, step=1, description=r'Verschiebung $n_0$', style=ient_wdgtl_style), \n",
" _h_type=widgets.Dropdown(options=list(signal_types.keys()), description=r'Wähle $h(n)$:'),\n",
" _h_n0=widgets.FloatSlider(min=-5, max=5, value=0, step=1, description=r'Verschiebung $n_0$', style=ient_wdgtl_style))\n",
"def update_signals(_s_type, _s_n0, _h_type, _h_n0):\n",
" # set global variables\n",
" global s_type, s_n0, h_type, h_n0\n",
" s_type = _s_type; s_n0 = _s_n0; h_type = _h_type; h_n0 = _h_n0\n",
" \n",
" global s, h, gn, container_s, container_h # reused in second interactive plot\n",
" s = lambda m: signal_types[_s_type]((m-_s_n0)); # s(m-n0)\n",
" h = lambda m: signal_types[_h_type]((m-_h_n0)); # h(m-n0)\n",
" gn = convolution(s, h) # numerical convolution\n",
" \n",
" # update second plot if existing\n",
" try:\n",
" global n0\n",
" update_plot(n0)\n",
" except NameError:\n",
" pass\n",
" \n",
" # show widgets according to chosen s and h\n",
" if _s_type == 'Exponentialimpuls' and _h_type == 'Rechteck':\n",
" box.children = [w_b, w_M]\n",
" elif _s_type == 'Rechteck' and _h_type == 'Exponentialimpuls':\n",
" box.children = [w_M, w_b]\n",
" elif _s_type == 'Exponentialimpuls' or _h_type == 'Exponentialimpuls':\n",
" box.children = [w_b]\n",
" elif _s_type == 'Rechteck' or _h_type == 'Rechteck':\n",
" box.children = [w_M]\n",
" else:\n",
" box.children = []\n",
" \n",
" # display s and h plots\n",
" if container_s is None:\n",
" ax = axs0[0]; \n",
" container_s = ient_stem(ax, m, s(m), 'rwth')\n",
" ax.set_xticks(np.arange(-10, 11, step=2))\n",
" ax.set_xlabel(r'$\\rightarrow n$'); ax.set_ylabel(r'$\\uparrow s(n)$')\n",
" ax.set_xlim([-10.9, 10.9]); ax.set_ylim([-1.19, 1.19]); ient_axis(ax); ient_grid(ax);\n",
" \n",
" ax = axs0[1]; \n",
" container_h = ient_stem(ax, m, h(m), 'rwth')\n",
" ax.set_xticks(np.arange(-10, 11, step=2))\n",
" ax.set_xlabel(r'$\\rightarrow n$'); ax.set_ylabel(r'$\\uparrow h(n)$')\n",
" ax.set_xlim(axs0[0].get_xlim()); ax.set_ylim(axs0[0].get_ylim()); ient_axis(ax); ient_grid(ax);\n",
"\n",
" else:\n",
" ient_stem_set_ydata(container_s, s(m))\n",
" ient_stem_set_ydata(container_h, h(m))\n",
" \n",
"\n",
"display(box)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"jupyter": {
"source_hidden": true
}
},
"outputs": [],
"source": [
"fig, axs = plt.subplots(2, 1, figsize=(8,6),) # gridspec_kw = {'width_ratios':[3, 1]}\n",
"global n0\n",
"container_ss = container_hh = container_gg = None\n",
"@widgets.interact(n=widgets.FloatSlider(min=-10, max=10, value=n0, step=1, description='Verschiebung $n$', style=ient_wdgtl_style))\n",
"def update_plot(n):\n",
" global container_ss, container_hh, container_gg\n",
" global n0\n",
" n0 = n\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\n",
" if container_gg is None:\n",
" ax = axs[1]\n",
" container_gg = ient_stem(ax, m, g_plot)\n",
" \n",
" if container_ss is not None:\n",
" ient_stem_set_ydata(container_ss, s(m))\n",
" ient_stem_set_ydata(container_hh, h(n-m))\n",
" ient_stem_set_ydata(container_gg, g_plot)\n",
" ax = axs[0]\n",
" ax.texts[0].set_x(n); ax.lines[3].set_xdata([n,n]) # update labels\n",
" ax = axs[1]\n",
" ient_update_ylim(ax, gn, 0.19, 20);\n",
" \n",
" else:\n",
" ax = axs[0];\n",
" container_ss = ient_stem(ax, m, s(m), 'grun', label=r'$s(m)$')\n",
" container_ss[0].set_markerfacecolor('none'); \n",
" container_ss[0].set_markersize(8); \n",
" container_ss[0].set_markeredgewidth(2);\n",
" \n",
" container_hh = ient_stem(ax, m, h(n-m), 'rwth', label=r'$h(n-m)$')\n",
" \n",
" ient_annotate_xtick(ax, r'$n$', n, -0.1, 'rwth', 15); # mark n on m axis\n",
" ax.set_xlabel(r'$\\rightarrow m$');\n",
" ax.set_xlim([-10.2,10.2]); ient_update_ylim(ax, np.concatenate((h(m), s(m))), 0.19, 5);\n",
" ax.set_xticks(np.arange(-10, 11, step=2))\n",
" ax.legend(); ient_grid(ax); ient_axis(ax);\n",
" \n",
" ax = axs[1]\n",
" ax.set_xlabel(r'$\\rightarrow n$'); ax.set_ylabel(r'$\\uparrow g(n)=s(n)\\ast h(n)$'); \n",
" ax.set_xlim(axs[0].get_xlim()); ient_update_ylim(ax, gn, 0.19, 20);\n",
" ax.set_xticks(np.arange(-10, 11, step=2))\n",
" ient_grid(ax); ient_axis(ax);"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
%% 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:
# Demonstrator Diskrete Faltung
%% Cell type:markdown id: tags:
Im Folgenden wird die Faltung
$g(n)=s(n)\ast h(n)$
betrachtet. <br>
$s(n)$ und $h(n)$ können gewählt werden als:
* $\delta(n)$
* $\epsilon(n)$
* $\epsilon(n)\cdot\mathrm{b}^{n}$
* $rect(n) = \epsilon(n+M)-\epsilon(n-M-1)$
%% Cell type:code id: tags:
``` python
n = np.linspace(-10, 10, 21)
m = np.linspace(-40, 40, 81) # m Achse
s_type = h_type = ''; s_n0 = h_n0 = 0
M = 1
b = .5
n0 = -2
def convolution(s, h):
# Convolve s and h numerically
return signal.convolve(s(m), h(m), mode='same')
signal_types = {'Dirac-Impuls' : lambda n: np.where(n==0, 1, 0),
'Sprungfunktion' : unitstep,
'Exponentialimpuls' : lambda n: unitstep(n)*b**n,
'Rechteck' : lambda n: unitstep(n+M) - unitstep(n-M-1)
}
def _update_b(_b):
global b
b = _b
update_signals(s_type, s_n0, h_type, h_n0)
def _update_M(_M):
global M
M = _M
update_signals(s_type, s_n0, h_type, h_n0)
# widgets for setting parameters b and M
w_b = interactive(_update_b, _b=widgets.FloatSlider(min=.1, max=1, value=.5, step=.1, description=r'$b$', style=ient_wdgtl_style))
w_M = interactive(_update_M, _M=widgets.FloatSlider(min=0, max=5, value=1, step=1, description=r'$M$', style=ient_wdgtl_style))
box = HBox([])
fig0, axs0 = plt.subplots(1, 2, figsize=(8,2)); container_s = container_h = None
@widgets.interact(_s_type=widgets.Dropdown(options=list(signal_types.keys()), description=r'Wähle $s(n)$:'),
_s_n0=widgets.FloatSlider(min=-5, max=5, value=0, step=1, description=r'Verschiebung $n_0$', style=ient_wdgtl_style),
_h_type=widgets.Dropdown(options=list(signal_types.keys()), description=r'Wähle $h(n)$:'),
_h_n0=widgets.FloatSlider(min=-5, max=5, value=0, step=1, description=r'Verschiebung $n_0$', style=ient_wdgtl_style))
def update_signals(_s_type, _s_n0, _h_type, _h_n0):
# set global variables
global s_type, s_n0, h_type, h_n0
s_type = _s_type; s_n0 = _s_n0; h_type = _h_type; h_n0 = _h_n0
global s, h, gn, container_s, container_h # reused in second interactive plot
s = lambda m: signal_types[_s_type]((m-_s_n0)); # s(m-n0)
h = lambda m: signal_types[_h_type]((m-_h_n0)); # h(m-n0)
gn = convolution(s, h) # numerical convolution
# update second plot if existing
try:
global n0
update_plot(n0)
except NameError:
pass
# show widgets according to chosen s and h
if _s_type == 'Exponentialimpuls' and _h_type == 'Rechteck':
box.children = [w_b, w_M]
elif _s_type == 'Rechteck' and _h_type == 'Exponentialimpuls':
box.children = [w_M, w_b]
elif _s_type == 'Exponentialimpuls' or _h_type == 'Exponentialimpuls':
box.children = [w_b]
elif _s_type == 'Rechteck' or _h_type == 'Rechteck':
box.children = [w_M]
else:
box.children = []
# 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([-1.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))
display(box)
```
%% Cell type:code id: tags:
``` python
fig, axs = plt.subplots(2, 1, figsize=(8,6),) # gridspec_kw = {'width_ratios':[3, 1]}
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:code id: tags:
``` python
```
......@@ -41,6 +41,8 @@ class pzPlot():
H = None
Hlog = None
P = 1 # no of poles for butterworth filter
def __init__(self, pp=np.array([0]), pz=np.array([]), ord_p=np.array([1]), ord_z=np.array([])):
self.H0 = 1
......@@ -135,9 +137,14 @@ class pzPlot():
self.w_action_type = interactive(self.update_action,action=widgets.Dropdown(options=list(self.action_types.keys()),value="Hinzufügen", description='Modus', disabled=True))
self.w_point_type = interactive(self.update_mode,mode=widgets.Dropdown(options=list(self.mode_types.keys()), value="Polstelle", description='Typ', disabled=True))
self.w_amp_type = interactive(self.update_amp, H0=widgets.IntSlider(min=1,max=10,step=1,value=1), description="H0")
self.w_no_of_poles = interactive(self.update_no_of_poles, P=widgets.IntSlider(min=1,max=7,step=1,value=1), description="P")
self.VBox_AMP = VBox([self.w_filter_type, self.w_amp_type]) # vertical box for displaying H0
self.VBox_Butter = VBox([self.w_filter_type, self.w_no_of_poles]) # vertical box for displaying no. of poles (only for butterworth)
self.VBox_mode_type = VBox([self.w_action_type, self.w_point_type]) # vertical box action type and point type
self.w_hbox = HBox([self.VBox_AMP, self.VBox_mode_type])
self.w_hbox = HBox([VBox([self.w_filter_type, self.w_amp_type]),
VBox([self.w_action_type, self.w_point_type])])
display(self.w_hbox)
def find_closest_point(self, p, mode='n'):
......@@ -307,6 +314,11 @@ class pzPlot():
self.update_plot()
def update_no_of_poles(self, P):
self.P = P
if self.w_filter_type.kwargs['filtr'] == 'Butterworth': # skip execution on startup
self.update_filter('Butterworth')
def update_filter(self, filtr):
self.filter = self.filter_types[filtr]
......@@ -314,17 +326,23 @@ class pzPlot():
ord_poles_butr = np.array([])
# calculate butterworth poles and orders
if filtr == 'Butterworth' :
# TODO - Filtergrad und -grenzfrequenz anpassen
filtergrad = 2
filtergrenzfrequenz = 1
# TODO - self.H0 je nach Filtergrad und -grenzfrequenz ändern
if filtr == 'Butterworth':
# show slider for no of poles (filtergrad)
self.w_hbox.children = [self.VBox_Butter, self.VBox_mode_type]
filtergrad = self.P
filtergrenzfrequenz = 1 # omega_g = 1
tmp = (np.linspace(0, filtergrad - 1, num=filtergrad) + 0.5) / filtergrad * np.pi + np.pi / 2
tmp = tmp[np.where(tmp <= np.pi)[0]]
poles_butr = np.array(filtergrenzfrequenz * np.exp(1j * tmp))
ord_poles_butr = np.array(np.ones(poles_butr.shape), dtype=int)
else:
# show slider for H0
self.w_hbox.children = [self.VBox_AMP, self.VBox_mode_type]
# clear plot
def clear_all_points():
tmp = list(self.pp) + list(self.pz)
......
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