Skip to content

Commit

Permalink
Add more plots for Laplace transform
Browse files Browse the repository at this point in the history
A plot demonstrating attenuating responses in the Laplace domain was
added. Also, a plot of the Laplace transform of the Fmajor4 chord was
added to demonstrate nonorthogonality.
  • Loading branch information
calcmogul committed Sep 4, 2018
1 parent 9a0c037 commit 2707d18
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ \section{The Fourier transform}
produce the original signal. That is, we create a sum of waveforms that are
multiplied by their respective contribution amount.

Think of an F major 4 chord which has the notes $F_4$ ($349.23\,Hz$), $A_4$
Think of an Fmajor4 chord which has the notes $F_4$ ($349.23\,Hz$), $A_4$
($440\,Hz$), and $C_4$ ($261.63\,Hz$). The waveform over time looks like figure
\ref{fig:fourier_chord}.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,37 @@ \section{The Laplace transform}
converges to zero. Figure \ref{fig:impulse_response_poles} shows this for
various points.

If we move the component frequencies in the Fmajor4 chord example parallel to
the real axis to $\sigma = -25$, the resulting time domain response attenuates
according to the decaying exponential $e^{-25t}$ (see figure
\ref{fig:laplace_chord_attenuating}).

\begin{svg}{build/code/laplace_chord_attenuating}
\caption{Fmajor4 chord at $\sigma = 0$ and $\sigma = -25$}
\label{fig:laplace_chord_attenuating}
\end{svg}

Note that this explanation as a basis isn't exact because the Laplace basis
isn't orthogonal (that is, the x and y coordinates affect each other and have
cross-talk). In the frequency domain, we had a basis of sine waves that we
represented as delta functions in the frequency domain. Each frequency
contribution was independent of the others. In the Laplace domain, this is not
the case; a pure exponential is $\frac{1}{s -a}$ (a rational function) instead
of a delta function. This function is nonzero at points that aren't actually
frequencies present in the time domain.
the case; a pure exponential is $\frac{1}{s - a}$ (a rational function where $a$
is a real number) instead of a delta function. This function is nonzero at
points that aren't actually frequencies present in the time domain. Figure
\ref{fig:laplace_chord_3d} demonstrates this, which shows the Laplace transform
of the Fmajor4 chord plotted in 3D.

\begin{svg}{build/code/laplace_chord}
\caption{Laplace transform of Fmajor4 chord plotted in 3D}
\label{fig:laplace_chord_3d}
\end{svg}

Notice how the values of the function around each component frequency decrease
according to $\frac{1}{\sqrt{x^2 + y^2}}$ in the $x$ and $y$ directions (in just
the $x$ direction, it would be $\frac{1}{x}$).

\subsection{The definition}

The Laplace transform of a function $f(t)$ is defined as

Expand All @@ -50,7 +73,7 @@ \section{The Laplace transform}
defined as $0$ for $t < 0$ and $1$ for $t \ge 0$.}, and exponential decay. We
can see that a derivative is equivalent to multiplying by $s$, and an integral
is equivalent to multiplying by $\frac{1}{s}$. We'll discuss the decaying
exponential shortly.
exponential in subsection \ref{subsec:poles_and_zeroes}.

\begin{booktable}
\begin{tabular}{|ccc|}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ \section{Transfer functions}
\end{equation}

\subsection{Poles and zeroes}
\label{subsec:poles_and_zeroes}

The roots of factors in the numerator of a transfer function are called
\textit{zeroes} because they make the transfer function approach zero. Likewise,
the roots of factors in the denominator of a transfer function are called
\textit{poles} because they make the transfer function approach infinity; on a
3D graph, these look like the poles of a circus tent. See figure
\ref{fig:tf_3d}.
3D graph, these look like the poles of a circus tent (see figure
\ref{fig:tf_3d}).

When the factors of the denominator are broken apart using partial fraction
expansion into something like $\frac{A}{s + a} + \frac{B}{s + b}$, the constants
Expand Down
93 changes: 93 additions & 0 deletions code/laplace_chord.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env python3

# Avoid needing display if plots aren't being shown
import sys

if "--noninteractive" in sys.argv:
import matplotlib as mpl

mpl.use("svg")
import latexutils

import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import math
import numpy as np

plt.rc("text", usetex=True)


def sin_tf(freq, s):
return freq / ((s - freq * 1j) * (s + freq * 1j))


def clamp(val, low, high):
return max(low, min(val, high))


def main():
f_f = 349.23
f_a = 440
f_c = 261.63

T = 0.000001
xlim = [0, 0.05]
ylim = [-3, 3]
x = np.arange(xlim[0], xlim[1], T)
plt.xlim(xlim)
plt.ylim(ylim)

yf = np.sin(f_f * 2 * math.pi * x)
ya = np.sin(f_a * 2 * math.pi * x)
yc = np.sin(f_c * 2 * math.pi * x)
ysum = yf + ya + yc
ysum_attenuating = ysum * np.exp(-25 * x)

num_plots = 2

plt.subplot(num_plots, 1, 1)
plt.ylim(ylim)
plt.ylabel("Fmaj4 ($\sigma = 0$)")
plt.plot(x, ysum)
plt.gca().axes.get_xaxis().set_ticks([])

plt.subplot(num_plots, 1, 2)
plt.ylim(ylim)
plt.ylabel("Attenuating Fmaj4 ($\sigma = -25$)")
plt.plot(x, ysum_attenuating)
plt.gca().axes.get_xaxis().set_ticks([])

plt.xlabel("$t$")

if "--noninteractive" in sys.argv:
latexutils.savefig("laplace_chord_attenuating")

x, y = np.mgrid[-150.0:150.0:500j, 200.0:500.0:500j]

# Need an (N, 2) array of (x, y) pairs.
xy = np.column_stack([x.flat, y.flat])

z = np.zeros(xy.shape[0])
for i, pair in enumerate(xy):
s = pair[0] + pair[1] * 1j
h = sin_tf(f_f, s) * sin_tf(f_a, s) * sin_tf(f_c, s)
z[i] = clamp(math.sqrt(h.real ** 2 + h.imag ** 2), -30, 30)
z = z.reshape(x.shape)

fig = plt.figure(2)
ax = fig.add_subplot(111, projection="3d")
ax.plot_surface(x, y, z, cmap=cm.coolwarm)
ax.set_xlabel("$Re(\sigma)$")
ax.set_ylabel("$Im(j\omega)$")
ax.set_zlabel("$H(s)$")
ax.set_zticks([])

if "--noninteractive" in sys.argv:
latexutils.savefig("laplace_chord_3d")
else:
plt.show()


if __name__ == "__main__":
main()

0 comments on commit 2707d18

Please sign in to comment.