Convolution & LTI Systems

Convolution computes the output of any linear time-invariant system from its impulse response. Learn continuous and discrete convolution, the flip-shift-multiply-sum procedure, graphical interpretation, properties (commutative, associative, distributive), step response as integrated impulse response, correlation, and engineering examples — with a Python check against an RC circuit.

Echoes in a room, blurring in a camera, filtering in audio, and the response of a building to ground motion are all convolutions of an input with the system's impulse response.

An analogy

Convolution is like the sound in a concert hall: every note you play (input sample) launches its own echo pattern (impulse response), and what you hear is the sum of all overlapping echoes.

Flip, shift, multiply, sum

Flip h to h(−τ), shift by t, multiply with x(τ), and add up (integrate) the overlap. Sliding the flipped response along the input builds the output point by point.

Impulse and step responses

A system's impulse response characterises it completely (if LTI). The step response is the running integral of h; measuring a step response is a common way to identify systems experimentally.

Transforms make it easy

Convolution in time becomes multiplication in frequency — why filters are designed in the frequency domain and long convolutions are computed with FFTs.

Correlation and applications

Correlation (convolution without flipping) measures similarity and delay — radar ranging, GPS, pattern matching. Deconvolution recovers inputs (image deblurring, seismic processing) but amplifies noise.

Formulas

Worked example: Discrete convolution by hand

Given: x = [1, 2, 3], h = [1, 1, 1]

Find: y.

Answer: [1, 3, 6, 5, 3] (length 3 + 3 − 1 = 5)

Worked example: RC step response

Given: h(t) = (1/τ)e^(−t/τ)u(t), x = u(t)

Find: y(t).

Answer: y = 1 − e^(−t/τ)

Discrete convolution and an RC step response

import numpy as np

# Discrete convolution y[n] = sum_k x[k] h[n-k]
x = np.array([1, 2, 3])
h = np.array([1, 1, 1])
print("x * h =", np.convolve(x, h))

# Continuous-time check: RC low-pass (tau = 1 s) driven by a unit step,
# computed as a Riemann-sum convolution of input with impulse response
dt, tau = 0.001, 1.0
t = np.arange(0, 5, dt)
h_rc = np.exp(-t / tau) / tau                  # impulse response
u = np.ones_like(t)                            # unit step input
y = np.convolve(u, h_rc)[: len(t)] * dt        # y = u * h
for T in (1, 3):
    i = int(T / dt)
    print(f"y({T}) = {y[i]:.4f}   exact 1 - e^-{T} = {1 - np.exp(-T):.4f}")
# x * h = [1 3 6 5 3]
# y(1) = 0.6328   exact 1 - e^-1 = 0.6321
# y(3) = 0.9507   exact 1 - e^-3 = 0.9502

Convolving a step with the RC impulse response reproduces the familiar 1 − e^(−t/τ) charging curve; the tiny difference is the Riemann-sum discretisation error (∝ dt).

Common mistakes

Applications

Key takeaways

Going further