Function Repository Resource:

PolynomialSmithDecomposition

Source Notebook

Compute the Smith decomposition of a matrix of univariate polynomials

Contributed by: Daniel Lichtblau

ResourceFunction["PolynomialSmithDecomposition"][mat]

computes the Smith decomposition of the matrix mat of univariate polynomials.

ResourceFunction["PolynomialSmithDecomposition"][mat,x]

computes the Smith decomposition for a matrix of polynomials in the variable x.

Details and Options

The result is given in the form {u,s,v}, where u and v are unimodular matrices, s is a diagonal matrix and u.mat.vs. Moreover, each diagonal element of s divides all subsequent diagonal elements.
A unimodular matrix over a ring of univariate polynomials is a matrix with nonzero determinant lying in the coefficient field (that is, constant).
The Smith decomposition is computed using iterations of the Hermite decomposition, as implemented in the resource function PolynomialHermiteDecomposition.
Multivariate polynomials are regarded as univariate in the specified variable, with all others treated as symbolic coefficients.
ResourceFunction["PolynomialSmithDecomposition"] takes Method and Modulus as options. These are the same as for PolynomialHermiteDecomposition.
For specifics of the Method option, see documentation for PolynomialHermiteDecomposition. The only uses in ResourceFunction["PolynomialSmithDecomposition"] are to pass it to the Hermite computations.
ResourceFunction["PolynomialSmithDecomposition"] is intended for matrices of polynomials in a single variable, with all coefficients being exact numbers.

Examples

Basic Examples (4) 

Compute the Smith decomposition of a 2×3 matrix of low degree polynomials:

In[1]:=
mat = {{x^3 - 11, x^2 - 2 x + 5, x^3 - 2 x^2 + 3 x - 7}, {x^2 + 4 x + 9, x^2 - 19, x^3 + 5 x - 6}};
{u, s, v} = ResourceFunction["PolynomialSmithDecomposition"][mat]
Out[1]=

Check the matrix equation:

In[2]:=
Expand[u . mat . v - s]
Out[2]=

Check that u and v are unimodular; that is, they are constants:

In[3]:=
{Det[u], Det[v]}
Out[3]=

Check that the diagonal entries of s divide into subsequent entries:

In[4]:=
Apply[Divisible, Reverse[#]] & /@ Partition[Diagonal[s], 2, 1]
Out[4]=

Options (6) 

Modulus (6) 

Generate and compute the Hermite decomposition for an 8×12 matrix of random degree-5 polynomials with coefficients between -10 and 10:

In[5]:=
randomPoly[deg_, max_, x_] := RandomInteger[{-max, max}, deg + 1] . x^Range[0, deg]
randomMatrix[m_, n_, deg_, max_, x_] := Table[randomPoly[deg, max, x], {m}, {n}]
SeedRandom[1111];
bigmat = randomMatrix[8, 12, 5, 10, x];
Timing[{u, s, v} = ResourceFunction["PolynomialSmithDecomposition"][bigmat]] // First
Out[5]=

As is often the case in symbolic computation, speed improves considerably when one works over a prime field of modest size:

In[6]:=
Timing[{umod, smod, vmod} = ResourceFunction["PolynomialSmithDecomposition"][bigmat, Modulus -> 103]] // First
Out[6]=

Check that the Smith form is a diagonal matrix:

In[7]:=
DiagonalMatrixQ[smod]
Out[7]=

Check that the decomposition satisfies the necessary matrix identity:

In[8]:=
PolynomialMod[Expand[umod . bigmat . vmod - smod, Modulus -> 103], Modulus -> 103]
Out[8]=

Check that the left factor is unimodular:

In[9]:=
Det[umod]
Out[9]=

The determinant of the right factor cannot easily be computed due to expression swell. A probabilistic test that it is unimodular (that is, a constant) is to check that it gives the same value with multiple substitutions of the polynomial variable:

In[10]:=
Table[Mod[Det[vmod /. x -> j], 103], {j, 1, 25, 3}]
Out[10]=

Neat Examples (2) 

Use the Smith decomposition to compute the minimal polynomial of a matrix:

In[11]:=
ResourceFunction["PolynomialSmithDecomposition"][
  IdentityMatrix[Length[mat]] x - mat, x][[2, -1, -1]]
Out[11]=

The result from PolynomialSmithDecomposition is a scalar multiple of the result of the resource function MatrixMinimalPolynomial:

In[12]:=
ResourceFunction["MatrixMinimalPolynomial"][mat, x]
Out[12]=

For a square matrix mat, the nontrivial diagonal elements in the Smith normal form for mat-x ℑ are the invariant factors of the characteristic polynomial of mat (here ℑ is the identity matrix of same dimension as mat). We can use this to compute the rational canonical form.

We start with code to create a companion matrix from a polynomial:

In[13]:=
companionMatrix[poly_, x_] := Module[
  {clist = CoefficientList[poly, x], len = Exponent[poly, x], cmat},
  cmat = ConstantArray[0, {len, len}];
  Do[cmat[[i, i - 1]] = 1, {i, 2, len}];
  cmat[[All, -1]] = -Most[clist]/Last[clist];
  cmat
  ]

Work with an upper triangular matrix having a nontrivial minimal polynomial and hence nontrivial rational canonical form:

In[14]:=
SeedRandom[1234];
mat = DiagonalMatrix[{1, 1, 2, 2, 2, 2, 3, 3, 3}];
Do[mat[[i, j]] = RandomInteger[], {i, 1, 4}, {j, i + 1, 5}];
MatrixForm[mat]
Out[17]=

Find the diagonal for the Smith normal form of mat-x:

In[18]:=
{uu, ss, vv} = ResourceFunction["PolynomialSmithDecomposition"][
   mat - x*IdentityMatrix[Length[mat]], x];
diag = Diagonal[ss]
Out[19]=

Compute the submatrices for the diagonal block:

In[20]:=
compmats = Map[companionMatrix[#, x] &, diag]
Out[20]=

Use SparseArray and Band to reconstruct the companion matrix for mat as a diagonal block matrix:

In[21]:=
compmat = Normal[SparseArray[Band[{1, 1}] -> (compmats /. {} -> Nothing)]]
Out[21]=

Version History

  • 1.0.3 – 18 October 2022
  • 1.0.2 – 19 January 2022

Related Resources

Author Notes

PolynomialSmithDecomposition inherits any weaknesses found in the resource function PolynomialHermiteDecomposition. Since the Smith decomposition uses iterations of the Hermite decomposition, such issues could be compounded. It might not give good results, for example, in the case where input polynomials have approximate coefficients.

License Information