scipy.signal.

zpk2sos#

scipy.signal.zpk2sos(z, p, k, pairing=None, *, analog=False)[Quelle]#

Gibt Zweikanalabschnitte aus Nullen, Polen und Verstärkung eines Systems zurück

Parameter:
zarray_like

Nullen der Übertragungsfunktion.

parray_like

Pole der Übertragungsfunktion.

kfloat

Systemverstärkung.

pairing{None, ‘nearest’, ‘keep_odd’, ‘minimal’}, optional

Die Methode, die verwendet wird, um Paare von Polen und Nullen in Abschnitte zu kombinieren. Wenn analog False ist und pairing None ist, wird pairing auf ‘nearest’ gesetzt; wenn analog True ist, muss pairing ‘minimal’ sein und wird auf diesen Wert gesetzt, falls es None ist.

analogbool, optional

Wenn True, ist das System analog, andernfalls diskret.

Hinzugefügt in Version 1.8.0.

Rückgabe:
sosndarray

Array von Zweikanalfilterkoeffizienten mit der Form (n_sections, 6). Siehe sosfilt für die Spezifikation des SOS-Filterformats.

Siehe auch

sosfilt

Hinweise

Der Algorithmus, der zur Konvertierung von ZPK in SOS verwendet wird, wurde entwickelt, um Fehler aufgrund von Problemen mit der numerischen Genauigkeit zu minimieren. Der Pairing-Algorithmus versucht, die maximale Verstärkung jedes biquadratischen Abschnitts zu minimieren. Dies geschieht durch die Paarung von Polen mit den nächstgelegenen Nullen, beginnend mit den Polen, die dem Einheitskreis am nächsten liegen (bei diskreten Systemen) bzw. der imaginären Achse am nächsten liegen (bei kontinuierlichen Systemen).

pairing='minimal' Ausgaben sind möglicherweise nicht für sosfilt geeignet, und analog=True Ausgaben sind niemals für sosfilt geeignet.

Algorithmen

Die Schritte in den Algorithmen pairing='nearest', pairing='keep_odd' und pairing='minimal' sind größtenteils gemeinsam. Der 'nearest' Algorithmus versucht, die maximale Verstärkung zu minimieren, während 'keep_odd' die maximale Verstärkung unter der Bedingung minimiert, dass ungeradzahlige Systeme einen Abschnitt als erstgradig behalten. 'minimal' ist ähnlich wie 'keep_odd', aber es werden keine zusätzlichen Pole oder Nullen eingeführt.

Die Algorithmus-Schritte sind wie folgt:

Als Vorverarbeitungsschritt für pairing='nearest' und pairing='keep_odd' werden Pole oder Nullen am Ursprung hinzugefügt, um die gleiche Anzahl von Polen und Nullen für das Pairing zu erhalten. Wenn pairing == 'nearest' und es eine ungerade Anzahl von Polen gibt, wird ein zusätzlicher Pol und eine Null am Ursprung hinzugefügt.

Die folgenden Schritte werden dann iteriert, bis keine Pole oder Nullen mehr übrig sind:

  1. Nehmen Sie den (nächsten verbleibenden) Pol (komplex oder reell), der dem Einheitskreis (oder der imaginären Achse für analog=True) am nächsten liegt, um einen neuen Filterabschnitt zu beginnen.

  2. Wenn der Pol reell ist und keine anderen reellen Pole mehr vorhanden sind [1], fügen Sie die nächstgelegene reelle Null zum Abschnitt hinzu und belassen Sie ihn als erstgradigen Abschnitt. Beachten Sie, dass wir nach diesem Schritt garantiert eine gerade Anzahl von reellen Polen, komplexen Polen, reellen Nullen und komplexen Nullen für nachfolgende Pairing-Iterationen übrig haben.

  3. Andernfalls

    1. Wenn der Pol komplex ist und die Null die einzige verbleibende reelle Null ist*, dann paaren Sie den Pol mit der *nächstgelegenen* Null (garantiert komplex). Dies ist notwendig, um sicherzustellen, dass eine reelle Null übrig bleibt, um schließlich einen erstgradigen Abschnitt zu erstellen (und somit die ungerade Ordnung beizubehalten).

    2. Andernfalls paaren Sie den Pol mit der nächstgelegenen verbleibenden Null (komplex oder reell).

    3. Fahren Sie mit dem Abschluss des Zweikanalabschnitts fort, indem Sie dem aktuellen Pol und der Null im Abschnitt einen weiteren Pol und eine weitere Null hinzufügen.

      1. Wenn der aktuelle Pol und die Null beide komplex sind, fügen Sie ihre Konjugierten hinzu.

      2. Andernfalls, wenn der Pol komplex und die Null reell ist, fügen Sie den konjugierten Pol und die nächstgelegene reelle Null hinzu.

      3. Andernfalls, wenn der Pol reell und die Null komplex ist, fügen Sie die konjugierte Null und den reellen Pol hinzu, der diesen Nullen am nächsten liegt.

      4. Andernfalls (wir müssen einen reellen Pol und eine reelle Null haben) fügen Sie den nächstgelegenen reellen Pol zum Einheitskreis hinzu und fügen Sie dann die reelle Null hinzu, die diesem Pol am nächsten liegt.

Hinzugefügt in Version 0.16.0.

Beispiele

Entwerfen Sie einen 6. Ordnung Tiefpass-Elliptisch-Digitalfilter für ein System mit einer Abtastrate von 8000 Hz, das eine Eckfrequenz im Durchlassbereich von 1000 Hz hat. Die Welligkeit im Durchlassbereich sollte 0,087 dB nicht überschreiten und die Dämpfung im Sperrbereich sollte mindestens 90 dB betragen.

Im folgenden Aufruf von ellip könnten wir output='sos' verwenden, aber für dieses Beispiel verwenden wir output='zpk' und konvertieren dann mit zpk2sos in das SOS-Format.

>>> from scipy import signal
>>> import numpy as np
>>> z, p, k = signal.ellip(6, 0.087, 90, 1000/(0.5*8000), output='zpk')

Konvertieren Sie nun in das SOS-Format.

>>> sos = signal.zpk2sos(z, p, k)

Die Koeffizienten der Zähler der Abschnitte

>>> sos[:, :3]
array([[0.0014152 , 0.00248677, 0.0014152 ],
       [1.        , 0.72976874, 1.        ],
       [1.        , 0.17607852, 1.        ]])

Die Symmetrie der Koeffizienten tritt auf, da alle Nullen auf dem Einheitskreis liegen.

Die Koeffizienten der Nenner der Abschnitte

>>> sos[:, 3:]
array([[ 1.        , -1.32544025,  0.46989976],
       [ 1.        , -1.26118294,  0.62625924],
       [ 1.        , -1.2570723 ,  0.8619958 ]])

Das nächste Beispiel zeigt die Auswirkung der Option pairing. Wir haben ein System mit drei Polen und drei Nullen, sodass das SOS-Array die Form (2, 6) hat. Das bedeutet, dass im SOS-Format effektiv ein zusätzlicher Pol und eine zusätzliche Null am Ursprung vorhanden sind.

>>> z1 = np.array([-1, -0.5-0.5j, -0.5+0.5j])
>>> p1 = np.array([0.75, 0.8+0.1j, 0.8-0.1j])

Mit pairing='nearest' (dem Standardwert) erhalten wir

>>> signal.zpk2sos(z1, p1, 1)
array([[ 1.  ,  1.  ,  0.5 ,  1.  , -0.75,  0.  ],
       [ 1.  ,  1.  ,  0.  ,  1.  , -1.6 ,  0.65]])

Der erste Abschnitt hat die Nullen {-0.5-0.05j, -0.5+0.5j} und die Pole {0, 0.75}, und der zweite Abschnitt hat die Nullen {-1, 0} und die Pole {0.8+0.1j, 0.8-0.1j}. Beachten Sie, dass der zusätzliche Pol und die zusätzliche Null am Ursprung auf verschiedene Abschnitte verteilt wurden.

Mit pairing='keep_odd' erhalten wir

>>> signal.zpk2sos(z1, p1, 1, pairing='keep_odd')
array([[ 1.  ,  1.  ,  0.  ,  1.  , -0.75,  0.  ],
       [ 1.  ,  1.  ,  0.5 ,  1.  , -1.6 ,  0.65]])

Der zusätzliche Pol und die zusätzliche Null am Ursprung befinden sich im selben Abschnitt. Der erste Abschnitt ist effektiv ein erstgradiger Abschnitt.

Mit pairing='minimal' hat der erstgradige Abschnitt nicht den zusätzlichen Pol und die zusätzliche Null am Ursprung.

>>> signal.zpk2sos(z1, p1, 1, pairing='minimal')
array([[ 0.  ,  1.  ,  1.  ,  0.  ,  1.  , -0.75],
       [ 1.  ,  1.  ,  0.5 ,  1.  , -1.6 ,  0.65]])