Univariate dense skew polynomials over a field with a finite order automorphism - Noncommutative Polynomials

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

# Univariate dense skew polynomials over a field with a finite order automorphism

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_order.SkewPolynomial_finite_order_dense

  Bases: `SkewPolynomial_generic_dense`

  This method constructs a generic dense skew polynomial over a field equipped with an automorphism of finite order.

  INPUT:

  - `parent` – parent of `self`

  - `x` – list of coefficients from which `self` can be constructed

  - `check` – flag variable to normalize the polynomial

  - `construct` – boolean (default: `False`)

  bound()

    Return a bound of this skew polynomial (i.e. a multiple of this skew polynomial lying in the center).

    Note

    Since \(b\) is central, it divides a skew polynomial on the left iff it divides it on the right

    ALGORITHM:

    1. Sage first checks whether self is itself in the center. It if is, it returns `self`

    2. If an optimal bound was previously computed and cached, Sage returns it

    3. Otherwise, Sage returns the reduced norm of `self`

    As a consequence, the output of this function may depend on previous computations (an example is given below).

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x', Frob]
        sage: Z = S.center(); Z
        Univariate Polynomial Ring in z over Finite Field of size 5

        sage: a = x^2 + (4*t + 2)*x + 4*t^2 + 3
        sage: b = a.bound(); b
        z^2 + z + 4

    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(); Z
        Univariate Polynomial Ring in z over Finite Field of size 5

        >>> a = x**Integer(2) + (Integer(4)*t + Integer(2))*x + Integer(4)*t**Integer(2) + Integer(3)
        >>> b = a.bound(); b
        z^2 + z + 4

    We observe that the bound is explicitly given as an element of the center (which is a univariate polynomial ring in the variable \(z\)). We can use conversion to send it in the skew polynomial ring:

    Sage

        sage: S(b)
        x^6 + x^3 + 4

    [Python]

        >>> from sage.all import *
        >>> S(b)
        x^6 + x^3 + 4

    We check that \(b\) is divisible by \(a\):

    Sage

        sage: S(b).is_right_divisible_by(a)
        True
        sage: S(b).is_left_divisible_by(a)
        True

    Python

        >>> from sage.all import *
        >>> S(b).is_right_divisible_by(a)
        True
        >>> S(b).is_left_divisible_by(a)
        True

    Actually, \(b\) is the reduced norm of \(a\):

    Sage

        sage: b == a.reduced_norm()
        True

    [Python]

        >>> from sage.all import *
        >>> b == a.reduced_norm()
        True

    Now, we compute the optimal bound of \(a\) and see that it affects the behaviour of `bound()`:

    Sage

        sage: a.optimal_bound()
        z + 3
        sage: a.bound()
        z + 3

    Python

        >>> from sage.all import *
        >>> a.optimal_bound()
        z + 3
        >>> a.bound()
        z + 3

  is_central()

    Return `True` if this skew polynomial lies in the center.

    EXAMPLES:

    Sage

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

        sage: x.is_central()
        False
        sage: (t*x^3).is_central()
        False
        sage: (x^6 + x^3).is_central()
        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)

        >>> x.is_central()
        False
        >>> (t*x**Integer(3)).is_central()
        False
        >>> (x**Integer(6) + x**Integer(3)).is_central()
        True

  optimal_bound()

    Return the optimal bound of this skew polynomial (i.e. the monic multiple of this skew polynomial of minimal degree lying in the center).

    Note

    The result is cached.

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<x> = k['x', Frob]
        sage: Z = S.center(); Z
        Univariate Polynomial Ring in z over Finite Field of size 5

        sage: a = x^2 + (4*t + 2)*x + 4*t^2 + 3
        sage: b = a.optimal_bound(); b
        z + 3

    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(); Z
        Univariate Polynomial Ring in z over Finite Field of size 5

        >>> a = x**Integer(2) + (Integer(4)*t + Integer(2))*x + Integer(4)*t**Integer(2) + Integer(3)
        >>> b = a.optimal_bound(); b
        z + 3

    We observe that the bound is explicitly given as an element of the center (which is a univariate polynomial ring in the variable \(z\)). We can use conversion to send it in the skew polynomial ring:

    Sage

        sage: S(b)
        x^3 + 3

    [Python]

        >>> from sage.all import *
        >>> S(b)
        x^3 + 3

    We check that \(b\) is divisible by \(a\):

    Sage

        sage: S(b).is_right_divisible_by(a)
        True
        sage: S(b).is_left_divisible_by(a)
        True

    Python

        >>> from sage.all import *
        >>> S(b).is_right_divisible_by(a)
        True
        >>> S(b).is_left_divisible_by(a)
        True

  reduced_charpoly(var=None)

    Return the reduced characteristic polynomial of this skew polynomial.

    INPUT:

    - `var` – string, a pair of strings or `None` (default: `None`); the variable names used for the characteristic polynomial and the center

    Note

    The result is cached.

    EXAMPLES:

    Sage

        sage: k.<t> = GF(5^3)
        sage: Frob = k.frobenius_endomorphism()
        sage: S.<u> = k['u', Frob]
        sage: a = u^3 + (2*t^2 + 3)*u^2 + (4*t^2 + t + 4)*u + 2*t^2 + 2
        sage: chi = a.reduced_charpoly()
        sage: chi
        x^3 + (2*z + 1)*x^2 + (3*z^2 + 4*z)*x + 4*z^3 + z^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['u', Frob]; (u,) = S._first_ngens(1)
        >>> a = u**Integer(3) + (Integer(2)*t**Integer(2) + Integer(3))*u**Integer(2) + (Integer(4)*t**Integer(2) + t + Integer(4))*u + Integer(2)*t**Integer(2) + Integer(2)
        >>> chi = a.reduced_charpoly()
        >>> chi
        x^3 + (2*z + 1)*x^2 + (3*z^2 + 4*z)*x + 4*z^3 + z^2 + 1

    The reduced characteristic polynomial has coefficients in the center of \(S\), which is itself a univariate polynomial ring in the variable \(z = u^3\) over \(\GF{5}\). Hence it appears as a bivariate polynomial:

    Sage

        sage: chi.parent()
        Univariate Polynomial Ring in x over Univariate Polynomial Ring in z over Finite Field of size 5

    [Python]

        >>> from sage.all import *
        >>> chi.parent()
        Univariate Polynomial Ring in x over Univariate Polynomial Ring in z over Finite Field of size 5

    The constant coefficient of the reduced characteristic polynomial is the reduced norm, up to a sign:

    Sage

        sage: chi[0] == -a.reduced_norm()
        True

    Python

        >>> from sage.all import *
        >>> chi[Integer(0)] == -a.reduced_norm()
        True

    Its coefficient of degree \(\deg(a) - 1\) is the opposite of the reduced trace:

    Sage

        sage: chi[2] == -a.reduced_trace()
        True

    [Python]

        >>> from sage.all import *
        >>> chi[Integer(2)] == -a.reduced_trace()
        True

    By default, the name of the variable of the reduced characteristic polynomial is `x` and the name of central variable is usually `z` (see `center()` for more details about this). The user can specify different names if desired:

    Sage

        sage: a.reduced_charpoly(var='T')  # variable name for the characteristic polynomial
        T^3 + (2*z + 1)*T^2 + (3*z^2 + 4*z)*T + 4*z^3 + z^2 + 1

        sage: a.reduced_charpoly(var=('T', 'c'))
        T^3 + (2*c + 1)*T^2 + (3*c^2 + 4*c)*T + 4*c^3 + c^2 + 1

    Python

        >>> from sage.all import *
        >>> a.reduced_charpoly(var='T')  # variable name for the characteristic polynomial
        T^3 + (2*z + 1)*T^2 + (3*z^2 + 4*z)*T + 4*z^3 + z^2 + 1

        >>> a.reduced_charpoly(var=('T', 'c'))
        T^3 + (2*c + 1)*T^2 + (3*c^2 + 4*c)*T + 4*c^3 + c^2 + 1

    See also

    `reduced_trace()`, `reduced_norm()`

  reduced_norm(var=None)

    Return the reduced norm of this skew polynomial.

    INPUT:

    - `var` – string or `False` or `None` (default: `None`); the variable name. If `False`, return the list of coefficients.

    Note

    The result is cached.

    EXAMPLES:

    Sage

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

    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) + (Integer(2)*t**Integer(2) + Integer(3))*x**Integer(2) + (Integer(4)*t**Integer(2) + t + Integer(4))*x + Integer(2)*t**Integer(2) + Integer(2)
        >>> N = a.reduced_norm(); N
        z^3 + 4*z^2 + 4

    The reduced norm lies in the center of \(S\), which is a univariate polynomial ring in the variable \(z = x^3\) over \(\GF{5}\):

    Sage

        sage: N.parent()
        Univariate Polynomial Ring in z over Finite Field of size 5
        sage: N.parent() is S.center()
        True

    [Python]

        >>> from sage.all import *
        >>> N.parent()
        Univariate Polynomial Ring in z over Finite Field of size 5
        >>> N.parent() is S.center()
        True

    We can use explicit conversion to view `N` as a skew polynomial:

    Sage

        sage: S(N)
        x^9 + 4*x^6 + 4

    Python

        >>> from sage.all import *
        >>> S(N)
        x^9 + 4*x^6 + 4

    By default, the name of the central variable is usually `z` (see `center()` for more details about this). However, the user can specify a different variable name if desired:

    Sage

        sage: a.reduced_norm(var='u')
        u^3 + 4*u^2 + 4

    [Python]

        >>> from sage.all import *
        >>> a.reduced_norm(var='u')
        u^3 + 4*u^2 + 4

    When passing in `var=False`, a tuple of coefficients (instead of an actual polynomial) is returned:

    Sage

        sage: a.reduced_norm(var=False)
        (4, 0, 4, 1)

    Python

        >>> from sage.all import *
        >>> a.reduced_norm(var=False)
        (4, 0, 4, 1)

    ALGORITHM:

    If \(r\) (= the order of the twist map) is small compared to \(d\) (= the degree of this skew polynomial), the reduced norm is computed as the determinant of the multiplication by \(P\) (= this skew polynomial) acting on \(K[X,\sigma]\) (= the underlying skew ring) viewed as a free module of rank \(r\) over \(K[X^r]\).

    Otherwise, the reduced norm is computed as the characteristic polynomial of the left multiplication by \(X\) on the quotient \(K[X,\sigma] / K[X,\sigma] P\) (which is a \(K\)-vector space of dimension \(d\)).

    See also

    `reduced_trace()`, `reduced_charpoly()`

  reduced_trace(var=None)

    Return the reduced trace of this skew polynomial.

    INPUT:

    - `var` – string or `False` or `None` (default: `None`); the variable name. If `False`, return the list of coefficients.

    EXAMPLES:

    Sage

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

    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) + (Integer(2)*t**Integer(2) + Integer(3))*x**Integer(2) + (Integer(4)*t**Integer(2) + t + Integer(4))*x + Integer(2)*t**Integer(2) + Integer(2)
        >>> tr = a.reduced_trace(); tr
        3*z + 4

    The reduced trace lies in the center of \(S\), which is a univariate polynomial ring in the variable \(z = x^3\) over \(\GF{5}\):

    Sage

        sage: tr.parent()
        Univariate Polynomial Ring in z over Finite Field of size 5
        sage: tr.parent() is S.center()
        True

    [Python]

        >>> from sage.all import *
        >>> tr.parent()
        Univariate Polynomial Ring in z over Finite Field of size 5
        >>> tr.parent() is S.center()
        True

    We can use explicit conversion to view `tr` as a skew polynomial:

    Sage

        sage: S(tr)
        3*x^3 + 4

    Python

        >>> from sage.all import *
        >>> S(tr)
        3*x^3 + 4

    By default, the name of the central variable is usually `z` (see `center()` for more details about this). However, the user can specify a different variable name if desired:

    Sage

        sage: a.reduced_trace(var='u')
        3*u + 4

    [Python]

        >>> from sage.all import *
        >>> a.reduced_trace(var='u')
        3*u + 4

    When passing in `var=False`, a tuple of coefficients (instead of an actual polynomial) is returned:

    Sage

        sage: a.reduced_trace(var=False)
        (4, 3)

    Python

        >>> from sage.all import *
        >>> a.reduced_trace(var=False)
        (4, 3)

    See also

    `reduced_norm()`, `reduced_charpoly()`