def _coerce_map_from_(self, P):
        r"""Return a coercion map from `P` to `self`, or `True`, or `None`.

        The following rings admit a coercion map to the Puiseux series ring
        `A((x-a)^(1/e))`:

        - any ring that admits a coercion map to `A`

        - any Laurent series ring, power series ring, or polynomial ring in the
          variable `(x-a)` over a ring admitting a coercion map to `A`

        - any Puiseux series ring with the same center `a` and ramification
          index equal to a multiple of `self`'s ramification index. For
          example, Puiseux series in (x-a)^(1/2) can be interpreted as Puiseux
          series in (x-a)^(1/4).

        """
        # any ring that has a coercion map to A
        A = self.base_ring()
        if A is P:
            return True
        f = A.coerce_map_from(P)
        if f is not None:
            return self.coerce_map_from(A) * f

        # Laurent series rings, power series rings, and polynomial rings with
        # the same variable name and the base rings are coercible
        if ((is_PuiseuxSeriesRing(P) or is_LaurentSeriesRing(P) or
             is_PowerSeriesRing(P))
            and P.variable_name() == self.variable_name()
            and A.has_coerce_map_from(P.base_ring())):
            return True
    def _coerce_impl(self, f):
        """
        Return the canonical coercion of ``f`` into this multivariate power
        series ring, if one is defined, or raise a TypeError.

        The rings that canonically coerce to this multivariate power series
        ring are:

            - this ring itself

            - a polynomial or power series ring in the same variables or a
              subset of these variables (possibly empty), over any base
              ring that canonically coerces into the base ring of this ring

        EXAMPLES::

            sage: R.<t,u,v> = PowerSeriesRing(QQ); R
            Multivariate Power Series Ring in t, u, v over Rational Field
            sage: S1.<t,v> = PolynomialRing(ZZ); S1
            Multivariate Polynomial Ring in t, v over Integer Ring
            sage: f1 = -t*v + 2*v^2 + v; f1
            -t*v + 2*v^2 + v
            sage: R(f1)
            v - t*v + 2*v^2
            sage: S2.<u,v> = PowerSeriesRing(ZZ); S2
            Multivariate Power Series Ring in u, v over Integer Ring
            sage: f2 = -2*v^2 + 5*u*v^2 + S2.O(6); f2
            -2*v^2 + 5*u*v^2 + O(u, v)^6
            sage: R(f2)
            -2*v^2 + 5*u*v^2 + O(t, u, v)^6

            sage: R2 = R.change_ring(GF(2))
            sage: R2(f1)
            v + t*v
            sage: R2(f2)
            u*v^2 + O(t, u, v)^6

        TESTS::

            sage: R.<t,u,v> = PowerSeriesRing(QQ)
            sage: S1.<t,v> = PolynomialRing(ZZ)
            sage: f1 = S1.random_element()
            sage: g1 = R._coerce_impl(f1)
            sage: f1.parent() == R
            False
            sage: g1.parent() == R
            True

        """

        P = f.parent()
        if is_MPolynomialRing(P) or is_MPowerSeriesRing(P) \
               or is_PolynomialRing(P) or is_PowerSeriesRing(P):
            if set(P.variable_names()).issubset(set(self.variable_names())):
                if self.has_coerce_map_from(P.base_ring()):
                    return self(f)
        else:
            return self._coerce_try(f,[self.base_ring()])
示例#3
0
    def _coerce_map_from_(self, P):
        """
        The rings that canonically coerce to this multivariate power series
        ring are:

            - this ring itself
 
            - a polynomial or power series ring in the same variables or a
              subset of these variables (possibly empty), over any base
              ring that canonically coerces into this ring

            - any ring that coerces into the foreground polynomial ring of this ring


        TESTS::

            sage: M = PowerSeriesRing(ZZ,3,'x,y,z');
            sage: M._coerce_map_from_(M)
            True
            sage: M._coerce_map_from_(M.remove_var(x))
            True
            sage: M._coerce_map_from_(PowerSeriesRing(ZZ,x))
            True
            sage: M._coerce_map_from_(PolynomialRing(ZZ,'x,z'))
            True
            sage: M._coerce_map_from_(PolynomialRing(ZZ,0,''))
            True
            sage: M._coerce_map_from_(ZZ)
            True

            sage: M._coerce_map_from_(Zmod(13))
            False
            sage: M._coerce_map_from_(PolynomialRing(ZZ,2,'x,t'))
            False
            sage: M._coerce_map_from_(PolynomialRing(Zmod(11),2,'x,y'))
            False

            sage: P = PolynomialRing(ZZ,3,'z')
            sage: H = PowerSeriesRing(P,4,'f'); H
            Multivariate Power Series Ring in f0, f1, f2, f3 over Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring
            sage: H._coerce_map_from_(P)
            True
            sage: H._coerce_map_from_(P.remove_var(P.gen(1)))
            True
            sage: H._coerce_map_from_(PolynomialRing(ZZ,'z2,f0'))
            True

        """
        if is_MPolynomialRing(P) or is_MPowerSeriesRing(P) \
                   or is_PolynomialRing(P) or is_PowerSeriesRing(P):
            if set(P.variable_names()).issubset(set(self.variable_names())):
                if self.has_coerce_map_from(P.base_ring()):
                    return True

        return self._poly_ring().has_coerce_map_from(P)
    def _coerce_map_from_(self, P):
        """
        Return a coercion map from `P` to ``self``, or True, or None.

        The following rings admit a coercion map to the Laurent series
        ring `A((t))`:

        - any ring that admits a coercion map to `A` (including `A`
          itself);

        - any Laurent series ring, power series ring or polynomial
          ring in the variable `t` over a ring admitting a coercion
          map to `A`.

        EXAMPLES::

            sage: R.<t> = LaurentSeriesRing(ZZ)
            sage: S.<t> = PowerSeriesRing(QQ)
            sage: R.has_coerce_map_from(S) # indirect doctest
            False
            sage: R.has_coerce_map_from(R)
            True
            sage: R.<t> = LaurentSeriesRing(QQ['x'])
            sage: R.has_coerce_map_from(S)
            True
            sage: R.has_coerce_map_from(QQ['t'])
            True
            sage: R.has_coerce_map_from(ZZ['x']['t'])
            True
            sage: R.has_coerce_map_from(ZZ['t']['x'])
            False
            sage: R.has_coerce_map_from(ZZ['x'])
            True
        """
        A = self.base_ring()
        if A is P:
            return True
        f = A.coerce_map_from(P)
        if f is not None:
            return self.coerce_map_from(A) * f

        from sage.rings.polynomial.polynomial_ring import is_PolynomialRing
        from sage.rings.power_series_ring import is_PowerSeriesRing
        if ((is_LaurentSeriesRing(P) or is_PowerSeriesRing(P) or is_PolynomialRing(P))
            and P.variable_name() == self.variable_name()
            and A.has_coerce_map_from(P.base_ring())):
            return True
    def __classcall__(cls, *args, **kwds):
        r"""
        TESTS::

            sage: L = LaurentSeriesRing(QQ, 'q')
            sage: L is LaurentSeriesRing(QQ, name='q')
            True
            sage: loads(dumps(L)) is L
            True

            sage: L.variable_names()
            ('q',)
            sage: L.variable_name()
            'q'
        """
        from .power_series_ring import PowerSeriesRing, is_PowerSeriesRing

        if not kwds and len(args) == 1 and is_PowerSeriesRing(args[0]):
            power_series = args[0]
        else:
            power_series = PowerSeriesRing(*args, **kwds)

        return UniqueRepresentation.__classcall__(cls, power_series)
    def _is_valid_homomorphism_(self, codomain, im_gens):
        """
        EXAMPLES::

            sage: R.<x> = LaurentSeriesRing(GF(17))
            sage: S.<y> = LaurentSeriesRing(GF(19))
            sage: R.hom([y], S) # indirect doctest
            Traceback (most recent call last):
            ...
            TypeError: images do not define a valid homomorphism
            sage: f = R.hom(x+x^3,R)
            sage: f(x^2)
            x^2 + 2*x^4 + x^6
        """
        ## NOTE: There are no ring homomorphisms from the ring of
        ## all formal power series to most rings, e.g, the p-adic
        ## field, since you can always (mathematically!) construct
        ## some power series that doesn't converge.
        ## Note that 0 is not a *ring* homomorphism.
        from power_series_ring import is_PowerSeriesRing
        if is_PowerSeriesRing(codomain) or is_LaurentSeriesRing(codomain):
            return im_gens[0].valuation() > 0 and codomain.has_coerce_map_from(self.base_ring())
        return False
    def _is_valid_homomorphism_(self, codomain, im_gens):
        """
        Replacement for method of PowerSeriesRing_generic.

        To be valid, a homomorphism must send generators to elements of
        positive valuation or to nilpotent elements.

        Note that the method is_nilpotent doesn't (as of sage 4.4) seem to
        be defined for obvious examples (matrices, quotients of polynomial
        rings).

        EXAMPLES::

            sage: R.<a,b,c> = PowerSeriesRing(Zmod(8)); R
            Multivariate Power Series Ring in a, b, c over Ring of integers
            modulo 8
            sage: M = PowerSeriesRing(ZZ,3,'x,y,z');
            sage: M._is_valid_homomorphism_(R,[a,c,b])
            True

            sage: M._is_valid_homomorphism_(R,[0,c,b])
            True

        2 is nilpotent in `ZZ/8`, but 3 is not::

            sage: M._is_valid_homomorphism_(R,[2,c,b])
            True
            sage: M._is_valid_homomorphism_(R,[3,c,b])
            False

        Over `ZZ`, 2 is not nilpotent::

            sage: S = R.change_ring(ZZ); S
            Multivariate Power Series Ring in a, b, c over Integer Ring
            sage: M._is_valid_homomorphism_(S,[a,c,b])
            True
            sage: M._is_valid_homomorphism_(S,[0,c,b])
            True
            sage: M._is_valid_homomorphism_(S,[2,c,b])
            False

            sage: g = [S.random_element(10)*v for v in S.gens()]
            sage: M._is_valid_homomorphism_(S,g)
            True
        """
        try:
            im_gens = [codomain(v) for v in im_gens]
        except TypeError:
            raise TypeError("The given generator images do not coerce to codomain.")

        if len(im_gens) is not self.ngens():
            raise ValueError("You must specify the image of each generator.")
        if all(v == 0 for v in im_gens):
            return True
        if is_MPowerSeriesRing(codomain) or is_PowerSeriesRing(codomain):
            try:
                B = all(v.valuation() > 0 or v.is_nilpotent() for v in im_gens)
            except NotImplementedError:
                B = all(v.valuation() > 0 for v in im_gens)
            return B
        if is_CommutativeRing(codomain):
            return all(v.is_nilpotent() for v in im_gens)
示例#8
0
    def __init__(self, parent, x=0, prec=infinity, is_gen=False, check=False):
        """
        input x can be an MPowerSeries, or an element of

          - the background univariate power series ring
        
          - the foreground polynomial ring

          - a ring that coerces to one of the above two


        TESTS::

            sage: S.<s,t> = PowerSeriesRing(ZZ)
            sage: f = s + 4*t + 3*s*t
            sage: f in S
            True
            sage: f = f.add_bigoh(4); f
            s + 4*t + 3*s*t + O(s, t)^4
            sage: g = 1 + s + t - s*t + S.O(5); g
            1 + s + t - s*t + O(s, t)^5

            sage: B.<s, t> = PowerSeriesRing(QQ)
            sage: C.<z> = PowerSeriesRing(QQ)
            sage: B(z)
            Traceback (most recent call last):
            ...
            TypeError: Cannot coerce input to polynomial ring.

            sage: D.<s> = PowerSeriesRing(QQ)
            sage: s.parent() is D
            True
            sage: B(s) in B
            True
            sage: d = D.random_element(20)
            sage: b = B(d) # test coercion from univariate power series ring
            sage: b in B
            True

        """
        PowerSeries.__init__(self, parent, prec, is_gen=is_gen)
        self._PowerSeries__is_gen = is_gen

        try:
            prec = min(prec, x.prec()) # use precision of input, if defined
        except AttributeError:
            pass


        # set the correct background value, depending on what type of input x is
        try:
            xparent = x.parent() # 'int' types have no parent
        except AttributeError:
            xparent = None

        # test whether x coerces to background univariate
        # power series ring of parent
        from sage.rings.multi_power_series_ring import is_MPowerSeriesRing
        if is_PowerSeriesRing(xparent) or is_MPowerSeriesRing(xparent):
            # x is either a multivariate or univariate power series
            #
            # test whether x coerces directly to designated parent
            if is_MPowerSeries(x):
                try:
                    self._bg_value = parent._bg_ps_ring(x._bg_value)
                except TypeError:
                    raise TypeError("Unable to coerce into background ring.")
                
            # test whether x coerces to background univariate
            # power series ring of parent
            elif xparent == parent._bg_ps_ring():
                self._bg_value = x
            elif parent._bg_ps_ring().has_coerce_map_from(xparent):
                # previous test may fail if precision or term orderings of
                # base rings do not match
                self._bg_value = parent._bg_ps_ring(x)
            else:
                # x is a univariate power series, but not from the 
                # background power series ring
                #
                # convert x to a polynomial and send to background
                # ring of parent
                x = x.polynomial()
                self._bg_value = parent._send_to_bg(x).add_bigoh(prec)                

        # test whether x coerces to underlying polynomial ring of parent
        elif is_PolynomialRing(xparent):
            self._bg_value = parent._send_to_bg(x).add_bigoh(prec)
                
        else:
            try:
                x = parent._poly_ring(x)
                #self._value = x
                self._bg_value = parent._send_to_bg(x).add_bigoh(prec)
            except (TypeError, AttributeError):
                raise TypeError("Input does not coerce to any of the expected rings.")
            
        self._go_to_fg = parent._send_to_fg
        self._prec = self._bg_value.prec()

        # self._parent is used a lot by the class PowerSeries
        self._parent = self.parent()
示例#9
0
    def _element_constructor_(self, x):
        r"""
        Return ``x`` coerced into this forms space.

        EXAMPLES::

            sage: from graded_ring import MModularFormsRing
            sage: from space import ModularForms
            sage: MF = ModularForms(k=12, ep=1)
            sage: (x,y,z,d) = MF.pol_ring().gens()

            sage: Delta = MModularFormsRing().Delta()
            sage: Delta.parent()
            MeromorphicModularFormsRing(n=3) over Integer Ring
            sage: MF(Delta)
            q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5)
            sage: MF(Delta).parent() == MF
            True

            sage: MF(x^3)
            1 + 720*q + 179280*q^2 + 16954560*q^3 + 396974160*q^4 + O(q^5)
            sage: MF(x^3).parent() == MF
            True

            sage: qexp = Delta.q_expansion(prec=2)
            sage: qexp
            q + O(q^2)
            sage: qexp.parent()
            Power Series Ring in q over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: MF(qexp)
            q - 24*q^2 + 252*q^3 - 1472*q^4 + O(q^5)
            sage: MF(qexp) == MF(Delta)
            True

            sage: MF([0,1]) == MF(Delta)
            True
            sage: MF([1,0]) == MF(x^3) - 720*MF(Delta) # todo: this should give True, the result is False because d!=1/1728 but a formal parameter
            False

            sage: vec = MF(Delta).coordinate_vector()
            sage: vec
            (0, 1)
            sage: vec.parent()
            Vector space of dimension 2 over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: vec in MF.module()
            True
            sage: MF(vec) == MF(Delta)
            True

            sage: subspace = MF.subspace([MF(Delta)])
            sage: subspace
            Subspace of dimension 1 of ModularForms(n=3, k=12, ep=1) over Integer Ring
            sage: subspace(MF(Delta)) == subspace(d*(x^3-y^2)) == subspace(qexp) == subspace([0,1]) == subspace(vec) == subspace.gen()
            True
            sage: subspace(MF(Delta)).parent() == subspace(d*(x^3-y^2)).parent() == subspace(qexp).parent() == subspace([0,1]).parent() == subspace(vec).parent()
            True
            sage: subspace([1]) == subspace.gen()
            True
            sage: ssvec = subspace(vec).coordinate_vector()
            sage: ssvec
            (1)
            sage: ssvec.parent()
            Vector space of dimension 1 over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            sage: ambvec = subspace(vec).ambient_coordinate_vector()
            sage: ambvec
            (0, 1)
            sage: ambvec.parent()
            Vector space of degree 2 and dimension 1 over Fraction Field of Univariate Polynomial Ring in d over Integer Ring
            Basis matrix:
            [0 1]
            sage: subspace(ambvec) == subspace(vec) and subspace(ambvec).parent() == subspace(vec).parent()
            True
        """

        from graded_ring_element import FormsRingElement
        if isinstance(x, FormsRingElement):
            return self.element_class(self, x._rat)
        if hasattr(x, 'parent') and (is_LaurentSeriesRing(x.parent()) or is_PowerSeriesRing(x.parent())):
            # This assumes that the series corresponds to a weakly holomorphic modular form!
            # But the construction method (with the assumption) may also be used for more general form spaces...
            return self.construct_form(x)
        if is_FreeModuleElement(x) and (self.module() == x.parent() or self.ambient_module() == x.parent()):
            return self.element_from_ambient_coordinates(x)
        if (not self.is_ambient()) and (isinstance(x, list) or isinstance(x, tuple) or is_FreeModuleElement(x)) and len(x) == self.rank():
            try:
                return self.element_from_coordinates(x)
            except ArithmeticError, TypeError:
                pass
示例#10
0
    def _is_valid_homomorphism_(self, codomain, im_gens):
        """
        Replacement for method of PowerSeriesRing_generic.

        To be valid, a homomorphism must send generators to elements of
        positive valuation or to nilpotent elements.

        Note that the method is_nilpotent doesn't (as of sage 4.4) seem to
        be defined for obvious examples (matrices, quotients of polynomial
        rings).

        EXAMPLES::

            sage: R.<a,b,c> = PowerSeriesRing(Zmod(8)); R
            Multivariate Power Series Ring in a, b, c over Ring of integers
            modulo 8
            sage: M = PowerSeriesRing(ZZ,3,'x,y,z');
            sage: M._is_valid_homomorphism_(R,[a,c,b])
            True

            sage: M._is_valid_homomorphism_(R,[0,c,b])
            True

        2 is nilpotent in `ZZ/8`, but 3 is not::

            sage: M._is_valid_homomorphism_(R,[2,c,b])
            True
            sage: M._is_valid_homomorphism_(R,[3,c,b])
            False

        Over `ZZ`, 2 is not nilpotent::

            sage: S = R.change_ring(ZZ); S
            Multivariate Power Series Ring in a, b, c over Integer Ring
            sage: M._is_valid_homomorphism_(S,[a,c,b])
            True
            sage: M._is_valid_homomorphism_(S,[0,c,b])
            True
            sage: M._is_valid_homomorphism_(S,[2,c,b])
            False

            sage: g = [S.random_element(10)*v for v in S.gens()]
            sage: M._is_valid_homomorphism_(S,g)
            True
        """
        try:
            im_gens = [codomain(v) for v in im_gens]
        except TypeError:
            raise TypeError(
                "The given generator images do not coerce to codomain.")

        if len(im_gens) is not self.ngens():
            raise ValueError("You must specify the image of each generator.")
        if all(v == 0 for v in im_gens):
            return True
        if is_MPowerSeriesRing(codomain) or is_PowerSeriesRing(codomain):
            try:
                B = all(v.valuation() > 0 or v.is_nilpotent() for v in im_gens)
            except NotImplementedError:
                B = all(v.valuation() > 0 for v in im_gens)
            return B
        if isinstance(codomain, CommutativeRing):
            return all(v.is_nilpotent() for v in im_gens)
示例#11
0
    def _coerce_map_from_(self, P):
        """
        Return a coercion map from `P` to ``self``, or True, or None.

        The following rings admit a coercion map to the Laurent series
        ring `A((t))`:

        - any ring that admits a coercion map to `A` (including `A`
          itself);

        - any Laurent series ring, power series ring or polynomial
          ring in the variable `t` over a ring admitting a coercion
          map to `A`.

        EXAMPLES::

            sage: S.<t> = LaurentSeriesRing(ZZ)
            sage: S.has_coerce_map_from(ZZ)
            True
            sage: S.has_coerce_map_from(PolynomialRing(ZZ, 't'))
            True
            sage: S.has_coerce_map_from(LaurentPolynomialRing(ZZ, 't'))
            True
            sage: S.has_coerce_map_from(PowerSeriesRing(ZZ, 't'))
            True
            sage: S.has_coerce_map_from(S)
            True

            sage: S.has_coerce_map_from(QQ)
            False
            sage: S.has_coerce_map_from(PolynomialRing(QQ, 't'))
            False
            sage: S.has_coerce_map_from(LaurentPolynomialRing(QQ, 't'))
            False
            sage: S.has_coerce_map_from(PowerSeriesRing(QQ, 't'))
            False
            sage: S.has_coerce_map_from(LaurentSeriesRing(QQ, 't'))
            False

            sage: R.<t> = LaurentSeriesRing(QQ['x'])
            sage: R.has_coerce_map_from(QQ[['t']])
            True
            sage: R.has_coerce_map_from(QQ['t'])
            True
            sage: R.has_coerce_map_from(ZZ['x']['t'])
            True
            sage: R.has_coerce_map_from(ZZ['t']['x'])
            False
            sage: R.has_coerce_map_from(ZZ['x'])
            True
        """
        A = self.base_ring()
        if A is P:
            return True
        f = A.coerce_map_from(P)
        if f is not None:
            return self.coerce_map_from(A) * f

        from sage.rings.polynomial.polynomial_ring import is_PolynomialRing
        from sage.rings.power_series_ring import is_PowerSeriesRing
        from sage.rings.polynomial.laurent_polynomial_ring import is_LaurentPolynomialRing
        if ((is_LaurentSeriesRing(P) or is_LaurentPolynomialRing(P)
             or is_PowerSeriesRing(P) or is_PolynomialRing(P))
                and P.variable_name() == self.variable_name()
                and A.has_coerce_map_from(P.base_ring())):
            return True
示例#12
0
def parent_to_repr_short(P):
    r"""
    Helper method which generates a short(er) representation string
    out of a parent.

    INPUT:

    - ``P`` -- a parent.

    OUTPUT:

    A string.

    EXAMPLES::

        sage: from sage.rings.asymptotic.misc import parent_to_repr_short
        sage: parent_to_repr_short(ZZ)
        'ZZ'
        sage: parent_to_repr_short(QQ)
        'QQ'
        sage: parent_to_repr_short(SR)
        'SR'
        sage: parent_to_repr_short(RR)
        'RR'
        sage: parent_to_repr_short(CC)
        'CC'
        sage: parent_to_repr_short(ZZ['x'])
        'ZZ[x]'
        sage: parent_to_repr_short(QQ['d, k'])
        'QQ[d, k]'
        sage: parent_to_repr_short(QQ['e'])
        'QQ[e]'
        sage: parent_to_repr_short(SR[['a, r']])
        'SR[[a, r]]'
        sage: parent_to_repr_short(Zmod(3))
        'Ring of integers modulo 3'
        sage: parent_to_repr_short(Zmod(3)['g'])
        'Univariate Polynomial Ring in g over Ring of integers modulo 3'
    """
    from sage.rings.all import RR, CC, RIF, CIF, RBF, CBF
    from sage.rings.integer_ring import ZZ
    from sage.rings.rational_field import QQ
    from sage.symbolic.ring import SR
    from sage.rings.polynomial.polynomial_ring import is_PolynomialRing
    from sage.rings.polynomial.multi_polynomial_ring_base import is_MPolynomialRing
    from sage.rings.power_series_ring import is_PowerSeriesRing
    def abbreviate(P):
        try:
            return P._repr_short_()
        except AttributeError:
            pass
        abbreviations = {ZZ: 'ZZ', QQ: 'QQ', SR: 'SR',
                         RR: 'RR', CC: 'CC',
                         RIF: 'RIF', CIF: 'CIF',
                         RBF: 'RBF', CBF: 'CBF'}
        try:
            return abbreviations[P]
        except KeyError:
            pass
        raise ValueError('Cannot abbreviate %s.' % (P,))

    poly = is_PolynomialRing(P) or is_MPolynomialRing(P)
    from sage.rings import multi_power_series_ring
    power = is_PowerSeriesRing(P) or \
            multi_power_series_ring.is_MPowerSeriesRing(P)

    if poly or power:
        if poly:
            op, cl = ('[', ']')
        else:
            op, cl = ('[[', ']]')
        try:
            s = abbreviate(P.base_ring()) + op + ', '.join(P.variable_names()) + cl
        except ValueError:
            s = str(P)
    else:
        try:
            s = abbreviate(P)
        except ValueError:
            s = str(P)

    return s
示例#13
0
    def __init__(self, parent, x=0, prec=infinity, is_gen=False, check=False):
        """
        input x can be an MPowerSeries, or an element of

          - the background univariate power series ring
        
          - the foreground polynomial ring

          - a ring that coerces to one of the above two


        TESTS::

            sage: S.<s,t> = PowerSeriesRing(ZZ)
            sage: f = s + 4*t + 3*s*t
            sage: f in S
            True
            sage: f = f.add_bigoh(4); f
            s + 4*t + 3*s*t + O(s, t)^4
            sage: g = 1 + s + t - s*t + S.O(5); g
            1 + s + t - s*t + O(s, t)^5

            sage: B.<s, t> = PowerSeriesRing(QQ)
            sage: C.<z> = PowerSeriesRing(QQ)
            sage: B(z)
            Traceback (most recent call last):
            ...
            TypeError: Cannot coerce input to polynomial ring.

            sage: D.<s> = PowerSeriesRing(QQ)
            sage: s.parent() is D
            True
            sage: B(s) in B
            True
            sage: d = D.random_element(20)
            sage: b = B(d) # test coercion from univariate power series ring
            sage: b in B
            True

        """
        PowerSeries.__init__(self, parent, prec, is_gen=is_gen)
        self._PowerSeries__is_gen = is_gen

        try:
            prec = min(prec, x.prec())  # use precision of input, if defined
        except AttributeError:
            pass

        # set the correct background value, depending on what type of input x is
        try:
            xparent = x.parent()  # 'int' types have no parent
        except AttributeError:
            xparent = None

        # test whether x coerces to background univariate
        # power series ring of parent
        from sage.rings.multi_power_series_ring import is_MPowerSeriesRing
        if is_PowerSeriesRing(xparent) or is_MPowerSeriesRing(xparent):
            # x is either a multivariate or univariate power series
            #
            # test whether x coerces directly to designated parent
            if is_MPowerSeries(x):
                try:
                    self._bg_value = parent._bg_ps_ring(x._bg_value)
                except TypeError:
                    raise TypeError("Unable to coerce into background ring.")

            # test whether x coerces to background univariate
            # power series ring of parent
            elif xparent == parent._bg_ps_ring():
                self._bg_value = x
            elif parent._bg_ps_ring().has_coerce_map_from(xparent):
                # previous test may fail if precision or term orderings of
                # base rings do not match
                self._bg_value = parent._bg_ps_ring(x)
            else:
                # x is a univariate power series, but not from the
                # background power series ring
                #
                # convert x to a polynomial and send to background
                # ring of parent
                x = x.polynomial()
                self._bg_value = parent._send_to_bg(x).add_bigoh(prec)

        # test whether x coerces to underlying polynomial ring of parent
        elif is_PolynomialRing(xparent):
            self._bg_value = parent._send_to_bg(x).add_bigoh(prec)

        else:
            try:
                x = parent._poly_ring(x)
                #self._value = x
                self._bg_value = parent._send_to_bg(x).add_bigoh(prec)
            except (TypeError, AttributeError):
                raise TypeError(
                    "Input does not coerce to any of the expected rings.")

        self._go_to_fg = parent._send_to_fg
        self._prec = self._bg_value.prec()

        # self._parent is used a lot by the class PowerSeries
        self._parent = self.parent()
示例#14
0
    def _coerce_map_from_(self, P):
        """
        The rings that canonically coerce to this multivariate power series
        ring are:

            - this ring itself

            - a polynomial or power series ring in the same variables or a
              subset of these variables (possibly empty), over any base
              ring that canonically coerces into this ring

            - any ring that coerces into the foreground polynomial ring of this ring

        EXAMPLES::

            sage: A = GF(17)[['x','y']]
            sage: A.has_coerce_map_from(ZZ)
            True
            sage: A.has_coerce_map_from(ZZ['x'])
            True
            sage: A.has_coerce_map_from(ZZ['y','x'])
            True
            sage: A.has_coerce_map_from(ZZ[['x']])
            True
            sage: A.has_coerce_map_from(ZZ[['y','x']])
            True
            sage: A.has_coerce_map_from(ZZ['x','z'])
            False
            sage: A.has_coerce_map_from(GF(3)['x','y'])
            False
            sage: A.has_coerce_map_from(Frac(ZZ['y','x']))
            False

        TESTS::

            sage: M = PowerSeriesRing(ZZ,3,'x,y,z')
            sage: M._coerce_map_from_(M)
            True
            sage: M._coerce_map_from_(M.remove_var(x))
            True
            sage: M._coerce_map_from_(PowerSeriesRing(ZZ,x))
            True
            sage: M._coerce_map_from_(PolynomialRing(ZZ,'x,z'))
            True
            sage: M._coerce_map_from_(PolynomialRing(ZZ,0,''))
            True
            sage: M._coerce_map_from_(ZZ)
            True

            sage: M._coerce_map_from_(Zmod(13))
            False
            sage: M._coerce_map_from_(PolynomialRing(ZZ,2,'x,t'))
            False
            sage: M._coerce_map_from_(PolynomialRing(Zmod(11),2,'x,y'))
            False

            sage: P = PolynomialRing(ZZ,3,'z')
            sage: H = PowerSeriesRing(P,4,'f'); H
            Multivariate Power Series Ring in f0, f1, f2, f3 over Multivariate Polynomial Ring in z0, z1, z2 over Integer Ring
            sage: H._coerce_map_from_(P)
            True
            sage: H._coerce_map_from_(P.remove_var(P.gen(1)))
            True
            sage: H._coerce_map_from_(PolynomialRing(ZZ,'z2,f0'))
            True

        """
        if is_MPolynomialRing(P) or is_MPowerSeriesRing(P) \
                   or is_PolynomialRing(P) or is_PowerSeriesRing(P):
            if set(P.variable_names()).issubset(set(self.variable_names())):
                if self.has_coerce_map_from(P.base_ring()):
                    return True

        return self._poly_ring().has_coerce_map_from(P)
示例#15
0
    def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None):
        """
        Replacement for method of PowerSeriesRing_generic.

        To be valid, a homomorphism must send generators to elements of
        positive valuation or to nilpotent elements.

        Note that the method is_nilpotent doesn't (as of sage 4.4) seem to
        be defined for obvious examples (matrices, quotients of polynomial
        rings).

        EXAMPLES::

            sage: R.<a,b,c> = PowerSeriesRing(Zmod(8)); R
            Multivariate Power Series Ring in a, b, c over Ring of integers
            modulo 8
            sage: M = PowerSeriesRing(ZZ,3,'x,y,z')
            sage: M._is_valid_homomorphism_(R,[a,c,b])
            True

            sage: M._is_valid_homomorphism_(R,[0,c,b])
            True

        2 is nilpotent in `ZZ/8`, but 3 is not::

            sage: M._is_valid_homomorphism_(R,[2,c,b])
            True
            sage: M._is_valid_homomorphism_(R,[3,c,b])
            False

        Over `ZZ`, 2 is not nilpotent::

            sage: S = R.change_ring(ZZ); S
            Multivariate Power Series Ring in a, b, c over Integer Ring
            sage: M._is_valid_homomorphism_(S,[a,c,b])
            True
            sage: M._is_valid_homomorphism_(S,[0,c,b])
            True
            sage: M._is_valid_homomorphism_(S,[2,c,b])
            False

            sage: g = [S.random_element(10)*v for v in S.gens()]
            sage: M._is_valid_homomorphism_(S,g)
            True

        You must either give a base map or there must be a coercion
        from the base ring to the codomain::

            sage: T.<t> = ZZ[]
            sage: K.<i> = NumberField(t^2 + 1)
            sage: Q8.<z> = CyclotomicField(8)
            sage: X.<x> = PowerSeriesRing(Q8)
            sage: M.<a,b,c> = PowerSeriesRing(K)
            sage: M._is_valid_homomorphism_(X, [x,x,x+x^2]) # no coercion
            False
            sage: M._is_valid_homomorphism_(X, [x,x,x+x^2], base_map=K.hom([z^2]))
            True
        """
        try:
            im_gens = [codomain(v) for v in im_gens]
        except TypeError:
            raise TypeError("The given generator images do not coerce to codomain.")

        if len(im_gens) is not self.ngens():
            raise ValueError("You must specify the image of each generator.")
        if base_map is None and not codomain.has_coerce_map_from(self.base_ring()):
            return False
        if all(v == 0 for v in im_gens):
            return True
        from .laurent_series_ring import is_LaurentSeriesRing
        if is_MPowerSeriesRing(codomain) or is_PowerSeriesRing(codomain) or is_LaurentSeriesRing(codomain):
            try:
                B = all(v.valuation() > 0 or v.is_nilpotent() for v in im_gens)
            except NotImplementedError:
                B = all(v.valuation() > 0 for v in im_gens)
            return B
        try:
            return all(v.is_nilpotent() for v in im_gens)
        except NotImplementedError:
            pass
        return False
示例#16
0
def parent_to_repr_short(P):
    r"""
    Helper method which generates a short(er) representation string
    out of a parent.

    INPUT:

    - ``P`` -- a parent.

    OUTPUT:

    A string.

    EXAMPLES::

        sage: from sage.rings.asymptotic.misc import parent_to_repr_short
        sage: parent_to_repr_short(ZZ)
        'ZZ'
        sage: parent_to_repr_short(QQ)
        'QQ'
        sage: parent_to_repr_short(SR)
        'SR'
        sage: parent_to_repr_short(ZZ['x'])
        'ZZ[x]'
        sage: parent_to_repr_short(QQ['d, k'])
        'QQ[d, k]'
        sage: parent_to_repr_short(QQ['e'])
        'QQ[e]'
        sage: parent_to_repr_short(SR[['a, r']])
        'SR[[a, r]]'
        sage: parent_to_repr_short(Zmod(3))
        'Ring of integers modulo 3'
        sage: parent_to_repr_short(Zmod(3)['g'])
        'Univariate Polynomial Ring in g over Ring of integers modulo 3'
    """
    from sage.rings.integer_ring import ZZ
    from sage.rings.rational_field import QQ
    from sage.symbolic.ring import SR
    from sage.rings.polynomial.polynomial_ring import is_PolynomialRing
    from sage.rings.polynomial.multi_polynomial_ring_generic import is_MPolynomialRing
    from sage.rings.power_series_ring import is_PowerSeriesRing

    def abbreviate(P):
        if P is ZZ:
            return 'ZZ'
        elif P is QQ:
            return 'QQ'
        elif P is SR:
            return 'SR'
        raise ValueError('Cannot abbreviate %s.' % (P, ))

    poly = is_PolynomialRing(P) or is_MPolynomialRing(P)
    from sage.rings import multi_power_series_ring
    power = is_PowerSeriesRing(P) or \
            multi_power_series_ring.is_MPowerSeriesRing(P)

    if poly or power:
        if poly:
            op, cl = ('[', ']')
        else:
            op, cl = ('[[', ']]')
        try:
            s = abbreviate(P.base_ring()) + op + ', '.join(
                P.variable_names()) + cl
        except ValueError:
            s = str(P)
    else:
        try:
            s = abbreviate(P)
        except ValueError:
            s = str(P)

    return s
示例#17
0
文件: misc.py 项目: mcognetta/sage
def parent_to_repr_short(P):
    r"""
    Helper method which generates a short(er) representation string
    out of a parent.

    INPUT:

    - ``P`` -- a parent.

    OUTPUT:

    A string.

    EXAMPLES::

        sage: from sage.rings.asymptotic.misc import parent_to_repr_short
        sage: parent_to_repr_short(ZZ)
        'ZZ'
        sage: parent_to_repr_short(QQ)
        'QQ'
        sage: parent_to_repr_short(SR)
        'SR'
        sage: parent_to_repr_short(ZZ['x'])
        'ZZ[x]'
        sage: parent_to_repr_short(QQ['d, k'])
        'QQ[d, k]'
        sage: parent_to_repr_short(QQ['e'])
        'QQ[e]'
        sage: parent_to_repr_short(SR[['a, r']])
        'SR[[a, r]]'
        sage: parent_to_repr_short(Zmod(3))
        'Ring of integers modulo 3'
        sage: parent_to_repr_short(Zmod(3)['g'])
        'Univariate Polynomial Ring in g over Ring of integers modulo 3'
    """
    from sage.rings.integer_ring import ZZ
    from sage.rings.rational_field import QQ
    from sage.symbolic.ring import SR
    from sage.rings.polynomial.polynomial_ring import is_PolynomialRing
    from sage.rings.polynomial.multi_polynomial_ring_generic import is_MPolynomialRing
    from sage.rings.power_series_ring import is_PowerSeriesRing
    def abbreviate(P):
        if P is ZZ:
            return 'ZZ'
        elif P is QQ:
            return 'QQ'
        elif P is SR:
            return 'SR'
        raise ValueError('Cannot abbreviate %s.' % (P,))

    poly = is_PolynomialRing(P) or is_MPolynomialRing(P)
    from sage.rings import multi_power_series_ring
    power = is_PowerSeriesRing(P) or \
            multi_power_series_ring.is_MPowerSeriesRing(P)

    if poly or power:
        if poly:
            op, cl = ('[', ']')
        else:
            op, cl = ('[[', ']]')
        try:
            s = abbreviate(P.base_ring()) + op + ', '.join(P.variable_names()) + cl
        except ValueError:
            s = str(P)
    else:
        try:
            s = abbreviate(P)
        except ValueError:
            s = str(P)

    return s