Skip to content
Snippets Groups Projects
Commit cdcc9259 authored by Nicolas Ewald Alfons Horst's avatar Nicolas Ewald Alfons Horst
Browse files

update

parent 41682a49
No related branches found
No related tags found
No related merge requests found
%% Cell type:code id: tags:
```
# Copyright 2020 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
import matplotlib.pyplot as plt
from rwth_nb.plots import colors
import rwth_nb.plots.mpl_decorations as rwth_plt
from rwth_nb.misc.signals import *
from rwth_nb.misc.transforms import *
t,deltat = np.linspace(-10,10,50001, retstep=True) # t-axis
f,deltaf = np.linspace(-10,10,len(t), retstep=True) # f-axis
kMax = 16 # number of k values in sum for Sa(f)
# language settings
_ = lambda s: s
```
%% Cell type:markdown id: tags:
<div>
<img src="figures/rwth_ient_logo@2x.png" style="float: right;height: 5em;">
</div>
%% Cell type:markdown id: tags:
# Demonstrator Discrete Fourier Transformation
To start: In the menu: Run <span class="fa-chevron-right fa"></span> Select Run All Cells.
## Introduction
$s(t)$ is sampled with sampling rate $r$.
Discrete Fourier transform with $F = \frac{1}{M}$
%% Cell type:markdown id: tags:
$$
S_\mathrm{d}(k)
=
\sum_{n=0}^{M-1} s_\mathrm{d}(n) \mathrm{e}^{-\mathrm{j}2\pi kFn} \quad k=0,\ldots,M-1 \text{ ,}
$$
%% Cell type:markdown id: tags:
where $s_\mathrm{d}(n)$ by $M$ periodic, discrete time signal with $t = n \cdot \frac{1}{r}$.
%% Cell type:markdown id: tags:
For transformation back into the time domain the following applies
%% Cell type:markdown id: tags:
$$
s_\mathrm{d}(n)
=
\frac{1}{M} \sum_{k=0}^{M-1}S_\mathrm{d}(k) \mathrm{e}^{\mathrm{j}2\pi kFn} \quad n=0,\ldots,M-1 \text{ ,}
$$
wobei
%% Cell type:markdown id: tags:
with
%% Cell type:markdown id: tags:
$f = k \cdot \frac{r}{M}$.
%% Cell type:code id: tags:
```
M = 24; # period of discrete signal
r = 4; # sampling rate
n = np.arange(M) # discrete time axis
sd = tri(n/r) + tri((n-M)/r) # discrete signal sd(n)
F = 1/M
Sd = np.zeros_like(sd, dtype=np.complex)
for k in np.arange(M): # very slow computation for teaching purpose! Fasten your seatbelts with FFT :)
Sd[k] = np.sum(sd * np.exp(-2j*np.pi*k*F*n))
#Sd = np.fft.fft(sd)
Sd = np.real(Sd) # discard super small imaginary part (1e-16)
# Plot
fig,axs = plt.subplots(2,1)
ax = axs[0]; rwth_plt.stem(ax, n, sd);
ax.set_xlabel(r'$\rightarrow n$'); ax.set_ylabel(r'$\uparrow s_\mathrm{d}(n)$')
rwth_plt.axis(ax);
ax = axs[1]; rwth_plt.stem(ax, np.arange(M), Sd/r);
ax.set_xlabel(r'$\rightarrow k$'); ax.set_ylabel(r'$\uparrow S_\mathrm{d}(k)/r$')
rwth_plt.axis(ax); fig.tight_layout()
```
%% Cell type:markdown id: tags:
## Demonstrator
%% Cell type:code id: tags:
```
def decorate_second_axis(ax):
ax.spines['top'].set_position(('axes',.9)); ax.spines['right'].set_color('none'); ax.spines['left'].set_color('none'); ax.spines['bottom'].set_color('none');
ax.xaxis.set_label_coords(.98,1); ax.xaxis.label.set_horizontalalignment('right')
fig, axs = plt.subplots(2, 1, **rwth_plt.landscape); #fig.tight_layout()
highlight_rect_style = {'facecolor': "none", 'edgecolor': 'rwth:orange', 'linestyle':'--', 'linewidth':2.0}
@widgets.interact( r = widgets.IntSlider(min=0, max=10, step=2, value=0, description='$r$ [Hz]'),
Mbr = widgets.IntSlider(min=0, max=10, step=2, value=0, description='$M/r$'))
def update_plots(r, Mbr):
M = r*Mbr
global n, snT, k, SkF
# Continuous functions s(t) and S(f)
s = tri
S = lambda f: si(np.pi*f) ** 2
# Ideal sampling
Sa_f = np.zeros_like(S(f))
nT = []; snT = nT; n = nT;
if r > 0:
T = 1/r
# Sampled function s(n)
nT, snT = sample(t, s(t), T); n = nT/T;
# Sampled continuous spectrum S_a(f)
for k in np.arange(-kMax, kMax+1): # evaluate infinite sum only for 2*kMax+1 elements
Sa_f += S(f-k/T)
#Sa_f = Sa_f/T # normalize here
# Periodic copies of s(n)
kF = []; SkF = kF; k = kF;
sd = np.zeros_like(snT)
if M > 0:
F = 1/M # in Hz
kF, SkF = sample(f, Sa_f, r*F); k = kF/F/r
for d in np.arange(-kMax, kMax+1): # evaluate infinite sum only for 2*kMax+1 elements
sd += s((n-d*M)*T)
display('M={}'.format(M))
# Plot
if not axs[0].lines: # Call plot() and decorate axes. Usually, these functions take some processing time
ax = axs[0]; ax.set_title(_('time domain'));
ax.plot(t, s(t), 'k', label='$s(t)$');
ax.set_xlabel(r'$\rightarrow t $ [s]')
ax.set_xlim([-5,10]); ax.set_ylim([-.09, 1.19]); ax.legend(loc='upper right', bbox_to_anchor=(1.0, 0.8)); rwth_plt.axis(ax);
axn = ax.twiny(); rwth_plt.stem(axn, [1], [1], color='rwth:blue', label=r'$s(n)$');
axn.set_xlabel(r'$\rightarrow n$'); decorate_second_axis(axn);
axn.legend(loc='upper right', bbox_to_anchor=(1.0, 0.6));
axn.fill_between([-.1, M-1+.1], -.05, 1.05, **highlight_rect_style)
ax = axs[1]; ax.set_title(_('frequency domain'));
ax.plot(f, S(f), 'k', label='$S(f)$')
ax.plot(f, Sa_f, 'rwth:red', label='$S_\mathrm{a}(f)/r$')
ax.set_xlabel(r'$\rightarrow f $ [Hz]')
ax.set_xlim([-5,10]); ax.set_ylim([-.09, 1.19]); ax.legend(loc='upper right', bbox_to_anchor=(1.0, 0.8)); rwth_plt.axis(ax);
axk = ax.twiny(); rwth_plt.stem(axk, [1], [1], label=r'$S_\mathrm{d}(k)/r$');
axk.set_xlabel(r'$\rightarrow k$'); decorate_second_axis(axk);
axk.legend(loc='upper right', bbox_to_anchor=(1.0, 0.5));
axk.fill_between([-.1, M-1+.1], -.05, 1.05, **highlight_rect_style)
else: # Update only the plot lines themselves. Should not take too much processing time
ax = axs[0] # time domain
axn = fig.axes[2];
if r > 0:
if len(axn.collections) > 1: axn.collections[1].remove()
if M == 0:
rwth_plt.stem_set_data(axn.containers[0], n, snT); #axn.containers[0].set_label(r'$s(n)$')
else:
rwth_plt.stem_set_data(axn.containers[0], n, sd); #axn.containers[0].set_label(r'$s_\mathrm{d}(n)$')
axn.fill_between([-.1, M-1+.1], -.05, 1.05, **highlight_rect_style)
ax = axs[1] # frequency domain
ax.lines[1].set_ydata(Sa_f)
axk = fig.axes[3];
if M > 0 and r > 0:
if len(axk.collections) > 1: axk.collections[1].remove()
axk.fill_between([-.1, M-1+.1], -.05, 1.05, **highlight_rect_style)
rwth_plt.stem_set_data(axk.containers[0], k, SkF)
axn = fig.axes[2]; axn.set_visible(r > 0)
axk = fig.axes[3]; axk.set_visible(M > 0 and r > 0)
if r > 0:
axn.set_xlim((ax.get_xlim()[0]*r,ax.get_xlim()[1]*r))
if M > 0:
axk.set_xlim((ax.get_xlim()[0]*M/r,ax.get_xlim()[1]*M/r))
```
%% 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, 2020, Institut für Nachrichtentechnik, RWTH Aachen University.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment