scipy.signal.

zpk2sos#

scipy.signal.zpk2sos(z, p, k, спаривание=None, *, аналог=False)[источник]#

Возвращает секции второго порядка из нулей, полюсов и коэффициента усиления системы

Параметры:
zarray_like

Нули передаточной функции.

parray_like

Полюса передаточной функции.

kfloat

Системное усиление.

спаривание{None, ‘nearest’, ‘keep_odd’, ‘minimal’}, опционально

Метод для объединения пар полюсов и нулей в секции. Если analog=False и pairing=None, pairing устанавливается в 'nearest'; если analog=True, pairing должен быть 'minimal', и устанавливается в это значение, если он None.

аналогbool, необязательно

Если True, система аналоговая, иначе дискретная.

Добавлено в версии 1.8.0.

Возвращает:
sosndarray

Массив коэффициентов фильтра второго порядка, с формой (n_sections, 6). См. sosfilt для спецификации формата фильтра SOS

Смотрите также

sosfilt

Примечания

Алгоритм, используемый для преобразования ZPK в формат SOS, разработан для минимизации ошибок из-за проблем с численной точностью. Алгоритм сопряжения пытается минимизировать пиковое усиление каждой биквадратной секции. Это делается путем сопряжения полюсов с ближайшими нулями, начиная с полюсов, ближайших к единичной окружности для дискретных систем, и полюсов, ближайших к мнимой оси для непрерывных систем.

pairing='minimal' выходные данные могут быть непригодны для sosfilt, и analog=True выходные данные никогда не будут пригодны для sosfilt.

Алгоритмы

Шаги в pairing='nearest', pairing='keep_odd', и pairing='minimal' алгоритмы в основном общие. The 'nearest' алгоритм пытается минимизировать пиковое усиление, в то время как 'keep_odd' минимизирует пиковое усиление при ограничении, что системы нечетного порядка должны сохранять одну секцию как первого порядка. 'minimal' похож на 'keep_odd', но дополнительные полюса или нули не вводятся

Шаги алгоритма следующие:

В качестве предварительного шага обработки для pairing='nearest', pairing='keep_odd', добавьте полюсы или нули в начало координат по мере необходимости, чтобы получить одинаковое количество полюсов и нулей для сопряжения. Если pairing == 'nearest' и если количество полюсов нечётное, добавить дополнительный полюс и ноль в начале координат.

Следующие шаги затем повторяются до тех пор, пока не останется полюсов или нулей:

  1. Возьмите (следующий оставшийся) полюс (комплексный или вещественный), ближайший к единичной окружности (или мнимой оси, для analog=True) чтобы начать новый раздел фильтра.

  2. Если полюс вещественный и нет других оставшихся вещественных полюсов [1], добавить ближайший действительный ноль к секции и оставить его как секцию первого порядка. Заметим, что после этого шага гарантированно остаётся чётное количество действительных полюсов, комплексных полюсов, действительных нулей и комплексных нулей для последующих итераций парного сопоставления.

  3. Иначе:

    1. Если полюс комплексный, а ноль — единственный оставшийся вещественный ноль*, то сопоставить полюс с next ближайший ноль (гарантированно комплексный). Это необходимо для обеспечения наличия вещественного нуля, который в конечном итоге создаст секцию первого порядка (сохраняя нечётный порядок).

    2. Иначе сопоставить полюс с ближайшим оставшимся нулем (комплексным или действительным).

    3. Перейдите к завершению секции второго порядка, добавив еще один полюс и ноль к текущим полюсу и нулю в секции:

      1. Если текущий полюс и ноль оба комплексные, добавьте их сопряженные.

      2. Иначе, если полюс комплексный, а ноль вещественный, добавьте сопряжённый полюс и следующий ближайший вещественный ноль.

      3. Иначе, если полюс вещественный, а ноль комплексный, добавьте сопряжённый ноль и ближайший вещественный полюс к этим нулям.

      4. Иначе (у нас должен быть вещественный полюс и вещественный ноль) добавить следующий вещественный полюс, ближайший к единичной окружности, а затем добавить вещественный ноль, ближайший к этому полюсу.

Добавлено в версии 0.16.0.

Примеры

Спроектировать эллиптический цифровой фильтр низких частот 6-го порядка для системы с частотой дискретизации 8000 Гц, имеющей граничную частоту полосы пропускания 1000 Гц. Пусть пульсации в полосе пропускания не превышают 0.087 дБ, а ослабление в полосе задерживания должно быть не менее 90 дБ.

В следующем вызове ellip, мы могли бы использовать output='sos', но для этого примера мы будем использовать output='zpk', а затем преобразовать в формат SOS с помощью zpk2sos:

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

Теперь преобразуйте в формат SOS.

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

Коэффициенты числителей секций:

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

Симметрия в коэффициентах возникает потому, что все нули находятся на единичной окружности.

Коэффициенты знаменателей секций:

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

Следующий пример демонстрирует эффект от спаривание опция. У нас есть система с тремя полюсами и тремя нулями, поэтому массив SOS будет иметь форму (2, 6). Это означает, что в представлении SOS, по сути, есть дополнительный полюс и дополнительный ноль в начале координат.

>>> 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])

С pairing='nearest' (по умолчанию), мы получаем

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

Первый раздел имеет нули {-0.5-0.05j, -0.5+0.5j} и полюсы {0, 0.75}, а второй раздел имеет нули {-1, 0} и полюсы {0.8+0.1j, 0.8-0.1j}. Обратите внимание, что дополнительные полюс и ноль в начале координат были назначены разным разделам.

С pairing='keep_odd', мы получаем:

>>> 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]])

Дополнительный полюс и ноль в начале координат находятся в том же разделе. Первый раздел, по сути, является разделом первого порядка.

С pairing='minimal', секция первого порядка не имеет дополнительного полюса и нуля в начале координат:

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