# 20. Laplace transforms in SymPy¶

The Laplace transform is

$\mathcal{L}\{f(t)\} = \int_0^\infty f(t) e^{-st} \mathrm{d}s$
:

import sympy
sympy.init_printing()

:

import matplotlib.pyplot as plt
%matplotlib inline


Let’s define some symbols to work with.

:

t, s = sympy.symbols('t, s')
a = sympy.symbols('a', real=True, positive=True)


## 20.1. Direct evaluation¶

:

f = sympy.exp(-a*t)
f

:

$\displaystyle e^{- a t}$

We can evaluate the integral directly using integrate:

:

sympy.integrate(f*sympy.exp(-s*t), (t, 0, sympy.oo))

:

$\displaystyle \begin{cases} \frac{1}{s \left(\frac{a}{s} + 1\right)} & \text{for}\: \left|{\arg{\left(s \right)}}\right| \leq \frac{\pi}{2} \\\int\limits_{0}^{\infty} e^{- a t} e^{- s t}\, dt & \text{otherwise} \end{cases}$

## 20.2. Library function¶

This works, but it is a bit cumbersome to have all the extra stuff in there.

Sympy provides a function called laplace_transform which does this more efficiently. By default it will return conditions of convergence as well (recall this is an improper integral, with an infinite bound, so it will not always converge).

:

sympy.laplace_transform(f, t, s)

:

$\displaystyle \left( \frac{1}{a + s}, \ 0, \ \text{True}\right)$

If we want just the function, we can specify noconds=True.

:

F = sympy.laplace_transform(f, t, s, noconds=True)
F

:

$\displaystyle \frac{1}{a + s}$

We will find it useful to define a quicker version of this:

:

def L(f):
return sympy.laplace_transform(f, t, s, noconds=True)


Inverses are simple as well,

:

def invL(F):
return sympy.inverse_laplace_transform(F, s, t)

:

invL(F)

:

$\displaystyle e^{- a t} \theta\left(t\right)$

## 20.3. What is that θ?¶

The unit step function is also known as the Heaviside step function. We will see this function often in inverse laplace transforms. It is typeset as $$\theta(t)$$ by sympy.

:

sympy.Heaviside(t)

:

$\displaystyle \theta\left(t\right)$
:

sympy.plot(sympy.Heaviside(t)); Look at the difference between $$f$$ and the inverse laplace transform we obtained, which contains the unit step to force it to zero before $$t=0$$.

:

invL(F).subs({a: 2})

:

$\displaystyle e^{- 2 t} \theta\left(t\right)$
:

p = sympy.plot(f.subs({a: 2}), invL(F).subs({a: 2}),
xlim=(-1, 4), ylim=(0, 3), show=False)
p.line_color = 'red'
p.show() ## 20.4. Reproducing standard transform table¶

Let’s see if we can match the functions in the table

:

omega = sympy.Symbol('omega', real=True)
exp = sympy.exp
sin = sympy.sin
cos = sympy.cos
functions = [1,
t,
exp(-a*t),
t*exp(-a*t),
t**2*exp(-a*t),
sin(omega*t),
cos(omega*t),
1 - exp(-a*t),
exp(-a*t)*sin(omega*t),
exp(-a*t)*cos(omega*t),
]
functions

:

$\displaystyle \left[ 1, \ t, \ e^{- a t}, \ t e^{- a t}, \ t^{2} e^{- a t}, \ \sin{\left(\omega t \right)}, \ \cos{\left(\omega t \right)}, \ 1 - e^{- a t}, \ e^{- a t} \sin{\left(\omega t \right)}, \ e^{- a t} \cos{\left(\omega t \right)}\right]$
:

Fs = [L(f) for f in functions]
Fs

:

$\displaystyle \left[ \frac{1}{s}, \ \frac{1}{s^{2}}, \ \frac{1}{a + s}, \ \frac{1}{\left(a + s\right)^{2}}, \ \frac{2}{\left(a + s\right)^{3}}, \ \frac{\omega}{\omega^{2} + s^{2}}, \ \frac{s}{\omega^{2} + s^{2}}, \ \frac{a}{s \left(a + s\right)}, \ \frac{\omega}{\omega^{2} + \left(a + s\right)^{2}}, \ \frac{a + s}{\omega^{2} + \left(a + s\right)^{2}}\right]$

We can make a pretty good approximation of the table with a little help from pandas

:

from pandas import DataFrame

:

def makelatex(args):
return ["$${}$$".format(sympy.latex(a)) for a in args]

:

DataFrame(list(zip(makelatex(functions), makelatex(Fs))))

:

0 1
0 $$1$$ $$\frac{1}{s}$$
1 $$t$$ $$\frac{1}{s^{2}}$$
2 $$e^{- a t}$$ $$\frac{1}{a + s}$$
3 $$t e^{- a t}$$ $$\frac{1}{\left(a + s\right)^{2}}$$
4 $$t^{2} e^{- a t}$$ $$\frac{2}{\left(a + s\right)^{3}}$$
5 $$\sin{\left(\omega t \right)}$$ $$\frac{\omega}{\omega^{2} + s^{2}}$$
6 $$\cos{\left(\omega t \right)}$$ $$\frac{s}{\omega^{2} + s^{2}}$$
7 $$1 - e^{- a t}$$ $$\frac{a}{s \left(a + s\right)}$$
8 $$e^{- a t} \sin{\left(\omega t \right)}$$ $$\frac{\omega}{\omega^{2} + \left(a + s\right... 9$$e^{- a t} \cos{\left(\omega t \right)}\frac{a + s}{\omega^{2} + \left(a + s\right)...

## 20.5. More complicated inverses¶

Why doesn’t the table feature more complicated functions? Because higher-order rational functions can be written as sums of simpler ones through application of partial fractions expansion.

:

F = ((s + 1)*(s + 2)* (s + 3))/((s + 4)*(s + 5)*(s + 6))

:

F

:

$\displaystyle \frac{\left(s + 1\right) \left(s + 2\right) \left(s + 3\right)}{\left(s + 4\right) \left(s + 5\right) \left(s + 6\right)}$
:

F.apart(s)

:

$\displaystyle 1 - \frac{30}{s + 6} + \frac{24}{s + 5} - \frac{3}{s + 4}$

Even sympy can benefit from a little help sometimes. When we try to calculate the inverse of $$F$$ we get a bit of a nasty answer:

:

invL(F)

:

$\displaystyle 3 \left(e^{2 t} - 2 e^{t} + 1\right) e^{- 6 t} \theta\left(t\right) - 11 \left(2 e^{2 t} - 5 e^{t} + 3\right) e^{- 6 t} \theta\left(t\right) + 6 \left(8 e^{2 t} - 25 e^{t} + 18\right) e^{- 6 t} \theta\left(t\right) + \mathcal{L}^{-1}_{s}\left[\frac{s^{3}}{s^{3} + 15 s^{2} + 74 s + 120}\right]\left(t\right)$

Perhaps it looks better if we simplify?

:

invL(F).simplify()

:

$\displaystyle \mathcal{L}^{-1}_{s}\left[\frac{s^{3}}{s^{3} + 15 s^{2} + 74 s + 120}\right]\left(t\right) + 29 e^{- 4 t} \theta\left(t\right) - 101 e^{- 5 t} \theta\left(t\right) + 78 e^{- 6 t} \theta\left(t\right)$

No, it still features an “unknown” laplace transform. If we do the partial fractions expansion first, we get a clean answer:

:

invL(F.apart(s))

:

$\displaystyle \delta\left(t\right) - 3 e^{- 4 t} \theta\left(t\right) + 24 e^{- 5 t} \theta\left(t\right) - 30 e^{- 6 t} \theta\left(t\right)$