How to Convert Analog Filter to Digital Filter in Signal Processing
scipy.signal.bilinear() or impulse invariance with scipy.signal.impulse_invariant() to map the analog filter coefficients to digital ones.Examples
How to Think About It
Algorithm
Code
import numpy as np from scipy.signal import bilinear # Analog filter coefficients (numerator and denominator) b = np.array([1]) a = np.array([1, 1]) fs = 8000 # Sampling frequency in Hz # Convert analog filter to digital using bilinear transform bz, az = bilinear(b, a, fs) print('Digital filter numerator:', bz) print('Digital filter denominator:', az)
Dry Run
Let's trace the bilinear transform conversion of an analog filter with numerator [1] and denominator [1, 1] at 8000 Hz sampling.
Input analog filter coefficients
Numerator b = [1], Denominator a = [1, 1]
Apply bilinear transform with fs=8000
Calculate digital numerator bz and denominator az coefficients
Output digital filter coefficients
bz = [0.29289322 0.29289322], az = [1.0, -0.41421356]
| Step | Operation | Value |
|---|---|---|
| 1 | Analog numerator b | [1] |
| 1 | Analog denominator a | [1, 1] |
| 2 | Sampling frequency fs | 8000 |
| 3 | Digital numerator bz | [0.29289322 0.29289322] |
| 3 | Digital denominator az | [1.0, -0.41421356] |
Why This Works
Step 1: Why use bilinear transform
The bilinear transform maps the analog filter's s-plane to the digital z-plane, preserving stability and avoiding aliasing by warping frequencies.
Step 2: Mapping coefficients
It converts the analog numerator and denominator polynomials into digital ones by substituting s with a function of z and sampling frequency.
Step 3: Resulting digital filter
The output coefficients define a digital filter that approximates the analog filter's behavior at discrete time steps.
Alternative Approaches
from scipy.signal import impulse_invariant b = [1] a = [1, 1] fs = 8000 bz, az = impulse_invariant(b, a, fs) print('Digital filter numerator:', bz) print('Digital filter denominator:', az)
from scipy.signal import zpk2tf, tf2zpk import numpy as np # Example analog poles and zeros z, p, k = [], [-1], 1 fs = 8000 # Map poles and zeros to digital domain p_d = [np.exp(pole / fs) for pole in p] bz, az = zpk2tf(z, p_d, k) print('Digital filter numerator:', bz) print('Digital filter denominator:', az)
Complexity: O(n) time, O(n) space
Time Complexity
The bilinear transform involves polynomial coefficient calculations proportional to filter order n, so it runs in O(n) time.
Space Complexity
It requires storing input and output coefficient arrays of size n, so space complexity is O(n).
Which Approach is Fastest?
Bilinear transform is efficient and widely used; impulse invariance is similar in complexity but less common due to aliasing.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Bilinear Transform | O(n) | O(n) | General analog to digital conversion, avoids aliasing |
| Impulse Invariance | O(n) | O(n) | Preserving impulse response, low-pass filters |
| Matched Z-Transform | O(n) | O(n) | Direct pole-zero mapping, simple filters |