View Raw SPL
/*****************************************************************************
*                                                                            *
*   ZP2TF.SPL   Copyright (C) 2015 DSP Development Corporation               *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Zeros, poles and gain to transfer function form             *
*                                                                            *
*   Revisions:   15 Jun 2015  RRR  Creation                                  *
*                                                                            *
*****************************************************************************/

#if @HELP_ZP2TF

    ZP2TF

    Purpose: Converts zeros, poles and gain to transfer function form.

    Syntax:  ZP2TF(z, p, k)

             (b, a) = ZP2TF(z, p, k)

                 z - A series, the zeros.

                 p - A series, the poles.

                 k - Optional. A scalar, the gain. Defaults to 1.0.


    Returns: A Nx2 array where the first column contains the numerator
             coefficients and the second column contains the denominator
             coefficients.

             (b, a) = zp2tf(z, p, k) returns the numerator and denominator
             coefficients in two separate series.

    Example:
             W1: zp2tf({0}, {0.5}, 1)

             W1 contains two columns, where the first column is {1, 0},
             the numerator coefficients and the second column is {1, -0.5},
             the denominator coefficients. The coefficients represent the
             system:

                     z + 0         1
             H(z) = ------- = ----------
                    z - 0.5   1 - 0.5z^-1

    Example:
             (b, a) = zp2tf({0}, {0.5}, 1);

             b == {1, 0}
             a == {1, -0.5}

            Same as above except the coefficients are returned in two separate
            variables.

    Example:
             z = {0.0, 2.0};
             p = {0.5, 0.2};
             k = 1.0;

             (b, a) = zp2tf(z, p, k);

             b == {1, -2, 0};
             a == {1, -0.7, 0.1};

             The coefficients represent the system:

                        z^2 - 2z
             H(z) = ----------------
                    z^2 - 0.7z + 0.1

    Remarks:
             For ZP2TF(z, p, k), the input series represent the zeros,
             poles and gain of the rational polynomial H(z) = b(z)/a(z)
             where:

             N = length(b) and M = length(a):

                     b(z)    b[1] + b[2] z^(-1) + ... + b[N] z^(-N+1)
             H(z) = ------ = ----------------------------------------
                     a(z)    a[1] + a[2] z^(-1) + ... + a[N] z^(-M+1)


             ZP2TF returns the numerator coefficients b(z) and the denominator
             coefficients a(z).

             ZP2TF also works for continuous systems in decreasing powers
             of S.

             See TF2ZP to convert a continuous S plane transfer function to
             zeros, poles and gain.

             See TF2ZPK to convert a discrete Z plane transfer function to
             zeros, poles and gain.

    See Also:
             Residuez
             Tf2zp
             Tf2zpk
             Zfreq
#endif


/* zeros, poles and gain to transfer function (direct) form */
ITERATE zp2tf(z, p, k)
{
        local a, b, n;

        if (argc < 3)
        {
                if (argc < 2)
                {
                        error("zp2tf - input zeros and poles series required");
                }

                k = 1.0;
        }

        /* force series */
        z = {z};
        p = {p};

        a = real(poly(p));

        if (isempty(z) || isinf(z))
        {
                b = {zeros(length(p), 1), k};
        }
        else
        {
                b = real(poly(z) * k);
        }

        n = length(b) - length(a) + 1;
        n = (n > 1) ? 1 : n;

        /* prepend with zeros */
        b = extract(b, n, -1);

        setcomment(b, "Num");
        setcomment(a, "Den");

        setdeltax(b, deltax(p));
        setdeltax(a, deltax(p));

        if (outargc > 1)
        {
                return(b, a);
        }
        else
        {
                return(ravel(b, a));
        }
}