def PuiseuxSeriesRing(base_ring, name=None, names=None, default_prec=None, sparse=False):
    if names is not None:
        name = names
    if name is None:
        raise TypeError('You must specify the name of the indeterminate of the Puiseux series ring.')

    if default_prec is None:
        from sage.misc.defaults import series_precision
        default_prec = series_precision()

    global puiseux_series
    key = (base_ring, name, default_prec, sparse)
    if key in puiseux_series:
        x = puiseux_series[key]()
        if x is not None: return x

    if isinstance(base_ring, Field):
        R = PuiseuxSeriesRing_field(base_ring, name, default_prec, sparse)
    elif isinstance(base_ring, IntegralDomain):
        R = PuiseuxSeriesRing_domain(base_ring, name, default_prec, sparse)
    elif isinstance(base_ring, CommutativeRing):
        R = PuiseuxSeriesRing_generic(base_ring, name, default_prec, sparse)
    else:
        raise TypeError("base_ring must be a commutative ring")
    puiseux_series[key] = weakref.ref(R)
    return R
Exemple #2
0
def _step_upper_bound_internal(r, m, q, generating_function):
    r"""
    Common implementation for :func:`step_upper_bound` and :func:`step_upper_bound_specific`
    """
    L = LieAlgebra(QQ, ['X_%d' % k for k in range(r)]).Lyndon()
    dim_fm = L.graded_dimension(m)

    t = var('t')
    pt = symbolic_prod(
        (1 / ((1 - t**k)**L.graded_dimension(k)) for k in range(1, m)),
        (1 - dim_fm * (1 - t**q)) * t**m)

    increment = series_precision()
    i = 0
    coeffsum = ZZ.zero()
    while True:
        # sum the coefficients of the series for t^i...t^(i+increment-1)
        p_series = pt.series(t, i + increment)
        for s in range(i, i + increment):
            coeffsum += ZZ(p_series.coefficient(t, s))
            if coeffsum > 0:
                verbose("upper bound for abnormality: step %d" % s)
                if generating_function:
                    return s, pt
                return s
        # exponential growth to avoid recomputing the series too much
        i += increment
        increment += increment
def PuiseuxSeriesRing(base_ring, name=None, names=None, default_prec=None, sparse=False):
    if not names is None: name = names
    if name is None:
        raise TypeError('You must specify the name of the indeterminate of the Puiseux series ring.')

    if default_prec is None:
        from sage.misc.defaults import series_precision
        default_prec = series_precision()

    global puiseux_series
    key = (base_ring, name, default_prec, sparse)
    if key in puiseux_series:
        x = puiseux_series[key]()
        if x is not None: return x

    if isinstance(base_ring, Field):
        R = PuiseuxSeriesRing_field(base_ring, name, default_prec, sparse)
    elif isinstance(base_ring, IntegralDomain):
        R = PuiseuxSeriesRing_domain(base_ring, name, default_prec, sparse)
    elif isinstance(base_ring, CommutativeRing):
        R = PuiseuxSeriesRing_generic(base_ring, name, default_prec, sparse)
    else:
        raise TypeError("base_ring must be a commutative ring")
    puiseux_series[key] = weakref.ref(R)
    return R
def LaurentSeriesRing(base_ring, name=None, names=None, default_prec=None, sparse=False):
    """
    EXAMPLES::

        sage: R = LaurentSeriesRing(QQ, 'x'); R
        Laurent Series Ring in x over Rational Field
        sage: x = R.0
        sage: g = 1 - x + x^2 - x^4 +O(x^8); g
        1 - x + x^2 - x^4 + O(x^8)
        sage: g = 10*x^(-3) + 2006 - 19*x + x^2 - x^4 +O(x^8); g
        10*x^-3 + 2006 - 19*x + x^2 - x^4 + O(x^8)

    You can also use more mathematical notation when the base is a
    field::

        sage: Frac(QQ[['x']])
        Laurent Series Ring in x over Rational Field
        sage: Frac(GF(5)['y'])
        Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5

    Here the fraction field is not just the Laurent series ring, so you
    can't use the ``Frac`` notation to make the Laurent
    series ring.

    ::

        sage: Frac(ZZ[['t']])
        Fraction Field of Power Series Ring in t over Integer Ring

    Laurent series rings are determined by their variable and the base
    ring, and are globally unique.

    ::

        sage: K = Qp(5, prec = 5)
        sage: L = Qp(5, prec = 200)
        sage: R.<x> = LaurentSeriesRing(K)
        sage: S.<y> = LaurentSeriesRing(L)
        sage: R is S
        False
        sage: T.<y> = LaurentSeriesRing(Qp(5,prec=200))
        sage: S is T
        True
        sage: W.<y> = LaurentSeriesRing(Qp(5,prec=199))
        sage: W is T
        False

    TESTS:

    Check if changing global series precision does it right (and
    that :trac:`17955` is fixed)::

        sage: set_series_precision(3)
        sage: R.<x> = LaurentSeriesRing(ZZ)
        sage: 1/(1 - 2*x)
        1 + 2*x + 4*x^2 + O(x^3)
        sage: set_series_precision(5)
        sage: R.<x> = LaurentSeriesRing(ZZ)
        sage: 1/(1 - 2*x)
        1 + 2*x + 4*x^2 + 8*x^3 + 16*x^4 + O(x^5)
        sage: set_series_precision(20)
    """
    if not names is None: name = names
    if name is None:
        raise TypeError("You must specify the name of the indeterminate of the Laurent series ring.")

    if default_prec is None:
        from sage.misc.defaults import series_precision
        default_prec = series_precision()

    global laurent_series
    key = (base_ring, name, default_prec, sparse)
    if key in laurent_series:
        x = laurent_series[key]()
        if x is not None: return x

    if isinstance(base_ring, ring.Field):
        R = LaurentSeriesRing_field(base_ring, name, default_prec, sparse)
    elif isinstance(base_ring, integral_domain.IntegralDomain):
        R = LaurentSeriesRing_domain(base_ring, name, default_prec, sparse)
    elif isinstance(base_ring, commutative_ring.CommutativeRing):
        R = LaurentSeriesRing_generic(base_ring, name, default_prec, sparse)
    else:
        raise TypeError("base_ring must be a commutative ring")
    laurent_series[key] = weakref.ref(R)
    return R
Exemple #5
0
    def __init__(self, base_ring, name=None, default_prec=None, sparse=False,
                 use_lazy_mpoly_ring=False, category=None):
        """
        Initializes a power series ring.

        INPUT:


        -  ``base_ring`` - a commutative ring

        -  ``name`` - name of the indeterminate

        -  ``default_prec`` - the default precision

        -  ``sparse`` - whether or not power series are
           sparse

        - ``use_lazy_mpoly_ring`` - if base ring is a poly ring compute with
          multivariate polynomials instead of a univariate poly over the base
          ring. Only use this for dense power series where you won't do too
          much arithmetic, but the arithmetic you do must be fast. You must
          explicitly call ``f.do_truncation()`` on an element
          for it to truncate away higher order terms (this is called
          automatically before printing).
          
        EXAMPLES:
    
        This base class inherits from :class:`~sage.rings.ring.CommutativeRing`.
        Since :trac:`11900`, it is also initialised as such, and since :trac:`14084`
        it is actually initialised as an integral domain::
    
            sage: R.<x> = ZZ[[]]
            sage: R.category()
            Category of integral domains
            sage: TestSuite(R).run()
    
        When the base ring `k` is a field, the ring `k[[x]]` is not only a
        commutative ring, but also a complete discrete valuation ring (CDVR).
        The appropriate (sub)category is automatically set in this case::
    
            sage: k = GF(11)
            sage: R.<x> = k[[]]
            sage: R.category()
            Category of complete discrete valuation rings
            sage: TestSuite(R).run()
        """
        R = PolynomialRing(base_ring, name, sparse=sparse)
        self.__poly_ring = R
        self.__is_sparse = sparse
        if default_prec is None:
            from sage.misc.defaults import series_precision
            default_prec = series_precision()
        self.__params = (base_ring, name, default_prec, sparse)

        if use_lazy_mpoly_ring and (is_MPolynomialRing(base_ring) or \
                                    is_PolynomialRing(base_ring)):
            K = base_ring
            names = K.variable_names() + (name,)
            self.__mpoly_ring = PolynomialRing(K.base_ring(), names=names)
            assert is_MPolynomialRing(self.__mpoly_ring)
            self.Element = power_series_mpoly.PowerSeries_mpoly
        commutative_ring.CommutativeRing.__init__(self, base_ring, names=name,
                                                  category=getattr(self,'_default_category',
                                                                  _CommutativeRings))
        Nonexact.__init__(self, default_prec)
        self.__generator = self.element_class(self, R.gen(), check=True, is_gen=True)
Exemple #6
0
def PowerSeriesRing(base_ring, name=None, arg2=None, names=None,
                    sparse=False, default_prec=None, order='negdeglex', num_gens=None):
    r"""
    Create a univariate or multivariate power series ring over a given
    (commutative) base ring.

    INPUT:


    -  ``base_ring`` - a commutative ring

    -  ``name``, ``names`` - name(s) of the indeterminate

    - ``default_prec`` - the default precision used if an exact object must
       be changed to an approximate object in order to do an arithmetic
       operation.  If left as ``None``, it will be set to the global
       default (20) in the univariate case, and 12 in the multivariate case.

    -  ``sparse`` - (default: ``False``) whether power series
       are represented as sparse objects.

    - ``order`` - (default: ``negdeglex``) term ordering, for multivariate case

    - ``num_gens`` - number of generators, for multivariate case


    There is a unique power series ring over each base ring with given
    variable name. Two power series over the same base ring with
    different variable names are not equal or isomorphic.

    EXAMPLES (Univariate)::

        sage: R = PowerSeriesRing(QQ, 'x'); R
        Power Series Ring in x over Rational Field

    ::

        sage: S = PowerSeriesRing(QQ, 'y'); S
        Power Series Ring in y over Rational Field

    ::

        sage: R = PowerSeriesRing(QQ, 10)
        Traceback (most recent call last):
        ...
        ValueError: first letter of variable name must be a letter: 10

    ::

        sage: S = PowerSeriesRing(QQ, 'x', default_prec = 15); S
        Power Series Ring in x over Rational Field
        sage: S.default_prec()
        15

    EXAMPLES (Multivariate) See also :doc:`multi_power_series_ring`::

        sage: R = PowerSeriesRing(QQ, 't,u,v'); R
        Multivariate Power Series Ring in t, u, v over Rational Field

    ::

        sage: N = PowerSeriesRing(QQ,'w',num_gens=5); N
        Multivariate Power Series Ring in w0, w1, w2, w3, w4 over Rational Field

    Number of generators can be specified before variable name without using keyword::

        sage: M = PowerSeriesRing(QQ,4,'k'); M
        Multivariate Power Series Ring in k0, k1, k2, k3 over Rational Field

    Multivariate power series can be constructed using angle bracket or double square bracket notation::

        sage: R.<t,u,v> = PowerSeriesRing(QQ, 't,u,v'); R
        Multivariate Power Series Ring in t, u, v over Rational Field

        sage: ZZ[['s,t,u']]
        Multivariate Power Series Ring in s, t, u over Integer Ring

    Sparse multivariate power series ring::

        sage: M = PowerSeriesRing(QQ,4,'k',sparse=True); M
        Sparse Multivariate Power Series Ring in k0, k1, k2, k3 over
        Rational Field

    Power series ring over polynomial ring::

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

    Power series ring over finite field::

        sage: S = PowerSeriesRing(GF(65537),'x,y'); S
        Multivariate Power Series Ring in x, y over Finite Field of size
        65537

    Power series ring with many variables::

        sage: R = PowerSeriesRing(ZZ, ['x%s'%p for p in primes(100)]); R
        Multivariate Power Series Ring in x2, x3, x5, x7, x11, x13, x17, x19,
        x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79,
        x83, x89, x97 over Integer Ring

    - Use :meth:`inject_variables` to make the variables available for
      interactive use.

      ::

        sage: R.inject_variables()
        Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37,
        x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97

        sage: f = x47 + 3*x11*x29 - x19 + R.O(3)
        sage: f in R
        True


    Variable ordering determines how series are displayed::

        sage: T.<a,b> = PowerSeriesRing(ZZ,order='deglex'); T
        Multivariate Power Series Ring in a, b over Integer Ring
        sage: T.term_order()
        Degree lexicographic term order
        sage: p = - 2*b^6 + a^5*b^2 + a^7 - b^2 - a*b^3 + T.O(9); p
        a^7 + a^5*b^2 - 2*b^6 - a*b^3 - b^2 + O(a, b)^9

        sage: U = PowerSeriesRing(ZZ,'a,b',order='negdeglex'); U
        Multivariate Power Series Ring in a, b over Integer Ring
        sage: U.term_order()
        Negative degree lexicographic term order
        sage: U(p)
        -b^2 - a*b^3 - 2*b^6 + a^7 + a^5*b^2 + O(a, b)^9


    TESTS::

        sage: N = PowerSeriesRing(QQ,'k',num_gens=5); N
        Multivariate Power Series Ring in k0, k1, k2, k3, k4 over Rational Field

    The following behavior of univariate power series ring will eventually
    be deprecated and then changed to return a multivariate power series
    ring::

        sage: N = PowerSeriesRing(QQ,'k',5); N
        Power Series Ring in k over Rational Field
        sage: N.default_prec()
        5
        sage: L.<m> = PowerSeriesRing(QQ,5); L
        Power Series Ring in m over Rational Field
        sage: L.default_prec()
        5

    By :trac:`14084`, a power series ring belongs to the category of integral
    domains, if the base ring does::

        sage: P = ZZ[['x']]
        sage: P.category()
        Category of integral domains
        sage: TestSuite(P).run()
        sage: M = ZZ[['x','y']]
        sage: M.category()
        Category of integral domains
        sage: TestSuite(M).run()

    Otherwise, it belongs to the category of commutative rings::

        sage: P = Integers(15)[['x']]
        sage: P.category()
        Category of commutative rings
        sage: TestSuite(P).run()
        sage: M = Integers(15)[['x','y']]
        sage: M.category()
        Category of commutative rings
        sage: TestSuite(M).run()

    .. SEEALSO::
    
        * :func:`sage.misc.defaults.set_series_precision`
    """
    #multivariate case:
    # examples for first case:
    # PowerSeriesRing(QQ,'x,y,z')
    # PowerSeriesRing(QQ,['x','y','z'])
    # PowerSeriesRing(QQ,['x','y','z'], 3)
    if names is None and name is not None:
        names = name
    if isinstance(names, (tuple, list)) and len(names) > 1 or (isinstance(names, str) and ',' in names):
        return _multi_variate(base_ring, num_gens=arg2, names=names,
                     order=order, default_prec=default_prec, sparse=sparse)
    # examples for second case:
    # PowerSeriesRing(QQ,3,'t')
    if arg2 is None and num_gens is not None:
        arg2 = names
        names = num_gens
    if isinstance(arg2, str) and isinstance(names, (int,long,integer.Integer)):
        return _multi_variate(base_ring, num_gens=names, names=arg2,
                     order=order, default_prec=default_prec, sparse=sparse)


    # univariate case: the arguments to PowerSeriesRing used to be
    # (base_ring, name=None, default_prec=20, names=None, sparse=False),
    # and thus that is what the code below expects; this behavior is being
    # deprecated, and will eventually be removed.
    if default_prec is None and arg2 is None:
        from sage.misc.defaults import series_precision
        default_prec = series_precision()
    elif arg2 is not None:
        default_prec = arg2

    ## too many things (padics, elliptic curves) depend on this behavior,
    ## so no warning for now.
    ##
    # from sage.misc.superseded import deprecation
    # if isinstance(name, (int,long,integer.Integer)) or isinstance(arg2,(int,long,integer.Integer)):
    #     deprecation(trac_number, "This behavior of PowerSeriesRing is being deprecated in favor of constructing multivariate power series rings. (See Trac ticket #1956.)")


    # the following is the original, univariate-only code

    if isinstance(name, (int,long,integer.Integer)):
        default_prec = name
    if not names is None:
        name = names
    try:
        name = normalize_names(1, name)
    except TypeError:
        raise TypeError("illegal variable name")

    if name is None:
        raise TypeError("You must specify the name of the indeterminate of the Power series ring.")

    key = (base_ring, name, default_prec, sparse)
    if PowerSeriesRing_generic.__classcall__.is_in_cache(key):
        return PowerSeriesRing_generic(*key)

    if isinstance(name, (tuple, list)):
        assert len(name) == 1
        name = name[0]

    if not (name is None or isinstance(name, str)):
        raise TypeError("variable name must be a string or None")

    if base_ring in _Fields:
        R = PowerSeriesRing_over_field(base_ring, name, default_prec, sparse=sparse)
    elif base_ring in _IntegralDomains:
        R = PowerSeriesRing_domain(base_ring, name, default_prec, sparse=sparse)
    elif base_ring in _CommutativeRings:
        R = PowerSeriesRing_generic(base_ring, name, default_prec, sparse=sparse)
    else:
        raise TypeError("base_ring must be a commutative ring")
    return R
Exemple #7
0
    def __init__(self,
                 base_ring,
                 name=None,
                 default_prec=None,
                 sparse=False,
                 use_lazy_mpoly_ring=False,
                 category=None):
        """
        Initializes a power series ring.

        INPUT:


        -  ``base_ring`` - a commutative ring

        -  ``name`` - name of the indeterminate

        -  ``default_prec`` - the default precision

        -  ``sparse`` - whether or not power series are
           sparse

        - ``use_lazy_mpoly_ring`` - if base ring is a poly ring compute with
          multivariate polynomials instead of a univariate poly over the base
          ring. Only use this for dense power series where you won't do too
          much arithmetic, but the arithmetic you do must be fast. You must
          explicitly call ``f.do_truncation()`` on an element
          for it to truncate away higher order terms (this is called
          automatically before printing).
          
        EXAMPLES:
    
        This base class inherits from :class:`~sage.rings.ring.CommutativeRing`.
        Since :trac:`11900`, it is also initialised as such, and since :trac:`14084`
        it is actually initialised as an integral domain::

            sage: R.<x> = ZZ[[]]
            sage: R.category()
            Category of integral domains
            sage: TestSuite(R).run()
    
        When the base ring `k` is a field, the ring `k[[x]]` is not only a
        commutative ring, but also a complete discrete valuation ring (CDVR).
        The appropriate (sub)category is automatically set in this case::
    
            sage: k = GF(11)
            sage: R.<x> = k[[]]
            sage: R.category()
            Category of complete discrete valuation rings
            sage: TestSuite(R).run()

        It is checked that the default precision is non-negative
        (see :trac:`19409`)::

            sage: PowerSeriesRing(ZZ, 'x', default_prec=-5)
            Traceback (most recent call last):
            ...
            ValueError: default_prec (= -5) must be non-negative

        """
        R = PolynomialRing(base_ring, name, sparse=sparse)
        self.__poly_ring = R
        self.__is_sparse = sparse
        if default_prec is None:
            from sage.misc.defaults import series_precision
            default_prec = series_precision()
        elif default_prec < 0:
            raise ValueError("default_prec (= %s) must be non-negative" %
                             default_prec)
        self.__params = (base_ring, name, default_prec, sparse)

        if use_lazy_mpoly_ring and (is_MPolynomialRing(base_ring) or \
                                    is_PolynomialRing(base_ring)):
            K = base_ring
            names = K.variable_names() + (name, )
            self.__mpoly_ring = PolynomialRing(K.base_ring(), names=names)
            assert is_MPolynomialRing(self.__mpoly_ring)
            self.Element = power_series_mpoly.PowerSeries_mpoly
        commutative_ring.CommutativeRing.__init__(
            self,
            base_ring,
            names=name,
            category=getattr(self, '_default_category', _CommutativeRings))
        Nonexact.__init__(self, default_prec)
        self.__generator = self.element_class(self,
                                              R.gen(),
                                              check=True,
                                              is_gen=True)
Exemple #8
0
def PowerSeriesRing(base_ring,
                    name=None,
                    arg2=None,
                    names=None,
                    sparse=False,
                    default_prec=None,
                    order='negdeglex',
                    num_gens=None):
    r"""
    Create a univariate or multivariate power series ring over a given
    (commutative) base ring.

    INPUT:


    -  ``base_ring`` - a commutative ring

    -  ``name``, ``names`` - name(s) of the indeterminate

    - ``default_prec`` - the default precision used if an exact object must
       be changed to an approximate object in order to do an arithmetic
       operation.  If left as ``None``, it will be set to the global
       default (20) in the univariate case, and 12 in the multivariate case.

    -  ``sparse`` - (default: ``False``) whether power series
       are represented as sparse objects.

    - ``order`` - (default: ``negdeglex``) term ordering, for multivariate case

    - ``num_gens`` - number of generators, for multivariate case


    There is a unique power series ring over each base ring with given
    variable name. Two power series over the same base ring with
    different variable names are not equal or isomorphic.

    EXAMPLES (Univariate)::

        sage: R = PowerSeriesRing(QQ, 'x'); R
        Power Series Ring in x over Rational Field

    ::

        sage: S = PowerSeriesRing(QQ, 'y'); S
        Power Series Ring in y over Rational Field

    ::

        sage: R = PowerSeriesRing(QQ, 10)
        Traceback (most recent call last):
        ...
        ValueError: variable name '10' does not start with a letter

    ::

        sage: S = PowerSeriesRing(QQ, 'x', default_prec = 15); S
        Power Series Ring in x over Rational Field
        sage: S.default_prec()
        15

    EXAMPLES (Multivariate) See also :doc:`multi_power_series_ring`::

        sage: R = PowerSeriesRing(QQ, 't,u,v'); R
        Multivariate Power Series Ring in t, u, v over Rational Field

    ::

        sage: N = PowerSeriesRing(QQ,'w',num_gens=5); N
        Multivariate Power Series Ring in w0, w1, w2, w3, w4 over Rational Field

    Number of generators can be specified before variable name without using keyword::

        sage: M = PowerSeriesRing(QQ,4,'k'); M
        Multivariate Power Series Ring in k0, k1, k2, k3 over Rational Field

    Multivariate power series can be constructed using angle bracket or double square bracket notation::

        sage: R.<t,u,v> = PowerSeriesRing(QQ, 't,u,v'); R
        Multivariate Power Series Ring in t, u, v over Rational Field

        sage: ZZ[['s,t,u']]
        Multivariate Power Series Ring in s, t, u over Integer Ring

    Sparse multivariate power series ring::

        sage: M = PowerSeriesRing(QQ,4,'k',sparse=True); M
        Sparse Multivariate Power Series Ring in k0, k1, k2, k3 over
        Rational Field

    Power series ring over polynomial ring::

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

    Power series ring over finite field::

        sage: S = PowerSeriesRing(GF(65537),'x,y'); S
        Multivariate Power Series Ring in x, y over Finite Field of size
        65537

    Power series ring with many variables::

        sage: R = PowerSeriesRing(ZZ, ['x%s'%p for p in primes(100)]); R
        Multivariate Power Series Ring in x2, x3, x5, x7, x11, x13, x17, x19,
        x23, x29, x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79,
        x83, x89, x97 over Integer Ring

    - Use :meth:`inject_variables` to make the variables available for
      interactive use.

      ::

        sage: R.inject_variables()
        Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37,
        x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97

        sage: f = x47 + 3*x11*x29 - x19 + R.O(3)
        sage: f in R
        True


    Variable ordering determines how series are displayed::

        sage: T.<a,b> = PowerSeriesRing(ZZ,order='deglex'); T
        Multivariate Power Series Ring in a, b over Integer Ring
        sage: T.term_order()
        Degree lexicographic term order
        sage: p = - 2*b^6 + a^5*b^2 + a^7 - b^2 - a*b^3 + T.O(9); p
        a^7 + a^5*b^2 - 2*b^6 - a*b^3 - b^2 + O(a, b)^9

        sage: U = PowerSeriesRing(ZZ,'a,b',order='negdeglex'); U
        Multivariate Power Series Ring in a, b over Integer Ring
        sage: U.term_order()
        Negative degree lexicographic term order
        sage: U(p)
        -b^2 - a*b^3 - 2*b^6 + a^7 + a^5*b^2 + O(a, b)^9


    TESTS::

        sage: N = PowerSeriesRing(QQ,'k',num_gens=5); N
        Multivariate Power Series Ring in k0, k1, k2, k3, k4 over Rational Field

    The following behavior of univariate power series ring will eventually
    be deprecated and then changed to return a multivariate power series
    ring::

        sage: N = PowerSeriesRing(QQ,'k',5); N
        Power Series Ring in k over Rational Field
        sage: N.default_prec()
        5
        sage: L.<m> = PowerSeriesRing(QQ,5); L
        Power Series Ring in m over Rational Field
        sage: L.default_prec()
        5

    By :trac:`14084`, a power series ring belongs to the category of integral
    domains, if the base ring does::

        sage: P = ZZ[['x']]
        sage: P.category()
        Category of integral domains
        sage: TestSuite(P).run()
        sage: M = ZZ[['x','y']]
        sage: M.category()
        Category of integral domains
        sage: TestSuite(M).run()

    Otherwise, it belongs to the category of commutative rings::

        sage: P = Integers(15)[['x']]
        sage: P.category()
        Category of commutative rings
        sage: TestSuite(P).run()
        sage: M = Integers(15)[['x','y']]
        sage: M.category()
        Category of commutative rings
        sage: TestSuite(M).run()

    .. SEEALSO::

        * :func:`sage.misc.defaults.set_series_precision`
    """
    #multivariate case:
    # examples for first case:
    # PowerSeriesRing(QQ,'x,y,z')
    # PowerSeriesRing(QQ,['x','y','z'])
    # PowerSeriesRing(QQ,['x','y','z'], 3)
    if names is None and name is not None:
        names = name
    if isinstance(names,
                  (tuple, list)) and len(names) > 1 or (isinstance(names, str)
                                                        and ',' in names):
        return _multi_variate(base_ring,
                              num_gens=arg2,
                              names=names,
                              order=order,
                              default_prec=default_prec,
                              sparse=sparse)
    # examples for second case:
    # PowerSeriesRing(QQ,3,'t')
    if arg2 is None and num_gens is not None:
        arg2 = names
        names = num_gens
    if isinstance(arg2, str) and isinstance(names,
                                            (int, long, integer.Integer)):
        return _multi_variate(base_ring,
                              num_gens=names,
                              names=arg2,
                              order=order,
                              default_prec=default_prec,
                              sparse=sparse)

    # univariate case: the arguments to PowerSeriesRing used to be
    # (base_ring, name=None, default_prec=20, names=None, sparse=False),
    # and thus that is what the code below expects; this behavior is being
    # deprecated, and will eventually be removed.
    if default_prec is None and arg2 is None:
        from sage.misc.defaults import series_precision
        default_prec = series_precision()
    elif arg2 is not None:
        default_prec = arg2

    ## too many things (padics, elliptic curves) depend on this behavior,
    ## so no warning for now.
    ##
    # from sage.misc.superseded import deprecation
    # if isinstance(name, (int,long,integer.Integer)) or isinstance(arg2,(int,long,integer.Integer)):
    #     deprecation(trac_number, "This behavior of PowerSeriesRing is being deprecated in favor of constructing multivariate power series rings. (See Trac ticket #1956.)")

    # the following is the original, univariate-only code

    if isinstance(name, (int, long, integer.Integer)):
        default_prec = name
    if not names is None:
        name = names
    name = normalize_names(1, name)

    if name is None:
        raise TypeError(
            "You must specify the name of the indeterminate of the Power series ring."
        )

    key = (base_ring, name, default_prec, sparse)
    if PowerSeriesRing_generic.__classcall__.is_in_cache(key):
        return PowerSeriesRing_generic(*key)

    if isinstance(name, (tuple, list)):
        assert len(name) == 1
        name = name[0]

    if not (name is None or isinstance(name, str)):
        raise TypeError("variable name must be a string or None")

    if base_ring in _Fields:
        R = PowerSeriesRing_over_field(base_ring,
                                       name,
                                       default_prec,
                                       sparse=sparse)
    elif base_ring in _IntegralDomains:
        R = PowerSeriesRing_domain(base_ring,
                                   name,
                                   default_prec,
                                   sparse=sparse)
    elif base_ring in _CommutativeRings:
        R = PowerSeriesRing_generic(base_ring,
                                    name,
                                    default_prec,
                                    sparse=sparse)
    else:
        raise TypeError("base_ring must be a commutative ring")
    return R
    def __init__(self, base_ring, name=None, default_prec=None, sparse=False,
                 use_lazy_mpoly_ring=None, implementation=None,
                 category=None):
        """
        Initializes a power series ring.

        INPUT:


        -  ``base_ring`` - a commutative ring

        -  ``name`` - name of the indeterminate

        -  ``default_prec`` - the default precision

        -  ``sparse`` - whether or not power series are
           sparse

        - ``implementation`` -- either ``'poly'``, ``'mpoly'``, or
          ``'pari'``.  The default is ``'pari'`` if the base field is
          a PARI finite field, and ``'poly'`` otherwise.

        - ``use_lazy_mpoly_ring`` -- This option is deprecated; use
          ``implementation='mpoly'`` instead.

        If the base ring is a polynomial ring, then the option
        ``implementation='mpoly'`` causes computations to be done with
        multivariate polynomials instead of a univariate polynomial
        ring over the base ring.  Only use this for dense power series
        where you won't do too much arithmetic, but the arithmetic you
        do must be fast.  You must explicitly call
        ``f.do_truncation()`` on an element for it to truncate away
        higher order terms (this is called automatically before
        printing).

        EXAMPLES:
    
        This base class inherits from :class:`~sage.rings.ring.CommutativeRing`.
        Since :trac:`11900`, it is also initialised as such, and since :trac:`14084`
        it is actually initialised as an integral domain::

            sage: R.<x> = ZZ[[]]
            sage: R.category()
            Category of integral domains
            sage: TestSuite(R).run()
    
        When the base ring `k` is a field, the ring `k[[x]]` is not only a
        commutative ring, but also a complete discrete valuation ring (CDVR).
        The appropriate (sub)category is automatically set in this case::
    
            sage: k = GF(11)
            sage: R.<x> = k[[]]
            sage: R.category()
            Category of complete discrete valuation rings
            sage: TestSuite(R).run()

        It is checked that the default precision is non-negative
        (see :trac:`19409`)::

            sage: PowerSeriesRing(ZZ, 'x', default_prec=-5)
            Traceback (most recent call last):
            ...
            ValueError: default_prec (= -5) must be non-negative

        """
        if use_lazy_mpoly_ring is not None:
            deprecation(15601, 'The option use_lazy_mpoly_ring is deprecated; use implementation="mpoly" instead')

        from sage.rings.finite_rings.finite_field_pari_ffelt import FiniteField_pari_ffelt

        if implementation is None:
            if isinstance(base_ring, FiniteField_pari_ffelt):
                implementation = 'pari'
            elif use_lazy_mpoly_ring and (is_MPolynomialRing(base_ring) or
                                          is_PolynomialRing(base_ring)):
                implementation = 'mpoly'
            else:
                implementation = 'poly'

        R = PolynomialRing(base_ring, name, sparse=sparse)
        self.__poly_ring = R
        self.__is_sparse = sparse
        if default_prec is None:
            from sage.misc.defaults import series_precision
            default_prec = series_precision()
        elif default_prec < 0:
            raise ValueError("default_prec (= %s) must be non-negative"
                             % default_prec)

        if implementation == 'poly':
            self.Element = power_series_poly.PowerSeries_poly
        elif implementation == 'mpoly':
            K = base_ring
            names = K.variable_names() + (name,)
            self.__mpoly_ring = PolynomialRing(K.base_ring(), names=names)
            assert is_MPolynomialRing(self.__mpoly_ring)
            self.Element = power_series_mpoly.PowerSeries_mpoly
        elif implementation == 'pari':
            self.Element = PowerSeries_pari
        else:
            raise ValueError('unknown power series implementation: %r' % implementation)

        ring.CommutativeRing.__init__(self, base_ring, names=name,
                                      category=getattr(self, '_default_category',
                                                       _CommutativeRings))
        Nonexact.__init__(self, default_prec)
        if self.Element is PowerSeries_pari:
            self.__generator = self.element_class(self, R.gen().__pari__())
        else:
            self.__generator = self.element_class(self, R.gen(), is_gen=True)
Exemple #10
0
def LaurentSeriesRing(base_ring,
                      name=None,
                      names=None,
                      default_prec=None,
                      sparse=False):
    """
    EXAMPLES::

        sage: R = LaurentSeriesRing(QQ, 'x'); R
        Laurent Series Ring in x over Rational Field
        sage: x = R.0
        sage: g = 1 - x + x^2 - x^4 +O(x^8); g
        1 - x + x^2 - x^4 + O(x^8)
        sage: g = 10*x^(-3) + 2006 - 19*x + x^2 - x^4 +O(x^8); g
        10*x^-3 + 2006 - 19*x + x^2 - x^4 + O(x^8)

    You can also use more mathematical notation when the base is a
    field::

        sage: Frac(QQ[['x']])
        Laurent Series Ring in x over Rational Field
        sage: Frac(GF(5)['y'])
        Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 5

    Here the fraction field is not just the Laurent series ring, so you
    can't use the ``Frac`` notation to make the Laurent
    series ring.

    ::

        sage: Frac(ZZ[['t']])
        Fraction Field of Power Series Ring in t over Integer Ring

    Laurent series rings are determined by their variable and the base
    ring, and are globally unique.

    ::

        sage: K = Qp(5, prec = 5)
        sage: L = Qp(5, prec = 200)
        sage: R.<x> = LaurentSeriesRing(K)
        sage: S.<y> = LaurentSeriesRing(L)
        sage: R is S
        False
        sage: T.<y> = LaurentSeriesRing(Qp(5,prec=200))
        sage: S is T
        True
        sage: W.<y> = LaurentSeriesRing(Qp(5,prec=199))
        sage: W is T
        False

    TESTS:

    Check if changing global series precision does it right (and
    that :trac:`17955` is fixed)::

        sage: set_series_precision(3)
        sage: R.<x> = LaurentSeriesRing(ZZ)
        sage: 1/(1 - 2*x)
        1 + 2*x + 4*x^2 + O(x^3)
        sage: set_series_precision(5)
        sage: R.<x> = LaurentSeriesRing(ZZ)
        sage: 1/(1 - 2*x)
        1 + 2*x + 4*x^2 + 8*x^3 + 16*x^4 + O(x^5)
        sage: set_series_precision(20)
    """
    if not names is None: name = names
    if name is None:
        raise TypeError(
            "You must specify the name of the indeterminate of the Laurent series ring."
        )

    if default_prec is None:
        from sage.misc.defaults import series_precision
        default_prec = series_precision()

    global laurent_series
    key = (base_ring, name, default_prec, sparse)
    if key in laurent_series:
        x = laurent_series[key]()
        if x is not None: return x

    if isinstance(base_ring, ring.Field):
        R = LaurentSeriesRing_field(base_ring, name, default_prec, sparse)
    elif isinstance(base_ring, integral_domain.IntegralDomain):
        R = LaurentSeriesRing_domain(base_ring, name, default_prec, sparse)
    elif isinstance(base_ring, commutative_ring.CommutativeRing):
        R = LaurentSeriesRing_generic(base_ring, name, default_prec, sparse)
    else:
        raise TypeError("base_ring must be a commutative ring")
    laurent_series[key] = weakref.ref(R)
    return R