View Raw SPL
/*****************************************************************************
*                                                                            *
*   TF2SS.SPL    Copyright (C) 1998 DSP Development Corporation              *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Matthew Tom                                                 *
*                                                                            *
*   Synopsis:    Transfer function to state space conversion                 *
*                                                                            *
*   Revisions:    3 Jul 1997  MAT  Creation                                  *
*                 8 Jun 1998  MAT  Help Menu Entry                           *
*                                                                            *
*****************************************************************************/

#include 

#if @HELP_TF2SS

    TF2SS

    Purpose: Calculates the state-space representation:

                        .
                        x = Ax + Bu
                        y = Cx + Du

             of the system:

                        NUM(s)
                H(s) = --------
                        DEN(s)

         from a single input.

    Syntax:  (A,B,C,D) = tf2ss(Num,Den)

              Num - Matrix NUM must contain the numerator
                    coefficients with as many rows as there are
                    outputs y.

              Den - Vector DEN must contain the coefficients of
                    the denominator in descending powers of s.

    Returns: The A,B,C,D matrices of the state space
             transformation in controller canonical form.

    Example:
             (A,B,C,D) = tf2ss(Num,Den)

             creates the A,B,C,D matrices of the state space
             transformation in controller canonical form.

    Remarks:
             TF2SS also works for discrete systems.

             For discrete systems, use a numerator polynomial padded
             with zeros to the same length as the denominator.

    See Also:
             Bilinear

#endif


/* convert state space */
tf2ss(num, den)
{
        local f1, f2, nnr, nnc, dnr, dnc, nz, a, b, c, d, d1;

        f1 = 0;
        f2 = 0;

        (nnr, nnc) = size(num);
        (dnr, dnc) = size(den);

        if (nnc == 1)
        {
                num = num';
                f1  = 1;
        }

        if (dnc == 1)
        {
                den = den';
                f2  = 1;
        }

        (nnr, nnc) = size(num);
        (dnr, dnc) = size(den);

        /* empty case */
        if (dnc == 0 && nnc == 0)
        {
                return({}, {}, {}, {});
        }

        /* strip leading zeros from denominator */
        nz  = find(not(den == 0));
        den = den[1..dnr, nz[1]..dnc];

        (dnr, dnc) = size(den);

        /* check numerator */
        if (nnc > dnc)
        {
                if (all(all(num[1..nnr, 1..nnc-dnc])) == 0)
                {
                        num = num[1..nnr, (nnc-dnc+1)..nnc];
                        (nnr, nnc) = size(num);
                }
                else
                {
                        error("tf2ss - denominator order must be >= numerator order");
                }
        }

        /* normalization factor */
        d1 = den[1];

        /* zero prepad num to have the same number of columns as den */
        num = ravel(zeros(nnr, dnc - nnc), num) / d1;

        d = (length(num) > 0) ? num[1..nnr, 1] : {};

        /* constant denominator */
        if (dnc == 1)
        {
                return({}, {}, {}, d);
        }

        /* normalize */
        den = den[1..dnr, 2..dnc] / d1;

        /* output arrays */
        a = {-den, eye(dnc - 2, dnc - 1)};
        b = eye(dnc - 1, 1);
        c = (nnr > 0) ? num[1..nnr, 2..dnc] - num[1..nnr, 1] *^ den : {};

        if (f1 == 1)
        {
                num = num';
        }

        if (f2 == 1)
        {
                den = den';
        }

        return(a, b, c, d);
}