Skip to main content

An educational module about digital filters

Project description

module digital_filter_tools

Outils pédagogiques pour l'étude des filtres numériques

Installation du module python digital_filter_tools

From Pypi repository :
https://pypi.org/project/digital-filter-tools

pip install digital-filter-tools

Fonctionnalités

Ce module propose des outils pédagogiques pour l'étude des filtres numériques :

  • passage de l'équation de récurrence aux transformées en z
  • passage de l'équation de récurrence à la fonction de transfert en z
  • écriture de la fonction de transfert en z en fonction des pôles et zéros
  • courbe des réponses impulsionnelle, indicielle, rampe, sinus
  • courbe de la réponse à une séquence d'entrée personnalisée
  • calcul des zéros et des pôles de la fonction de transfert en z
  • diagramme des pôles et zéros
  • étude de la stabilité
  • courbe de la réponse en fréquence (gain et phase)

Rappels sur les filtres numériques

Equation de récurrence

x(n) désigne l'entrée et y(n) la sortie.

L'équation de récurrence (algorithme) d'un filtre numérique a la forme générale suivante :

a0*y(n) +a1*y(n-1) +a2*y(n-2) + ... = b0*x(n) + b1*x(n-1) + b2*x(n-2) + ...

ou :

a0*y(n) = b0*x(n) + b1*x(n-1) + b2*x(n-2) + ...
          -a1*y(n-1) -a2*y(n-2) -a3*y(n-3) + ...

Par la suite, les paramètres a et b représentent les listes des coefficients (réels) de l'équation de récurrence :

a = [a0, a1, a2, ...]  # avec a0 non nul  
b = [b0, b1, b2, ...]  # avec au moins un coefficient non nul  

Exemple :

>>> from digital_filter_tools import *
>>> f = FiltreNumerique(a=[2, -0.2], b=[1, 0.5])

Transmittance en z

On peut aussi définir un filtre numérique par ses pôles et ses zéros.
La transmittance en z s'écrit alors :

          (z-z1).(z-z2)...(z-zm)
H(z) = k. -----------------------------
          (z-p1).(z-p2).(z-p3)...(z-pn)

k est un nombre non nul (constante d'amplification)

zeros est la liste des m zéros de la transmittance :

zeros = [z1, z2, ..., zm]  

poles est la liste des n pôles de la transmittance :

poles = [p1, p2, ..., pn]  

avec les conditions suivantes :

  • n >= m
  • pôles et zéros réels ou complexes par paires conjuguées

Exemple :

>>> from digital_filter_tools import *
>>> f = FiltreNumerique(k=2, zeros=[0.5], poles=[0, 0.6-0.2j, 0.6+0.2j])

Un exemple complet : filtre à moyenne glissante

On s'intéresse à un filtre à moyenne glissante sur 4 échantillons (sous forme récursive).

>>> from digital_filter_tools import *
>>> f = FiltreNumerique(a=[1, -1], b=[0.25, 0, 0, 0, -0.25])

Equation de récurrence

>>> f.afficher_equation_recurrence()
y(n) = 0.25*x(n) -0.25*x(n-4) 
       +y(n-1)

Ordre du filtre

>>> print(f.ordre())
4

Passage à la transformée en z

>>> f.afficher_transformee_en_z()
Y(z) = 0.25*X(z) -0.25*X(z)z⁻⁴ 
       +Y(z)z⁻¹

Transmittance (fonction de transfert) en z

Par définition : H(z) = Y(z)/X(z)

>>> f.afficher_transmittance_z()
        0.25 -0.25z⁻⁴
H(z) =  -------------
        1 -z⁻¹

Autre écriture avec puissances de z positives :

>>> f.afficher_transmittance_z_puissance_positive()
        0.25z -0.25
H(z) =  ------------
        z -z³

Pôles et zéros

>>> print(f.zeros)
[-1.0, (-0-1j), 1j, 1.0]
>>> print(f.poles)
[0.0, 0.0, 0.0, 1.0]

Pôles et zéros communs

>>> print(f.poles_zeros_commun())
[1.0]

Transmittance en z avec pôles et zéros

>>> f.afficher_transmittance_z_poles_zeros()
        0.25(z+1)(z+1j)(z-1j)(z-1)
H(z) =  --------------------------
        z.z.z(z-1)

Etude de la stabilité

>>> f.afficher_bilan_stabilite()

Etude de la stabilité
---------------------
Le filtre est récursif.
La transmittance en z possède 4 pôles.
En module :
|0| = 0
|0| = 0
|0| = 0
|1| = 1
Filtre stable car tous les pôles ont un module <= 1

Réponse impulsionnelle

>>> f.tracer_reponse_impulsionnelle()    

screenshot01

Réponse indicielle

>>> f.tracer_reponse_indicielle()   

screenshot02

Réponse en fréquence

fs désigne la fréquence d'échantillonnage (en Hz).

>>> f.fs = 5000
>>> f.tracer_reponse_en_frequence(magnitude_unit='linear')

screenshot03

Fonction de transfert complexe H(jω) (transmittance complexe)

>>> H = f.hw
>>> # help(H)
>>> H.properties(600)   # transmittance à 600 Hz
Frequency (Hz) : 600
Angular frequency (rad/s) : 3769.91

Complex value : 0.288584-0.613272j
Magnitude : 0.677778
Magnitude (dB) : -3.37825
Phase (degrees) : -64.8
Phase (radians) : -1.13097
>>> H.db(600)  # gain en dB à 600 Hz
-3.37825
>>> H.phase_deg(600)  # déphasage en degrés à 600 Hz
-64.8

Diagramme des pôles et zéros

>>> f.tracer_diagramme_poles_zeros() 

screenshot04

Un deuxième exemple : lowpass iir elliptic order 5

>>> from digital_filter_tools import *
>>> k = 0.004691927277691961
>>> zeros = [(-0.024456055354309697+0.9997009059496281j),
(-0.024456055354309697-0.9997009059496281j),
-1.0,
(0.39282986017485766+0.9196111683505163j),
(0.39282986017485766-0.9196111683505163j)]
>>> poles = [0.7098495779640238,
(0.710102705797963+0.3470090677215467j),
(0.710102705797963-0.3470090677215467j),
(0.736600454346126+0.569377854177767j),
(0.736600454346126-0.569377854177767j)]
>>> f = FiltreNumerique(fs=10000, k=k, zeros=zeros, poles=poles)

Equation de récurrence

>>> f.afficher_equation_recurrence()                                       
y(n) = 0.00469193*x(n) +0.00123516*x(n-1) +0.00574679*x(n-2) +0.00574679*x(n-3)
       +0.00123516*x(n-4) +0.00469193*x(n-5) 
       +3.60326*y(n-1) -5.63756*y(n-2) +4.69512*y(n-3) -2.0685*y(n-4) +0.38434*y(n-5)
>>> print(f.b)
[0.004691927277691961, 0.001235161071242554, 0.005746785676190226,
 0.0057467856761902235, 0.0012351610712425533, 0.004691927277691962]
>>> print(f.a)
[1.0, -3.603255898252202, 5.637563674261337, -4.695118791175536,
 2.0684985810278094, -0.38433981781115933]

Etude de la stabilité

>>> f.afficher_bilan_stabilite()  

Etude de la stabilité
---------------------
Le filtre est récursif.
La transmittance en z possède 5 pôles.
En module :
|0.70985| = 0.70985
|0.710103+0.347009j| = 0.790355
|0.710103-0.347009j| = 0.790355
|0.7366+0.569378j| = 0.931006
|0.7366-0.569378j| = 0.931006
Filtre stable car tous les pôles ont un module <= 1

Réponse impulsionnelle

>>> f.tracer_reponse_impulsionnelle(nfin=50)    

screenshot11

Réponse indicielle

>>> f.tracer_reponse_indicielle(nfin=50)   

screenshot12

Réponse en fréquence

>>> f.tracer_reponse_en_frequence(magnitude_unit='dB')

screenshot13

Diagramme des pôles et zéros

>>> f.tracer_diagramme_poles_zeros() 

screenshot14

Aide complète

>>> import digital_filter_tools
>>> help(digital_filter_tools)

Documentation complète

https://framagit.org/fsincere/digital-filter-tools

En particulier, des exemples d'utilisation ici.

TO DO

documentation : english translation...

Complément

L'utilitaire Python pyFDA

https://github.com/chipmuenk/pyFDA

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

digital-filter-tools-0.4.1.tar.gz (26.4 kB view hashes)

Uploaded Source

Built Distribution

digital_filter_tools-0.4.1-py3-none-any.whl (26.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page