Commit 095aae6f authored by Hafiz Emin Kosar's avatar Hafiz Emin Kosar
Browse files

modularization

parent 93dc3561
%% Cell type:code id: tags:
``` python
%matplotlib notebook
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 src.laplace.laplace_plot import pzPoint, pzPlot
from src.laplace.inline_plot import inline_plot
from src.funcs import calc_Hf, calc_ht
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
```
%% Cell type:code id: tags:
``` python
inline_plot('right')
```
pp = [1+1j]; pz = [2+1j]; ord_p = [2]; ord_z = [1]
roc = [np.amax(np.real(pp)), 12] # rechtsseitige Konvergenz
# Übertragungsfunktion im Laplace-Bereich
fig,ax = plt.subplots(1,1)
ient_axis(ax)
ax.set_xlim(-6, 6); ax.set_ylim(-6, 6)
ax.plot(np.real(pp), np.imag(pp), **ient_style_poles); ax.plot(np.real(pp), -np.imag(pp), **ient_style_poles)
ax.plot(np.real(pz), np.imag(pz), **ient_style_zeros); ax.plot(np.real(pz), -np.imag(pz), **ient_style_zeros)
ient_plot_roc(ax, roc)
# print orders
for index, order in enumerate(ord_p+ord_z):
if order > 1:
ax.text(np.real((pp+pz)[index]), np.imag((pp+pz)[index]), '(' + str(order) + ')', color='black')
ax.text(np.real((pp+pz)[index]), -np.imag((pp+pz)[index]), '(' + str(order) + ')', color='black')
H0 = 1
# Impulsantwort im Zeitbereich
t = np.linspace(-6,6,1024)
h, _ = calc_ht(t, H0, pp, pz, ord_p, ord_z, roc)
fig,ax = plt.subplots(1,1)
ax.plot(t,np.real(h), **ient_style_graph); ax.set_xlabel(r'$t$'); ax.set_ylabel(r'$h(t)$'); # won't work with dirac
# Frequenzbereich
f = np.linspace(-6,6,1024)
H = calc_Hf(f, H0, pp, pz, ord_p, ord_z)
fig,ax = plt.subplots(1,1)
ax.plot(f, H, **ient_style_graph); ax.set_xlabel(r'$f$'); ax.set_ylabel(r'$H(f) / dB$');
%% Cell type:code id: tags:
``` python
inline_plot('left')
```
%% Cell type:code id: tags:
``` python
%matplotlib notebook
%matplotlib notebook
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:code id: tags:
``` python
# update_signal todos beachten
```
%% Cell type:code id: tags:
``` python
HBox([left_box, right_box])
```
%% Cell type:code id: tags:
``` python
```
......
......@@ -95,54 +95,39 @@ def getSignalType(array):
signal_type = signal_type + 'dirac'
return signal_type
def calc_laplace(t=np.linspace(-6, 6, num=1024), f = np.linspace(-6, 6, num=1024), H0=1, pp=np.array([]), pz=np.array([]), ord_p=np.array([]),
ord_z=np.array([]), roc = [-12, 12]):
def calc_Hf(f=np.linspace(-6, 6, num=1024), H0=1, pp=np.array([]), pz=np.array([]), ord_p=np.array([]),
ord_z=np.array([])):
"""
Frequenzbereich
"""
Calculates time domain and frequency domain function
Parameters
----------
t : array_like
time array
f: array_like
frequency array (mostly equal to t)
H0: int
self explaining
zaehler = H0 * np.ones(f.shape)
pp: array_like
poles in pz plot
for i in range(0, len(pz)):
for j in range(1, ord_z[i] + 1):
zaehler = zaehler * (1j * f - pz[i])
if np.abs(np.imag(pz[i])) > 0:
zaehler = zaehler * (1j * f - np.conj(pz[i]))
pz: array_like
zeroes in pz plot
#####
ord_p: array_like
poles' orders in pz plot
nenner = np.ones(f.shape)
ord_z: array_like
zeroes' orders in pz plot
for i in range(0, len(pp)):
for j in range(1, ord_p[i] + 1):
nenner = nenner * (1j * f - pp[i])
if np.abs(np.imag(pp[i])) > 0:
nenner = nenner * (1j * f - np.conj(pp[i]))
roc: array_like
range of convergence
H = 20 * np.log10(np.maximum(2e-16, np.abs(zaehler / nenner)))
Returns
-------
h: numpy array
calculated time domain signal
return H
H: numpy array
calculated frq domain signal
def calc_ht(t=np.linspace(-6, 6, num=1024), H0=1, pp=np.array([]), pz=np.array([]),
ord_p=np.array([]), ord_z=np.array([]), roc=[-12, 12]): # TODO - roc ninf und inf?
type: string
'dirac' - if h contains dirac
'' - if not
"""
# Fehlerbehandlung: Mehr Pol-/Nullstellen als Grade?
# -> raise ValueError("Arrays must have the same size")
type = ''
......@@ -172,31 +157,7 @@ def calc_laplace(t=np.linspace(-6, 6, num=1024), f = np.linspace(-6, 6, num=1024
GradPolstellen = GradPolstellen.astype(int)
GradNullstellen = GradNullstellen.astype(int)
"""
Frequenzbereich
"""
#####
zaehler = H0 * np.ones(f.shape)
for i in range(0, len(pz)):
for j in range(1, ord_z[i] + 1):
zaehler = zaehler * (1j * f - pz[i])
if np.abs(np.imag(pz[i])) > 0:
zaehler = zaehler * (1j * f - np.conj(pz[i]))
#####
nenner = np.ones(f.shape)
for i in range(0, len(pp)):
for j in range(1, ord_p[i] + 1):
nenner = nenner * (1j * f - pp[i])
if np.abs(np.imag(pp[i])) > 0:
nenner = nenner * (1j * f - np.conj(pp[i]))
#####
left = roc[0]
right = roc[1]
IstKausalerPol = np.array([])
......@@ -207,18 +168,8 @@ def calc_laplace(t=np.linspace(-6, 6, num=1024), f = np.linspace(-6, 6, num=1024
elif np.real(point) <= left:
IstKausalerPol = np.append(IstKausalerPol, True)
#####
H = 20 * np.log10(np.maximum(2e-16, np.abs(zaehler / nenner)));
"""
Zeitbereich
"""
if np.sum(GradPolstellen) >= np.sum(GradNullstellen):
# TODO - t_min, t_max global
......@@ -268,7 +219,7 @@ def calc_laplace(t=np.linspace(-6, 6, num=1024), f = np.linspace(-6, 6, num=1024
b[-1:, 0] = p
try:
A_inv = np.around(np.linalg.inv(A), 8) # precision
A_inv = np.around(np.linalg.inv(A), 8) # precision
except np.linalg.LinAlgError:
# Not invertible.
pass
......@@ -305,14 +256,16 @@ def calc_laplace(t=np.linspace(-6, 6, num=1024), f = np.linspace(-6, 6, num=1024
type = 'dirac'
else:
#Zaehlergrad größer als Nennergrad. Keine Partialbruchzerlegung möglich
# Zaehlergrad größer als Nennergrad. Keine Partialbruchzerlegung möglich
h = np.array([np.NaN for x in t])
return h, H, type
return h, type
def calc_dft(t, s, length, k_max):
s_shifted = np.concatenate((s[int(length / 2):], s[:int(length / 2)]))
S = np.fft.fft(s_shifted) / length
# fft = np.fft.fftshift(fft)
Y = np.concatenate((S[-k_max:], S[:k_max + 1]))
return Y, S
......@@ -54,7 +54,7 @@ class pzPlot():
self.length = 1024
self.t = np.linspace(-6, 6, num=self.length)
self.f = np.linspace(-6, 6, num=self.length) # TODO - f statt omega
self.f = np.linspace(-6, 6, num=self.length)
self.open_figure()
......@@ -84,7 +84,7 @@ class pzPlot():
def open_figure(self):
fig = plt.figure(figsize=(13, 13))
fig = plt.figure(figsize=(10, 9))
gs = gridspec.GridSpec(2, 2)
# First axis for plotting s and h
......@@ -189,16 +189,16 @@ class pzPlot():
if mode == 'p':
self.pp = np.append(self.pp, pPoint)
ind = self.pp.size - 1
plotstyle = "xk"
plotstyle = ient_style_poles
else:
self.pz = np.append(self.pz, pPoint)
ind = self.pz.size - 1
plotstyle = "ok"
plotstyle = ient_style_zeros
# Plot points
pPoint.h_point, = self.ax.plot(p.real, p.imag, plotstyle, mfc='none')
pPoint.h_point, = self.ax.plot(p.real, p.imag, **plotstyle, mfc='none')
if np.abs(p.imag) > 0: # plot complex conjugated poles/zeroes
pPoint.h_point_conj, = self.ax.plot(p.real, -p.imag, plotstyle, mfc='none')
pPoint.h_point_conj, = self.ax.plot(p.real, -p.imag, **plotstyle, mfc='none')
elif self.action == 'del':
return
......@@ -383,11 +383,11 @@ class pzPlot():
zeroes_order = np.array(list((x.order for x in self.pz)))
# TODO - butterworth? -> verändere H0 nicht
H0 = self.H0
roc = self.roc['sigma']
s_t, S_f, signal_type = func.calc_laplace(self.t, self.f, H0, poles, zeroes, poles_order, zeroes_order, roc)
s_t, signal_type = func.calc_ht(self.t, self.H0, poles, zeroes, poles_order, zeroes_order, roc)
S_f = func.calc_Hf(self.f, self.H0, poles, zeroes, poles_order, zeroes_order)
# process signals
# TODO - Das Ausrechnen von Minimal- und Maximalwerten für die Achsenlimitbestimmung dauert zu lange
......
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