def __classcall__(cls, base_ring, twist_map=None, name=None, sparse=False,
                      element_class=None):
        r"""
        Set the default values for ``name``, ``sparse`` and ``element_class``.

        EXAMPLES::

            sage: R.<t> = ZZ[]
            sage: sigma = R.hom([t+1])
            sage: S.<x> = SkewPolynomialRing(R, sigma)
            sage: S.__class__(R, sigma, x)
            Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
             twisted by t |--> t + 1
        """
        if not element_class:
            if sparse:
                raise NotImplementedError("sparse skew polynomials are not implemented")
            else:
                from sage.rings.polynomial import skew_polynomial_element
                element_class = skew_polynomial_element.SkewPolynomial_generic_dense
        if twist_map is None:
            twist_map = IdentityMorphism(base_ring)
        else:
            if not isinstance(twist_map, Morphism):
                raise TypeError("given map is not a ring homomorphism")
            if twist_map.domain() != base_ring or twist_map.codomain() != base_ring:
                raise TypeError("given map is not an automorphism of %s" % base_ring)
        return super(SkewPolynomialRing_general,cls).__classcall__(cls,
                         base_ring, twist_map, name, sparse, element_class)
Beispiel #2
0
def OrePolynomialRing(base_ring, base_ring_automorphism = None, base_ring_derivation = None, names = None, sparse = False):
    if base_ring not in categories.rings.Rings().Commutative():
        raise TypeError("base_ring must be a commutative ring")
    if base_ring_automorphism is None:
        base_ring_automorphism = IdentityMorphism(base_ring)
    else:
        if (not isinstance(base_ring_automorphism, Morphism)
            or base_ring_automorphism.domain() != base_ring
            or base_ring_automorphism.codomain() != base_ring):
            raise TypeError("base_ring_automorphism must be a ring automorphism of base_ring (=%s)" % base_ring)
    if base_ring_derivation is None:
        if not isinstance(base_ring, (PolynomialRing_general, MpolynomialRing_generic)):
            raise NotImplementedError()
        else:
            H = Homset(base_ring, base_ring)
            base_ring_derivation = RingDerivation_polynomial(H, base_ring_automorphisme, [0 for _ in range(base_ring.ngens())])
    else:
        if (not isinstance(base_ring_derivation, RingDerivation)
            or base_ring_derivation.domain() != base_ring
            or base_ring_derivation.codomain() != base_ring):
            raise TypeError("base_ring_derivation must be a derivation of base_ring (=%s)" % base_ring)
        elif base_ring_derivation._theta != base_ring_automorphism:
            raise TypeError("base_ring_derivation must be a base_ring_automorphism-derivation")
    if sparse:
        raise NotImplementedError("Sparse Ore polynomial rings are not implemented")
    if names is None:
        raise TypeError("you must specify the name of the variable")
    try:
        names = normalize_names(1, names)[0]
    except IndexError:
        raise NotImplementedError("multivariate Ore polynomials rings not supported")
    from Ore_polynomial_ring import OrePolynomialRing_general
    return OrePolynomialRing_general(base_ring, base_ring_automorphism, base_ring_derivation, names, sparse)
Beispiel #3
0
    def __init__(self, base_ring, twist_map, name, sparse, element_class):
        r"""
        Initialize ``self``.

        INPUT:

        - ``base_ring`` -- a commutative ring

        - ``twist_map`` -- an automorphism of the base ring

        - ``name`` -- string or list of strings representing the name of
          the variables of ring

        - ``sparse`` -- boolean (default: ``False``)

        - ``element_class`` -- class representing the type of element to
          be used in ring

        EXAMPLES::

            sage: R.<t> = ZZ[]
            sage: sigma = R.hom([t+1])
            sage: S.<x> = SkewPolynomialRing(R,sigma)
            sage: S([1]) + S([-1])
            0
            sage: TestSuite(S).run()

            sage: k.<t> = GF(5^3)
            sage: Frob = k.frobenius_endomorphism()
            sage: T.<x> = k['x', Frob]; T
            Skew Polynomial Ring in x over Finite Field in t of size 5^3
             twisted by t |--> t^5

        We skip the pickling tests currently because ``Frob`` does not
        pickle correctly (see note on :trac:`13215`)::

            sage: TestSuite(T).run(skip=["_test_pickling", "_test_elements"])
        """
        self.__is_sparse = sparse
        self._polynomial_class = element_class
        self._map = twist_map
        self._maps = {0: IdentityMorphism(base_ring), 1: self._map}
        self._no_generic_basering_coercion = True
        Algebra.__init__(self,
                         base_ring,
                         names=name,
                         normalize=True,
                         category=Rings())
        base_inject = SkewPolynomialBaseringInjection(base_ring, self)
        self._populate_coercion_lists_(coerce_list=[base_inject],
                                       convert_list=[list, base_inject])
Beispiel #4
0
    def __classcall__(cls,
                      base_ring,
                      twist_map=None,
                      name=None,
                      sparse=False,
                      element_class=None):
        r"""
        Set the default values for ``name``, ``sparse`` and ``element_class``.

        EXAMPLES::

            sage: R.<t> = ZZ[]
            sage: sigma = R.hom([t+1])
            sage: S.<x> = SkewPolynomialRing(R, sigma)
            sage: S.__class__(R, sigma, x)
            Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
             twisted by t |--> t + 1
        """
        if not element_class:
            if sparse:
                raise NotImplementedError(
                    "sparse skew polynomials are not implemented")
            else:
                from sage.rings.polynomial import skew_polynomial_element
                element_class = skew_polynomial_element.SkewPolynomial_generic_dense
        if twist_map is None:
            twist_map = IdentityMorphism(base_ring)
        else:
            if not isinstance(twist_map, Morphism):
                raise TypeError("given map is not a ring homomorphism")
            if twist_map.domain() != base_ring or twist_map.codomain(
            ) != base_ring:
                raise TypeError("given map is not an automorphism of %s" %
                                base_ring)
        return super(SkewPolynomialRing_general,
                     cls).__classcall__(cls, base_ring, twist_map, name,
                                        sparse, element_class)
def SkewPolynomialRing(base_ring, base_ring_automorphism=None, names=None, sparse=False):
    r"""
    Return the globally unique skew polynomial ring with the given properties
    and variable names.

    Given a ring `R` and a ring automorphism `\sigma` of `R`, the ring of
    skew polynomials `R[X, \sigma]` is the usual abelian group polynomial
    `R[X]` equipped with the modification multiplication deduced from the
    rule `X a = \sigma(a) X`.

    .. SEEALSO::

        - :class:`sage.rings.polynomial.skew_polynomial_ring.SkewPolynomialRing_general`
        - :class:`sage.rings.polynomial.skew_polynomial_element.SkewPolynomial`

    INPUT:

    - ``base_ring`` -- a commutative ring

    - ``base_ring_automorphism`` -- an automorphism of the base ring
      (also called twisting map)

    - ``names`` -- a string or a list of strings

    - ``sparse`` -- a boolean (default: ``False``). Currently not supported.

    .. NOTE::

        The current implementation of skew polynomial rings does not
        support derivations. Sparse skew polynomials and multivariate skew
        polynomials are also not implemented.

    OUTPUT:

    A univariate skew polynomial ring over ``base_ring`` twisted by
    ``base_ring_automorphism`` when ``names`` is a string with no
    commas (``,``) or a list of length 1. Otherwise we raise a
    ``NotImplementedError`` as multivariate skew polynomial rings are
    not yet implemented.

    UNIQUENESS and IMMUTABILITY:

    In Sage, there is exactly one skew polynomial ring for each
    triple (base ring, twisting map, name of the variable).

        EXAMPLES of VARIABLE NAME CONTEXT::

            sage: R.<t> = ZZ[]
            sage: sigma = R.hom([t+1])
            sage: S.<x> = SkewPolynomialRing(R, sigma); S
            Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
             twisted by t |--> t + 1

        The names of the variables defined above cannot be arbitrarily
        modified because each skew polynomial ring is unique in Sage and other
        objects in Sage could have pointers to that skew polynomial ring.

        However, the variable can be changed within the scope of a ``with``
        block using the localvars context::

            sage: with localvars(S, ['y']):
            ....:     print(S)
            Skew Polynomial Ring in y over Univariate Polynomial Ring in t over Integer Ring
             twisted by t |--> t + 1

    SQUARE BRACKETS NOTATION:

    You can alternatively create a skew polynomial ring over `R`
    twisted by ``base_ring_automorphism`` by writing
    ``R['varname', base_ring_automorphism]``.

    EXAMPLES:

    We first define the base ring::

        sage: R.<t> = ZZ[]; R
        Univariate Polynomial Ring in t over Integer Ring

    and the twisting map::

        sage: base_ring_automorphism = R.hom([t+1]); base_ring_automorphism
        Ring endomorphism of Univariate Polynomial Ring in t over Integer Ring
          Defn: t |--> t + 1

    Now, we are ready to define the skew polynomial ring::

        sage: S = SkewPolynomialRing(R, base_ring_automorphism, names='x'); S
        Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
         twisted by t |--> t + 1

    Use the diamond brackets notation to make the variable ready
    for use after you define the ring::

        sage: S.<x> = SkewPolynomialRing(R, base_ring_automorphism)
        sage: (x + t)^2
        x^2 + (2*t + 1)*x + t^2

    Here is an example with the square bracket notations::

        sage: S.<x> = R['x', base_ring_automorphism]; S
        Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
         twisted by t |--> t + 1

    Rings with different variables names are different::

        sage: R['x', base_ring_automorphism] == R['y', base_ring_automorphism]
        False

    TESTS:

    You must specify a variable name::

        sage: SkewPolynomialRing(R, base_ring_automorphism)
        Traceback (most recent call last):
        ...
        TypeError: you must specify the name of the variable

    With this syntax, it is not possible to omit the name of the
    variable neither in LHS nor in RHS. If we omit it in LHS, the
    variable is not created::

        sage: Sy = R['y', base_ring_automorphism]; Sy
        Skew Polynomial Ring in y over Univariate Polynomial Ring in t over Integer Ring
         twisted by t |--> t + 1
        sage: y.parent()
        Traceback (most recent call last):
        ...
        NameError: name 'y' is not defined

    If we omit it in RHS, sage tries to create a polynomial ring and fails::

        sage: Sz.<z> = R[base_ring_automorphism]
        Traceback (most recent call last):
        ...
        ValueError: variable name 'Ring endomorphism of Univariate Polynomial Ring in t over Integer Ring\n  Defn: t |--> t + 1' is not alphanumeric

    Multivariate skew polynomial rings are not supported::

        sage: S = SkewPolynomialRing(R, base_ring_automorphism,names=['x','y'])
        Traceback (most recent call last):
        ...
        NotImplementedError: multivariate skew polynomials rings not supported

    Sparse skew polynomial rings are not implemented::

        sage: S = SkewPolynomialRing(R, base_ring_automorphism, names='x', sparse=True)
        Traceback (most recent call last):
        ...
        NotImplementedError: sparse skew polynomial rings are not implemented

    .. TODO::

        - Sparse Skew Polynomial Ring
        - Multivariate Skew Polynomial Ring
        - Add derivations.
    """
    if base_ring not in categories.rings.Rings().Commutative():
        raise TypeError("base_ring must be a commutative ring")
    if base_ring_automorphism is None:
        base_ring_automorphism = IdentityMorphism(base_ring)
    else:
        if (not isinstance(base_ring_automorphism,Morphism)
                or base_ring_automorphism.domain() != base_ring
                or base_ring_automorphism.codomain() != base_ring):
            raise TypeError("base_ring_automorphism must be a ring automorphism of base_ring (=%s)" % base_ring)
    if sparse:
        raise NotImplementedError("sparse skew polynomial rings are not implemented")
    if names is None:
        raise TypeError("you must specify the name of the variable")
    try:
        names = normalize_names(1, names)[0]
    except IndexError:
        raise NotImplementedError("multivariate skew polynomials rings not supported")

    from sage.rings.polynomial.skew_polynomial_ring import SkewPolynomialRing_general
    return SkewPolynomialRing_general(base_ring, base_ring_automorphism, names, sparse)
def SkewPolynomialRing(base_ring,
                       base_ring_automorphism=None,
                       names=None,
                       sparse=False):
    r"""
    Return the globally unique skew polynomial ring with the given properties
    and variable names.

    Given a ring `R` and a ring automorphism `\sigma` of `R`, the ring of
    skew polynomials `R[X, \sigma]` is the usual abelian group polynomial
    `R[X]` equipped with the modification multiplication deduced from the
    rule `X a = \sigma(a) X`.

    .. SEEALSO::

        - :class:`sage.rings.polynomial.skew_polynomial_ring.SkewPolynomialRing_general`
        - :class:`sage.rings.polynomial.skew_polynomial_element.SkewPolynomial`

    INPUT:

    - ``base_ring`` -- a commutative ring

    - ``base_ring_automorphism`` -- an automorphism of the base ring
      (also called twisting map)

    - ``names`` -- a string or a list of strings

    - ``sparse`` -- a boolean (default: ``False``). Currently not supported.

    .. NOTE::

        The current implementation of skew polynomial rings does not
        support derivations. Sparse skew polynomials and multivariate skew
        polynomials are also not implemented.

    OUTPUT:

    A univariate skew polynomial ring over ``base_ring`` twisted by
    ``base_ring_automorphism`` when ``names`` is a string with no
    commas (``,``) or a list of length 1. Otherwise we raise a
    ``NotImplementedError`` as multivariate skew polynomial rings are
    not yet implemented.

    UNIQUENESS and IMMUTABILITY:

    In Sage, there is exactly one skew polynomial ring for each
    triple (base ring, twisting map, name of the variable).

        EXAMPLES of VARIABLE NAME CONTEXT::

            sage: R.<t> = ZZ[]
            sage: sigma = R.hom([t+1])
            sage: S.<x> = SkewPolynomialRing(R, sigma); S
            Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
             twisted by t |--> t + 1

        The names of the variables defined above cannot be arbitrarily
        modified because each skew polynomial ring is unique in Sage and other
        objects in Sage could have pointers to that skew polynomial ring.

        However, the variable can be changed within the scope of a ``with``
        block using the localvars context::

            sage: with localvars(S, ['y']):
            ....:     print(S)
            Skew Polynomial Ring in y over Univariate Polynomial Ring in t over Integer Ring
             twisted by t |--> t + 1

    SQUARE BRACKETS NOTATION:

    You can alternatively create a skew polynomial ring over `R`
    twisted by ``base_ring_automorphism`` by writing
    ``R['varname', base_ring_automorphism]``.

    EXAMPLES:

    We first define the base ring::

        sage: R.<t> = ZZ[]; R
        Univariate Polynomial Ring in t over Integer Ring

    and the twisting map::

        sage: base_ring_automorphism = R.hom([t+1]); base_ring_automorphism
        Ring endomorphism of Univariate Polynomial Ring in t over Integer Ring
          Defn: t |--> t + 1

    Now, we are ready to define the skew polynomial ring::

        sage: S = SkewPolynomialRing(R, base_ring_automorphism, names='x'); S
        Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
         twisted by t |--> t + 1

    Use the diamond brackets notation to make the variable ready
    for use after you define the ring::

        sage: S.<x> = SkewPolynomialRing(R, base_ring_automorphism)
        sage: (x + t)^2
        x^2 + (2*t + 1)*x + t^2

    Here is an example with the square bracket notations::

        sage: S.<x> = R['x', base_ring_automorphism]; S
        Skew Polynomial Ring in x over Univariate Polynomial Ring in t over Integer Ring
         twisted by t |--> t + 1

    Rings with different variables names are different::

        sage: R['x', base_ring_automorphism] == R['y', base_ring_automorphism]
        False

    TESTS:

    You must specify a variable name::

        sage: SkewPolynomialRing(R, base_ring_automorphism)
        Traceback (most recent call last):
        ...
        TypeError: you must specify the name of the variable

    With this syntax, it is not possible to omit the name of the
    variable neither in LHS nor in RHS. If we omit it in LHS, the
    variable is not created::

        sage: Sy = R['y', base_ring_automorphism]; Sy
        Skew Polynomial Ring in y over Univariate Polynomial Ring in t over Integer Ring
         twisted by t |--> t + 1
        sage: y.parent()
        Traceback (most recent call last):
        ...
        NameError: name 'y' is not defined

    If we omit it in RHS, sage tries to create a polynomial ring and fails::

        sage: Sz.<z> = R[base_ring_automorphism]
        Traceback (most recent call last):
        ...
        ValueError: variable name 'Ring endomorphism of Univariate Polynomial Ring in t over Integer Ring\n  Defn: t |--> t + 1' is not alphanumeric

    Multivariate skew polynomial rings are not supported::

        sage: S = SkewPolynomialRing(R, base_ring_automorphism,names=['x','y'])
        Traceback (most recent call last):
        ...
        NotImplementedError: multivariate skew polynomials rings not supported

    Sparse skew polynomial rings are not implemented::

        sage: S = SkewPolynomialRing(R, base_ring_automorphism, names='x', sparse=True)
        Traceback (most recent call last):
        ...
        NotImplementedError: sparse skew polynomial rings are not implemented

    .. TODO::

        - Sparse Skew Polynomial Ring
        - Multivariate Skew Polynomial Ring
        - Add derivations.
    """
    if base_ring not in categories.rings.Rings().Commutative():
        raise TypeError("base_ring must be a commutative ring")
    if base_ring_automorphism is None:
        base_ring_automorphism = IdentityMorphism(base_ring)
    else:
        if (not isinstance(base_ring_automorphism, Morphism)
                or base_ring_automorphism.domain() != base_ring
                or base_ring_automorphism.codomain() != base_ring):
            raise TypeError(
                "base_ring_automorphism must be a ring automorphism of base_ring (=%s)"
                % base_ring)
    if sparse:
        raise NotImplementedError(
            "sparse skew polynomial rings are not implemented")
    if names is None:
        raise TypeError("you must specify the name of the variable")
    try:
        names = normalize_names(1, names)[0]
    except IndexError:
        raise NotImplementedError(
            "multivariate skew polynomials rings not supported")

    from sage.rings.polynomial.skew_polynomial_ring import SkewPolynomialRing_general
    return SkewPolynomialRing_general(base_ring, base_ring_automorphism, names,
                                      sparse)