The eigenvalues of a square matrix $A$ are the roots of its characteristic polynomial $\chi(\lambda)$. Conversely, if we have a monic polynomial $p(\lambda)=a_0 + a_1 \lambda + \cdots + a_{n-1}\lambda^{n-1} + \lambda^n,$ we can define a companion matrix of the polynomial $p$:
$C=\begin{bmatrix} 0 & 0 & \dots & 0 & -a_0 \\ 1 & 0 & \dots & 0 & -a_1 \\ 0 & 1 & \dots & 0 & -a_2 \\ \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & 0 & \dots & 1 & -a_{n-1} \end{bmatrix}.$
$C$ will have the property that its characteristic polynomial will recover $p$; i.e., $\chi(\lambda) = p(\lambda)$.
Question #1: Is there a built-in function to produce the companion matrix for a polynomial? I don't seem to be finding one.
In the meantime, I have cobbled together the following:
p[x_] := With[{maxDegree = 10000},
Sum[a[n] x^n, {n, 0, maxDegree}] + x^maxDegree]
companionMatrix[poly_]:= With[
{coeff = -Drop[CoefficientList[poly[x], x],-1]},
Transpose[
PadLeft[IdentityMatrix[Length@coeff -1],{Length@coeff-1,Length@coeff} ]
~Join~ {coeff}
]]
companionMatrix[p]//MatrixForm
Question #2: Is this code reasonable? Is there a better way?
My code seems to run reasonably fast ($\approx 0.03$ seconds when I bump $p$ up to a degree 1000 monic polynomial, $\approx 4.8$ seconds for degree 10,000). However, there are a lot of zeroes in this matrix. I presume that this would be much much more efficient as a SparseArray
?