Path: blob/master/src/sage/rings/laurent_series_ring.py
8817 views
"""1Laurent Series Rings23EXAMPLES::45sage: R = LaurentSeriesRing(QQ, "x")6sage: R.base_ring()7Rational Field8sage: S = LaurentSeriesRing(GF(17)['x'], 'y')9sage: S10Laurent Series Ring in y over Univariate Polynomial Ring in x over11Finite Field of size 1712sage: S.base_ring()13Univariate Polynomial Ring in x over Finite Field of size 1714"""1516import weakref1718import laurent_series_ring_element19import power_series_ring20import polynomial21import commutative_ring22import integral_domain23import field2425from sage.structure.parent_gens import ParentWithGens26from sage.libs.pari.all import pari_gen2728from sage.structure.category_object import check_default_category29from sage.categories.fields import Fields30from sage.categories.complete_discrete_valuation import CompleteDiscreteValuationFields3132laurent_series = {}33def LaurentSeriesRing(base_ring, name=None, names=None, default_prec=20, sparse=False):34"""35EXAMPLES::3637sage: R = LaurentSeriesRing(QQ, 'x'); R38Laurent Series Ring in x over Rational Field39sage: x = R.040sage: g = 1 - x + x^2 - x^4 +O(x^8); g411 - x + x^2 - x^4 + O(x^8)42sage: g = 10*x^(-3) + 2006 - 19*x + x^2 - x^4 +O(x^8); g4310*x^-3 + 2006 - 19*x + x^2 - x^4 + O(x^8)4445You can also use more mathematical notation when the base is a46field::4748sage: Frac(QQ[['x']])49Laurent Series Ring in x over Rational Field50sage: Frac(GF(5)['y'])51Fraction Field of Univariate Polynomial Ring in y over Finite Field of size 55253Here the fraction field is not just the Laurent series ring, so you54can't use the ``Frac`` notation to make the Laurent55series ring.5657::5859sage: Frac(ZZ[['t']])60Fraction Field of Power Series Ring in t over Integer Ring6162Laurent series rings are determined by their variable and the base63ring, and are globally unique.6465::6667sage: K = Qp(5, prec = 5)68sage: L = Qp(5, prec = 200)69sage: R.<x> = LaurentSeriesRing(K)70sage: S.<y> = LaurentSeriesRing(L)71sage: R is S72False73sage: T.<y> = LaurentSeriesRing(Qp(5,prec=200))74sage: S is T75True76sage: W.<y> = LaurentSeriesRing(Qp(5,prec=199))77sage: W is T78False79"""80if not names is None: name = names81if name is None:82raise TypeError, "You must specify the name of the indeterminate of the Laurent series ring."8384global laurent_series85key = (base_ring, name, default_prec, sparse)86if laurent_series.has_key(key):87x = laurent_series[key]()88if x != None: return x8990if isinstance(base_ring, field.Field):91R = LaurentSeriesRing_field(base_ring, name, default_prec, sparse)92elif isinstance(base_ring, integral_domain.IntegralDomain):93R = LaurentSeriesRing_domain(base_ring, name, default_prec, sparse)94elif isinstance(base_ring, commutative_ring.CommutativeRing):95R = LaurentSeriesRing_generic(base_ring, name, default_prec, sparse)96else:97raise TypeError, "base_ring must be a commutative ring"98laurent_series[key] = weakref.ref(R)99return R100101def is_LaurentSeriesRing(x):102"""103TESTS::104105sage: from sage.rings.laurent_series_ring import is_LaurentSeriesRing106sage: K.<q> = LaurentSeriesRing(QQ)107sage: is_LaurentSeriesRing(K)108True109"""110return isinstance(x, LaurentSeriesRing_generic)111112class LaurentSeriesRing_generic(commutative_ring.CommutativeRing):113"""114Univariate Laurent Series Ring115116EXAMPLES::117118sage: K, q = LaurentSeriesRing(CC, 'q').objgen(); K119Laurent Series Ring in q over Complex Field with 53 bits of precision120sage: loads(K.dumps()) == K121True122sage: P = QQ[['x']]123sage: F = Frac(P)124sage: TestSuite(F).run()125126When the base ring `k` is a field, the ring `k((x))` is a CDVF, that is127a field equipped with a discrete valuation for which it is complete.128The appropriate (sub)category is automatically set in this case::129130sage: k = GF(11)131sage: R.<x> = k[[]]132sage: F = Frac(R)133sage: F.category()134Category of complete discrete valuation fields135sage: TestSuite(F).run()136"""137138def __init__(self, base_ring, name=None, default_prec=20, sparse=False, category=None):139"""140Initialization141142EXAMPLES::143144sage: K.<q> = LaurentSeriesRing(QQ,default_prec=4); K145Laurent Series Ring in q over Rational Field146sage: 1 / (q-q^2)147q^-1 + 1 + q + q^2 + O(q^3)148"""149commutative_ring.CommutativeRing.__init__(self, base_ring, names=name,150category=getattr(self, '_default_category', Fields()))151self._polynomial_ring = polynomial.polynomial_ring_constructor.PolynomialRing(self.base_ring(),152self.variable_name(),153sparse=sparse)154self._power_series_ring = power_series_ring.PowerSeriesRing(self.base_ring(),155self.variable_name(),156default_prec=default_prec,157sparse=sparse)158159def base_extend(self, R):160"""161Returns the laurent series ring over R in the same variable as162self, assuming there is a canonical coerce map from the base ring163of self to R.164165EXAMPLES::166167sage: K.<x> = LaurentSeriesRing(QQ, default_prec=4)168sage: K.base_extend(QQ['t'])169Laurent Series Ring in x over Univariate Polynomial Ring in t over Rational Field170"""171if R.has_coerce_map_from(self.base_ring()):172return self.change_ring(R)173else:174raise TypeError, "no valid base extension defined"175176def change_ring(self, R):177"""178EXAMPLES::179180sage: K.<x> = LaurentSeriesRing(QQ, default_prec=4)181sage: R = K.change_ring(ZZ); R182Laurent Series Ring in x over Integer Ring183sage: R.default_prec()1844185"""186return LaurentSeriesRing(R, self.variable_name(), default_prec=self.default_prec(), sparse=self.is_sparse())187188def is_sparse(self):189"""190EXAMPLES::191192sage: K.<x> = LaurentSeriesRing(QQ, sparse=True)193sage: K.is_sparse()194True195"""196return self.power_series_ring().is_sparse()197198def is_field(self, proof = True):199"""200A Laurent series ring is a field if and only if the base ring is a field.201202TESTS::203204sage: LaurentSeriesRing(QQ,'t').is_field()205True206sage: LaurentSeriesRing(ZZ,'t').is_field()207False208"""209return self.base_ring().is_field()210211def is_dense(self):212"""213EXAMPLES::214215sage: K.<x> = LaurentSeriesRing(QQ, sparse=True)216sage: K.is_dense()217False218"""219return self.power_series_ring().is_dense()220221def __reduce__(self):222"""223TESTS::224225sage: K.<q> = LaurentSeriesRing(QQ,default_prec=4)226sage: L = loads(dumps(K))227sage: L.default_prec()2284229"""230return self.__class__, (self.base_ring(), self.variable_name(), self.default_prec(), self.is_sparse())231232def _repr_(self):233"""234EXAMPLES::235236sage: LaurentSeriesRing(QQ,'q') # indirect doctest237Laurent Series Ring in q over Rational Field238sage: LaurentSeriesRing(ZZ,'t',sparse=True)239Sparse Laurent Series Ring in t over Integer Ring240"""241s = "Laurent Series Ring in %s over %s"%(self.variable_name(), self.base_ring())242if self.is_sparse():243s = 'Sparse ' + s244return s245246def __call__(self, x, n=0):247r"""248Coerces the element x into this Laurent series ring.249250INPUT:251252253- ``x`` - the element to coerce254255- ``n`` - the result of the coercion will be256multiplied by `t^n` (default: 0)257258259EXAMPLES::260261sage: R.<u> = LaurentSeriesRing(Qp(5, 10))262sage: S.<t> = LaurentSeriesRing(RationalField())263sage: print R(t + t^2 + O(t^3))264(1 + O(5^10))*u + (1 + O(5^10))*u^2 + O(u^3)265266Note that coercing an element into its own parent just produces267that element again (since Laurent series are immutable)::268269sage: u is R(u)270True271272Rational functions are accepted::273274sage: I = sqrt(-1)275sage: K.<I> = QQ[I]276sage: P.<t> = PolynomialRing(K)277sage: L.<u> = LaurentSeriesRing(QQ[I])278sage: L((t*I)/(t^3+I*2*t))2791/2 + 1/4*I*u^2 - 1/8*u^4 - 1/16*I*u^6 + 1/32*u^8 +2801/64*I*u^10 - 1/128*u^12 - 1/256*I*u^14 + 1/512*u^16 +2811/1024*I*u^18 + O(u^20)282283::284285sage: L(t*I) / L(t^3+I*2*t)2861/2 + 1/4*I*u^2 - 1/8*u^4 - 1/16*I*u^6 + 1/32*u^8 +2871/64*I*u^10 - 1/128*u^12 - 1/256*I*u^14 + 1/512*u^16 +2881/1024*I*u^18 + O(u^20)289290Various conversions from PARI (see also #2508)::291292sage: L.<q> = LaurentSeriesRing(QQ)293sage: L.set_default_prec(10)294sage: L(pari('1/x'))295q^-1296sage: L(pari('poltchebi(5)'))2975*q - 20*q^3 + 16*q^5298sage: L(pari('poltchebi(5) - 1/x^4'))299-q^-4 + 5*q - 20*q^3 + 16*q^5300sage: L(pari('1/poltchebi(5)'))3011/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + O(q^9)302sage: L(pari('poltchebi(5) + O(x^40)'))3035*q - 20*q^3 + 16*q^5 + O(q^40)304sage: L(pari('poltchebi(5) - 1/x^4 + O(x^40)'))305-q^-4 + 5*q - 20*q^3 + 16*q^5 + O(q^40)306sage: L(pari('1/poltchebi(5) + O(x^10)'))3071/5*q^-1 + 4/5*q + 64/25*q^3 + 192/25*q^5 + 2816/125*q^7 + 8192/125*q^9 + O(q^10)308sage: L(pari('1/poltchebi(5) + O(x^10)'), -10) # Multiply by q^-103091/5*q^-11 + 4/5*q^-9 + 64/25*q^-7 + 192/25*q^-5 + 2816/125*q^-3 + 8192/125*q^-1 + O(1)310sage: L(pari('O(x^-10)'))311O(q^-10)312"""313from sage.rings.fraction_field_element import is_FractionFieldElement314from sage.rings.polynomial.polynomial_element import is_Polynomial315from sage.rings.polynomial.multi_polynomial_element import is_MPolynomial316317if isinstance(x, laurent_series_ring_element.LaurentSeries) and n==0 and self is x.parent():318return x # ok, since Laurent series are immutable (no need to make a copy)319elif isinstance(x, pari_gen):320t = x.type()321if t == "t_RFRAC": # Rational function322x = self(self.polynomial_ring()(x.numerator())) / \323self(self.polynomial_ring()(x.denominator()))324return (x << n)325elif t == "t_SER": # Laurent series326n += x._valp()327bigoh = n + x.length()328x = self(self.polynomial_ring()(x.Vec()))329return (x << n).add_bigoh(bigoh)330else: # General case, pretend to be a polynomial331return self(self.polynomial_ring()(x)) << n332elif is_FractionFieldElement(x) and \333(x.base_ring() is self.base_ring() or x.base_ring() == self.base_ring()) and \334(is_Polynomial(x.numerator()) or is_MPolynomial(x.numerator())):335x = self(x.numerator())/self(x.denominator())336return (x << n)337else:338return laurent_series_ring_element.LaurentSeries(self, x, n)339340def _coerce_impl(self, x):341"""342Return canonical coercion of x into self.343344Rings that canonically coerce to this power series ring R:345346- R itself347348- Any laurent series ring in the same variable whose base ring349canonically coerces to the base ring of R.350351- Any ring that canonically coerces to the power series ring352over the base ring of R.353354- Any ring that canonically coerces to the base ring of R355356EXAMPLES::357358sage: R.<t> = LaurentSeriesRing(ZZ)359sage: S.<t> = PowerSeriesRing(QQ)360sage: R.has_coerce_map_from(S) # indirect doctest361False362sage: R.has_coerce_map_from(R)363True364sage: R.<t> = LaurentSeriesRing(QQ['x'])365sage: R.has_coerce_map_from(S)366True367sage: R.has_coerce_map_from(QQ['t'])368True369sage: R.has_coerce_map_from(ZZ['x']['t'])370True371sage: R.has_coerce_map_from(ZZ['t']['x'])372False373sage: R.has_coerce_map_from(ZZ['x'])374True375"""376try:377P = x.parent()378if is_LaurentSeriesRing(P):379if P.variable_name() == self.variable_name():380if self.has_coerce_map_from(P.base_ring()):381return self(x)382else:383raise TypeError, "no natural map between bases of power series rings"384except AttributeError:385pass386387return self._coerce_try(x, [self.power_series_ring(), self.base_ring()])388389def __cmp__(self, other):390"""391Compare this Laurent series ring to something else.392393Laurent series rings are considered equal if the base ring, variable394names, and default truncation precision are the same.395396First the base rings are compared, then the variable names, then397the default precision.398399EXAMPLES::400401sage: R.<t> = LaurentSeriesRing(ZZ)402sage: S.<t> = LaurentSeriesRing(ZZ)403sage: R is S404True405sage: R == S406True407sage: S.<t> = LaurentSeriesRing(ZZ, default_prec=10)408sage: R == S409False410sage: LaurentSeriesRing(ZZ,'t') == LaurentSeriesRing(QQ,'t')411False412sage: LaurentSeriesRing(QQ,'t') == 5413False414"""415if not isinstance(other, LaurentSeriesRing_generic):416return cmp(type(self),type(other))417c = cmp(self.base_ring(), other.base_ring())418if c: return c419c = cmp(self.variable_name(), other.variable_name())420if c: return c421c = cmp(self.default_prec(), other.default_prec())422if c: return c423return 0424425426def _is_valid_homomorphism_(self, codomain, im_gens):427"""428EXAMPLES::429430sage: R.<x> = LaurentSeriesRing(GF(17))431sage: S.<y> = LaurentSeriesRing(GF(19))432sage: R.hom([y], S) # indirect doctest433Traceback (most recent call last):434...435TypeError: images do not define a valid homomorphism436sage: f = R.hom(x+x^3,R)437sage: f(x^2)438x^2 + 2*x^4 + x^6439"""440## NOTE: There are no ring homomorphisms from the ring of441## all formal power series to most rings, e.g, the p-adic442## field, since you can always (mathematically!) construct443## some power series that doesn't converge.444## Note that 0 is not a *ring* homomorphism.445from power_series_ring import is_PowerSeriesRing446if is_PowerSeriesRing(codomain) or is_LaurentSeriesRing(codomain):447return im_gens[0].valuation() > 0 and codomain.has_coerce_map_from(self.base_ring())448return False449450def characteristic(self):451"""452EXAMPLES::453454sage: R.<x> = LaurentSeriesRing(GF(17))455sage: R.characteristic()45617457"""458return self.base_ring().characteristic()459460def residue_field(self):461"""462Return the residue field of this Laurent series field463if it is a complete discrete valuation field (i.e. if464the base ring is a field, in which base it is also the465residue field).466467EXAMPLES::468469sage: R.<x> = LaurentSeriesRing(GF(17))470sage: R.residue_field()471Finite Field of size 17472473sage: R.<x> = LaurentSeriesRing(ZZ)474sage: R.residue_field()475Traceback (most recent call last):476...477TypeError: The base ring is not a field478"""479if self.base_ring().is_field():480return self.base_ring()481else:482raise TypeError("The base ring is not a field")483484def set_default_prec(self, n):485"""486Sets the default precision.487488This operation should be discouraged: parents should be489immutable and this function may be deprecated in the future.490491TESTS::492493sage: R.<x> = LaurentSeriesRing(QQ)494sage: R.set_default_prec(3)495sage: 1/(x^5-x^7)496x^-5 + x^-3 + O(x^-2)497"""498self.power_series_ring().set_default_prec(n)499500def default_prec(self):501"""502Sets the precision to which exact elements are truncated when503necessary (most frequently when inverting)504505EXAMPLES::506507sage: R.<x> = LaurentSeriesRing(QQ, default_prec=5)508sage: R.default_prec()5095510"""511return self.power_series_ring().default_prec()512513def is_exact(self):514"""515Laurent series rings are inexact.516517EXAMPLES::518519sage: R = LaurentSeriesRing(QQ, "x")520sage: R.is_exact()521False522"""523return False524525def gen(self, n=0):526"""527EXAMPLES::528529sage: R = LaurentSeriesRing(QQ, "x")530sage: R.gen()531x532"""533if n != 0:534raise IndexError, "Generator n not defined."535try:536return self.__generator537except AttributeError:538self.__generator = laurent_series_ring_element.LaurentSeries(self, [0,1])539return self.__generator540541def uniformizer(self):542"""543Return a uniformizer of this Laurent series field if it is544a discrete valuation field (i.e. if the base ring is actually545a field). Otherwise, an error is raised.546547EXAMPLES::548549sage: R.<t> = LaurentSeriesRing(QQ)550sage: R.uniformizer()551t552553sage: R.<t> = LaurentSeriesRing(ZZ)554sage: R.uniformizer()555Traceback (most recent call last):556...557TypeError: The base ring is not a field558"""559if self.base_ring().is_field():560return self.gen()561else:562raise TypeError("The base ring is not a field")563564def ngens(self):565"""566Laurent series rings are univariate.567568EXAMPLES::569570sage: R = LaurentSeriesRing(QQ, "x")571sage: R.ngens()5721573"""574return 1575576def polynomial_ring(self):577r"""578If this is the Laurent series ring `R((t))`, return the579polynomial ring `R[t]`.580581EXAMPLES::582583sage: R = LaurentSeriesRing(QQ, "x")584sage: R.polynomial_ring()585Univariate Polynomial Ring in x over Rational Field586"""587return self._polynomial_ring588589def laurent_polynomial_ring(self):590r"""591If this is the Laurent series ring `R((t))`, return the Laurent592polynomial ring `R[t,1/t]`.593594EXAMPLES::595596sage: R = LaurentSeriesRing(QQ, "x")597sage: R.laurent_polynomial_ring()598Univariate Laurent Polynomial Ring in x over Rational Field599"""600try:601return self.__laurent_polynomial_ring602except AttributeError:603self.__laurent_polynomial_ring = polynomial.laurent_polynomial_ring.LaurentPolynomialRing( \604self.base_ring(), self.variable_name(), sparse=self.is_sparse())605return self.__laurent_polynomial_ring606607def power_series_ring(self):608r"""609If this is the Laurent series ring `R((t))`, return the610power series ring `R[[t]]`.611612EXAMPLES::613614sage: R = LaurentSeriesRing(QQ, "x")615sage: R.power_series_ring()616Power Series Ring in x over Rational Field617"""618return self._power_series_ring619620class LaurentSeriesRing_domain(LaurentSeriesRing_generic, integral_domain.IntegralDomain):621def __init__(self, base_ring, name=None, default_prec=20, sparse=False):622"""623Initialization624625TESTS::626627sage: TestSuite(LaurentSeriesRing(ZZ,'t')).run()628"""629LaurentSeriesRing_generic.__init__(self, base_ring, name, default_prec, sparse)630631class LaurentSeriesRing_field(LaurentSeriesRing_generic, field.Field):632_default_category = CompleteDiscreteValuationFields()633634def __init__(self, base_ring, name=None, default_prec=20, sparse=False):635"""636Initialization637638TESTS::639640sage: TestSuite(LaurentSeriesRing(QQ,'t')).run()641"""642LaurentSeriesRing_generic.__init__(self, base_ring, name, default_prec, sparse)643644645646