View Raw SPL
/*****************************************************************************
* *
* HANKEL.SPL Copyright (C) 2014-2016 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Creates a Hankel matrix *
* *
* Revisions: 6 Jun 2014 RRR Creation *
* 1 Jun 2016 RRR outerprod speedup *
* *
*****************************************************************************/
#if @HELP_HANKEL
HANKEL
Purpose: Creates a Hankel matrix
Syntax: HANKEL(c, r)
c - A series, the first column of the output array.
r - Optional. A series, the last row of the output array.
If not specified, the first element of the last row
equals the last column value and the remaining values
are all 0.
Returns: An array, a Hankel matrix.
Example:
c = {1, 2, 3};
h = hankel(c);
h == {{1, 2, 3},
{2, 3, 0},
{3, 0, 0}}
The first row and column of H is identical to C.
Example:
c = {1, 2, 3};
r = {3, 8, 9};
h = hankel(c, r);
h == {{1, 2, 3},
{2, 3, 8},
{3, 8, 9}}
The last row is identical to R and the first column is identical
to C.
Remarks:
For column C and row R, a Hankel matrix takes the form:
C[1] C[2] C[3] ... R[1]
C[2] C[1] R[1] ... R[2]
C[3] R[1] R[2] ... R[3]
. . . . .
. . . . .
. . . . .
C[n] R[n-2] R[n-1] ... R[n]
If R is not specified, a square Hankel matrix is returned
where C represents the first row and column. The elements
below the first anti-diagonal are zero such that:
H[i, j] = c[i + j - 1] if i + j - 1 <= n
H[i, j] = 0 otherwise
If R is specified, an unsymmetric Hankel matrix is returned
where the first column is C and the last row is R such that:
H[i, j] = c[i + j - 1] if i + j - 1 <= n
H[i, j] = r[i + j - n] otherwise
In this case, if C[end] != R[1], C[end] is used as the last
element.
See Also:
Kron
Toeplitz
Vander
#endif
/* create a symmetric or unsymmetric Hankel matrix */
hankel(c, r)
{
local nr, nc, hk, hs, cc;
if (argc < 1)
{
error("hankel - input series required");
}
/* cast and flatten */
c = unravel({c});
nc = length(c);
if (nc == 0) return({});
if (argc < 2)
{
r = zeros(nc, 1);
nr = nc;
}
else
{
/* cast and flatten row */
r = unravel({r});
nr = length(r);
if (nr == 0) return({});
/* check diagonal conflict */
if (r[1] != c[nc])
{
echo("hankel - last column value used as last diagonal value");
}
}
/* subscript vector */
hs = concat(c, extract(r, 2, nr - 1));
/* subscript array */
hk = outerprod(repcol(1..nc, nr), 0..nr - 1, "+");
/* preserve Hankel shape */
hk[..] = hs[hk];
return(hk);
}