Skip to content

Python Cheatsheet

TIP

Ce guide de référence rapide présente les fonctions Python essentielles pour l'analyse des systèmes SLIT. Il utilise principalement les bibliothèques scipy.signal et matplotlib.

General

dB 2 linear conversion

python
def dB_2_nat(V_dB):
    """
    dB_2_nat
    Convert dB value to natural value
    """
    return 10**(V_dB/20)

Usage

python
V_dB = -3
V_N = dB_2_nat(V_dB)
print(f"Natural Value: {V_N}")

Combination of Transfer Functions

python
def series(H_list):
    """
    Combine multiple LTI systems in series.

    This function takes a list of LTI systems (scipy.signal.lti objects)
    and returns a new LTI system that represents the series connection
    of all the systems in the list.

    Parameters:
        H_list (list): A list of scipy.signal.lti objects.

    Returns:
        scipy.signal.lti: The resulting LTI system after combining all systems in series.
    """
    num = [1]  # Initial numerator
    den = [1]  # Initial denominator

    # Loop through each LTI system in the list
    for H_temp in H_list:
        num = np.polymul(num, H_temp.num)
        den = np.polymul(den, H_temp.den)

    H = sig.lti(num, den)
    return H

Plotting

Pole and Zero Diagram

python
import matplotlib.pyplot as plt

# Assuming poles and zeros are numpy arrays
plt.plot(poles.real, poles.imag, "x", label="poles", markersize=10)
plt.plot(zeros.real, zeros.imag, "o", label="zeros", markersize=8)
plt.axhline(y=0, color='k', linewidth=0.5)
plt.axvline(x=0, color='k', linewidth=0.5)
plt.axis("equal")
plt.grid(True)
plt.xlabel("Real part")
plt.ylabel("Imaginary part")
plt.legend()
plt.title("Pole-Zero Diagram")

Step Response

python
from scipy.signal import lti
import matplotlib.pyplot as plt

# Define transfer function
H = lti([b0], [a1, a0])  # Example: first order

# Compute step response
t, y = H.step()

# Plot
plt.plot(t, y)
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Step Response')
plt.grid()
plt.show()

Bode Diagram

python
from scipy.signal import lti
import matplotlib.pyplot as plt
import numpy as np

# Define transfer function
H = lti([b0], [a1, a0])

# Compute frequency response
w, Hjw = H.freqresp()
H_modulus = np.abs(Hjw)
H_angle = (180/np.pi) * np.angle(Hjw)

# Plot magnitude
plt.subplot(211)
plt.loglog(w, H_modulus, label='Magnitude')
plt.ylabel('$|H(j\\omega)|$')
plt.title('Bode Diagram')
plt.grid(which='both')
plt.legend()

# Plot phase
plt.subplot(212)
plt.semilogx(w, H_angle, label='Phase')
plt.xlabel('$\\omega$ [rad/s]')
plt.ylabel('$\\arg(H(j\\omega))$ [deg]')
plt.grid(which='both')
plt.legend()

plt.tight_layout()
plt.show()

Draw LP Prototype

python
import matplotlib.pyplot as plt

def plot_prototype(ax, xc, Tc, xs, Ts):
    """
    plot_LP_prototype
    Plot low-pass prototype filter specification

    Parameters:
        ax: matplotlib axis
        xc: cutoff frequency
        Tc: passband tolerance
        xs: stopband frequency
        Ts: stopband attenuation
    """
    xmin, xmax = ax.get_xlim()
    ymin, ymax = ax.get_ylim()

    # Passband region
    polygon_data1 = [[xmin, Tc], [xc, Tc], [xc, ymin], [xmin, ymin]]

    # Stopband region
    polygon_data2 = [[xmin, ymax], [xmin, 1], [xs, 1], [xs, Ts],
                     [xmax, Ts], [xmax, ymax], [xmin, ymax]]

    options = {"fill": False, "closed": True, "color": 'b', "hatch": "/"}
    patch1 = plt.Polygon(polygon_data1, **options)
    patch2 = plt.Polygon(polygon_data2, **options)

    ax.add_patch(patch1)
    ax.add_patch(patch2)
    ax.set_xscale('log')
    ax.set_yscale('log')

Usage

python
# Specifications
fc, Tc = 1e3, 0.7      # Cutoff: 1kHz, tolerance: 0.7
fs, Ts = 1e4, 1e-4     # Stopband: 10kHz, attenuation: 0.0001

# Create figure
fig = plt.figure()
ax = fig.gca()
ax.set_xlim([1e2, 1e6])
ax.set_ylim([1e-5, 2])

# Plot prototype
plot_prototype(ax, fc, Tc, fs, Ts)
ax.set_xlabel("Frequency [Hz]")
ax.set_ylabel("Magnitude")
ax.set_title("Filter Specification (Gabarit)")
plt.show()

Prototype and Frequency Response Superposition

python
import scipy.signal as sig
import matplotlib.pyplot as plt
import numpy as np

# Design Butterworth filter
N = 3  # Filter order
z, p, k = sig.butter(N, 1, btype='low', analog=True, output='zpk')

# Create LTI system
H = sig.lti(z, p, k)

# Compute frequency response
w, Hjw = H.freqresp()

# Plot
fig = plt.figure()
ax = fig.gca()
ax.loglog(w, np.abs(Hjw), label=f'Butterworth N={N}')
plot_prototype(ax, 1, 0.7, 5, 1e-4)
ax.set_xlabel("Normalized frequency")
ax.set_ylabel("Magnitude")
ax.legend()
plt.show()

Common Transfer Function Creation

From Polynomial Coefficients [ba]

python
from scipy.signal import lti

# H(s) = (b1*s + b0) / (a2*s^2 + a1*s + a0)
num = [b1, b0]
den = [a2, a1, a0]
H = lti(num, den)

From Zeros, Poles, and Gain [zpk]

python
from scipy.signal import lti

# Define zeros, poles, and gain
zeros = [-1, -2]
poles = [-0.5+1j, -0.5-1j]
gain = 2.0

H = lti(zeros, poles, gain)

Standard Second Order Forms

python
import numpy as np
from scipy.signal import lti

# Low-pass
def second_order_LP(T0, omega0, m):
    """Second order low-pass filter"""
    num = [T0 * omega0**2]
    den = [1, 2*m*omega0, omega0**2]
    return lti(num, den)

# Band-pass
def second_order_BP(Tm, omega0, m):
    """Second order band-pass filter"""
    num = [2*m*Tm*omega0, 0]
    den = [1, 2*m*omega0, omega0**2]
    return lti(num, den)

# High-pass
def second_order_HP(Tinf, omega0, m):
    """Second order high-pass filter"""
    num = [Tinf, 0, 0]
    den = [1, 2*m*omega0, omega0**2]
    return lti(num, den)

Useful scipy.signal Functions

python
import scipy.signal as sig

# Filter design
sig.butter(N, Wn)        # Butterworth filter
sig.cheby1(N, rp, Wn)    # Chebyshev Type I
sig.cheby2(N, rs, Wn)    # Chebyshev Type II
sig.ellip(N, rp, rs, Wn) # Elliptic (Cauer)
sig.bessel(N, Wn)        # Bessel/Thomson

# System analysis
H.freqresp(w)            # Frequency response
H.step()                 # Step response
H.impulse()              # Impulse response
H.bode()                 # Bode plot

# System properties
H.poles                  # System poles
H.zeros                  # System zeros

References