19
19
"""
20
20
from __future__ import print_function , absolute_import
21
21
22
- from .laurent_series_ring_element import LaurentSeries
22
+ from sage .categories .rings import Rings
23
+ from sage .categories .integral_domains import IntegralDomains
24
+ from sage .categories .fields import Fields
25
+ from sage .categories .complete_discrete_valuation import CompleteDiscreteValuationFields
23
26
27
+ from .laurent_series_ring_element import LaurentSeries
24
28
from . import polynomial
25
- from . import ring
29
+ from .ring import CommutativeRing
26
30
27
- from sage .libs .pari .all import pari_gen
28
- from sage .categories .fields import Fields
29
- from sage .categories .complete_discrete_valuation import CompleteDiscreteValuationFields
30
31
from sage .structure .unique_representation import UniqueRepresentation
31
32
from sage .misc .cachefunc import cached_method
32
33
33
- def LaurentSeriesRing ( base_ring , name = None , names = None , default_prec = None , sparse = False ):
34
+ def is_LaurentSeriesRing ( x ):
34
35
"""
36
+ Return ``True`` if this is a *univariate* Laurent series ring.
37
+
38
+ This is in keeping with the behavior of ``is_PolynomialRing``
39
+ versus ``is_MPolynomialRing``.
40
+
41
+ TESTS::
42
+
43
+ sage: from sage.rings.laurent_series_ring import is_LaurentSeriesRing
44
+ sage: K.<q> = LaurentSeriesRing(QQ)
45
+ sage: is_LaurentSeriesRing(K)
46
+ True
47
+ """
48
+ return isinstance (x , LaurentSeriesRing )
49
+
50
+ class LaurentSeriesRing (UniqueRepresentation , CommutativeRing ):
51
+ r"""
52
+ Univariate Laurent Series Ring.
53
+
35
54
EXAMPLES::
36
55
37
56
sage: R = LaurentSeriesRing(QQ, 'x'); R
@@ -73,6 +92,26 @@ def LaurentSeriesRing(base_ring, name=None, names=None, default_prec=None, spars
73
92
sage: W is T
74
93
False
75
94
95
+ sage: K = LaurentSeriesRing(CC, 'q')
96
+ sage: K
97
+ Laurent Series Ring in q over Complex Field with 53 bits of precision
98
+ sage: loads(K.dumps()) == K
99
+ True
100
+ sage: P = QQ[['x']]
101
+ sage: F = Frac(P)
102
+ sage: TestSuite(F).run()
103
+
104
+ When the base ring `k` is a field, the ring `k((x))` is a CDVF, that is
105
+ a field equipped with a discrete valuation for which it is complete.
106
+ The appropriate (sub)category is automatically set in this case::
107
+
108
+ sage: k = GF(11)
109
+ sage: R.<x> = k[[]]
110
+ sage: F = Frac(R)
111
+ sage: F.category()
112
+ Category of infinite complete discrete valuation fields
113
+ sage: TestSuite(F).run()
114
+
76
115
TESTS:
77
116
78
117
Check if changing global series precision does it right (and
@@ -87,85 +126,94 @@ def LaurentSeriesRing(base_ring, name=None, names=None, default_prec=None, spars
87
126
sage: 1/(1 - 2*x)
88
127
1 + 2*x + 4*x^2 + 8*x^3 + 16*x^4 + O(x^5)
89
128
sage: set_series_precision(20)
90
- """
91
- if not names is None :
92
- name = names
93
- if name is None :
94
- raise TypeError ("you must specify the name of the indeterminate of the Laurent series ring" )
95
-
96
- if default_prec is None :
97
- from sage .misc .defaults import series_precision
98
- default_prec = series_precision ()
99
-
100
- if isinstance (base_ring , ring .Field ):
101
- return LaurentSeriesRing_field (base_ring , name , default_prec , sparse )
102
- elif isinstance (base_ring , ring .IntegralDomain ):
103
- return LaurentSeriesRing_domain (base_ring , name , default_prec , sparse )
104
- elif isinstance (base_ring , ring .CommutativeRing ):
105
- return LaurentSeriesRing_generic (base_ring , name , default_prec , sparse )
106
- else :
107
- raise TypeError ("base_ring must be a commutative ring" )
108
129
109
- def is_LaurentSeriesRing (x ):
110
- """
111
- Return ``True`` if this is a *univariate* Laurent series ring.
112
-
113
- This is in keeping with the behavior of ``is_PolynomialRing``
114
- versus ``is_MPolynomialRing``.
115
-
116
- TESTS::
130
+ Check categories (:trac:`24420`)::
117
131
118
- sage: from sage.rings.laurent_series_ring import is_LaurentSeriesRing
119
- sage: K.<q> = LaurentSeriesRing(QQ)
120
- sage: is_LaurentSeriesRing(K)
121
- True
132
+ sage: LaurentSeriesRing(ZZ, 'x').category()
133
+ Category of infinite integral domains
134
+ sage: LaurentSeriesRing(QQ, 'x').category()
135
+ Category of infinite complete discrete valuation fields
136
+ sage: LaurentSeriesRing(Zmod(4), 'x').category()
137
+ Category of infinite commutative rings
122
138
"""
123
- return isinstance ( x , LaurentSeriesRing_generic )
139
+ Element = LaurentSeries
124
140
125
- class LaurentSeriesRing_generic (UniqueRepresentation , ring .CommutativeRing ):
126
- r"""
127
- Univariate Laurent Series Ring.
141
+ @staticmethod
142
+ def __classcall__ (cls , * args , ** kwds ):
143
+ r"""
144
+ TESTS::
128
145
129
- EXAMPLES::
146
+ sage: L = LaurentSeriesRing(QQ, 'q')
147
+ sage: L is LaurentSeriesRing(QQ, name='q')
148
+ True
149
+ sage: loads(dumps(L)) is L
150
+ True
151
+ """
152
+ from .power_series_ring import PowerSeriesRing , is_PowerSeriesRing
130
153
131
- sage: K = LaurentSeriesRing(CC, 'q')
132
- sage: K
133
- Laurent Series Ring in q over Complex Field with 53 bits of precision
134
- sage: loads(K.dumps()) == K
135
- True
136
- sage: P = QQ[['x']]
137
- sage: F = Frac(P)
138
- sage: TestSuite(F).run()
154
+ if not kwds and len (args ) == 1 and is_PowerSeriesRing (args [0 ]):
155
+ power_series = args [0 ]
156
+ else :
157
+ power_series = PowerSeriesRing (* args , ** kwds )
139
158
140
- When the base ring `k` is a field, the ring `k((x))` is a CDVF, that is
141
- a field equipped with a discrete valuation for which it is complete.
142
- The appropriate (sub)category is automatically set in this case::
159
+ return UniqueRepresentation .__classcall__ (cls , power_series )
143
160
144
- sage: k = GF(11)
145
- sage: R.<x> = k[[]]
146
- sage: F = Frac(R)
147
- sage: F.category()
148
- Category of complete discrete valuation fields
149
- sage: TestSuite(F).run()
150
- """
151
- def __init__ (self , base_ring , name = None , default_prec = None , sparse = False , category = None ):
161
+ def __init__ (self , power_series ):
152
162
"""
153
163
Initialization
154
164
155
165
EXAMPLES::
156
166
157
- sage: K.<q> = LaurentSeriesRing(QQ,default_prec=4); K
167
+ sage: K.<q> = LaurentSeriesRing(QQ, default_prec=4); K
158
168
Laurent Series Ring in q over Rational Field
159
169
sage: 1 / (q-q^2)
160
170
q^-1 + 1 + q + q^2 + O(q^3)
161
- """
162
- from .power_series_ring import PowerSeriesRing
163
- ring .CommutativeRing .__init__ (self , base_ring , names = name ,
164
- category = getattr (self , '_default_category' , Fields ()))
165
- self ._power_series_ring = PowerSeriesRing (self .base_ring (),
166
- self .variable_name (),
167
- default_prec = default_prec ,
168
- sparse = sparse )
171
+
172
+ sage: RZZ = LaurentSeriesRing(ZZ, 't')
173
+ sage: RZZ.category()
174
+ Category of infinite integral domains
175
+ sage: TestSuite(RZZ).run()
176
+
177
+ sage: R1 = LaurentSeriesRing(Zmod(1), 't')
178
+ sage: R1.category()
179
+ Category of finite commutative rings
180
+ sage: TestSuite(R1).run()
181
+
182
+ sage: R2 = LaurentSeriesRing(Zmod(2), 't')
183
+ sage: R2.category()
184
+ Category of infinite complete discrete valuation fields
185
+ sage: TestSuite(R2).run()
186
+
187
+ sage: R4 = LaurentSeriesRing(Zmod(4), 't')
188
+ sage: R4.category()
189
+ Category of infinite commutative rings
190
+ sage: TestSuite(R4).run()
191
+
192
+ sage: RQQ = LaurentSeriesRing(QQ, 't')
193
+ sage: RQQ.category()
194
+ Category of infinite complete discrete valuation fields
195
+ sage: TestSuite(RQQ).run()
196
+ """
197
+ base_ring = power_series .base_ring ()
198
+ if base_ring in Fields ():
199
+ category = CompleteDiscreteValuationFields ()
200
+ elif base_ring in IntegralDomains ():
201
+ category = IntegralDomains ()
202
+ elif base_ring in Rings ().Commutative ():
203
+ category = Rings ().Commutative ()
204
+ else :
205
+ raise ValueError ('unrecognized base ring' )
206
+
207
+ if base_ring .is_zero ():
208
+ category = category .Finite ()
209
+ else :
210
+ category = category .Infinite ()
211
+
212
+ CommutativeRing .__init__ (self , base_ring ,
213
+ names = power_series .variable_names (),
214
+ category = category )
215
+
216
+ self ._power_series_ring = power_series
169
217
170
218
def base_extend (self , R ):
171
219
"""
@@ -184,6 +232,38 @@ def base_extend(self, R):
184
232
else :
185
233
raise TypeError ("no valid base extension defined" )
186
234
235
+ def fraction_field (self ):
236
+ r"""
237
+ Return the fraction field of this ring of Laurent series.
238
+
239
+ If the base ring is a field, then Laurent series are already a field.
240
+ If the base ring is a domain, then the Laurent series over its fraction
241
+ field is returned. Otherwise, raise a ``ValueError``.
242
+
243
+ EXAMPLES::
244
+
245
+ sage: R = LaurentSeriesRing(ZZ, 't', 30).fraction_field()
246
+ sage: R
247
+ Laurent Series Ring in t over Rational Field
248
+ sage: R.default_prec()
249
+ 30
250
+
251
+ sage: LaurentSeriesRing(Zmod(4), 't').fraction_field()
252
+ Traceback (most recent call last):
253
+ ...
254
+ ValueError: must be an integral domain
255
+ """
256
+ from sage .categories .integral_domains import IntegralDomains
257
+ from sage .categories .fields import Fields
258
+ if self in Fields ():
259
+ return self
260
+ elif self in IntegralDomains ():
261
+ return LaurentSeriesRing (self .base_ring ().fraction_field (),
262
+ self .variable_names (),
263
+ self .default_prec ())
264
+ else :
265
+ raise ValueError ('must be an integral domain' )
266
+
187
267
def change_ring (self , R ):
188
268
"""
189
269
EXAMPLES::
@@ -194,7 +274,7 @@ def change_ring(self, R):
194
274
sage: R.default_prec()
195
275
4
196
276
"""
197
- return LaurentSeriesRing (R , self .variable_name (),
277
+ return LaurentSeriesRing (R , self .variable_names (),
198
278
default_prec = self .default_prec (),
199
279
sparse = self .is_sparse ())
200
280
@@ -248,8 +328,6 @@ def _repr_(self):
248
328
s = 'Sparse ' + s
249
329
return s
250
330
251
- Element = LaurentSeries
252
-
253
331
def _element_constructor_ (self , x , n = 0 ):
254
332
r"""
255
333
Construct a Laurent series from `x`.
@@ -332,6 +410,7 @@ def _element_constructor_(self, x, n=0):
332
410
from sage .rings .polynomial .polynomial_element import is_Polynomial
333
411
from sage .rings .polynomial .multi_polynomial_element import is_MPolynomial
334
412
from sage .structure .element import parent
413
+ from sage .libs .pari .all import pari_gen
335
414
336
415
P = parent (x )
337
416
if isinstance (x , self .element_class ) and n == 0 and P is self :
@@ -606,22 +685,3 @@ def power_series_ring(self):
606
685
"""
607
686
return self ._power_series_ring
608
687
609
- class LaurentSeriesRing_domain (LaurentSeriesRing_generic , ring .IntegralDomain ):
610
- """
611
- Laurent series ring over a domain.
612
-
613
- TESTS::
614
-
615
- sage: TestSuite(LaurentSeriesRing(ZZ,'t')).run()
616
- """
617
-
618
- class LaurentSeriesRing_field (LaurentSeriesRing_generic , ring .Field ):
619
- """
620
- Laurent series ring over a field.
621
-
622
- TESTS::
623
-
624
- sage: TestSuite(LaurentSeriesRing(QQ,'t')).run()
625
- """
626
- _default_category = CompleteDiscreteValuationFields ()
627
-
0 commit comments