View Raw SPL
/*****************************************************************************
*                                                                            *
*   TOEPLITZ.SPL Copyright (C) 2014 DSP Development Corporation              *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Creates a Toeplitz matrix                                   *
*                                                                            *
*   Revisions:    6 Jun 2014  RRR  Creation                                  *
*                                                                            *
*****************************************************************************/


#if @HELP_TOEPLITZ

    TOEPLITZ

    Purpose: Creates a Toeplitz matrix                         

    Syntax:  TOEPLITZ(c, r)

              c - A series, the first column of the output array.

              r - Optional, a series, the first row of the output
                  array. Defaults to c.

    Returns: An array, a symmetric or unsymmetric Toeplitz matrix.

    Example:
             c = {1, 2, 3};
             t = toeplitz(c);

             t == {{1, 2, 3},
                   {2, 1, 2},
                   {3, 2, 1}}

             The first row and column of T is identical to C.

    Example:
             c = {1, 2, 3};
             r = {1, 8, 9};
             t = toeplitz(c, r);

             t == {{1, 8, 9},
                   {2, 1, 8},
                   {3, 2, 1}}

             The first row is identical to R and the first column is identical
             to C.

    Remarks:
             For column C and row R, a square Toeplitz matrix takes the form:

              C[1]   R[2]   R[3]  ...  R[n]
              C[2]   C[1]   R[2]  ...  R[n-1]
              C[3]   C[2]   C[1]  ...  R[n-2]
              .      .      .   .      .
              .      .      .     .    .
              .      .      .       .  .
              C[n]   C[n-1] C[n-2] ... C[1]


             If R is not specified, a symmetric Toeplitz matrix is returned
             where C represents the first row and column.

             If R is specified, an unsymmetric Toeplitz matrix is returned
             where the first column is C and the first row is R. In this case,
             if C[1] != R[1], C[1] is used as the first element.

    See Also:
             Hankel
             Kron
             Vander
#endif


/* create a symmetric or unsymmetric Toeplitz matrix */
toeplitz(c, r)
{
        local nr, nc, tp, ts, cc;

        if (argc < 2)
        {
                if (argc < 1) error("toeplitz - input series required");

                if (iscomplex(c))
                {
                        /* hermitian */
                        cc    = c;
                        cc[1] = conj(cc[1]);
                        r     = cc;
                        c     = conj(cc);
                }
                else
                {
                        r = c;
                }
        }

        /* cast to arrays, flatten row */
        c = {c};
        r = unravel({r});

        /* sizes */        
        nc = max(numcols(c), numrows(c));
        nr = length(r);        

        /* check if empty */
        if (nc == 0 || nr == 0)
        {
                return({});
        }

        /* check diagonal conflict */
        if (c[1] != r[1])
        {
                echo("toeplitz - first column value used as first diagonal value");
        }

        /* subscript vector */
        ts = concat(extract(rev(r), 1, nr - 1), unravel(c));

        /* subscript array */
        tp = repcol((0..nc - 1), nr) + rep((nr..-1..1)', nc);

        /* preserve Toeplitz shape */
        tp[..] = ts[tp];

        return(tp);
}