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
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
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)
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
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)
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)
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