Univariate dense skew polynomials over finite fields - Noncommutative Polynomials

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

# Univariate dense skew polynomials over finite fields

This module provides the class:\(~sage.rings.polynomial.skew_polynomial_finite_field.SkewPolynomial_finite_field_dense\), which constructs a single univariate skew polynomial over a finite field equipped with the Frobenius endomorphism. Among other things, it implements the fast factorization algorithm designed in [CL2017].

AUTHOR:

    - Xavier Caruso (2012-06-29): initial version

- Arpit Merchant (2016-08-04): improved docstrings, fixed doctests and refactored classes and methods

class sage.rings.polynomial.skew_polynomial_finite_field.SkewPolynomial_finite_field_dense

  Bases: `SkewPolynomial_finite_order_dense`

  count_factorizations()

    Return the number of factorizations (as a product of a unit and a product of irreducible monic factors) of this skew polynomial.

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]
        sage: a = x^4 + (4*t + 3)*x^3 + t^2*x^2 + (4*t^2 + 3*t)*x + 3*t
        sage: a.count_factorizations()
        216

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)
        >>> a = x**Integer(4) + (Integer(4)*t + Integer(3))*x**Integer(3) + t**Integer(2)*x**Integer(2) + (Integer(4)*t**Integer(2) + Integer(3)*t)*x + Integer(3)*t
        >>> a.count_factorizations()
        216

    We illustrate that an irreducible polynomial in the center have in general a lot of distinct factorizations in the skew polynomial ring:

    Sage

        sage: Z.<x3> = S.center()
        sage: N = x3^5 + 4*x3^4 + 4*x3^2 + 4*x3 + 3
        sage: N.is_irreducible()
        True
        sage: S(N).count_factorizations()
        30537115626

    [Python]

        >>> from sage.all import *
        >>> Z = S.center(names=('x3',)); (x3,) = Z._first_ngens(1)
        >>> N = x3**Integer(5) + Integer(4)*x3**Integer(4) + Integer(4)*x3**Integer(2) + Integer(4)*x3 + Integer(3)
        >>> N.is_irreducible()
        True
        >>> S(N).count_factorizations()
        30537115626

  count_irreducible_divisors()

    Return the number of irreducible monic divisors of this skew polynomial.

    Note

    One can prove that there are always as many left irreducible monic divisors as right irreducible monic divisors.

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)

    We illustrate that a skew polynomial may have a number of irreducible divisors greater than its degree:

    Sage

        sage: a = x^4 + (4*t + 3)*x^3 + t^2*x^2 + (4*t^2 + 3*t)*x + 3*t
        sage: a.count_irreducible_divisors()
        12

    [Python]

        >>> from sage.all import *
        >>> a = x**Integer(4) + (Integer(4)*t + Integer(3))*x**Integer(3) + t**Integer(2)*x**Integer(2) + (Integer(4)*t**Integer(2) + Integer(3)*t)*x + Integer(3)*t
        >>> a.count_irreducible_divisors()
        12

    We illustrate that an irreducible polynomial in the center have in general a lot of irreducible divisors in the skew polynomial ring:

    Sage

        sage: Z.<x3> = S.center()
        sage: N = x3^5 + 4*x3^4 + 4*x3^2 + 4*x3 + 3; N
        x3^5 + 4*x3^4 + 4*x3^2 + 4*x3 + 3
        sage: N.is_irreducible()
        True
        sage: S(N).count_irreducible_divisors()
        9768751

    Python

        >>> from sage.all import *
        >>> Z = S.center(names=('x3',)); (x3,) = Z._first_ngens(1)
        >>> N = x3**Integer(5) + Integer(4)*x3**Integer(4) + Integer(4)*x3**Integer(2) + Integer(4)*x3 + Integer(3); N
        x3^5 + 4*x3^4 + 4*x3^2 + 4*x3 + 3
        >>> N.is_irreducible()
        True
        >>> S(N).count_irreducible_divisors()
        9768751

  factor(uniform=False)

    Return a factorization of this skew polynomial.

    INPUT:

    - `uniform` – boolean (default: `False`); whether the output irreducible divisor should be uniformly distributed among all possibilities

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]
        sage: a = x^3 + (t^2 + 4*t + 2)*x^2 + (3*t + 3)*x + t^2 + 1
        sage: F = a.factor(); F   # random
        (x + t^2 + 4) * (x + t + 3) * (x + t)
        sage: F.value() == a
        True

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)
        >>> a = x**Integer(3) + (t**Integer(2) + Integer(4)*t + Integer(2))*x**Integer(2) + (Integer(3)*t + Integer(3))*x + t**Integer(2) + Integer(1)
        >>> F = a.factor(); F   # random
        (x + t^2 + 4) * (x + t + 3) * (x + t)
        >>> F.value() == a
        True

    The result of the factorization is cached. Hence, if we try again to factor \(a\), we will get the same answer:

    Sage

        sage: a.factor()  # random
        (x + t^2 + 4) * (x + t + 3) * (x + t)

    [Python]

        >>> from sage.all import *
        >>> a.factor()  # random
        (x + t^2 + 4) * (x + t + 3) * (x + t)

    However, the algorithm is probabilistic. Hence if we first reinitialize \(a\), we may get a different answer:

    Sage

        sage: a = x^3 + (t^2 + 4*t + 2)*x^2 + (3*t + 3)*x + t^2 + 1
        sage: F = a.factor(); F   # random
        (x + t^2 + t + 2) * (x + 2*t^2 + t + 4) * (x + t)
        sage: F.value() == a
        True

    Python

        >>> from sage.all import *
        >>> a = x**Integer(3) + (t**Integer(2) + Integer(4)*t + Integer(2))*x**Integer(2) + (Integer(3)*t + Integer(3))*x + t**Integer(2) + Integer(1)
        >>> F = a.factor(); F   # random
        (x + t^2 + t + 2) * (x + 2*t^2 + t + 4) * (x + t)
        >>> F.value() == a
        True

    There is a priori no guarantee on the distribution of the factorizations we get. Passing in the keyword `uniform=True` ensures the output is uniformly distributed among all factorizations:

    Sage

        sage: a.factor(uniform=True)   # random
        (x + t^2 + 4) * (x + t) * (x + t + 3)
        sage: a.factor(uniform=True)   # random
        (x + 2*t^2) * (x + t^2 + t + 1) * (x + t^2 + t + 2)
        sage: a.factor(uniform=True)   # random
        (x + 2*t^2 + 3*t) * (x + 4*t + 2) * (x + 2*t + 2)

    [Python]

        >>> from sage.all import *
        >>> a.factor(uniform=True)   # random
        (x + t^2 + 4) * (x + t) * (x + t + 3)
        >>> a.factor(uniform=True)   # random
        (x + 2*t^2) * (x + t^2 + t + 1) * (x + t^2 + t + 2)
        >>> a.factor(uniform=True)   # random
        (x + 2*t^2 + 3*t) * (x + 4*t + 2) * (x + 2*t + 2)

    By convention, the zero skew polynomial has no factorization:

    Sage

        sage: S(0).factor()
        Traceback (most recent call last):
        ...
        ValueError: factorization of 0 not defined

    Python

        >>> from sage.all import *
        >>> S(Integer(0)).factor()
        Traceback (most recent call last):
        ...
        ValueError: factorization of 0 not defined

  factorizations()

    Return an iterator over all factorizations (as a product of a unit and a product of irreducible monic factors) of this skew polynomial.

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]
        sage: a = x^3 + (t^2 + 1)*x^2 + (2*t + 3)*x + t^2 + t + 2
        sage: iter = a.factorizations(); iter
        <...generator object at 0x...>
        sage: next(iter)   # random
        (x + 3*t^2 + 4*t) * (x + 2*t^2) * (x + 4*t^2 + 4*t + 2)
        sage: next(iter)   # random
        (x + 3*t^2 + 4*t) * (x + 3*t^2 + 2*t + 2) * (x + 4*t^2 + t + 2)

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)
        >>> a = x**Integer(3) + (t**Integer(2) + Integer(1))*x**Integer(2) + (Integer(2)*t + Integer(3))*x + t**Integer(2) + t + Integer(2)
        >>> iter = a.factorizations(); iter
        <...generator object at 0x...>
        >>> next(iter)   # random
        (x + 3*t^2 + 4*t) * (x + 2*t^2) * (x + 4*t^2 + 4*t + 2)
        >>> next(iter)   # random
        (x + 3*t^2 + 4*t) * (x + 3*t^2 + 2*t + 2) * (x + 4*t^2 + t + 2)

    We can use this function to build the list of factorizations of \(a\):

    Sage

        sage: factorizations = [ F for F in a.factorizations() ]

    [Python]

        >>> from sage.all import *
        >>> factorizations = [ F for F in a.factorizations() ]

    We do some checks:

    Sage

        sage: len(factorizations) == a.count_factorizations()
        True
        sage: len(factorizations) == Set(factorizations).cardinality()  # check no duplicates
        True
        sage: for F in factorizations:
        ....:     assert F.value() == a, "factorization has a different value"
        ....:     for d,_ in F:
        ....:         assert d.is_irreducible(), "a factor is not irreducible"

    Python

        >>> from sage.all import *
        >>> len(factorizations) == a.count_factorizations()
        True
        >>> len(factorizations) == Set(factorizations).cardinality()  # check no duplicates
        True
        >>> for F in factorizations:
        ...     assert F.value() == a, "factorization has a different value"
        ...     for d,_ in F:
        ...         assert d.is_irreducible(), "a factor is not irreducible"

    Note that the algorithm used in this method is probabilistic. As a consequence, if we call it two times with the same input, we can get different orderings:

    Sage

        sage: factorizations2 = [ F for F in a.factorizations() ]
        sage: factorizations == factorizations2  # random
        False
        sage: sorted(factorizations) == sorted(factorizations2)
        True

    [Python]

        >>> from sage.all import *
        >>> factorizations2 = [ F for F in a.factorizations() ]
        >>> factorizations == factorizations2  # random
        False
        >>> sorted(factorizations) == sorted(factorizations2)
        True

  is_irreducible()

    Return `True` if this skew polynomial is irreducible.

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]

        sage: a = x^2 + t*x + 1
        sage: a.is_irreducible()
        False
        sage: a.factor()
        (x + 4*t^2 + 4*t + 1) * (x + 3*t + 2)

        sage: a = x^2 + t*x + t + 1
        sage: a.is_irreducible()
        True
        sage: a.factor()
        x^2 + t*x + t + 1

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)

        >>> a = x**Integer(2) + t*x + Integer(1)
        >>> a.is_irreducible()
        False
        >>> a.factor()
        (x + 4*t^2 + 4*t + 1) * (x + 3*t + 2)

        >>> a = x**Integer(2) + t*x + t + Integer(1)
        >>> a.is_irreducible()
        True
        >>> a.factor()
        x^2 + t*x + t + 1

    Skew polynomials of degree \(1\) are of course irreducible:

    Sage

        sage: a = x + t
        sage: a.is_irreducible()
        True

    [Python]

        >>> from sage.all import *
        >>> a = x + t
        >>> a.is_irreducible()
        True

    A random irreducible skew polynomial is irreducible:

    Sage

        sage: a = S.random_irreducible(degree=4,monic=True); a   # random
        x^4 + (t + 1)*x^3 + (3*t^2 + 2*t + 3)*x^2 + 3*t*x + 3*t
        sage: a.is_irreducible()
        True

    Python

        >>> from sage.all import *
        >>> a = S.random_irreducible(degree=Integer(4),monic=True); a   # random
        x^4 + (t + 1)*x^3 + (3*t^2 + 2*t + 3)*x^2 + 3*t*x + 3*t
        >>> a.is_irreducible()
        True

    By convention, constant skew polynomials are not irreducible:

    Sage

        sage: S(1).is_irreducible()
        False
        sage: S(0).is_irreducible()
        False

    [Python]

        >>> from sage.all import *
        >>> S(Integer(1)).is_irreducible()
        False
        >>> S(Integer(0)).is_irreducible()
        False

  left_irreducible_divisor(uniform=False)

    Return a left irreducible divisor of this skew polynomial.

    INPUT:

    - `uniform` – boolean (default: `False`); whether the output irreducible divisor should be uniformly distributed among all possibilities

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]
        sage: a = x^6 + 3*t*x^5 + (3*t + 1)*x^3 + (4*t^2 + 3*t + 4)*x^2 + (t^2 + 2)*x + 4*t^2 + 3*t + 3
        sage: dl = a.left_irreducible_divisor(); dl  # random
        x^3 + (t^2 + t + 2)*x^2 + (t + 2)*x + 3*t^2 + t + 4
        sage: a.is_left_divisible_by(dl)
        True

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)
        >>> a = x**Integer(6) + Integer(3)*t*x**Integer(5) + (Integer(3)*t + Integer(1))*x**Integer(3) + (Integer(4)*t**Integer(2) + Integer(3)*t + Integer(4))*x**Integer(2) + (t**Integer(2) + Integer(2))*x + Integer(4)*t**Integer(2) + Integer(3)*t + Integer(3)
        >>> dl = a.left_irreducible_divisor(); dl  # random
        x^3 + (t^2 + t + 2)*x^2 + (t + 2)*x + 3*t^2 + t + 4
        >>> a.is_left_divisible_by(dl)
        True

    The algorithm is probabilistic. Hence, if we ask again for a left irreducible divisor of \(a\), we may get a different answer:

    Sage

        sage: a.left_irreducible_divisor()  # random
        x^3 + (4*t + 3)*x^2 + (2*t^2 + 3*t + 4)*x + 4*t^2 + 2*t

    [Python]

        >>> from sage.all import *
        >>> a.left_irreducible_divisor()  # random
        x^3 + (4*t + 3)*x^2 + (2*t^2 + 3*t + 4)*x + 4*t^2 + 2*t

    We can also generate uniformly distributed irreducible monic divisors as follows:

    Sage

        sage: a.left_irreducible_divisor(uniform=True)  # random
        x^3 + (4*t^2 + 3*t + 4)*x^2 + (t^2 + t + 3)*x + 2*t^2 + 3
        sage: a.left_irreducible_divisor(uniform=True)  # random
        x^3 + (2*t^2 + t + 4)*x^2 + (2*t^2 + 4*t + 4)*x + 2*t + 3
        sage: a.left_irreducible_divisor(uniform=True)  # random
        x^3 + (t^2 + t + 2)*x^2 + (3*t^2 + t)*x + 2*t + 1

    Python

        >>> from sage.all import *
        >>> a.left_irreducible_divisor(uniform=True)  # random
        x^3 + (4*t^2 + 3*t + 4)*x^2 + (t^2 + t + 3)*x + 2*t^2 + 3
        >>> a.left_irreducible_divisor(uniform=True)  # random
        x^3 + (2*t^2 + t + 4)*x^2 + (2*t^2 + 4*t + 4)*x + 2*t + 3
        >>> a.left_irreducible_divisor(uniform=True)  # random
        x^3 + (t^2 + t + 2)*x^2 + (3*t^2 + t)*x + 2*t + 1

    By convention, the zero skew polynomial has no irreducible divisor:

    Sage

        sage: S(0).left_irreducible_divisor()
        Traceback (most recent call last):
        ...
        ValueError: 0 has no irreducible divisor

    [Python]

        >>> from sage.all import *
        >>> S(Integer(0)).left_irreducible_divisor()
        Traceback (most recent call last):
        ...
        ValueError: 0 has no irreducible divisor

  left_irreducible_divisors()

    Return an iterator over all irreducible monic left divisors of this skew polynomial.

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]
        sage: a = x^4 + 2*t*x^3 + 3*t^2*x^2 + (t^2 + t + 1)*x + 4*t + 3
        sage: iter = a.left_irreducible_divisors(); iter
        <...generator object at 0x...>
        sage: next(iter)  # random
        x + 3*t + 3
        sage: next(iter)  # random
        x + 4*t + 2

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)
        >>> a = x**Integer(4) + Integer(2)*t*x**Integer(3) + Integer(3)*t**Integer(2)*x**Integer(2) + (t**Integer(2) + t + Integer(1))*x + Integer(4)*t + Integer(3)
        >>> iter = a.left_irreducible_divisors(); iter
        <...generator object at 0x...>
        >>> next(iter)  # random
        x + 3*t + 3
        >>> next(iter)  # random
        x + 4*t + 2

    We can use this function to build the list of all monic irreducible divisors of \(a\):

    Sage

        sage: leftdiv = [ d for d in a.left_irreducible_divisors() ]

    [Python]

        >>> from sage.all import *
        >>> leftdiv = [ d for d in a.left_irreducible_divisors() ]

    Note that the algorithm is probabilistic. As a consequence, if we build again the list of left monic irreducible divisors of \(a\), we may get a different ordering:

    Sage

        sage: leftdiv2 = [ d for d in a.left_irreducible_divisors() ]
        sage: Set(leftdiv) == Set(leftdiv2)
        True

    Python

        >>> from sage.all import *
        >>> leftdiv2 = [ d for d in a.left_irreducible_divisors() ]
        >>> Set(leftdiv) == Set(leftdiv2)
        True

  right_irreducible_divisor(uniform=False)

    Return a right irreducible divisor of this skew polynomial.

    INPUT:

    - `uniform` – boolean (default: `False`); whether the output irreducible divisor should be uniformly distributed among all possibilities

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]
        sage: a = x^6 + 3*t*x^5 + (3*t + 1)*x^3 + (4*t^2 + 3*t + 4)*x^2 + (t^2 + 2)*x + 4*t^2 + 3*t + 3

        sage: dr = a.right_irreducible_divisor(); dr  # random
        x^3 + (2*t^2 + t + 4)*x^2 + (4*t + 1)*x + 4*t^2 + t + 1
        sage: a.is_right_divisible_by(dr)
        True

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)
        >>> a = x**Integer(6) + Integer(3)*t*x**Integer(5) + (Integer(3)*t + Integer(1))*x**Integer(3) + (Integer(4)*t**Integer(2) + Integer(3)*t + Integer(4))*x**Integer(2) + (t**Integer(2) + Integer(2))*x + Integer(4)*t**Integer(2) + Integer(3)*t + Integer(3)

        >>> dr = a.right_irreducible_divisor(); dr  # random
        x^3 + (2*t^2 + t + 4)*x^2 + (4*t + 1)*x + 4*t^2 + t + 1
        >>> a.is_right_divisible_by(dr)
        True

    Right divisors are cached. Hence, if we ask again for a right divisor, we will get the same answer:

    Sage

        sage: a.right_irreducible_divisor()  # random
        x^3 + (2*t^2 + t + 4)*x^2 + (4*t + 1)*x + 4*t^2 + t + 1

    [Python]

        >>> from sage.all import *
        >>> a.right_irreducible_divisor()  # random
        x^3 + (2*t^2 + t + 4)*x^2 + (4*t + 1)*x + 4*t^2 + t + 1

    However the algorithm is probabilistic. Hence, if we first reinitialize \(a\), we may get a different answer:

    Sage

        sage: a = x^6 + 3*t*x^5 + (3*t + 1)*x^3 + (4*t^2 + 3*t + 4)*x^2 + (t^2 + 2)*x + 4*t^2 + 3*t + 3
        sage: a.right_irreducible_divisor()  # random
        x^3 + (t^2 + 3*t + 4)*x^2 + (t + 2)*x + 4*t^2 + t + 1

    Python

        >>> from sage.all import *
        >>> a = x**Integer(6) + Integer(3)*t*x**Integer(5) + (Integer(3)*t + Integer(1))*x**Integer(3) + (Integer(4)*t**Integer(2) + Integer(3)*t + Integer(4))*x**Integer(2) + (t**Integer(2) + Integer(2))*x + Integer(4)*t**Integer(2) + Integer(3)*t + Integer(3)
        >>> a.right_irreducible_divisor()  # random
        x^3 + (t^2 + 3*t + 4)*x^2 + (t + 2)*x + 4*t^2 + t + 1

    We can also generate uniformly distributed irreducible monic divisors as follows:

    Sage

        sage: a.right_irreducible_divisor(uniform=True)  # random
        x^3 + (4*t + 2)*x^2 + (2*t^2 + 2*t + 2)*x + 2*t^2 + 2
        sage: a.right_irreducible_divisor(uniform=True)  # random
        x^3 + (t^2 + 2)*x^2 + (3*t^2 + 1)*x + 4*t^2 + 2*t
        sage: a.right_irreducible_divisor(uniform=True)  # random
        x^3 + x^2 + (4*t^2 + 2*t + 4)*x + t^2 + 3

    [Python]

        >>> from sage.all import *
        >>> a.right_irreducible_divisor(uniform=True)  # random
        x^3 + (4*t + 2)*x^2 + (2*t^2 + 2*t + 2)*x + 2*t^2 + 2
        >>> a.right_irreducible_divisor(uniform=True)  # random
        x^3 + (t^2 + 2)*x^2 + (3*t^2 + 1)*x + 4*t^2 + 2*t
        >>> a.right_irreducible_divisor(uniform=True)  # random
        x^3 + x^2 + (4*t^2 + 2*t + 4)*x + t^2 + 3

    By convention, the zero skew polynomial has no irreducible divisor:

    Sage

        sage: S(0).right_irreducible_divisor()
        Traceback (most recent call last):
        ...
        ValueError: 0 has no irreducible divisor

    Python

        >>> from sage.all import *
        >>> S(Integer(0)).right_irreducible_divisor()
        Traceback (most recent call last):
        ...
        ValueError: 0 has no irreducible divisor

  right_irreducible_divisors()

    Return an iterator over all irreducible monic right divisors of this skew polynomial.

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]
        sage: a = x^4 + 2*t*x^3 + 3*t^2*x^2 + (t^2 + t + 1)*x + 4*t + 3
        sage: iter = a.right_irreducible_divisors(); iter
        <...generator object at 0x...>
        sage: next(iter)   # random
        x + 2*t^2 + 4*t + 4
        sage: next(iter)   # random
        x + 3*t^2 + 4*t + 1

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)
        >>> a = x**Integer(4) + Integer(2)*t*x**Integer(3) + Integer(3)*t**Integer(2)*x**Integer(2) + (t**Integer(2) + t + Integer(1))*x + Integer(4)*t + Integer(3)
        >>> iter = a.right_irreducible_divisors(); iter
        <...generator object at 0x...>
        >>> next(iter)   # random
        x + 2*t^2 + 4*t + 4
        >>> next(iter)   # random
        x + 3*t^2 + 4*t + 1

    We can use this function to build the list of all monic irreducible divisors of \(a\):

    Sage

        sage: rightdiv = [ d for d in a.right_irreducible_divisors() ]

    [Python]

        >>> from sage.all import *
        >>> rightdiv = [ d for d in a.right_irreducible_divisors() ]

    Note that the algorithm is probabilistic. As a consequence, if we build again the list of right monic irreducible divisors of \(a\), we may get a different ordering:

    Sage

        sage: rightdiv2 = [ d for d in a.right_irreducible_divisors() ]
        sage: rightdiv == rightdiv2
        False
        sage: Set(rightdiv) == Set(rightdiv2)
        True

    Python

        >>> from sage.all import *
        >>> rightdiv2 = [ d for d in a.right_irreducible_divisors() ]
        >>> rightdiv == rightdiv2
        False
        >>> Set(rightdiv) == Set(rightdiv2)
        True

  type(N)

    Return the \(N\)-type of this skew polynomial (see definition below).

    INPUT:

    - `N` – an irreducible polynomial in the center of the underlying skew polynomial ring

    Note

    The result is cached.

    DEFINITION:

    The \(N\)-type of a skew polynomial \(a\) is the Partition \((t_0, t_1, t_2, \ldots)\) defined by

    \[t_0 + \cdots + t_i = \frac{\deg gcd(a,N^i)}{\deg N},\]

    where \(\deg N\) is the degree of \(N\) considered as an element in the center.

    This notion has an important mathematical interest because it corresponds to the Jordan type of the \(N\)-typical part of the associated Galois representation.

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x',Frob]
        sage: Z = S.center(); x3 = Z.gen()

        sage: a = x^4 + x^3 + (4*t^2 + 4)*x^2 + (t^2 + 2)*x + 4*t^2
        sage: N = x3^2 + x3 + 1
        sage: a.type(N)
        [1]
        sage: N = x3 + 1
        sage: a.type(N)
        [2]

        sage: a = x^3 + (3*t^2 + 1)*x^2 + (3*t^2 + t + 1)*x + t + 1
        sage: N = x3 + 1
        sage: a.type(N)
        [2, 1]

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1)
        >>> Frob = k.frobenius_endomorphism()
        >>> S = k['x',Frob]; (x,) = S._first_ngens(1)
        >>> Z = S.center(); x3 = Z.gen()

        >>> a = x**Integer(4) + x**Integer(3) + (Integer(4)*t**Integer(2) + Integer(4))*x**Integer(2) + (t**Integer(2) + Integer(2))*x + Integer(4)*t**Integer(2)
        >>> N = x3**Integer(2) + x3 + Integer(1)
        >>> a.type(N)
        [1]
        >>> N = x3 + Integer(1)
        >>> a.type(N)
        [2]

        >>> a = x**Integer(3) + (Integer(3)*t**Integer(2) + Integer(1))*x**Integer(2) + (Integer(3)*t**Integer(2) + t + Integer(1))*x + t + Integer(1)
        >>> N = x3 + Integer(1)
        >>> a.type(N)
        [2, 1]

    If \(N\) does not divide the reduced map of \(a\), the type is empty:

    Sage

        sage: N = x3 + 2
        sage: a.type(N)
        []

    [Python]

        >>> from sage.all import *
        >>> N = x3 + Integer(2)
        >>> a.type(N)
        []

    If \(a = N\), the type is just \([r]\) where \(r\) is the order of the twisting morphism `Frob`:

    Sage

        sage: N = x3^2 + x3 + 1
        sage: S(N).type(N)
        [3]

    Python

        >>> from sage.all import *
        >>> N = x3**Integer(2) + x3 + Integer(1)
        >>> S(N).type(N)
        [3]

    \(N\) must be irreducible:

    Sage

        sage: N = (x3 + 1) * (x3 + 2)
        sage: a.type(N)
        Traceback (most recent call last):
        ...
        ValueError: N is not irreducible

    [Python]

        >>> from sage.all import *
        >>> N = (x3 + Integer(1)) * (x3 + Integer(2))
        >>> a.type(N)
        Traceback (most recent call last):
        ...
        ValueError: N is not irreducible