{
    "nbformat": 4,
    "nbformat_minor": 5,
    "metadata": {
        "kernelspec": {
            "display_name": "Python",
            "language": "python",
            "name": "python"
        },
        "language_info": {
            "name": "python"
        }
    },
    "cells": [
        {
            "id": "ed7099c5",
            "cell_type": "markdown",
            "source": "<div class='alert alert-warning'>\n\nSciPy's interactive examples with Jupyterlite are experimental and may not always work as expected. Execution of cells containing imports may result in large downloads (up to 60MB of content for the first import from SciPy). Load times when importing from SciPy may take roughly 10-20 seconds. If you notice any problems, feel free to open an [issue](https://github.com/scipy/scipy/issues/new/choose).\n\n</div>",
            "metadata": {}
        },
        {
            "id": "02a5f7b8",
            "cell_type": "markdown",
            "source": "Design a 6th order low-pass elliptic digital filter for a system with a\nsampling rate of 8000 Hz that has a pass-band corner frequency of\n1000 Hz. The ripple in the pass-band should not exceed 0.087 dB, and\nthe attenuation in the stop-band should be at least 90 dB.\n\nIn the following call to `ellip`, we could use ``output='sos'``,\nbut for this example, we'll use ``output='zpk'``, and then convert\nto SOS format with `zpk2sos`:\n",
            "metadata": {}
        },
        {
            "id": "bd7573b0",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "from scipy import signal\nimport numpy as np\nz, p, k = signal.ellip(6, 0.087, 90, 1000/(0.5*8000), output='zpk')",
            "outputs": []
        },
        {
            "id": "11d3e6b1",
            "cell_type": "markdown",
            "source": "Now convert to SOS format.\n",
            "metadata": {}
        },
        {
            "id": "74d36396",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "sos = signal.zpk2sos(z, p, k)",
            "outputs": []
        },
        {
            "id": "56a66aff",
            "cell_type": "markdown",
            "source": "The coefficients of the numerators of the sections:\n",
            "metadata": {}
        },
        {
            "id": "488c66b7",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "sos[:, :3]",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([[0.0014152 , 0.00248677, 0.0014152 ],\n       [1.        , 0.72976874, 1.        ],\n       [1.        , 0.17607852, 1.        ]])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "f6fc6763",
            "cell_type": "markdown",
            "source": "The symmetry in the coefficients occurs because all the zeros are on the\nunit circle.\n\nThe coefficients of the denominators of the sections:\n",
            "metadata": {}
        },
        {
            "id": "4d494666",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "sos[:, 3:]",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([[ 1.        , -1.32544025,  0.46989976],\n       [ 1.        , -1.26118294,  0.62625924],\n       [ 1.        , -1.2570723 ,  0.8619958 ]])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "5c555850",
            "cell_type": "markdown",
            "source": "The next example shows the effect of the `pairing` option.  We have a\nsystem with three poles and three zeros, so the SOS array will have\nshape (2, 6). The means there is, in effect, an extra pole and an extra\nzero at the origin in the SOS representation.\n",
            "metadata": {}
        },
        {
            "id": "786d9462",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "z1 = np.array([-1, -0.5-0.5j, -0.5+0.5j])\np1 = np.array([0.75, 0.8+0.1j, 0.8-0.1j])",
            "outputs": []
        },
        {
            "id": "63c01844",
            "cell_type": "markdown",
            "source": "With ``pairing='nearest'`` (the default), we obtain\n",
            "metadata": {}
        },
        {
            "id": "988c092b",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "signal.zpk2sos(z1, p1, 1)",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([[ 1.  ,  1.  ,  0.5 ,  1.  , -0.75,  0.  ],\n       [ 1.  ,  1.  ,  0.  ,  1.  , -1.6 ,  0.65]])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "8a1a95a9",
            "cell_type": "markdown",
            "source": "The first section has the zeros {-0.5-0.05j, -0.5+0.5j} and the poles\n{0, 0.75}, and the second section has the zeros {-1, 0} and poles\n{0.8+0.1j, 0.8-0.1j}. Note that the extra pole and zero at the origin\nhave been assigned to different sections.\n\nWith ``pairing='keep_odd'``, we obtain:\n",
            "metadata": {}
        },
        {
            "id": "f22802de",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "signal.zpk2sos(z1, p1, 1, pairing='keep_odd')",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([[ 1.  ,  1.  ,  0.  ,  1.  , -0.75,  0.  ],\n       [ 1.  ,  1.  ,  0.5 ,  1.  , -1.6 ,  0.65]])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "e6b9ddc1",
            "cell_type": "markdown",
            "source": "The extra pole and zero at the origin are in the same section.\nThe first section is, in effect, a first-order section.\n\nWith ``pairing='minimal'``, the first-order section doesn't have\nthe extra pole and zero at the origin:\n",
            "metadata": {}
        },
        {
            "id": "1bfb6652",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "signal.zpk2sos(z1, p1, 1, pairing='minimal')",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([[ 0.  ,  1.  ,  1.  ,  0.  ,  1.  , -0.75],\n       [ 1.  ,  1.  ,  0.5 ,  1.  , -1.6 ,  0.65]])"
                    },
                    "execution_count": null
                }
            ]
        }
    ]
}