Esempio n. 1
0
    def center(self, name=None, names=None, default=False):
        r"""
        Return the center of this skew polynomial ring.

        .. NOTE::

            If `F` denotes the subring of `R` fixed by `\sigma` and `\sigma`
            has order `r`, the center of `K[x,\sigma]` is `F[x^r]`, that
            is a univariate polynomial ring over `F`.

        INPUT:

        - ``name`` -- a string or ``None`` (default: ``None``);
          the name for the central variable (namely `x^r`)

        - ``default`` -- a boolean (default: ``False``); if ``True``,
          set the default variable name for the center to ``name``

        EXAMPLES::

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

            sage: Z = S.center(); Z
            Univariate Polynomial Ring in z over Finite Field of size 5
            sage: Z.gen()
            z

        We can pass in another variable name::

            sage: S.center(name='y')
            Univariate Polynomial Ring in y over Finite Field of size 5

        or use the bracket notation::

            sage: Zy.<y> = S.center(); Zy
            Univariate Polynomial Ring in y over Finite Field of size 5
            sage: y.parent() is Zy
            True

        A coercion map from the center to the skew polynomial ring is set::

            sage: S.has_coerce_map_from(Zy)
            True

            sage: P = y + x; P
            x^3 + x
            sage: P.parent()
            Ore Polynomial Ring in x over Finite Field in t of size 5^3 twisted by t |--> t^5
            sage: P.parent() is S
            True

        together with a conversion map in the reverse direction::

            sage: Zy(x^6 + 2*x^3 + 3)
            y^2 + 2*y + 3

            sage: Zy(x^2)
            Traceback (most recent call last):
            ...
            ValueError: x^2 is not in the center

        Two different skew polynomial rings can share the same center::

            sage: S1.<x1> = k['x1', Frob]
            sage: S2.<x2> = k['x2', Frob]
            sage: S1.center() is S2.center()
            True

        .. RUBRIC:: About the default name of the central variable

        A priori, the default is ``z``.

        However, a variable name is given the first time this method is
        called, the given name become the default for the next calls::

            sage: K.<t> = GF(11^3)
            sage: phi = K.frobenius_endomorphism()
            sage: A.<X> = K['X', phi]

            sage: C.<u> = A.center()  # first call
            sage: C
            Univariate Polynomial Ring in u over Finite Field of size 11
            sage: A.center()  # second call: the variable name is still u
            Univariate Polynomial Ring in u over Finite Field of size 11
            sage: A.center() is C
            True

        We can update the default variable name by passing in the argument
        ``default=True``::

            sage: D.<v> = A.center(default=True)
            sage: D
            Univariate Polynomial Ring in v over Finite Field of size 11
            sage: A.center()
            Univariate Polynomial Ring in v over Finite Field of size 11
            sage: A.center() is D
            True

        TESTS::

            sage: C.<a,b> = S.center()
            Traceback (most recent call last):
            ...
            IndexError: the number of names must equal the number of generators
        """
        if name is not None and names is not None:
            raise ValueError("you must specify the name of the variable")
        if names is None:
            if name is None:
                name = self._center_variable_name
            if name is None:
                name = 'z'
            names = (name, )
        names = normalize_names(1, names)
        name = names[0]
        if name in self._center:
            center = self._center[name]
        else:
            center = PolynomialRing(self._constants, names)
            embed = SkewPolynomialCenterInjection(center, self,
                                                  self._embed_constants,
                                                  self._order)
            try:
                assert not self.has_coerce_map_from(center)
                self.register_coercion(embed)
                center.register_conversion(embed.section())
            except AssertionError:
                raise ValueError(
                    "creation of coercion map fails; consider using another variable name"
                )
            self._center[name] = center
        if default or (self._center_variable_name is None):
            self._center_variable_name = name
        return center