diff --git a/src/sage/rings/polynomial/skew_polynomial_ring.py b/src/sage/rings/polynomial/skew_polynomial_ring.py index a8784912312..49282373ad0 100644 --- a/src/sage/rings/polynomial/skew_polynomial_ring.py +++ b/src/sage/rings/polynomial/skew_polynomial_ring.py @@ -217,7 +217,7 @@ def _lagrange_polynomial(R, eval_pts, values): # Generic implementation of skew polynomial rings ################################################# -class SkewPolynomialRing_general(Algebra, UniqueRepresentation): +class SkewPolynomialRing_general(Algebra): r""" A general implementation of univariate skew polynomialring over a commutative ring. @@ -283,38 +283,7 @@ class SkewPolynomialRing_general(Algebra, UniqueRepresentation): :meth:`sage.rings.polynomial.skew_polynomial_ring_constructor.SkewPolynomialRing` :mod:`sage.rings.polynomial.skew_polynomial_element` """ - @staticmethod - 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. = ZZ[] - sage: sigma = R.hom([t+1]) - sage: S. = 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 __init__(self, base_ring, twist_map, name, sparse, element_class): + def __init__(self, base_ring, twist_map, name, sparse, element_class=None): r""" Initialize ``self``. @@ -356,7 +325,10 @@ def __init__(self, base_ring, twist_map, name, sparse, element_class): sage: TestSuite(T).run(skip=["_test_pickling", "_test_elements"]) """ self.__is_sparse = sparse - self._polynomial_class = element_class + if element_class is None: + from sage.rings.polynomial.skew_polynomial_element import SkewPolynomial_generic_dense + element_class = SkewPolynomial_generic_dense + self.Element = self._polynomial_class = element_class self._map = twist_map self._maps = {0: IdentityMorphism(base_ring), 1: self._map} Algebra.__init__(self, base_ring, names=name, normalize=True, @@ -1380,17 +1352,10 @@ class SkewPolynomialRing_finite_order(SkewPolynomialRing_general): :class:`sage.rings.polynomial.skew_polynomial_ring.SkewPolynomialRing_general` :mod:`sage.rings.polynomial.skew_polynomial_finite_order` """ - @staticmethod - def __classcall__(cls, base_ring, map, name=None, sparse=False, element_class=None): - if not element_class: - if sparse: - raise NotImplementedError("sparse skew polynomials are not implemented") - else: - from sage.rings.polynomial import skew_polynomial_finite_order - element_class = skew_polynomial_finite_order.SkewPolynomial_finite_order_dense - return super(SkewPolynomialRing_general,cls).__classcall__(cls, base_ring, map, name, sparse, element_class) - - def __init__(self, base_ring, twist_map, name, sparse, element_class): + def __init__(self, base_ring, twist_map, name, sparse, element_class=None): + if element_class is None: + from sage.rings.polynomial.skew_polynomial_finite_order import SkewPolynomial_finite_order_dense + element_class = SkewPolynomial_finite_order_dense SkewPolynomialRing_general.__init__(self, base_ring, twist_map, name, sparse, element_class) self._order = twist_map.order() diff --git a/src/sage/rings/polynomial/skew_polynomial_ring_constructor.py b/src/sage/rings/polynomial/skew_polynomial_ring_constructor.py index 02f1b276844..72c2a2d7c41 100644 --- a/src/sage/rings/polynomial/skew_polynomial_ring_constructor.py +++ b/src/sage/rings/polynomial/skew_polynomial_ring_constructor.py @@ -26,6 +26,7 @@ # *************************************************************************** from __future__ import print_function, absolute_import, division +from sage.structure.factory import UniqueFactory from sage import categories from sage.structure.category_object import normalize_names from sage.categories.morphism import Morphism, IdentityMorphism @@ -34,8 +35,7 @@ from sage.categories.commutative_rings import CommutativeRings - -def SkewPolynomialRing(base_ring, base_ring_automorphism=None, names=None, sparse=False): +class SkewPolynomialRingFactory(UniqueFactory): r""" Return the globally unique skew polynomial ring with the given properties and variable names. @@ -191,36 +191,76 @@ def SkewPolynomialRing(base_ring, base_ring_automorphism=None, names=None, spars - 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 not in CommutativeRings(): - 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") - - import sage.rings.polynomial.skew_polynomial_ring as spr - - # We check whether sigma has finite order - if base_ring in Fields(): + def create_key(self, base_ring, base_ring_automorphism=None, names=None, sparse=False): + r""" + Create a key from the input parameters + + INPUT: + + - ``base_ring`` -- a ring + + - ``base_ring_automorphism`` -- a homomorphism of rings + + - ``names`` -- a string; names of the indeterminates + + - ``sparse`` - a boolean + + EXAMPLES:: + + sage: k. = GF(11^2) + sage: Frob = k.frobenius_endomorphism() + sage: SkewPolynomialRing.create_key(k, Frob, 'x') + (Finite Field in a of size 11^2, + Frobenius endomorphism a |--> a^11 on Finite Field in a of size 11^2, + 'x', + False) + """ + if base_ring not in categories.rings.Rings().Commutative(): + raise TypeError("base_ring must be a commutative ring") + if base_ring not in CommutativeRings(): + 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: - order = base_ring_automorphism.order() - if order is not Infinity: - return spr.SkewPolynomialRing_finite_order(base_ring, base_ring_automorphism, names, sparse) - except AttributeError: - pass - - # Generic implementation - return spr.SkewPolynomialRing_general(base_ring, base_ring_automorphism, names, sparse) + names = normalize_names(1, names)[0] + except IndexError: + raise NotImplementedError("multivariate skew polynomials rings not supported") + return (base_ring, base_ring_automorphism, names, sparse) + + def create_object(self, version, key): + """ + Create an object using the given key + + TESTS:: + + sage: k. = GF(11^2) + sage: Frob = k.frobenius_endomorphism() + sage: key = SkewPolynomialRing.create_key(k, Frob, 'x') + sage: SkewPolynomialRing.create_object((9,1,9), key) + Skew Polynomial Ring in x over Finite Field in a of size 11^2 twisted by a |--> a^11 + """ + import sage.rings.polynomial.skew_polynomial_ring as spr + (base_ring, base_ring_automorphism, names, sparse) = key + + # We check if the twisting morphism has finite order + if base_ring in Fields(): + try: + order = base_ring_automorphism.order() + if order is not Infinity: + return spr.SkewPolynomialRing_finite_order(base_ring, base_ring_automorphism, names, sparse) + except AttributeError: + pass + + # We fallback to generic implementation + return spr.SkewPolynomialRing_general(base_ring, base_ring_automorphism, names, sparse) + +SkewPolynomialRing = SkewPolynomialRingFactory("SkewPolynomialRing")