View Raw SPL
/*****************************************************************************
* *
* POLY.SPL Copyright (C) 1997-2015 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Carl Trapanni *
* *
* Synopsis: Calculates coefficents of characteristic polynomial *
* *
* Revisions: 18 Sep 1997 CCT Creation *
* 1 Oct 1997 CCT complex input *
* 17 Feb 2005 RRR use convolution for polynomial multiply *
* *
*****************************************************************************/
#if @HELP_POLY
POLY
Purpose:
Calculates coefficients of the characteristic polynomial
Syntax:
POLY(x)
x - A series or matrix. A matrix where the eigenvalues are
the roots of the returned polynomial coefficients or
a series of the roots of the returned polynomial
coefficients.
Returns:
A series, the polynomial coefficients in descending order..
Example:
W1: {{1, 2, 3},
{3, 4, 5},
{5, 6, 0}}
W2: poly(W1)
W3: polyroot(W2, 1)
W4: eigval(W1)
W2 contains the series {1, -5, -47, -14}, the coefficients in
descending order of the characteristic polynomial of the matrix
in W1. The roots of this polynomial are the eigenvalues of the
input matrix.
W3 == {9.894, -4.585, -0.309}
W4 == {9.894, -0.309, -4.585}
If the input is a series, the series represents the roots of
the polynomial coefficients returned by POLY. For example,
consider the polynomial:
P(x) = (x + 2) * (x + 1) = x^2 + 3*x + 2
poly({-2, -1}) == {1, 3, 2}
polyroot({1, 3, 2}, 1) == {-2, -1}
Remarks:
As indicated above, if the input is a matrix, POLY returns the
coefficients of the characteristic polynomial in descending
order.
If the input is a series, the input represents the roots of a
polynomial and POLY returns the coefficients of this polynomial
in descending order.
See Also:
POLYFIT
POLYDER
POLYROOT
POLYVAL
ROOTS
#endif
/* find characteristic polynomial or polynomial from roots */
poly(x)
{
local a, k, m, n, v, y, cj1, cj2;
(m, n) = size(x);
/* empty case first since EIGVAL won't accept empty input */
if (m == 0)
{
return({1});
}
else if (n == 1)
{
/* scalar or use faster reference */
v = (m == 1) ? {x} : refseries(x);
}
/* convert single row into column */
else if ((m == 1) && (n > 1))
{
v = x';
}
/* characteristic polynomial if square x */
else if (m == n)
{
/* eigenvalues are the roots of the characteristic polynomial */
v = eigval(x);
if (length(v) == 0)
{
return({1});
}
}
else
{
error("poly - series or square matrix required");
}
/* strip infinites */
v = delete(v, isinf(v));
if (length(v) == 0)
{
/* empty or all inf */
return({1});
}
/* create array where each column is (1 - ROOT_k) */
a = ones(2, length(v));
a[2, ..] = -v';
y = {1};
/* use convolution to multiply root terms */
loop (k = 1..numcols(a))
{
y = conv(y, col(a, int(k)));
}
if (not(iscomplex(x)))
{
/* force real if matrix was real */
y = real(y);
}
else
{
/* check for all complex conjugate roots */
cj1 = sort(v[find(imag(v) > 0)]);
cj2 = sort(conj(v[find(imag(v) < 0))]);
if (length(cj1) == length(cj2))
{
if (all(cj1 == cj2))
{
y = real(y);
}
}
}
return(y);
}