Commit 8c7d1262 authored by Christian Rohlfing's avatar Christian Rohlfing
Browse files

- small changes to Laplace GUI

parent d0cd550e
%% Cell type:code id: tags:
``` python
# Copyright 2019 Institut für Nachrichtentechnik, RWTH Aachen University
%matplotlib widget
from ipywidgets import interact, interactive, fixed, HBox, VBox
import ipywidgets as widgets
from IPython.display import clear_output, display, HTML
from IPython.display import Markdown as md
from ient_nb.ient_plots import *
from ient_nb.ient_signals import *
from ient_nb.ient_transforms import *
from ient_nb.ient_signals import *
from src.laplace.laplace_plot import pzPoint, pzPlot
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
t = np.linspace(-6,6,1024)
f = np.linspace(-6,6,1024)
```
%% Cell type:markdown id: tags:
<div>
<img src="ient_nb/figures/rwth_ient_logo@2x.png" style="float: right;height: 5em;">
</div>
# Laplace-Transformation
%% Cell type:markdown id: tags:
## Interaktive Demo
%% Cell type:markdown id: tags:
In der interaktiven Demo kann eine Laplace-Übertragungsfunktion vom Typ
$$
H(p) = H_0 \frac{
\prod\limits_{q=1}^Q \left( p-p_{\mathrm{N},q} \right)
}{
\prod\limits_{r=1}^R \left( p-p_{\mathrm{P},r} \right)
}
$$
mit $Q$ Nullstellen $p_{\mathrm{N},q}$ und $R$ Polstellen $p_{\mathrm{P},r}$ betrachtet und verändert werden. Dargestellt ist ein Pol-/Nullstellendiagramm, sowie die zugehörige Impulsantwort und Übertragungsfunktion.
%% Cell type:code id: tags:
``` python
pzp = pzPlot()
filter_type = interactive(pzp.update_filter,filtr=widgets.Dropdown(options=list(pzp.filter_types.keys()), value="Sprungfunktion", description='Filter'))
action_type = interactive(pzp.update_action,action=widgets.Dropdown(options=list(pzp.action_types.keys()),value="Hinzufügen", description='Modus'))
point_type = interactive(pzp.update_mode,mode=widgets.Dropdown(options=list(pzp.mode_types.keys()), value="Polstelle", description='Typ'))
amp_type = interactive(pzp.update_amp, H0=widgets.IntSlider(min=1,max=10,step=1,value=1), description="H0")
left_box = VBox([filter_type, amp_type])
right_box = VBox([action_type, point_type])
HBox([left_box, right_box])
```
%% Cell type:markdown id: tags:
### Anleitung
Es können vier verschiedene Filter (Butterworth, Sprungfunktion, Sinus und Cosinus) voreingestellt werden. Über den Schieberegler kann der Wert für $H_0$ angepasst werden.
Bei *Modus* kann die Position des Konvergenzbereichs geändert werden, indem die entsprechende Option eingestellt und im Pol-/Nullstellendiagramm auf den Bereich geklickt wird, der der neue Konvergenzbereich sein soll.
Ähnlich können auch Pol- und Nullstellen hinzugefügt oder gelöscht werden. Bei *Typ* wird eingestellt, ob es sich um eine Pol- oder Nullstelle handeln soll und unter *Modus* wird dann *hinzufügen* oder *löschen* ausgewählt. Durch Klicken im Pol-/Nullstellendiagramm können nun Pol- und Nullstellen hinzugefügt oder gelöscht werden. Entsprechend ändern sich dann auch die zugehörige Impulsantwort und Übertragungsfunktion.
### Aufgaben
* Teste verschiedene Einstellungen und ihre Auswirkungen auf Impulsantwort und Übertragungsfunktion. Welche Auswirkung hat das Ändern von $H_0$? Wie sehen die voreingestellten Funktionen aus?
* Entferne alle Pole und Nullstellen. Wie sieht die Impulsantwort aus? Welche Auswirkung hat das Ändern von $H_0$?
* Erstelle eine Polstelle auf der imaginären Achse. Welche Auswirkung hat diese auf die Übertragungsfunktion?
* Erstelle ein Pol-/Nullstellendiagram mit mehreren möglichen Polstellen. Ändere den Konvergenzbereich. Wann existiert eine Übertragungsfunktion?
%% 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:
*Emin Kosar, Christian Rohlfing, Übungsbeispiele zur Vorlesung "Grundgebiete der Elektrotechnik 3 - Signale und Systeme"*, gehalten von Jens-Rainer Ohm, 2019, Institut für Nachrichtentechnik, RWTH Aachen University.
......
import bisect
from ipywidgets import interact, interactive, fixed, HBox, VBox
import ipywidgets as widgets
from IPython.display import clear_output, display, HTML
from ient_nb.ient_plots import *
from ient_nb.ient_transforms import *
......@@ -24,14 +27,13 @@ class pzPlot():
pp = np.array([])
pz = np.array([])
roc = {'sigma': [0, 0], 'lleft': None, 'lright': None, 'hatch': None, 'inf': 12}
qdelta = 0.5
qdelta = 0.1
qthresh = 0.1
fig = None
ax = None
handles = {'ph': None, 'axh': None, 'pH': None, 'axH': None}
filter_types = {#'manuell' : 'man',
'Butterworth' : 'butr', 'Sprungfunktion' : 'unit', 'Sinus' : 'sin',
'Cosinus' : 'cos'}
filter_types = {'Manuell' : 'man', 'Butterworth' : 'butr', 'Sprungfunktion' : 'unit',
'Sinus' : 'sin', 'Cosinus' : 'cos'}
mode = 'p'
mode_types = {'Polstelle': 'p', 'Nullstelle': 'z'}
action = 'add'
......@@ -52,11 +54,11 @@ class pzPlot():
self.t = np.linspace(-6, 6, num=self.length)
self.f = np.linspace(-6, 6, num=self.length)
self.open_figure()
# Poles
return
self.pp = np.array([])
if pp.size != 0 and ord_p.size == 0:
ord_p = np.ones(pp.size)
......@@ -87,7 +89,6 @@ class pzPlot():
# axes limits and labels
ax = plt.subplot(gs[0, :])
# fig, ax = plt.subplots()
ax.set_xlim(-6, 6)
ax.set_ylim(-6, 6)
ax.set_xlabel(r'$\rightarrow \mathrm{Re}$')
......@@ -99,18 +100,17 @@ class pzPlot():
def onclick(event):
if event.inaxes != self.ax: return
if self.filter != 'man': return
p = event.xdata + 1j * event.ydata
self.update_point(p, self.mode)
self.fig.canvas.mpl_connect('button_press_event', onclick)
self.handles['axh'] = plt.subplot(gs[1, 0])
self.handles['axh'].set_title('Impulsantwort', fontsize='12')
self.handles['axh'].set_xlabel(r'$\rightarrow t$')
self.handles['axh'].set_ylabel(r'$\uparrow h(t)$')
self.pbzErrortxt = self.handles['axh'].text(-7,
3.25,
self.pbzErrortxt = self.handles['axh'].text(-7, 3.25,
'Zählergrad größer als Nennergrad. \nKeine Partialbruchzerlegung möglich!',
fontsize=12, color='rot', visible=False, bbox=ient_wbbox)
self.handles['lineh'], = self.handles['axh'].plot(self.t, self.t)
......@@ -126,8 +126,19 @@ class pzPlot():
# initial dirac plot
(self.cp, self.cn) = ient_plot_dirac(self.handles['axh'], [-1, 1], [-1, 1], 'rwth')
ient_dirac_set_data((self.cp, self.cn), [], [])
plt.subplots_adjust(wspace=.25)
self.fig.canvas.layout.height = '800px'
fig.tight_layout();
#plt.subplots_adjust(wspace=.25)
# Widgets
self.w_filter_type = interactive(self.update_filter,filtr=widgets.Dropdown(options=list(self.filter_types.keys()), value="Sprungfunktion", description='Filter'))
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_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'):
if mode == 'n': mode = self.mode
......@@ -316,9 +327,18 @@ class pzPlot():
# clear plot
def clear_all_points():
list(map(lambda p: p.clear(), list(self.pp) + list(self.pz)));
tmp = list(self.pp) + list(self.pz)
list(map(lambda p: p.clear(), tmp));
self.pp = self.pz = np.array([])
def update_widgets(filtr):
if filtr == "Manuell":
b = False
else:
b = True
self.w_action_type.children[0].disabled = b
self.w_point_type.children[0].disabled = b
# add default filter poles and zeroes to plot
def def_points():
......@@ -353,7 +373,7 @@ class pzPlot():
# default filters (usage: [ poles, zeroes, order_poles, order_zeroes ] )
cases = {
# 'man': [[0], [], [1], []],
'man': [[], [], [], []],
'butr': [poles_butr, [], ord_poles_butr, []],
'unit': [[0], [], [1], []],
'sin': [[1j], [], [1], []],
......@@ -361,6 +381,7 @@ class pzPlot():
}
def_points()
update_widgets(filtr)
def update_plot(self):
poles = np.array(list((x.p for x in self.pp)), dtype=complex)
......
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