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

- introduced ient_landscape to some notebooks (not all, to be checked!)

- rearanged zeitverschiebung a little bit
parent 89302350
Pipeline #235178 passed with stages
in 17 minutes and 24 seconds
%% 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
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 Faltung
Zum Starten: Im Menü: Run <span class="fa-chevron-right fa"></span> Run All Cells auswählen.
## Einleitung
Im Folgenden wird das Faltungsintegral
$$g(t)
= s(t)\ast h(t)
= \int\limits_{-\infty}^{\infty} s(\tau) h(t-\tau) \,\mathrm{d}\tau
$$
betrachtet.
%% Cell type:markdown id: tags:
## Demo
Wähle $s(t)$ und $h(t)$ sowie jeweils Verschiebung $t_0$ und Dehnungsfaktor $T$ für beide Signale: $s\left(\frac{t-t_0}{T}\right)$ und $h\left(\frac{t-t_0}{T}\right)$.
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 t: rect(t/2-1/2)*(-t)
```
%% Cell type:code id: tags:
``` python
def convolution(s, h):
# Convolve s and h numerically
return signal.convolve(s(tau), h(tau), mode='same')*deltat
(tau,deltat) = np.linspace(-15, 15, 10001, retstep=True) # tau Achse
signal_types = {'Rechteck' : rect,
'Dreieck' : tri,
'Sprungfunktion' : unitstep,
'si-Funktion' : lambda t: si(t*np.pi),
'Exponentialimpuls' : lambda t: unitstep(t)*np.exp(-t),
'Gauß-Signal' : gauss,
'Doppelrechteck' : lambda t: rect(t*2+0.5)-rect(t*2-0.5),
'Rampe' : lambda t: t*rect(t-0.5),
'Versch. Rechteck' : lambda t: -rect(t-0.5),
'Eigene Kreation s0(t)' : s_0,
}
# Plot
fig0, axs0 = plt.subplots(1, 2, figsize=(8,2))
fig0, axs0 = plt.subplots(1, 2, figsize=(12,2))
def update_signals(s_type, s_T, s_t0, h_type, h_T, h_t0):
global s, h, gt # reused in second interactive plot
s = lambda tau: signal_types[s_type]((tau-s_t0)/s_T);
h = lambda tau: signal_types[h_type]((tau-h_t0)/h_T);
gt = convolution(s, h) # numerical convolution
if not axs0[0].lines: # plot s(t) and g(t)
ax = axs0[0]; ax.plot(tau, s(tau), 'rwth');
ax.set_xlabel(r'$\rightarrow t$'); ax.set_ylabel(r'$\uparrow s(t)$')
ax.set_xlim([-2.9, 2.9]); ax.set_ylim([-1.19, 1.19]); ient_axis(ax); ient_grid(ax);
ax = axs0[1]; ax.plot(tau, h(tau), 'rwth');
ax.set_xlabel(r'$\rightarrow t$'); ax.set_ylabel(r'$\uparrow h(t)$')
ax.set_xlim(axs0[0].get_xlim()); ax.set_ylim(axs0[0].get_ylim()); ient_axis(ax); ient_grid(ax); fig0.tight_layout();
else: # update lines
axs0[0].lines[0].set_ydata(s(tau));
axs0[1].lines[0].set_ydata(h(tau));
try: # if convolution figure is already opened, update s(tau)
if axs[0].lines:
axs[0].lines[1].set_ydata(s(tau));
ient_update_ylim(axs[0], np.concatenate((h(tau), s(tau))), 0.19, 5); ient_update_ylim(axs[1], gt, 0.19, 5);
update_plot(-2) # update convolution plot
except: pass
ient_update_ylim(axs0[0], s(tau), 0.19, 5); ient_update_ylim(axs0[1], h(tau), 0.19, 5);
# Widgets
w_s_type = widgets.Dropdown(options=list(signal_types.keys()), description=r'Wähle $s(t)$:')
w_s_T = widgets.FloatSlider(min=0.5, max=4, value=1, step=.1, description=r'Dehnung T', style=ient_wdgtl_style)
w_s_t0 = s_t0=widgets.FloatSlider(min=-2, max=2, value=0, step=.1, description=r'Verschiebung $t_0$', style=ient_wdgtl_style)
w_h_type = widgets.Dropdown(options=list(signal_types.keys()), description=r'Wähle $h(t)$:')
w_h_T = widgets.FloatSlider(min=0.5, max=4, value=1, step=.1, description=r'Dehnung T', style=ient_wdgtl_style)
w_h_t0 = s_t0=widgets.FloatSlider(min=-2, max=2, value=0, step=.1, description=r'Verschiebung $t_0$', style=ient_wdgtl_style)
w = widgets.interactive(update_signals, s_type=w_s_type, s_T=w_s_T, s_t0=w_s_t0, h_type=w_h_type, h_T=w_h_T, h_t0 = w_h_t0)
display(widgets.HBox((widgets.VBox((w_s_type, w_s_T, w_s_t0)), widgets.VBox((w_h_type, w_h_T, w_h_t0), layout=Layout(margin='0 0 0 100px'))))); w.update();
```
%% Cell type:markdown id: tags:
... und betrachte hier das Faltungsergebnis:
%% Cell type:code id: tags:
``` python
fig, axs = plt.subplots(2, 1, figsize=(8,6),) # gridspec_kw = {'width_ratios':[3, 1]}
fig, axs = plt.subplots(2, 1, figsize=(12, 12/ient_fig_aspect)) # gridspec_kw = {'width_ratios':[3, 1]}
@widgets.interact(t=widgets.FloatSlider(min=-4, max=4, value=-2, step=.1, description='Verschiebung $t$', style=ient_wdgtl_style),
show_integrand=widgets.Checkbox(value=True, description='Zeige Integrand', style=ient_wdgtl_style))
def update_plot(t, show_integrand=True):
t_ind = np.where(tau>=t); t_ind = t_ind[0][0]; g_plot = gt.copy(); g_plot[t_ind:] = np.nan; # hide g(t') with t'>t
sh = s(tau)*h(t-tau) # integrand
if not axs[0].lines: # Call plot() and decorate axes. Usually, these functions take some processing time
ax = axs[0]; ax.plot(tau, h(t-tau), 'rwth', label=r'$h(t-\tau)$'); # plot h(t-tau)
ax.plot(tau, s(tau), 'grun', label=r'$s(\tau)$'); # plot s(tau)
ax.plot(tau, sh, '--', color='orange', lw=1, label=r'$s(\tau)h(t-\tau)$'); # plot integrand
ient_annotate_xtick(ax, r'$t$', t, -0.1, 'rwth', 15); # mark t on tau axis
ax.fill_between(tau, 0, sh, facecolor="none", hatch="//", edgecolor='k', linewidth=0.0); # hatch common area
ax.set_xlabel(r'$\rightarrow \tau$');
ax.set_xlim([-4.2,4.2]); ient_update_ylim(ax, np.concatenate((h(tau), s(tau))), 0.19, 5);
ax.legend(); ient_grid(ax); ient_axis(ax);
ax = axs[1]; ax.plot(tau, g_plot); # plot g(t)
ax.plot([t, t], [0, gt[t_ind]], 'ko--', lw=1);
ax.set_xlabel(r'$\rightarrow t$'); ax.set_ylabel(r'$\uparrow g(t)=s(t)\ast h(t)$');
ax.set_xlim(axs[0].get_xlim()); ient_update_ylim(ax, gt, 0.19, 5);
ient_grid(ax); ient_axis(ax); fig.tight_layout(); #plt.subplots_adjust(wspace=.1,hspace=.1)
else: # Replace only xdata and ydata since plt.plot() takes longer time
ax = axs[0]; ax.lines[0].set_ydata(h(t-tau)); ax.lines[2].set_ydata(sh); # update signals
ax.texts[0].set_x(t); ax.lines[3].set_xdata([t,t]) # update labels
if ax.collections: ax.collections[0].remove(); # update integrand
if show_integrand: ax.fill_between(tau,0,sh, facecolor="none", hatch="//", edgecolor='k', linewidth=0.0);
ax = axs[1]; ax.lines[0].set_ydata(g_plot); # update signals
ax.lines[1].set_xdata([t, t]); ax.lines[1].set_ydata([0, gt[t_ind]]); # update labels
axs[0].lines[2].set_visible(show_integrand)
```
%% Cell type:markdown id: tags:
### Aufgaben:
* Bewege den Schieberegler für $t$ und betrachte das entstehende Faltungsintegral. Wie sind die zugehörigen Integralsgrenzen und welche Intervalle (vgl. Notebook zur Faltung) sind zu beobachten?
* Wähle zwei Rechtecke unterschiedlicher Breite aus. Wie sieht das entstehende Signal aus? Wie breit ist es? Was passiert, wenn eins der Rechtecke um $t_0$ verschoben wird?
* Welche Höhe bei $t=0$ hat das Resultat der Faltung $g(t) = \mathrm{rect}\left(\frac{t}{2}\right)\ast \mathrm{rect}\left(\frac{t}{2}\right)$? Überprüfe die Überlegungen mit Hilfe der entsprechenden Funktionen in der Demo.
* Gilt das Kommutativgesetz $s(t) \ast h(t) = h(t) \ast s(t)$?
* Wie sieht das Faltungsergebnis zweier si-Funktionen aus? Wie das Ergebnis zweier Gaußfunktionen?
* Reale Rechteckimpulse weisen nur eine endliche Flankensteilheit auf. Diese können beispielsweise mit $s(t)=\mathrm{rect}(t)*\mathrm{rect}(t/T)$ oder $s(t)=\mathrm{rect}(t)*\Lambda(\frac{t}{T})$ beschrieben werden. Betrachte diese Fälle für $|T|<\frac{1}{2}$. Wie hängen Gesamtdauer und Dauer der Anstiegsflanke von $T$ ab?
%% 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, Übungsbeispiele zur Vorlesung "Grundgebiete der Elektrotechnik 3 - Signale und Systeme"*, gehalten von Jens-Rainer Ohm, 2019, Institut für Nachrichtentechnik, RWTH Aachen University.
......
%% 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
import scipy as sp
import scipy.special
import scipy.signal
from ient_nb.ient_plots import *
from ient_nb.ient_signals import *
rect_pulse = lambda t, Tr=0.5 : ((t+.25) % 1)< Tr
def correlation(s, g):
# Correlate s and g numerically
return sp.signal.convolve(np.conj(np.flipud(s)), g, mode='full')/(len(t))
fs = 200 # Samplingrate
(t,deltat) = np.linspace(-50,50, 100*fs, retstep=True) # Zeitachse
(tau,deltatau) = np.linspace(-100,100, 2*len(t)-1, retstep=True) # Korrelation
```
%% Cell type:markdown id: tags:
<div>
<img src="ient_nb/figures/rwth_ient_logo@2x.png" style="float: right;height: 5em;">
</div>
# Korrelationsempfänger
Wird ein bekanntes Signal bei Übertragung über einen Kanal gestört, kann es bei starker Überlagerung durch Rauschen schwierig sein, dieses wieder zu entdecken. Trotzdem soll das Signal entdeckt und bezüglich Amplitude und Dauer geschätzt werden. Bei Störung durch weißes Rauschen ist die optimale Lösung für dieses Problem ein sogenannter Korrelationsempfänger. Dieser nutzt ein Korrelationsverfahren, bei dem das gestörte Signal mit einem ungestörten Mustersignal verglichen wird. Genutzt wird dies zum Beispiel für Synchronisierung oder Radarortung, ebenso ist es hiermit möglich, mehrere Signale auf einem gemeinsamen Kanal zu übertragen.
Dieses Verfahren soll hier veranschaulicht werden.
%% Cell type:markdown id: tags:
Das in der nächsten Abbildung dargestellte Signal $s(t)$ ist ein Burst-Signal
$$
s(t) = \sin(2\pi F t) \cdot \sum_n \mathrm{rect}\left(\frac{t}{D}-\frac{1}{2}-nT\right)
$$
%% Cell type:code id: tags:
``` python
T = 3 # Periode in Sekunden
D = 1 # Burstdauer in Sekunden
F = 2 # Frequenz des Sinus in Hertz
A = 1 # Amplitude
s = A*np.sin(2*np.pi*F*t)*rect_pulse(t/T-.25, D/T)
# Plot
fig,ax = plt.subplots(1,1); ax.plot(t, s, 'rwth'); ax.plot(t, rect_pulse(t/T-.25, D/T), 'k--')
ax.set_xlabel(r'$\rightarrow t$ [s]', bbox=ient_wbbox); ax.set_ylabel(r'$\uparrow s(t)$', bbox=ient_wbbox)
ax.set_xlim([-4.5,5.25]); ax.set_ylim([-1.2,1.2]); ient_grid(ax); ient_axis(ax);
ient_annotate_distance(ax, r'$D$', (0,-1.1), (D,-1.1))
ient_annotate_distance(ax, r'$T$', (0,-.9), (T,-.9))
```
%% Cell type:markdown id: tags:
In der nächsten Abbildung ist das Störsignal $n(t)$ und die zugehörige Verteilungsdichte $p_n(x)$ dargestellt. $n(t)$ ist gleichverteiltes weißes Rauschen im Amplitudenwertebereich $-1$ und $1$.
%% Cell type:code id: tags:
``` python
n = np.random.uniform(-1, 1, len(t))
x = np.linspace(-5,5, 1024)
pn_hist, bins = np.histogram(n, bins=100, range=(-2, 2), density=True)
x_nhist = (bins[:-1] + bins[1:])/2 # x-axis
# Plot
fig,axs = plt.subplots(2,1);
ax = axs[0]; ax.plot(t, n, 'rwth');
ax.set_ylabel(r'$\uparrow {}^k n(t)$', bbox=ient_wbbox); ax.set_xlabel(r'$\rightarrow t$ [s]', bbox=ient_wbbox);
ax.set_xlim([-4.5,5.25]); ient_axis(ax);
ax = axs[1]; ient_stem(ax, x_nhist, pn_hist, 'black-50', markerfmt=" ");
ax.plot(x, 0.5*rect(x/2), 'rwth')
ax.set_ylabel(r'$\uparrow p_n(x)$', bbox=ient_wbbox); ax.set_xlabel(r'$\rightarrow x$', bbox=ient_wbbox);
ax.set_xlim([-1.75,1.75]); ient_axis(ax);
```
%% Cell type:markdown id: tags:
## Interaktive Demo
In dieser interaktiven Demo soll nun betrachtet werden, wie man mit Hilfe der Korrelation das Nutzsignal $s(t)$ detektieren kann.
Dargestellt sind auf der rechten Seite das Nutzsignal $s(t)$ und das Störsignal $n(t)$. Die beiden Signale werden nun überlagert und das Summensignal $g(t) = s(t) + n(t)$ betrachtet, dies ist oben links abgebildet.
Ebenfalls dargestellt ist die Autokorrelationsfunktion $\varphi_{gg}(\tau)$.
Mit Hilfe der Schieberegler können nun verschiedene Variationen des Signals dargestellt werden. Der erste Schieberegler ändert die Frequenz $F$ von $s(t)$, der zweite die Dauer $D$ und der dritte die Periode $T$ mit der die Anteile von $s(t)$ wiederholt werden.
Über den letzten Schieberegler kann das Signal-zu-Rausch-Verhältnisse (SNR) eingestellt werden.
%% Cell type:code id: tags:
``` python
fig,axs = plt.subplots(2,2, figsize=(8,6), gridspec_kw = {'width_ratios':[2, 1]})
fig,axs = plt.subplots(2,2, **ient_landscape, gridspec_kw = {'width_ratios':[2, 1]})
Twdgt = widgets.FloatSlider(min=1, max=20, value=10, step=1, description=r'Periode T', style=ient_wdgtl_style)
Dwdgt = widgets.FloatSlider(min=0.5, max=10, value=5, step=.5, description=r'Dauer D', style=ient_wdgtl_style)
def update_x_range(*args):
Dwdgt.max = Twdgt.value
Twdgt.observe(update_x_range, 'value')# D ist an den Wert von T gekoppelt, da D immer kleiner gleich T
@interact(F=widgets.FloatSlider(min=1, max=20, value=1, step=1, description=r'Frequenz F', style=ient_wdgtl_style),
D=Dwdgt, T=Twdgt,
SNR=widgets.FloatSlider(min=-50, max=50, value=-10, step=1, description=r'SNR', style=ient_wdgtl_style))
def update_plot(F, D, T, SNR):
# Empfänger: Burst-Signal
A = 10**(SNR/20)*np.sqrt(2/3);
s = A*rect_pulse(t/T-.25, D/T)*np.sin(2*np.pi*F*t)
# Kanal: Additives weißes Rauschen
g = s + n
# Empfänger: Korrelation
phi_gg = correlation(g, g)
if not axs[0,0].lines:
ax = axs[0,0]; ax.plot(t, g, 'rwth');
ax.set_xlabel(r'$\rightarrow t$', bbox=ient_wbbox);
ax.set_ylabel(r'$\uparrow g(t) = s(t)+n(t)$', bbox=ient_wbbox); ient_axis(ax);
ax = axs[0, 1]; ax.plot(t, s, 'rwth');
ax.set_xlabel(r'$\rightarrow t$', bbox=ient_wbbox);
ax.set_ylabel(r'$\uparrow s(t)$', bbox=ient_wbbox); ient_axis(ax);
ax = axs[1,0]; ax.plot(tau, phi_gg, 'rwth');
ax.set_xlabel(r'$\rightarrow \tau$', bbox=ient_wbbox);
ax.set_ylabel(r'$\uparrow \varphi_{gg}(\tau)$', bbox=ient_wbbox); ient_axis(ax);
ax = axs[1, 1]; ax.plot(t, n, 'rwth');
ax.set_xlabel(r'$\rightarrow t$', bbox=ient_wbbox); ax.set_ylabel(r'$\uparrow n(t)$', bbox=ient_wbbox);
ient_update_ylim(ax,n,.25,1000); ient_axis(ax); fig.tight_layout();
else:
axs[0,0].lines[0].set_ydata(g); axs[0,1].lines[0].set_ydata(s); axs[1,0].lines[0].set_ydata(phi_gg);
axs[0,0].set_xlim([-2.1*T,2.1*T]); ient_update_ylim(axs[0,0], g, .5*np.max(np.abs(g)), 1e6);
axs[0,1].set_xlim(axs[0,0].get_xlim()); ient_update_ylim(axs[0,1], s, .5*np.max(np.abs(s)), 1e6)
axs[1,0].set_xlim(axs[0,0].get_xlim()); ient_update_ylim(axs[1,0], phi_gg[int(len(phi_gg)/2+1):-int(len(phi_gg)/4)], .5*np.max(np.abs(phi_gg[int(len(phi_gg)/2+1):-int(len(phi_gg)/4)])), 1e6)
axs[1,1].set_xlim(axs[0,0].get_xlim());
```
%% Cell type:markdown id: tags:
## Aufgaben
* Betrachte $g(t)$ und $\varphi_{gg}(\tau)$ für die voreingestellten Startwerte. Vergleiche den Bereich, in dem sich $s(t)$ befindet. Wie stellt sich dies in der Korrelationsfunktion dar?
* Variiere nun die Frequenz $F$. Wie ändern sich $g(t)$ und $\varphi_{gg}(\tau)$?
* Was passiert, wenn $D$ sehr große Werte annimmt? Warum?
* Welchen Einfluss hat die Periode $T$?
Abschließend wird nun der Einfluss des Signal-zu-Rauschverhältnisses betrachtet.
* Starte mit kleinen Werten für das SNR und erhöhe es schrittweise. Was passiert mit dem Signal? Was passiert mit der Korrelationsfunktion?
* Probiere aus, für welche Konstellationen von $F$, $D$, $T$ und $SNR$ aus dem Korrelationssignal noch genügend Information gewonnen werden kann um Position und Dauer des Originalsignals zu identifizieren.
%% 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, Übungsbeispiele zur Vorlesung "Grundgebiete der Elektrotechnik 3 - Signale und Systeme"*, gehalten von Jens-Rainer Ohm, 2019, Institut für Nachrichtentechnik, RWTH Aachen University.
......
%% 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 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:
Beispiele
$s_1(t) = \mathrm{e}^{-bt}\cdot\epsilon(t)$
transformiert sich zu
$S_1(p) = \frac{1}{b+p}$ mit Konvergenzbereich $\mathrm{Re}\{p\}>\mathrm{Re}\{-b\}$
%% Cell type:code id: tags:
``` python
b = 2
pp = np.array([-b]); pz = np.array([])
roc = np.array([-b, np.inf])
fig,axs = plt.subplots(1,2)
fig,axs = plt.subplots(1,2, **ient_landscape)
# Laplace-Bereich
ax = axs[0]; ient_plot_lroc(ax, roc)
ax.plot(np.real(pp), np.imag(pp), **ient_style_poles); ax.plot(np.real(pp), -np.imag(pp), **ient_style_poles)
ax.set_xlabel(r'$\rightarrow \mathrm{Re}$'); ax.set_ylabel(r'$\uparrow \mathrm{Im}$');
ax.set_xlim(-5, 5); ax.set_ylim(-5, 5); ient_grid(ax); ient_axis(ax)
# Zeitbereich
s1, _, _ = ient_ilaplace_ht(t, 1, pp, pz, [1], [], roc)
ax = axs[1]; ax.plot(t, np.real(s1), **ient_style_graph);
ax.set_xlabel(r'$\rightarrow t$'); ax.set_ylabel(r'$\uparrow s_1(t)$'); ient_grid(ax); ient_axis(ax)
```
%% Cell type:markdown id: tags:
Da der Konvergenzbereich die imaginäre Achse umschließt, existiert auch die Fouriertransformierte $S_1(f)$:
%% Cell type:code id: tags:
``` python
# Frequenzbereich
S1f = ient_ilaplace_Hf(f, 1, pp, pz, [1], [], dB=False)
fig, ax = plt.subplots(1,1)
ax.plot(f, S1f, **ient_style_graph);
ax.set_xlabel(r'$\rightarrow f$'); ax.set_ylabel(r'$\uparrow S_1(f)$');
ax.set_xlim([-5.5,5.5]); ax.set_ylim([-0.1,0.55]); ient_grid(ax); ient_axis(ax)
```
%% Cell type:markdown id: tags:
$s_2(t) = -\mathrm{e}^{-bt}\cdot\epsilon(-t)$
transformiert sich zu
$S_2(p) = \frac{1}{b+p}$ mit Konvergenzbereich $\mathrm{Re}\{p\}<\mathrm{Re}\{-b\}$:
%% Cell type:code id: tags:
``` python
roc = np.array([-np.inf, -b])
fig,axs = plt.subplots(1,2)
fig,axs = plt.subplots(1,2, **ient_landscape)
# Laplace-Bereich
ax = axs[0]; ient_plot_lroc(ax, roc); ient_annotate_order(ax, pp, [1]);
ax.plot(np.real(pp), np.imag(pp), **ient_style_poles); ax.plot(np.real(pp), -np.imag(pp), **ient_style_poles)
ax.set_xlabel(r'$\rightarrow \mathrm{Re}$'); ax.set_ylabel(r'$\uparrow \mathrm{Im}$');
ax.set_xlim(-5, 5); ax.set_ylim(-5, 5); ient_axis(ax); ient_grid(ax)
# Zeitbereich
s2, _, _ = ient_ilaplace_ht(t, 1, pp, pz, [1], [], roc)
ax = axs[1]; ax.plot(t, np.real(s2), **ient_style_graph);
ax.set_xlabel(r'$\rightarrow t$'); ax.set_ylabel(r'$\uparrow s_2(t)$');
ax.set_ylim([-45,5]); ax.grid(); ient_axis(ax)
```
%% Cell type:markdown id: tags:
Da in diesem Fall der Konvergenzbereich links vom linkesten Pol liegt und somit nicht die imaginäre Achse beinhaltet, existiert die Fouriertransformierte nicht.
Eine ausführlichere Demo zur Laplacetransformation findet man [hier](GDET3%20Laplace-Transformation%20GUI.ipynb).
%% 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.
......
%% Cell type:code id: tags:
``` python
# Copyright 2019 Institut für Nachrichtentechnik, RWTH Aachen University
%matplotlib widget
from ipywidgets import interact, interactive, Layout
import ipywidgets as widgets
import numpy as np
import scipy as sp
import scipy.special # erfc(x)
from ient_nb.ient_plots import *
from ient_nb.ient_signals import *
from ient_nb.ient_audio import *
import matplotlib
from matplotlib.patches import ConnectionPatch
highlight_args = {'color':'rot', 'marker':'o'}; arrow_args = {'width':1,'headlength':10,'headwidth':10,'fc':'rot'}
anno_args = {'color':'rot', 'linestyle':'--', 'arrowstyle':"-", 'coordsA':'data', 'coordsB':'data'}
```
%% Cell type:markdown id: tags:
<div>
<img src="ient_nb/figures/rwth_ient_logo@2x.png" style="float: right;height: 5em;">
</div>
# Verteilungsfunktion und Verteilungsdichtefunktion
Zum Starten: Im Menü: Run <span class="fa-chevron-right fa"></span> Run All Cells auswählen.
## Einleitung
Bei der Betrachtung einer Schar von Zufallssignalen ${}^k s(t)$ ist eine Beschreibung über die tatsächlichen Amplitudenwerte oft wenig sinnvoll. Statt dieser werden deswegen die statistischen Eigenschaften betrachtet. Grundlegende Aussagen über ein Signal können aus der Verteilungs- und der Verteilungsdichtefunktion gewonnen werden. Ebenso relevant sind der Mittelwert $m_s$, die Standardabweichung $\sigma_s$ und die Frequenz $F$.
### Verteilungsfunktion
Die Verteilungsfunktion $P_s(x,t_1)$ gibt an, wie wahrscheinlich es ist, dass das Signal zum Zeitpunkt $t_1$ einen Wert kleiner oder gleich $x$ annimmt:
$$P_s(x,t_1) = \mathrm{Prob}\left[s(t_1) \leq x\right]$$
Ist das Signal ein stationäres Signal, gilt dies für alle Zeitpunkte $t$:
$$P_s(x) = \mathrm{Prob}\left[s(t) \leq x\right]$$
Für einen stationären Prozess gilt, dass alle möglichen Mittelwerte unabhängig von der Verschiebung des Beobachtungszeitpunktes sind. Ein Prozess, der zwar im strengen Sinn der Definition nicht-stationär ist, dessen Autokorrelationsfunktion aber nur von der Differenz der Abtastzeiten abhängt und dessen Mittelwert zeitunabhängig ist, wird auch *stationär im weiten Sinn* oder *schwach stationär* genannt.
Erfüllt ein Signal zusätzlich die Eigenschaft, dass die Scharmittelwerte den Zeitmittelwerten entsprechen, ist das Signal *ergodisch*.
Es gilt dann:
$$P_s(x) = \frac{1}{2T}\sum_i \Delta t_i(x)$$
### Verteilungsdichtefunktion
Die Verteilungsdichtefunktion gibt an, mit welcher Wahrscheinlichkeit ein bestimmter Wert $x$ auftritt. Sie kann aus der Verteilungsfunktion durch Ableitung gewonnen werden:
$$p_s(x) = \frac{\mathrm{d}}{\mathrm{d}x} P_s(x)$$
Typische Verteilungsdichtefunktionen sind die Gleichverteilung und die Gauß-Verteilung.
### Mittelwert, Leistung und Standardabweichung
Der Mittelwert $m_s$ eines Signals ist der Erwartungswert:
$$m_s=\mathcal{E}\{s(t)\}=\int_{-\infty}^{\infty}xp_s(x)\mathrm{d}x$$
Der Mittelwert eines ergodischen Prozesses entspricht dem Gleichanteil des Signals.
Die Leistung $L_s$ eines Signals ist definiert als
$$m_s=\mathcal{E}\{s^2(t)\}=\int_{-\infty}^{\infty}x^2p_s(x)\mathrm{d}x\text{.}$$
Die Standardabweichung $\sigma_s$ kann nun aus Mittelwert und Leistung berechnet werden:
$$\sigma_s=\sqrt{L_s-m_s^2}$$
In der Formelsammlung können die Zusammenhänge zwischen Verteilungsdichtefunktion, Mittelwert, Leistung und Standardabweichung für Gauß- und gleichverteilte stationäre Prozesse gefunden werden.
%% Cell type:markdown id: tags:
## Signale
Im Folgenden werden einige Signale beispielhaft betrachtet. Hierzu wird im folgenden Fenster eine $t$-Achse generiert und weitere [Elementarsignalen](GDET3%20Elementarsignale.ipynb) sowie einige Verteilungsdichtefunktionen definiert.
%% Cell type:code id: tags:
``` python
fs = 44100;
(t, deltat) = np.linspace(-10, 10, 20*fs, retstep=True) # t axis in seconds
Amax = 6 # limit of histogram (the total range would be from -Amax to Amax)
(x, deltax) = np.linspace(-Amax, Amax, 4001, retstep=True) # x axis (corresponds to amplitude)
rect_sum = lambda t: unitstep(np.cos(np.pi*t))
tri_sum = lambda t: np.abs(np.mod(t,2)-1)
gaussian_pdf = lambda x, ms, sigmas: 1/(sigmas*np.sqrt(2*np.pi)) * np.exp(-(x-ms)**2/(2*sigmas**2))
gaussian_pf = lambda x, ms, sigmas: 0.5*sp.special.erfc((ms-x)/np.sqrt(2*sigmas**2))
uniform_pdf = lambda x, ms, a: 1/a* rect((x-ms)/a)
uniform_pf = lambda x, ms, a: rect((x-ms)/a)*((x-ms)/a+1/2)+unitstep(x-(ms+a/2))
```
%% Cell type:markdown id: tags:
Zunächst wird eine gleichverteilte Dreiecksfolge betrachtet. In der folgenden Abbildung kann sowohl das Dreieckssignal $s(t)$ als auch die zugehörige Verteilungsdichte $p_s(x)$ betrachtet werden. Ebenso kann das entstehende Signal als Audiofile angehört werden.
%% Cell type:code id: tags:
``` python
F = 500 # frequency
s = tri_sum(2*F*t); # sum of triangles
fig, axs = plt.subplots(1, 2);
ax = axs[0]; ax.plot(1000*t, s, 'rwth');
ax.set_xlim([-4.5,4.5]); ax.set_ylim([-0.1,1.1]);
ax.set_xlabel(r'$\rightarrow t$ [ms]'); ax.set_ylabel(r'$\uparrow s(t)$'); ient_axis(ax);
ax = axs[1]; ax.plot(x, rect(x-1/2), 'rwth');
ax.set_xlim([-0.25,1.25]); ax.set_ylim([-0.1,1.1]);
ax.set_xlabel(r'$\rightarrow x$'); ax.set_ylabel(r'$\uparrow p_s(x)$'); ient_axis(ax);
ient_audio_play(s, fs)
```
%% Cell type:markdown id: tags:
Als nächstes wird gleichverteiltes weißes Rauschen betrachtet, welches dieselbe Verteilungsdichtefunktion hat. Hört man sich dieses Signal ebenfalls an, ist zu bemerken, dass die Signale trotz gleicher Verteilungsdichtefunktion sehr unterschiedlich sind.
%% Cell type:code id: tags:
``` python
s = np.random.uniform(0, 1, len(t)); # sample uniform distribution between smin = 0 and smax = 1
# Plot
fig, axs = plt.subplots(1, 2);
ax = axs[0]; ax.plot(1000*t, s, 'rwth');
ax.set_xlim([-4.5,4.5]); ax.set_ylim([-0.1,1.1]);
ax.set_xlabel(r'$\rightarrow t$'); ax.set_ylabel(r'$\uparrow {}^k s(t)$'); ient_axis(ax);
ax = axs[1]; ax.plot(x, rect(x-1/2), 'rwth');
ax.set_xlim([-0.25,1.25]); ax.set_ylim([-0.1,1.1]);
ax.set_xlabel(r'$\rightarrow x$'); ax.set_ylabel(r'$\uparrow p_s(x)$'); ient_axis(ax);
ient_audio_play(s, fs)
```
%% Cell type:markdown id: tags: