Example: Animated illustration of the convolution of two functions.

Published 2010-03-31 | Author: Berteun Damman

A convolution is an operation on two functions that produces a third function, the result can be thought of as a blending, or weighted average of both functions. The result has various interpretations; this particular example can be seen as the convolution of two block waves, or for example, the convolution of two independent uniform probability density functions; the convolution represents the pdf of the sum.

Frame by frame the value of the convolution is computed; note that f*g is a function of t for every t we draw f(τ), g(t - τ), and the product f(τ)g(t - τ), this drawn in yellow. The area of this product, which can be thought of as ‘overlap’, is the outcome of the integral. The value of t is indicated by the dashed green line. Note however that in the top graph g is drawn as a function of τ for a certain value of t.

For more information, see:

Download as: [PDF] [TEX]  •  [Open in Overleaf]

Animated illustration of the convolution of two functions.

Do you have a question regarding this example, TikZ or LaTeX in general? Just ask in the LaTeX Forum.
Oder frag auf Deutsch auf TeXwelt.de. En français: TeXnique.fr.

% Animated illustration of the convolution of two functions.
% Author: Berteun Damman
%
% A convolution is an operation on two functions that produces a third
% function, the result can be thought of as a blending, or weighted
% average of both functions. The result has various interpretations; this
% particular example can be seen as the convolution of two block waves,
% or for example, the convolution of two independent uniform probability
% density functions; the convolution represents the pdf of their sum.

\documentclass{article}
\usepackage{tikz,animate}
\tikzset{overlap/.style={fill=yellow!30},
    block wave/.style={thick},
    function f/.style={block wave, red!50},
    function g/.style={block wave, green!50},
    convolution/.style={block wave, blue!50},
    function g position/.style={function g, dashed, semithick},
    major tick/.style={semithick},
    axis label/.style={anchor=west},
    x tick label/.style={anchor=north, minimum width=7mm},
    y tick label/.style={anchor=east},
}
\pgfkeys{/pgf/number format/.cd,fixed,precision=1}

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\begin{document}
    \newcommand{\mainaxis}{
        % Main axis
        \draw (-2, 0) -- (2, 0) (0, 0) -- (0, 1.15);

        % Small tickmarks on the x axis
        \foreach \x in {-2,-1.9,...,2} {
            \draw (\x, 0) -- (\x, -0.8pt);
        }

        % Labels on the $x$ axis; the llap makes the label center on the
        % number without the minus.
        \foreach \x/\label in {-2/\llap{$-$}2,-1/\llap{$-$}1,0/0,1/1,2/2} {
            \node[x tick label] at (\x, 0) {$\label$};
            \draw[major tick] (\x, 0) -- (\x, -1.25pt);
        }

        % Y tick mark.
        \draw[major tick] (-1.25pt,.5) -- (0,.5);

        % Y labels.
        \node[y tick label] at (0,.5) {$\frac{1}{2}$};
        \node[y tick label] at (0,1) {$1$};
    }

    \def\yshift{-2cm} % Shift of the lower axis
    \newcommand{\drawaxes}{
        \mainaxis
        \node[axis label] at (2,0) {$\scriptstyle \tau$};

        % Second axis, where the convultion will be drawn.
        \begin{scope}[yshift=\yshift]
            \foreach \y in {0.1,0.2,...,1.0}
                \draw[black!20] (-2,\y) -- (2,\y);
            \mainaxis
            \node[axis label] at (2,0) {$\scriptstyle t$};
        \end{scope}

        \begin{pgfonlayer}{foreground}
            \node at (0,1.25) {$f$};
            \node[anchor=base] at (0,-.55)
                {$f*g =\!\!\displaystyle\int\limits_{-\infty}^{\infty}
                    \!\!f(\tau)g(t-\tau)\,d\tau$};
        \end{pgfonlayer}

        \draw[major tick] (-1.25pt,.5) -- (0,.5) (-1.25pt,1) -- (0,1);

        % f(\tau) is basically fixed.
        \draw[function f] (-0.5, 0) -- +(0,1) -- +(1,1) -- +(1,0);
        \clip (-2,-2) rectangle (2, 1.75);
    }

    \newcommand{\drawg}[1]{
        \draw[function g] (#1,0) ++(-0.5, 0) -- +(0,1) -- +(1,1) -- +(1,0);
        \draw[function g position] (#1,1.4) -- (#1,\yshift);
        \node[fill=white] at (#1, 1.25) {$g$};

        % We now slightly abuse \ifdim to determine whether
        % there's an overlap.
        \ifdim#1pt>-1pt\ifdim#1pt<1.01pt
            % Draw legend.
            \fill[overlap] (-2,1.51) rectangle +(0.15,0.15);
            % The right side of f overlaps with the left side of g:
            % 'entering'
            \ifdim#1pt<0pt
                \node[anchor=west] at (-1.85, 1.575)
                    {$f(\tau)g(\pgfmathprintnumber{#1} - \tau$)};
                \begin{pgfonlayer}{background}
                    \fill[overlap] (-.5,0) rectangle (#1+.5,1);
                \end{pgfonlayer}
                \draw[convolution] (-1,\yshift) -- (#1, \yshift+1cm+#1 cm);
            \else
                % The left side of f overlaps with the right side of g:
                % 'leaving'
                \node[anchor=west] at (-1.85, 1.575)
                    {$f(\tau)g(\pgfmathprintnumber{#1} - \tau$)};
                \begin{pgfonlayer}{background}
                    \fill[overlap] (#1-.5,0) rectangle (.5,1);
                \end{pgfonlayer}
                \draw[convolution] (-1,\yshift) -- +(1, 1) --
                    (#1,\yshift+1cm-#1 cm);
            \fi
        \else
            % 'g' is completely past 'f', draw the result.
            \draw[convolution] (-1,\yshift) -- +(1,1) -- +(2,0);
        \fi\fi
    }

    \begin{animateinline}[controls,
        autoplay,buttonsize=1.2em,
        buttonbg=0.6:0.6:1,buttonfg=0.2:0.2:1,
        begin={\begin{tikzpicture}[scale=2]\drawaxes},
        end={\end{tikzpicture}}]{8}

        % Generate frames for -2 ... 2
        \xdef\pos{-2}
        \whiledo{\lengthtest{\pos pt < 2.1 pt}}{
            \drawg{\pos}\newframe
            \pgfmathsetmacro{\pos}{\pos + 0.1}
            \xdef\pos{\pos}
        }

        \drawg{\pos}
    \end{animateinline}
\end{document}

Comments

  • #1 Cédric André, April 7, 2010 at 11:13 a.m.

    Absolutely amazing ! Thank you !

  • #2 Miguel Bazdresch, April 22, 2010 at 4:10 p.m.

    I have tried opening the pdf in evince and xpdf, and I see the controls at the bottom, but I can't see the animation -- the buttons are not responsive. What do I need to do to see it?

  • #3 Kjell Magne Fauske, April 22, 2010 at 5:30 p.m.

    @Miguel: AFAIK you have to use Acrobat to view the animation.

  • #4 Miguel Bazdresch, April 22, 2010 at 6:51 p.m.

    Thanks for the information Kjell. I haven't been able to get acroread to run on my 64-bit linux, but I'll get there eventually.

  • #5 Won, May 3, 2010 at 2:30 a.m.

    Amazing! Any way to view the animation WITHOUT Adobe?

  • #6 Thommy M. Malmström, July 15, 2010 at 3:43 p.m.

    Works fine with AcroRead on 64-bit OpenSolaris 2009.06_134, but I get some errors building the pdf from TeX.

    ! Package pgfkeys Error: I do not know the key '/pgf/number format/fixed' and I am going to ignore it. Perhaps you misspelled it.

    See the pgfkeys package documentation for explanation. Type H for immediate help. ...

    l.58 ...{/pgf/number format/.cd,fixed,precision=1}

    Any hints?

  • #7 B.J. Muth, April 22, 2013 at 1:02 p.m.

    As of today, the animation is still problematic with Acrobat on Windows, within or outside Mozilla, though it works fine with PDF-XChange Viewer. There's no better way to illustrate convolution, congratulations.

Adding comments is currently not enabled.

Features
Tags
Scientific and technical areas

Cookbook

LaTeX Beginners Guide

Limited discount 50%
coupon code tDRet6Y

Creative Commons License