Characterization of Systems in the Time Domain

This Jupyter notebook is part of a collection of notebooks in the bachelors module Signals and Systems, Communications Engineering, Universität Rostock. Please direct questions and suggestions to


As shown in the previous Section, the convolution is an important operation in the theory of signals and systems. It also shows up in a wide range of other physical and mathematical problems. The convolution operation is therefore of general interest and well known. The properties of the convolution are reviewed, followed by a widely used graphical interpretation of the operation.

The convolution of two signals $x(t)$ and $h(t)$ is defined as

\begin{equation} (x * h)(t) = x(t) * h(t) = \int_{\tau = -\infty}^{\tau=\infty} x(\tau) \cdot h(t - \tau) \; d\tau = \int_{\tau=-\infty}^{\tau=\infty} x(t - \tau) \cdot h(\tau) \; d\tau \end{equation}

where $*$ is a common short-hand notation of the convolution.


For the signals $x(t)$, $h(t)$, $g(t) \in \mathbb{C}$ the convolution shows the following properties

  1. The Dirac impulse is the identity element of the convolution \begin{equation} x(t) * \delta(t) = x(t) \end{equation}

  2. The convolution is commutative \begin{equation} x(t) * h(t) = h(t) * x(t) \end{equation}

  3. The convolution is associative \begin{equation} \left[ x(t) * h(t) \right] * g(t) = x(t) * \left[ h(t) * g(t) \right] \end{equation}

  4. The convolution is distributive \begin{equation} x(t) * \left[ h(t) + g(t) \right] = x(t) * h(t) + x(t) * g(t) \end{equation}

  5. Multiplication with a scalar $a \in \mathbb{C}$ \begin{equation} a \cdot \left[ x(t) * h(t) \right] = \left[ a \cdot x(t) \right] * h(t) = x(t) * \left[ a \cdot h(t) \right] \end{equation}

  6. Derivative of the convolution \begin{equation} \frac{d}{dt} \left[ x(t) * h(t) \right] = \frac{d x(t)}{dt} * h(t) = x(t) * \frac{d h(t)}{dt} \end{equation}

The first property is a consequence of the sifting property of the Dirac pulse, the second to fifth property can be proven by considering the convolution integral and the sixth property follows from the properties of the derivative of the Dirac delta function.

Graphical Interpretation

The convolution is commonly interpreted in a graphical manner. This interpretation provides valuable insights into its calculation and allows to derive a first estimate of the result. The calculation of the convolution integral

\begin{equation} y(t) = \int_{\tau = -\infty}^{\tau = \infty} x(\tau) \cdot h(t-\tau) \; d\tau \end{equation}

can be decomposed into four subsequent operations:

  1. substitute $t$ by $\tau$ in both $x(t)$ and $h(t)$,

  2. time-reverse $h(\tau)$ (mirroring at vertical axis),

  3. shift $h(-\tau)$ by $t$ to yield $h(t - \tau)$, i.e. a shift to right for $t>0$ or a shift to left for $t<0$,

  4. check for which $t = -\infty \dots \infty$ the mirrored & shifted $h(t - \tau)$ overlaps with $x(\tau)$, calculate the specific integral (i.e. the area of the overlap) for all these relevant $t$ to yield $y(t)$

The graphical interpretation of the convolution is illustrated by means of the following example.


The convolution $y(t) = x(t) * h(t)$ is illustrated using the particular signals

\begin{align} h(t) &= e^{-t} \\ x(t) &= \frac{3}{4} \cdot \text{rect} \left(t - \frac{1}{2}\right) \end{align}

Before proceeding, helper functions for the rectangular signal and plotting of the signals are defined

In [1]:
import sympy as sym

t, tau = sym.symbols('t tau', real=True)

class rect(sym.Function):

    def eval(cls, arg):
        return sym.Heaviside(arg + sym.S.Half) - sym.Heaviside(arg - sym.S.Half)

def plot_signals(x_axis, x, h, ylabel, xlabel):
    p1 = sym.plot(x, (x_axis, -5, 5), show=False,
                  line_color='C0', ylabel=ylabel, xlabel=xlabel)
    p2 = sym.plot(h, (x_axis, -5, 5), show=False, line_color='C1')

Now lets define and plot the signals. In the following, the impulse response $h(t)$ is illustrated by the blue graph and the input signal $x(t)$ by the orange graph.

In [2]:
h = sym.exp(-t) * sym.Heaviside(t)
x = sym.Rational(3, 4) * rect(t - 1/2)

plot_signals(t, x, h, r'$h(t)$, $x(t)$', r'$t$')
2021-04-27T15:57:02.326930 image/svg+xml Matplotlib v3.3.4,

The first step is to substitute $t$ by $\tau$ to yield $h(\tau)$ and $x(\tau)$. Note, the horizontal axis of the plot represents now $\tau$, which is our temporal helper variable for the integration

In [3]:
h1 = h.subs(t, tau)
x1 = x.subs(t, tau)

plot_signals(tau, x1, h1, r'$h(\tau)$, $x(\tau)$', r'$\tau$')
2021-04-27T15:57:02.858600 image/svg+xml Matplotlib v3.3.4,

The second step is to time-reverse $h(\tau)$ to yield $h(-\tau)$

In [4]:
h2 = h.subs(t, -tau)

plot_signals(tau, x1, h2, r'$h(-\tau)$, $x(\tau)$', r'$\tau$')
2021-04-27T15:57:03.411525 image/svg+xml Matplotlib v3.3.4,

In the third step the impulse response $h(-\tau)$ is shifted by $t$ to yield $h(t - \tau)$. The temporal shift is performed to the right for $t>0$ and to the left for $t<0$.

In [5]:
h3 = h.subs(t, t-tau)

For the fourth step it is often useful to split the calculation of the result according to the overlap between $h(t-\tau)$ and $x(\tau)$. For the given particular signals three different cases may be considered

  1. no overlap for $t<0$,
  2. partial overlap for $0 \leq t < 1$, and
  3. full overlap for $t > 1$ (note that the chosen impulse response decays asymptotically).

The first case, no overlap, is illustrated for $t = -2$

In [6]:
plot_signals(tau, x1, h3.subs(t, -2), r'$h(t-\tau)$, $x(\tau)$', r'$\tau$')
2021-04-27T15:57:03.935897 image/svg+xml Matplotlib v3.3.4,

From this it becomes clear that the convolution result for the first case is given as

\begin{equation} y(t) = 0 \qquad \text{for } t < 0 \end{equation}

The second case, partial overlap, is illustrated for $t = \frac{1}{2}$

In [7]:
plot_signals(tau, x1, h3.subs(t, .5), r'$h(t-\tau)$, $x(\tau)$', r'$\tau$')
2021-04-27T15:57:04.450235 image/svg+xml Matplotlib v3.3.4,

Hence, for the second case the convolution integral degenerates to

\begin{equation} y(t) = \frac{3}{4}\int_{0}^{t} e^{-(t - \tau)} d\tau = \frac{3}{4} (1 - e^{-t}) \qquad \text{for } 0 \leq t < 1 \end{equation}

The third case, full overlap, is illustrated for $t = 3$

In [8]:
plot_signals(tau, x1, h3.subs(t, 3), r'$h(t-\tau)$, $x(\tau)$', r'$\tau$')
2021-04-27T15:57:04.984904 image/svg+xml Matplotlib v3.3.4,

For the third case the convolution integral degenerates to

\begin{equation} y(t) = \frac{3}{4} \int_{0}^{1} e^{-(t - \tau)} d\tau = \frac{3}{4} (e - 1) e^{-t} \qquad \text{for } t \geq 1 \end{equation}

The overall result is composed from the three individual results. As alternative and in order to plot the result, the convolution integral is evaluated in SymPy

In [9]:
y = sym.integrate(h.subs(t, t-tau) * x.subs(t, tau), (tau, 0, t))
sym.plot(y, (t, 0, 6), ylabel=r'$y(t)$', line_color='C2');
2021-04-27T15:57:06.941256 image/svg+xml Matplotlib v3.3.4,

The entire process is illustrated in the following animation. The upper plot shows the integrands $h(t-\tau)$ and $x(\tau)$ of the convolution integral, the lower plot the result $y(t) = x(t) * h(t)$ of the convolution. The red dot in the lower plot indicates the particular time instant $t$ for which the result of the convolution is computed. The filled red area in the upper plot illustrates the area below $x(\tau) \cdot h(t-\tau)$ for the same time instant. The area constitutes the result of the convolution integral. The time $t$ is varied in the animation.

In [10]:
import matplotlib.pyplot as plt
import numpy as np
from animation import animate_convolution
plt.rcParams['animation.html'] = 'jshtml'

anim = animate_convolution(x, h, y, t, tau, np.arange(-2, 5, .1), np.arange(-5, 5, 0.02))