Similarity class types of matrices with entries in a finite field - Combinatorics

Skip to content
Back to top
View this page
Edit this page

# Similarity class types of matrices with entries in a finite field

The notion of a matrix conjugacy class type was introduced by J. A. Green in [Green55], in the context of computing the irreducible characters of finite general linear groups. The class types are equivalence classes of similarity classes of square matrices with entries in a finite field which, roughly speaking, have the same qualitative properties.

For example, all similarity classes of the same class type have centralizers of the same cardinality and the same degrees of elementary divisors. Qualitative properties of similarity classes such as semisimplicity and regularity descend to class types.

The most important feature of similarity class types is that, for any \(n\), the number of similarity class types of \(n\times n\) matrices is independent of \(q\). This makes it possible to perform many combinatorial calculations treating \(q\) as a formal variable.

In order to define similarity class types, recall that similarity classes of \(n\times n\) matrices with entries in \(\GF{q}\) correspond to functions

\[c: \mathrm{Irr}\GF{q[t]} \to \Lambda\]

such that

\[\sum_{f\in \mathrm{Irr}\GF{q[t]}} |c(f)|\deg f = n,\]

where we denote the set of irreducible monic polynomials in \(\GF{q[t]}\) by \(\mathrm{Irr}\GF{q[t]}\), the set of all partitions by \(\Lambda\), and the size of \(\lambda \in \Lambda\) by \(|\lambda|\).

Similarity classes indexed by functions \(c_1\) and \(c_2\) as above are said to be of the same type if there exists a degree-preserving self-bijection \(\sigma\) of \(\mathrm{Irr}\GF{q[t]}\) such that \(c_2 = c_1\circ \sigma\). Thus, the type of \(c\) remembers only the degrees of the polynomials (and not the polynomials themselves) for which \(c\) takes a certain value \(\lambda\). Replacing each irreducible polynomial of degree \(d\) for which \(c\) takes a non-trivial value \(\lambda\) by the pair \((d, \lambda)\), we obtain a multiset of such pairs. Clearly, \(c_1\) and \(c_2\) have the same type if and only if these multisets are equal. Thus a similarity class type may be viewed as a multiset of pairs of the form \((d, \lambda)\).

For \(2 \times 2\) matrices there are four types:

Sage

    sage: for tau in SimilarityClassTypes(2):
    ....:    print(tau)
    [[1, [1]], [1, [1]]]
    [[1, [2]]]
    [[1, [1, 1]]]
    [[2, [1]]]

Python

    >>> from sage.all import *
    >>> for tau in SimilarityClassTypes(Integer(2)):
    ...    print(tau)
    [[1, [1]], [1, [1]]]
    [[1, [2]]]
    [[1, [1, 1]]]
    [[2, [1]]]

These four types correspond to the regular split semisimple matrices, the non-semisimple matrices, the central matrices and the irreducible matrices respectively.

For any matrix \(A\) in a given similarity class type, it is possible to calculate the number elements in the similarity class of \(A\), the dimension of the algebra of matrices in \(M_n(A)\) that commute with \(A\), and the cardinality of the subgroup of \(GL_n(\GF{q})\) that commute with \(A\). For each similarity class type, it is also possible to compute the number of classes of that type (and hence, the total number of matrices of that type). All these calculations treat the cardinality \(q\) of the finite field as a formal variable:

Sage

    sage: M = SimilarityClassType([[1, [1]], [1, [1]]])
    sage: M.class_card()
    q^2 + q
    sage: M.centralizer_algebra_dim()
    2
    sage: M.centralizer_group_card()
    q^2 - 2*q + 1
    sage: M.number_of_classes()
    1/2*q^2 - 1/2*q
    sage: M.number_of_matrices()
    1/2*q^4 - 1/2*q^2

[Python]

    >>> from sage.all import *
    >>> M = SimilarityClassType([[Integer(1), [Integer(1)]], [Integer(1), [Integer(1)]]])
    >>> M.class_card()
    q^2 + q
    >>> M.centralizer_algebra_dim()
    2
    >>> M.centralizer_group_card()
    q^2 - 2*q + 1
    >>> M.number_of_classes()
    1/2*q^2 - 1/2*q
    >>> M.number_of_matrices()
    1/2*q^4 - 1/2*q^2

We now describe two applications of similarity class types.

We say that an \(n \times n\) matrix has rational canonical form type \(\lambda\) for some partition \(\lambda\) of \(n\) if the diagonal blocks in the rational canonical form have sizes given by the parts of \(\lambda\). Thus the matrices with rational canonical type \((n)\) are the regular ones, while the matrices with rational canonical type \((1^n)\) are the central ones.

Using similarity class types, it becomes easy to get a formula for the number of matrices with a given rational canonical type:

Sage

    sage: def matrices_with_rcf(la):
    ....:    return sum([tau.number_of_matrices() for tau in filter(lambda tau:tau.rcf()==la, SimilarityClassTypes(la.size()))])
    sage: matrices_with_rcf(Partition([2,1]))
    q^6 + q^5 + q^4 - q^3 - q^2 - q

Python

    >>> from sage.all import *
    >>> def matrices_with_rcf(la):
    ...    return sum([tau.number_of_matrices() for tau in filter(lambda tau:tau.rcf()==la, SimilarityClassTypes(la.size()))])
    >>> matrices_with_rcf(Partition([Integer(2),Integer(1)]))
    q^6 + q^5 + q^4 - q^3 - q^2 - q

Similarity class types can also be used to calculate the number of simultaneous similarity classes of \(k\)-tuples of \(n\times n\) matrices with entries in \(\GF{q}\) by using Burnside’s lemma:

Sage

    sage: from sage.combinat.similarity_class_type import order_of_general_linear_group, centralizer_algebra_dim
    sage: q = ZZ['q'].gen()
    sage: def simultaneous_similarity_classes(n, k):
    ....:     return SimilarityClassTypes(n).sum(lambda la: q**(k*centralizer_algebra_dim(la)), invertible = True)/order_of_general_linear_group(n)
    sage: simultaneous_similarity_classes(3, 2)
    q^10 + q^8 + 2*q^7 + 2*q^6 + 2*q^5 + q^4

[Python]

    >>> from sage.all import *
    >>> from sage.combinat.similarity_class_type import order_of_general_linear_group, centralizer_algebra_dim
    >>> q = ZZ['q'].gen()
    >>> def simultaneous_similarity_classes(n, k):
    ...     return SimilarityClassTypes(n).sum(lambda la: q**(k*centralizer_algebra_dim(la)), invertible = True)/order_of_general_linear_group(n)
    >>> simultaneous_similarity_classes(Integer(3), Integer(2))
    q^10 + q^8 + 2*q^7 + 2*q^6 + 2*q^5 + q^4

Similarity class types can be used to compute the coefficients of generating functions coming from the cycle index type techniques of Kung and Stong (see Morrison [Morrison06]).

They can also be used to compute the number of invariant subspaces for a matrix over a finite field of any given dimension. For this we use the elegant recursive formula of Ramaré [R17] (see also [PR22]).

Along with the results of [PSS13], similarity class types can be used to calculate the number of similarity classes of matrices of order \(n\) with entries in a principal ideal local ring of length two with residue field of cardinality \(q\) with centralizer of any given cardinality up to \(n = 4\). Among these, the classes which are selftranspose can also be counted:

Sage

    sage: from sage.combinat.similarity_class_type import matrix_centralizer_cardinalities_length_two
    sage: list(matrix_centralizer_cardinalities_length_two(3))
    [(q^6 - 3*q^5 + 3*q^4 - q^3, 1/6*q^6 - 1/2*q^5 + 1/3*q^4),
    (q^6 - 2*q^5 + q^4, q^5 - q^4),
    (q^8 - 3*q^7 + 3*q^6 - q^5, 1/2*q^5 - q^4 + 1/2*q^3),
    (q^8 - 2*q^7 + q^6, q^4 - q^3),
    (q^10 - 2*q^9 + 2*q^7 - q^6, q^4 - q^3),
    (q^8 - q^7 - q^6 + q^5, 1/2*q^5 - q^4 + 1/2*q^3),
    (q^6 - q^5 - q^4 + q^3, 1/2*q^6 - 1/2*q^5),
    (q^6 - q^5, q^4),
    (q^10 - 2*q^9 + q^8, q^3),
    (q^8 - 2*q^7 + q^6, q^4 - q^3),
    (q^8 - q^7, q^3 + q^2),
    (q^12 - 3*q^11 + 3*q^10 - q^9, 1/6*q^4 - 1/2*q^3 + 1/3*q^2),
    (q^12 - 2*q^11 + q^10, q^3 - q^2),
    (q^14 - 2*q^13 + 2*q^11 - q^10, q^3 - q^2),
    (q^12 - q^11 - q^10 + q^9, 1/2*q^4 - 1/2*q^3),
    (q^12 - q^11, q^2),
    (q^14 - 2*q^13 + q^12, q^2),
    (q^18 - q^17 - q^16 + q^14 + q^13 - q^12, q^2),
    (q^12 - q^9, 1/3*q^4 - 1/3*q^2),
    (q^6 - q^3, 1/3*q^6 - 1/3*q^4)]

Python

    >>> from sage.all import *
    >>> from sage.combinat.similarity_class_type import matrix_centralizer_cardinalities_length_two
    >>> list(matrix_centralizer_cardinalities_length_two(Integer(3)))
    [(q^6 - 3*q^5 + 3*q^4 - q^3, 1/6*q^6 - 1/2*q^5 + 1/3*q^4),
    (q^6 - 2*q^5 + q^4, q^5 - q^4),
    (q^8 - 3*q^7 + 3*q^6 - q^5, 1/2*q^5 - q^4 + 1/2*q^3),
    (q^8 - 2*q^7 + q^6, q^4 - q^3),
    (q^10 - 2*q^9 + 2*q^7 - q^6, q^4 - q^3),
    (q^8 - q^7 - q^6 + q^5, 1/2*q^5 - q^4 + 1/2*q^3),
    (q^6 - q^5 - q^4 + q^3, 1/2*q^6 - 1/2*q^5),
    (q^6 - q^5, q^4),
    (q^10 - 2*q^9 + q^8, q^3),
    (q^8 - 2*q^7 + q^6, q^4 - q^3),
    (q^8 - q^7, q^3 + q^2),
    (q^12 - 3*q^11 + 3*q^10 - q^9, 1/6*q^4 - 1/2*q^3 + 1/3*q^2),
    (q^12 - 2*q^11 + q^10, q^3 - q^2),
    (q^14 - 2*q^13 + 2*q^11 - q^10, q^3 - q^2),
    (q^12 - q^11 - q^10 + q^9, 1/2*q^4 - 1/2*q^3),
    (q^12 - q^11, q^2),
    (q^14 - 2*q^13 + q^12, q^2),
    (q^18 - q^17 - q^16 + q^14 + q^13 - q^12, q^2),
    (q^12 - q^9, 1/3*q^4 - 1/3*q^2),
    (q^6 - q^3, 1/3*q^6 - 1/3*q^4)]

REFERENCES:

[Green55]

Green, J. A. The characters of the finite general linear groups. Trans. Amer. Math. Soc. 80 (1955), 402–447. doi:10.1090/S0002-9947-1955-0072878-2

[Morrison06]

Morrison, Kent E. Integer sequences and matrices over finite fields. J. Integer Seq. 9 (2006), no. 2, Article 06.2.1, 28 pp. https://cs.uwaterloo.ca/journals/JIS/VOL9/Morrison/morrison37.html

[PSS13] (1,2)

Prasad, A., Singla, P., and Spallone, S., Similarity of matrices over local rings of length two. arXiv 1212.6157

[PR22]

Prasad, A., Ram, S., Splitting subspaces and a finite field interpretation of the Touchard-Riordan formula. arXiv 2205.11076

[R17]

Ramaré, O., Rationality of the zeta function of the subgroups of abelian p-groups. Publ. Math. Debrecen 90.1-2. doi:10.5486/PMD.2017.7466

AUTHOR:

- Amritanshu Prasad (2013-07-18): initial implementation

- Amritanshu Prasad (2013-09-09): added functions for similarity classes over rings of length two

- Amritanshu Prasad (2022-07-31): added computation of similarity class type of a given matrix and invariant subspace generating function

class sage.combinat.similarity_class_type.PrimarySimilarityClassType(parent, deg, par)

  Bases: `Element`

  A primary similarity class type is a pair consisting of a partition and a positive integer.

  For a partition \(\lambda\) and a positive integer \(d\), the primary similarity class type \((d, \lambda)\) represents similarity classes of square matrices of order \(|\lambda| \cdot d\) with entries in a finite field of order \(q\) which correspond to the \(\GF{q[t]}\)-module

  \[\frac{\GF{q[t]}}{p(t)^{\lambda_1} } \oplus \frac{\GF{q[t]}}{p(t)^{\lambda_2}} \oplus \dotsb\]

  for some irreducible polynomial \(p(t)\) of degree \(d\).

  centralizer_algebra_dim()

    Return the dimension of the algebra of matrices which commute with a matrix of type `self`.

    For a partition \((d, \lambda)\) this dimension is given by \(d(\lambda_1 + 3\lambda_2 + 5\lambda_3 + \cdots)\).

    EXAMPLES:

    Sage

        sage: PT = PrimarySimilarityClassType(2, [3, 2, 1])
        sage: PT.centralizer_algebra_dim()
        28

    Python

        >>> from sage.all import *
        >>> PT = PrimarySimilarityClassType(Integer(2), [Integer(3), Integer(2), Integer(1)])
        >>> PT.centralizer_algebra_dim()
        28

  centralizer_group_card(q=None)

    Return the cardinality of the centralizer group of a matrix of type `self` in a field of order `q`.

    INPUT:

    - `q` – integer or an indeterminate

    EXAMPLES:

    Sage

        sage: PT = PrimarySimilarityClassType(1, [])
        sage: PT.centralizer_group_card()
        1
        sage: PT = PrimarySimilarityClassType(2, [1, 1])
        sage: PT.centralizer_group_card()
        q^8 - q^6 - q^4 + q^2

    Python

        >>> from sage.all import *
        >>> PT = PrimarySimilarityClassType(Integer(1), [])
        >>> PT.centralizer_group_card()
        1
        >>> PT = PrimarySimilarityClassType(Integer(2), [Integer(1), Integer(1)])
        >>> PT.centralizer_group_card()
        q^8 - q^6 - q^4 + q^2

  degree()

    Return degree of `self`.

    EXAMPLES:

    Sage

        sage: PT = PrimarySimilarityClassType(2, [3, 2, 1])
        sage: PT.degree()
        2

    Python

        >>> from sage.all import *
        >>> PT = PrimarySimilarityClassType(Integer(2), [Integer(3), Integer(2), Integer(1)])
        >>> PT.degree()
        2

  invariant_subspace_generating_function(q=None, t=None)

    Return the invariant subspace generating function of `self`.

    INPUT:

    - `q` – (optional) an integer or an inderminate

    - `t` – (optional) an indeterminate

    EXAMPLES:

    Sage

        sage: PrimarySimilarityClassType(1, [2, 2]).invariant_subspace_generating_function()
        t^4 + (q + 1)*t^3 + (q^2 + q + 1)*t^2 + (q + 1)*t + 1

    Python

        >>> from sage.all import *
        >>> PrimarySimilarityClassType(Integer(1), [Integer(2), Integer(2)]).invariant_subspace_generating_function()
        t^4 + (q + 1)*t^3 + (q^2 + q + 1)*t^2 + (q + 1)*t + 1

  partition()

    Return partition corresponding to `self`.

    EXAMPLES:

    Sage

        sage: PT = PrimarySimilarityClassType(2, [3, 2, 1])
        sage: PT.partition()
        [3, 2, 1]

    Python

        >>> from sage.all import *
        >>> PT = PrimarySimilarityClassType(Integer(2), [Integer(3), Integer(2), Integer(1)])
        >>> PT.partition()
        [3, 2, 1]

  size()

    Return the size of `self`.

    EXAMPLES:

    Sage

        sage: PT = PrimarySimilarityClassType(2, [3, 2, 1])
        sage: PT.size()
        12

    Python

        >>> from sage.all import *
        >>> PT = PrimarySimilarityClassType(Integer(2), [Integer(3), Integer(2), Integer(1)])
        >>> PT.size()
        12

  statistic(func, q=None)

    Return \(n_{\lambda}(q^d)\) where \(n_{\lambda}\) is the value returned by `func` upon input \(\lambda\), if `self` is \((d, \lambda)\).

    EXAMPLES:

    Sage

        sage: PT = PrimarySimilarityClassType(2, [3, 1])
        sage: q = ZZ['q'].gen()
        sage: PT.statistic(lambda la:q**la.size(), q = q)
        q^8

    Python

        >>> from sage.all import *
        >>> PT = PrimarySimilarityClassType(Integer(2), [Integer(3), Integer(1)])
        >>> q = ZZ['q'].gen()
        >>> PT.statistic(lambda la:q**la.size(), q = q)
        q^8

class sage.combinat.similarity_class_type.PrimarySimilarityClassTypes(n, min)

  Bases: `UniqueRepresentation`, `Parent`

  All primary similarity class types of size `n` whose degree is greater than that of `min` or whose degree is that of `min` and whose partition is less than of `min` in lexicographic order.

  A primary similarity class type of size \(n\) is a pair \((\lambda, d)\) consisting of a partition \(\lambda\) and a positive integer \(d\) such that \(|\lambda| d = n\).

  INPUT:

  - `n` – positive integer

  - `min` – a primary matrix type of size `n`

  EXAMPLES:

  If `min` is not specified, then the class of all primary similarity class types of size `n` is created:

  Sage

      sage: PTC = PrimarySimilarityClassTypes(2)
      sage: for PT in PTC:
      ....:     print(PT)
      [1, [2]]
      [1, [1, 1]]
      [2, [1]]

  Python

      >>> from sage.all import *
      >>> PTC = PrimarySimilarityClassTypes(Integer(2))
      >>> for PT in PTC:
      ...     print(PT)
      [1, [2]]
      [1, [1, 1]]
      [2, [1]]

  If `min` is specified, then the class consists of only those primary similarity class types whose degree is greater than that of `min` or whose degree is that of `min` and whose partition is less than of `min` in lexicographic order:

  Sage

      sage: PTC = PrimarySimilarityClassTypes(2, min = PrimarySimilarityClassType(1, [1, 1]))
      sage: for PT in PTC:
      ....:     print(PT)
      [1, [1, 1]]
      [2, [1]]

  [Python]

      >>> from sage.all import *
      >>> PTC = PrimarySimilarityClassTypes(Integer(2), min = PrimarySimilarityClassType(Integer(1), [Integer(1), Integer(1)]))
      >>> for PT in PTC:
      ...     print(PT)
      [1, [1, 1]]
      [2, [1]]

  Element

    alias of `PrimarySimilarityClassType`

  size()

    Return size of elements of `self`.

    The size of a primary similarity class type \((d, \lambda)\) is \(d |\lambda|\).

    EXAMPLES:

    Sage

        sage: PTC = PrimarySimilarityClassTypes(2)
        sage: PTC.size()
        2

    Python

        >>> from sage.all import *
        >>> PTC = PrimarySimilarityClassTypes(Integer(2))
        >>> PTC.size()
        2

class sage.combinat.similarity_class_type.SimilarityClassType(parent, tau)

  Bases: `CombinatorialElement`

  A similarity class type.

  A matrix type is a multiset of primary similarity class types.

  INPUT:

  - `tau` – list of primary similarity class types or a square matrix over a finite field

  EXAMPLES:

  Sage

      sage: tau1 = SimilarityClassType([[3, [3, 2, 1]], [2, [2, 1]]]); tau1
      [[2, [2, 1]], [3, [3, 2, 1]]]

      sage: SimilarityClassType(Matrix(GF(2), [[1,1],[0,1]]))
      [[1, [2]]]

  Python

      >>> from sage.all import *
      >>> tau1 = SimilarityClassType([[Integer(3), [Integer(3), Integer(2), Integer(1)]], [Integer(2), [Integer(2), Integer(1)]]]); tau1
      [[2, [2, 1]], [3, [3, 2, 1]]]

      >>> SimilarityClassType(Matrix(GF(Integer(2)), [[Integer(1),Integer(1)],[Integer(0),Integer(1)]]))
      [[1, [2]]]

  as_partition_dictionary()

    Return a dictionary whose keys are the partitions of types occurring in `self` and the value at the key \(\lambda\) is the partition formed by sorting the degrees of primary types with partition \(\lambda\).

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
        sage: tau.as_partition_dictionary()
        {[1]: [1, 1]}

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(1), [Integer(1)]], [Integer(1), [Integer(1)]]])
        >>> tau.as_partition_dictionary()
        {[1]: [1, 1]}

  centralizer_algebra_dim()

    Return the dimension of the algebra of matrices which commute with a matrix of type `self`.

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
        sage: tau.centralizer_algebra_dim()
        2

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(1), [Integer(1)]], [Integer(1), [Integer(1)]]])
        >>> tau.centralizer_algebra_dim()
        2

  centralizer_group_card(q=None)

    Return the cardinality of the group of matrices in \(GL_n(\GF{q})\) which commute with a matrix of type `self`.

    INPUT:

    - `q` – integer or an indeterminate

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
        sage: tau.centralizer_group_card()
        q^2 - 2*q + 1

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(1), [Integer(1)]], [Integer(1), [Integer(1)]]])
        >>> tau.centralizer_group_card()
        q^2 - 2*q + 1

  class_card(q=None)

    Return the number of matrices in each similarity class of type `self`.

    INPUT:

    - `q` – integer or an indeterminate

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[1, [1, 1, 1, 1]]])
        sage: tau.class_card()
        1
        sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
        sage: tau.class_card()
        q^2 + q

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(1), [Integer(1), Integer(1), Integer(1), Integer(1)]]])
        >>> tau.class_card()
        1
        >>> tau = SimilarityClassType([[Integer(1), [Integer(1)]], [Integer(1), [Integer(1)]]])
        >>> tau.class_card()
        q^2 + q

  invariant_subspace_generating_function(q=None, t=None)

    Return the invariant subspace generating function of `self`.

    The invariant subspace generating function is the function is the polynomial

    \[\sum_{j\geq 0} a_j(q) t^j,\]

    where \(a_j(q)\) denotes the number of \(j\)-dimensional invariant subspaces of dimensiona \(j\) for any matrix with the similarity class type `self` with entries in a field of order \(q\).

    EXAMPLES:

    Sage

        sage: SimilarityClassType([[1, [2, 2]]]).invariant_subspace_generating_function()
        t^4 + (q + 1)*t^3 + (q^2 + q + 1)*t^2 + (q + 1)*t + 1
        sage: A = Matrix(GF(2),[(0, 1, 0, 0), (0, 1, 1, 1), (1, 0, 1, 0), (1, 1, 0, 0)])
        sage: SimilarityClassType(A).invariant_subspace_generating_function()
        t^4 + 1

    Python

        >>> from sage.all import *
        >>> SimilarityClassType([[Integer(1), [Integer(2), Integer(2)]]]).invariant_subspace_generating_function()
        t^4 + (q + 1)*t^3 + (q^2 + q + 1)*t^2 + (q + 1)*t + 1
        >>> A = Matrix(GF(Integer(2)),[(Integer(0), Integer(1), Integer(0), Integer(0)), (Integer(0), Integer(1), Integer(1), Integer(1)), (Integer(1), Integer(0), Integer(1), Integer(0)), (Integer(1), Integer(1), Integer(0), Integer(0))])
        >>> SimilarityClassType(A).invariant_subspace_generating_function()
        t^4 + 1

  is_regular()

    Return `True` if every primary type in `self` has partition with one part.

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[2, [1]], [1, [3]]])
        sage: tau.is_regular()
        True
        sage: tau = SimilarityClassType([[2, [1, 1]], [1, [3]]])
        sage: tau.is_regular()
        False

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(2), [Integer(1)]], [Integer(1), [Integer(3)]]])
        >>> tau.is_regular()
        True
        >>> tau = SimilarityClassType([[Integer(2), [Integer(1), Integer(1)]], [Integer(1), [Integer(3)]]])
        >>> tau.is_regular()
        False

  is_semisimple()

    Return `True` if every primary similarity class type in `self` has all parts equal to `1`.

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[2, [1, 1]], [1, [1]]])
        sage: tau.is_semisimple()
        True
        sage: tau = SimilarityClassType([[2, [1, 1]], [1, [2]]])
        sage: tau.is_semisimple()
        False

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(2), [Integer(1), Integer(1)]], [Integer(1), [Integer(1)]]])
        >>> tau.is_semisimple()
        True
        >>> tau = SimilarityClassType([[Integer(2), [Integer(1), Integer(1)]], [Integer(1), [Integer(2)]]])
        >>> tau.is_semisimple()
        False

  number_of_classes(invertible=False, q=None)

    Return the number of similarity classes of matrices of type `self`.

    INPUT:

    - `invertible` – boolean; return number of invertible classes if set to `True`

    - `q` – integer or an indeterminate

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
        sage: tau.number_of_classes()
        1/2*q^2 - 1/2*q

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(1), [Integer(1)]], [Integer(1), [Integer(1)]]])
        >>> tau.number_of_classes()
        1/2*q^2 - 1/2*q

  number_of_matrices(invertible=False, q=None)

    Return the number of matrices of type `self`.

    INPUT:

    - `invertible` – a boolean; return the number of invertible matrices if set

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[1, [1]]])
        sage: tau.number_of_matrices()
        q
        sage: tau.number_of_matrices(invertible = True)
        q - 1
        sage: tau = SimilarityClassType([[1, [1]], [1, [1]]])
        sage: tau.number_of_matrices()
        1/2*q^4 - 1/2*q^2

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(1), [Integer(1)]]])
        >>> tau.number_of_matrices()
        q
        >>> tau.number_of_matrices(invertible = True)
        q - 1
        >>> tau = SimilarityClassType([[Integer(1), [Integer(1)]], [Integer(1), [Integer(1)]]])
        >>> tau.number_of_matrices()
        1/2*q^4 - 1/2*q^2

  rcf()

    Return the partition corresponding to the rational canonical form of a matrix of type `self`.

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[2, [1, 1, 1]], [1, [3, 2]]])
        sage: tau.rcf()
        [5, 4, 2]

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(2), [Integer(1), Integer(1), Integer(1)]], [Integer(1), [Integer(3), Integer(2)]]])
        >>> tau.rcf()
        [5, 4, 2]

  size()

    Return the sum of the sizes of the primary parts of `self`.

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[3, [3, 2, 1]], [2, [2, 1]]])
        sage: tau.size()
        24

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(3), [Integer(3), Integer(2), Integer(1)]], [Integer(2), [Integer(2), Integer(1)]]])
        >>> tau.size()
        24

  statistic(func, q=None)

    Return.

    \[\prod_{(d, \lambda)\in \tau} n_{\lambda}(q^d)\]

    where \(n_{\lambda}(q)\) is the value returned by `func` on the input \(\lambda\).

    INPUT:

    - `func` – a function that takes a partition to a polynomial in `q`

    - `q` – integer or an indeterminate

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[1, [1]], [1, [2, 1]], [2, [1, 1]]])
        sage: from sage.combinat.similarity_class_type import fq
        sage: tau.statistic(lambda la: prod([fq(m) for m in la.to_exp()]))
        (q^9 - 3*q^8 + 2*q^7 + 2*q^6 - 4*q^5 + 4*q^4 - 2*q^3 - 2*q^2 + 3*q - 1)/q^9
        sage: q = ZZ['q'].gen()
        sage: tau.statistic(lambda la: q**la.size(), q = q)
        q^8

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(1), [Integer(1)]], [Integer(1), [Integer(2), Integer(1)]], [Integer(2), [Integer(1), Integer(1)]]])
        >>> from sage.combinat.similarity_class_type import fq
        >>> tau.statistic(lambda la: prod([fq(m) for m in la.to_exp()]))
        (q^9 - 3*q^8 + 2*q^7 + 2*q^6 - 4*q^5 + 4*q^4 - 2*q^3 - 2*q^2 + 3*q - 1)/q^9
        >>> q = ZZ['q'].gen()
        >>> tau.statistic(lambda la: q**la.size(), q = q)
        q^8

class sage.combinat.similarity_class_type.SimilarityClassTypes(n, min)

  Bases: `UniqueRepresentation`, `Parent`

  Class of all similarity class types of size `n` with all primary matrix types greater than or equal to the primary matrix type `min`.

  A similarity class type is a multiset of primary matrix types.

  INPUT:

  - `n` – nonnegative integer

  - `min` – a primary similarity class type

  EXAMPLES:

  If `min` is not specified, then the class of all matrix types of size `n` is constructed:

  Sage

      sage: M = SimilarityClassTypes(2)
      sage: for tau in M:
      ....:     print(tau)
      [[1, [1]], [1, [1]]]
      [[1, [2]]]
      [[1, [1, 1]]]
      [[2, [1]]]

  Python

      >>> from sage.all import *
      >>> M = SimilarityClassTypes(Integer(2))
      >>> for tau in M:
      ...     print(tau)
      [[1, [1]], [1, [1]]]
      [[1, [2]]]
      [[1, [1, 1]]]
      [[2, [1]]]

  If `min` is specified, then the class consists of only those similarity class types which are multisets of primary matrix types which either have size greater than that of `min`, or if they have size equal to that of `min`, then they occur after `min` in the iterator for `PrimarySimilarityClassTypes(n)`, where `n` is the size of `min`:

  Sage

      sage: M = SimilarityClassTypes(2, min = [1, [1, 1]])
      sage: for tau in M:
      ....:     print(tau)
      [[1, [1, 1]]]
      [[2, [1]]]

  [Python]

      >>> from sage.all import *
      >>> M = SimilarityClassTypes(Integer(2), min = [Integer(1), [Integer(1), Integer(1)]])
      >>> for tau in M:
      ...     print(tau)
      [[1, [1, 1]]]
      [[2, [1]]]

  Element

    alias of `SimilarityClassType`

  size()

    Return size of `self`.

    EXAMPLES:

    Sage

        sage: tau = SimilarityClassType([[3, [3, 2, 1]], [2, [2, 1]]])
        sage: tau.parent().size()
        24

    Python

        >>> from sage.all import *
        >>> tau = SimilarityClassType([[Integer(3), [Integer(3), Integer(2), Integer(1)]], [Integer(2), [Integer(2), Integer(1)]]])
        >>> tau.parent().size()
        24

  sum(stat, sumover='matrices', invertible=False, q=None)

    Return the sum of a local statistic over all types.

    Given a set of functions \(n_{\lambda}(q)\) (these could be polynomials or rational functions in \(q\), for each similarity class type \(\tau\) define

    \[n_\tau(q) = \prod_{(d,\lambda)\in \tau} n_{\lambda}(q^d).\]

    This function returns

    \[\sum n_{\tau(g)}(q)\]

    where \(\tau(g)\) denotes the type of a matrix \(g\), and the sum is over all \(n \times n\) matrices if `sumover` is set to `'matrices'`, is over all \(n \times n\) similarity classes if `sumover` is set to `'classes'`, and over all \(n \times n\) types if `sumover` is set to `'types'`. If `invertible` is set to `True`, then the sum is only over invertible matrices or classes.

    INPUT:

    - `stat` – a function which takes partitions and returns a function of `q`

    - `sumover` – can be one of the following:

      - `'matrices'`

      - `'classes'`

      - `'types'`

    - `q` – integer or an indeterminate

    OUTPUT: a function of `q`

    EXAMPLES:

    Sage

        sage: M = SimilarityClassTypes(2)
        sage: M.sum(lambda la:1)
        q^4
        sage: M.sum(lambda la:1, invertible = True)
        q^4 - q^3 - q^2 + q
        sage: M.sum(lambda la:1, sumover = "classes")
        q^2 + q
        sage: M.sum(lambda la:1, sumover = "classes", invertible = True)
        q^2 - 1

    Python

        >>> from sage.all import *
        >>> M = SimilarityClassTypes(Integer(2))
        >>> M.sum(lambda la:Integer(1))
        q^4
        >>> M.sum(lambda la:Integer(1), invertible = True)
        q^4 - q^3 - q^2 + q
        >>> M.sum(lambda la:Integer(1), sumover = "classes")
        q^2 + q
        >>> M.sum(lambda la:Integer(1), sumover = "classes", invertible = True)
        q^2 - 1

    Burside’s lemma can be used to calculate the number of similarity classes of matrices:

    Sage

        sage: from sage.combinat.similarity_class_type import centralizer_algebra_dim, order_of_general_linear_group
        sage: q = ZZ['q'].gen()
        sage: M.sum(lambda la:q**centralizer_algebra_dim(la), invertible = True)/order_of_general_linear_group(2)
        q^2 + q

    [Python]

        >>> from sage.all import *
        >>> from sage.combinat.similarity_class_type import centralizer_algebra_dim, order_of_general_linear_group
        >>> q = ZZ['q'].gen()
        >>> M.sum(lambda la:q**centralizer_algebra_dim(la), invertible = True)/order_of_general_linear_group(Integer(2))
        q^2 + q

sage.combinat.similarity_class_type.centralizer_algebra_dim()

  Return the dimension of the centralizer algebra in \(M_n(\GF{q})\) of a nilpotent matrix whose Jordan blocks are given by `la`.

  EXAMPLES:

  Sage

      sage: from sage.combinat.similarity_class_type import centralizer_algebra_dim
      sage: centralizer_algebra_dim(Partition([2, 1]))
      5

  Python

      >>> from sage.all import *
      >>> from sage.combinat.similarity_class_type import centralizer_algebra_dim
      >>> centralizer_algebra_dim(Partition([Integer(2), Integer(1)]))
      5

  Note

  If it is a list, `la` is expected to be sorted in decreasing order.

sage.combinat.similarity_class_type.centralizer_group_cardinality(q=None)

  Return the cardinality of the centralizer group in \(GL_n(\GF{q})\) of a nilpotent matrix whose Jordan blocks are given by `la`.

  INPUT:

  - `lambda` – a partition

  - `q` – an integer or an indeterminate

  OUTPUT: a polynomial function of `q`

  EXAMPLES:

  Sage

      sage: from sage.combinat.similarity_class_type import centralizer_group_cardinality
      sage: q = ZZ['q'].gen()
      sage: centralizer_group_cardinality(Partition([2, 1]))
      q^5 - 2*q^4 + q^3

  Python

      >>> from sage.all import *
      >>> from sage.combinat.similarity_class_type import centralizer_group_cardinality
      >>> q = ZZ['q'].gen()
      >>> centralizer_group_cardinality(Partition([Integer(2), Integer(1)]))
      q^5 - 2*q^4 + q^3

sage.combinat.similarity_class_type.dictionary_from_generator(gen)

  Given a generator for a list of pairs \((c,f)\), construct a dictionary whose keys are the distinct values for \(c\) and whose value at \(c\) is the sum of \(f\) over all pairs of the form \((c',f)\) such that \(c=c'\).

  EXAMPLES:

  Sage

      sage: from sage.combinat.similarity_class_type import dictionary_from_generator
      sage: dictionary_from_generator(((x // 2, x) for x in range(10)))
      {0: 1, 1: 5, 2: 9, 3: 13, 4: 17}

  Python

      >>> from sage.all import *
      >>> from sage.combinat.similarity_class_type import dictionary_from_generator
      >>> dictionary_from_generator(((x // Integer(2), x) for x in range(Integer(10))))
      {0: 1, 1: 5, 2: 9, 3: 13, 4: 17}

  It also works with lists:

  Sage

      sage: dictionary_from_generator([(x // 2, x) for x in range(10)])
      {0: 1, 1: 5, 2: 9, 3: 13, 4: 17}

  [Python]

      >>> from sage.all import *
      >>> dictionary_from_generator([(x // Integer(2), x) for x in range(Integer(10))])
      {0: 1, 1: 5, 2: 9, 3: 13, 4: 17}

  Note

  Since the generator is first converted to a list, memory usage could be high.

sage.combinat.similarity_class_type.ext_orbit_centralizers(input_data, q=None, selftranspose=False)

  Generate pairs consisting of centralizer cardinalities of orbits in \(\mathrm{Ext}^1(M, M)\) for the action of \(\mathrm{Aut}(M, M)\), where \(M\) is the \(\GF{q[t]}\)-module constructed from `input` and their frequencies.

  INPUT:

  - `input_data` – input for `input_parsing()`

  - `q` – (default: \(q\)) an integer or an indeterminate

  - `selftranspose` – boolean (default: `False`); stating if we only want selftranspose type

sage.combinat.similarity_class_type.ext_orbits(input_data, q=None, selftranspose=False)

  Return the number of orbits in \(\mathrm{Ext}^1(M, M)\) for the action of \(\mathrm{Aut}(M, M)\), where \(M\) is the \(\GF{q[t]}\)-module constructed from `input_data`.

  INPUT:

  - `input_data` – input for `input_parsing()`

  - `q` – (default: \(q\)) an integer or an indeterminate

  - `selftranspose` – boolean (default: `False`); stating if we only want selftranspose type

sage.combinat.similarity_class_type.fq(q=None)

  Return \((1-q^{-1}) (1-q^{-2}) \cdots (1-q^{-n})\).

  INPUT:

  - `n` – nonnegative integer

  - `q` – integer or an indeterminate

  OUTPUT: a rational function in `q`

  EXAMPLES:

  Sage

      sage: from sage.combinat.similarity_class_type import fq
      sage: fq(0)
      1
      sage: fq(3)
      (q^6 - q^5 - q^4 + q^2 + q - 1)/q^6

  Python

      >>> from sage.all import *
      >>> from sage.combinat.similarity_class_type import fq
      >>> fq(Integer(0))
      1
      >>> fq(Integer(3))
      (q^6 - q^5 - q^4 + q^2 + q - 1)/q^6

sage.combinat.similarity_class_type.input_parsing(data)

  Recognize and return the intended type of `input`.

sage.combinat.similarity_class_type.invariant_subspace_generating_function(la, q=None, t=None)

  Return the invariant subspace generating function of a nilpotent matrix with Jordan block sizes given by `la`.

  INPUT:

  - `la` – a partition

  - `q` – (optional) an integer or an inderminate

  - `t` – (optional) an indeterminate

  OUTPUT: a polynomial in `t` whose coefficients are polynomials in `q`

  EXAMPLES:

  Sage

      sage: from sage.combinat.similarity_class_type import invariant_subspace_generating_function
      sage: invariant_subspace_generating_function([2,2])
      t^4 + (q + 1)*t^3 + (q^2 + q + 1)*t^2 + (q + 1)*t + 1

  Python

      >>> from sage.all import *
      >>> from sage.combinat.similarity_class_type import invariant_subspace_generating_function
      >>> invariant_subspace_generating_function([Integer(2),Integer(2)])
      t^4 + (q + 1)*t^3 + (q^2 + q + 1)*t^2 + (q + 1)*t + 1

sage.combinat.similarity_class_type.matrix_centralizer_cardinalities(n, q=None, invertible=False)

  Generate pairs consisting of centralizer cardinalities of matrices over a finite field and their frequencies.

sage.combinat.similarity_class_type.matrix_centralizer_cardinalities_length_two(n, q=None, selftranspose=False, invertible=False)

  Generate pairs consisting of centralizer cardinalities of matrices over a principal ideal local ring of length two with residue field of order `q` and their frequencies.

  INPUT:

  - `n` – the order

  - `q` – (default: \(q\)) an integer or an indeterminate

  - `selftranspose` – boolean (default: `False`); stating if we only want selftranspose type

  - `invertible` – boolean (default: `False`); stating if we only want invertible type

sage.combinat.similarity_class_type.matrix_similarity_classes(n, q=None, invertible=False)

  Return the number of matrix similarity classes over a finite field of order `q`.

sage.combinat.similarity_class_type.matrix_similarity_classes_length_two(n, q=None, selftranspose=False, invertible=False)

  Return the number of similarity classes of matrices of order `n` with entries in a principal ideal local ring of length two.

  INPUT:

  - `n` – the order

  - `q` – (default: \(q\)) an integer or an indeterminate

  - `selftranspose` – boolean (default: `False`); stating if we only want selftranspose type

  - `invertible` – boolean (default: `False`); stating if we only want invertible type

  EXAMPLES:

  We can generate Table 6 of [PSS13]:

  Sage

      sage: from sage.combinat.similarity_class_type import matrix_similarity_classes_length_two
      sage: matrix_similarity_classes_length_two(2)
      q^4 + q^3 + q^2
      sage: matrix_similarity_classes_length_two(2, invertible = True)
      q^4 - q
      sage: matrix_similarity_classes_length_two(3)
      q^6 + q^5 + 2*q^4 + q^3 + 2*q^2
      sage: matrix_similarity_classes_length_two(3, invertible = true)
      q^6 - q^3 + 2*q^2 - 2*q
      sage: matrix_similarity_classes_length_two(4)
      q^8 + q^7 + 3*q^6 + 3*q^5 + 5*q^4 + 3*q^3 + 3*q^2
      sage: matrix_similarity_classes_length_two(4, invertible = True)
      q^8 + q^6 - q^5 + 2*q^4 - 2*q^3 + 2*q^2 - 3*q

  Python

      >>> from sage.all import *
      >>> from sage.combinat.similarity_class_type import matrix_similarity_classes_length_two
      >>> matrix_similarity_classes_length_two(Integer(2))
      q^4 + q^3 + q^2
      >>> matrix_similarity_classes_length_two(Integer(2), invertible = True)
      q^4 - q
      >>> matrix_similarity_classes_length_two(Integer(3))
      q^6 + q^5 + 2*q^4 + q^3 + 2*q^2
      >>> matrix_similarity_classes_length_two(Integer(3), invertible = true)
      q^6 - q^3 + 2*q^2 - 2*q
      >>> matrix_similarity_classes_length_two(Integer(4))
      q^8 + q^7 + 3*q^6 + 3*q^5 + 5*q^4 + 3*q^3 + 3*q^2
      >>> matrix_similarity_classes_length_two(Integer(4), invertible = True)
      q^8 + q^6 - q^5 + 2*q^4 - 2*q^3 + 2*q^2 - 3*q

  And also Table 7:

  Sage

      sage: matrix_similarity_classes_length_two(2, selftranspose = True)
      q^4 + q^3 + q^2
      sage: matrix_similarity_classes_length_two(2, selftranspose = True, invertible = True)
      q^4 - q
      sage: matrix_similarity_classes_length_two(3, selftranspose = True)
      q^6 + q^5 + 2*q^4 + q^3
      sage: matrix_similarity_classes_length_two(3, selftranspose = True, invertible = True)
      q^6 - q^3
      sage: matrix_similarity_classes_length_two(4, selftranspose = True)
      q^8 + q^7 + 3*q^6 + 3*q^5 + 3*q^4 + q^3 + q^2
      sage: matrix_similarity_classes_length_two(4, selftranspose = True, invertible = True)
      q^8 + q^6 - q^5 - q

  [Python]

      >>> from sage.all import *
      >>> matrix_similarity_classes_length_two(Integer(2), selftranspose = True)
      q^4 + q^3 + q^2
      >>> matrix_similarity_classes_length_two(Integer(2), selftranspose = True, invertible = True)
      q^4 - q
      >>> matrix_similarity_classes_length_two(Integer(3), selftranspose = True)
      q^6 + q^5 + 2*q^4 + q^3
      >>> matrix_similarity_classes_length_two(Integer(3), selftranspose = True, invertible = True)
      q^6 - q^3
      >>> matrix_similarity_classes_length_two(Integer(4), selftranspose = True)
      q^8 + q^7 + 3*q^6 + 3*q^5 + 3*q^4 + q^3 + q^2
      >>> matrix_similarity_classes_length_two(Integer(4), selftranspose = True, invertible = True)
      q^8 + q^6 - q^5 - q

sage.combinat.similarity_class_type.order_of_general_linear_group(q=None)

  Return the cardinality of the group of \(n \times n\) invertible matrices with entries in a field of order `q`.

  INPUT:

  - `n` – nonnegative integer

  - `q` – integer or an indeterminate

  EXAMPLES:

  Sage

      sage: from sage.combinat.similarity_class_type import order_of_general_linear_group
      sage: order_of_general_linear_group(0)
      1
      sage: order_of_general_linear_group(2)
      q^4 - q^3 - q^2 + q

  Python

      >>> from sage.all import *
      >>> from sage.combinat.similarity_class_type import order_of_general_linear_group
      >>> order_of_general_linear_group(Integer(0))
      1
      >>> order_of_general_linear_group(Integer(2))
      q^4 - q^3 - q^2 + q

sage.combinat.similarity_class_type.primitives(invertible=False, q=None)

  Return the number of similarity classes of simple matrices of order `n` with entries in a finite field of order `q`. This is the same as the number of irreducible polynomials of degree \(d\).

  If `invertible` is `True`, then only the number of similarity classes of invertible matrices is returned.

  Note

  All primitive classes are invertible unless `n` is \(1\).

  INPUT:

  - `n` – positive integer

  - `invertible` – boolean; if set, only number of nonzero classes is returned

  - `q` – integer or an indeterminate

  OUTPUT: a rational function of the variable `q`

  EXAMPLES:

  Sage

      sage: from sage.combinat.similarity_class_type import primitives
      sage: primitives(1)
      q
      sage: primitives(1, invertible = True)
      q - 1
      sage: primitives(4)
      1/4*q^4 - 1/4*q^2
      sage: primitives(4, invertible = True)
      1/4*q^4 - 1/4*q^2

  Python

      >>> from sage.all import *
      >>> from sage.combinat.similarity_class_type import primitives
      >>> primitives(Integer(1))
      q
      >>> primitives(Integer(1), invertible = True)
      q - 1
      >>> primitives(Integer(4))
      1/4*q^4 - 1/4*q^2
      >>> primitives(Integer(4), invertible = True)
      1/4*q^4 - 1/4*q^2