Skip to content

Commit cfc9e9d

Browse files
author
Release Manager
committedOct 11, 2024
gh-38741: move power series to Parent make the power series rings inherit from Parent instead of the auld `Ring` class ### 📝 Checklist - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation and checked the documentation preview. URL: #38741 Reported by: Frédéric Chapoton Reviewer(s): Frédéric Chapoton, Martin Rubey
2 parents cd4e53e + 576784f commit cfc9e9d

File tree

2 files changed

+51
-22
lines changed

2 files changed

+51
-22
lines changed
 

‎src/sage/rings/multi_power_series_ring.py

+17-4
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,8 @@
213213
from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
214214
from sage.rings.polynomial.term_order import TermOrder
215215
from sage.rings.power_series_ring import PowerSeriesRing, PowerSeriesRing_generic
216-
from sage.rings.ring import CommutativeRing
217216
from sage.structure.nonexact import Nonexact
217+
from sage.structure.parent import Parent
218218

219219
from sage.categories.commutative_rings import CommutativeRings
220220
_CommutativeRings = CommutativeRings()
@@ -389,8 +389,9 @@ def __init__(self, base_ring, num_gens, name_list,
389389
# Multivariate power series rings inherit from power series rings. But
390390
# apparently we can not call their initialisation. Instead, initialise
391391
# CommutativeRing and Nonexact:
392-
CommutativeRing.__init__(self, base_ring, name_list, category=_IntegralDomains if base_ring in
393-
_IntegralDomains else _CommutativeRings)
392+
Parent.__init__(self, base=base_ring, names=name_list,
393+
category=_IntegralDomains if base_ring in
394+
_IntegralDomains else _CommutativeRings)
394395
Nonexact.__init__(self, default_prec)
395396

396397
# underlying polynomial ring in which to represent elements
@@ -1005,7 +1006,7 @@ def gen(self, n=0):
10051006
if n < 0 or n >= self._ngens:
10061007
raise ValueError("Generator not defined.")
10071008
#return self(self._poly_ring().gens()[int(n)])
1008-
return self.element_class(parent=self,x=self._poly_ring().gens()[int(n)], is_gen=True)
1009+
return self.element_class(parent=self, x=self._poly_ring().gens()[int(n)], is_gen=True)
10091010

10101011
def ngens(self):
10111012
"""
@@ -1019,6 +1020,18 @@ def ngens(self):
10191020
"""
10201021
return self._ngens
10211022

1023+
def gens(self) -> tuple:
1024+
"""
1025+
Return the generators of this ring.
1026+
1027+
EXAMPLES::
1028+
1029+
sage: M = PowerSeriesRing(ZZ, 3, 'v')
1030+
sage: M.gens()
1031+
(v0, v1, v2)
1032+
"""
1033+
return tuple(self.gen(i) for i in range(self._ngens))
1034+
10221035
def prec_ideal(self):
10231036
"""
10241037
Return the ideal which determines precision; this is the ideal

‎src/sage/rings/power_series_ring.py

+34-18
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 + O(x^10)
4545
sage: R.<x> = PowerSeriesRing(QQ, default_prec=15)
4646
sage: sin(x)
47-
x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 - 1/39916800*x^11 + 1/6227020800*x^13 + O(x^15)
47+
x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 - 1/39916800*x^11
48+
+ 1/6227020800*x^13 + O(x^15)
4849
4950
An iterated example::
5051
@@ -139,8 +140,6 @@
139140
from sage.misc.lazy_import import lazy_import
140141
from sage.rings import (
141142
integer,
142-
laurent_series_ring,
143-
laurent_series_ring_element,
144143
power_series_mpoly,
145144
power_series_poly,
146145
power_series_ring_element,
@@ -153,6 +152,7 @@
153152
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
154153
from sage.structure.category_object import normalize_names
155154
from sage.structure.element import Expression, parent
155+
from sage.structure.parent import Parent
156156
from sage.structure.nonexact import Nonexact
157157
from sage.structure.unique_representation import UniqueRepresentation
158158

@@ -355,7 +355,7 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None,
355355
356356
* :func:`sage.misc.defaults.set_series_precision`
357357
"""
358-
#multivariate case:
358+
# multivariate case:
359359
# examples for first case:
360360
# PowerSeriesRing(QQ,'x,y,z')
361361
# PowerSeriesRing(QQ,['x','y','z'])
@@ -364,7 +364,7 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None,
364364
names = name
365365
if isinstance(names, (tuple, list)) and len(names) > 1 or (isinstance(names, str) and ',' in names):
366366
return _multi_variate(base_ring, num_gens=arg2, names=names,
367-
order=order, default_prec=default_prec, sparse=sparse)
367+
order=order, default_prec=default_prec, sparse=sparse)
368368
# examples for second case:
369369
# PowerSeriesRing(QQ,3,'t')
370370
if arg2 is None and num_gens is not None:
@@ -373,7 +373,7 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None,
373373
if (isinstance(arg2, str) and
374374
isinstance(names, (int, integer.Integer))):
375375
return _multi_variate(base_ring, num_gens=names, names=arg2,
376-
order=order, default_prec=default_prec, sparse=sparse)
376+
order=order, default_prec=default_prec, sparse=sparse)
377377

378378
# univariate case: the arguments to PowerSeriesRing used to be
379379
# (base_ring, name=None, default_prec=20, names=None, sparse=False),
@@ -385,11 +385,10 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None,
385385
elif arg2 is not None:
386386
default_prec = arg2
387387

388-
## too many things (padics, elliptic curves) depend on this behavior,
389-
## so no warning for now.
390-
##
388+
# ## too many things (padics, elliptic curves) depend on this behavior,
389+
# ## so no warning for now.
391390

392-
# if isinstance(name, (int,integer.Integer)) or isinstance(arg2,(int,integer.Integer)):
391+
# if isinstance(name, (int, integer.Integer)) or isinstance(arg2, (int, integer.Integer)):
393392
# deprecation(issue_number, "This behavior of PowerSeriesRing is being deprecated in favor of constructing multivariate power series rings. (See Github issue #1956.)")
394393

395394
# the following is the original, univariate-only code
@@ -427,16 +426,17 @@ def PowerSeriesRing(base_ring, name=None, arg2=None, names=None,
427426
raise TypeError("base_ring must be a commutative ring")
428427
return R
429428

429+
430430
def _multi_variate(base_ring, num_gens=None, names=None,
431-
order='negdeglex', default_prec=None, sparse=False):
431+
order='negdeglex', default_prec=None, sparse=False):
432432
"""
433433
Construct multivariate power series ring.
434434
"""
435435
if names is None:
436436
raise TypeError("you must specify a variable name or names")
437437

438438
if num_gens is None:
439-
if isinstance(names,str):
439+
if isinstance(names, str):
440440
num_gens = len(names.split(','))
441441
elif isinstance(names, (list, tuple)):
442442
num_gens = len(names)
@@ -458,6 +458,7 @@ def _multi_variate(base_ring, num_gens=None, names=None,
458458
def _single_variate():
459459
pass
460460

461+
461462
def is_PowerSeriesRing(R):
462463
"""
463464
Return ``True`` if this is a *univariate* power series ring. This is in
@@ -489,7 +490,8 @@ def is_PowerSeriesRing(R):
489490
else:
490491
return False
491492

492-
class PowerSeriesRing_generic(UniqueRepresentation, ring.CommutativeRing, Nonexact):
493+
494+
class PowerSeriesRing_generic(UniqueRepresentation, Parent, Nonexact):
493495
"""
494496
A power series ring.
495497
"""
@@ -592,9 +594,9 @@ def __init__(self, base_ring, name=None, default_prec=None, sparse=False,
592594
else:
593595
raise ValueError('unknown power series implementation: %r' % implementation)
594596

595-
ring.CommutativeRing.__init__(self, base_ring, names=name,
596-
category=getattr(self, '_default_category',
597-
_CommutativeRings))
597+
Parent.__init__(self, base=base_ring, names=name,
598+
category=getattr(self, '_default_category',
599+
_CommutativeRings))
598600
Nonexact.__init__(self, default_prec)
599601
if implementation == 'pari':
600602
self.__generator = self.element_class(self, R.gen().__pari__())
@@ -832,7 +834,7 @@ def _element_constructor_(self, f, prec=infinity, check=True):
832834
elif isinstance(f, LaurentSeries) and f.parent().power_series_ring() is self:
833835
return self(f.power_series(), prec, check=check)
834836
elif isinstance(f, MagmaElement) and str(f.Type()) == 'RngSerPowElt':
835-
v = sage_eval(f.Eltseq())
837+
v = sage_eval(f.Eltseq()) # could use .sage() ?
836838
return self(v) * (self.gen(0)**f.Valuation())
837839
elif isinstance(f, FractionFieldElement):
838840
if self.base_ring().has_coerce_map_from(f.parent()):
@@ -846,7 +848,8 @@ def _element_constructor_(self, f, prec=infinity, check=True):
846848
if isinstance(f, SymbolicSeries):
847849
if str(f.default_variable()) == self.variable_name():
848850
return self.element_class(self, f.list(),
849-
f.degree(f.default_variable()), check=check)
851+
f.degree(f.default_variable()),
852+
check=check)
850853
else:
851854
raise TypeError("Can only convert series into ring with same variable name.")
852855
else:
@@ -1097,6 +1100,18 @@ def gen(self, n=0):
10971100
raise IndexError("generator n>0 not defined")
10981101
return self.__generator
10991102

1103+
def gens(self) -> tuple:
1104+
"""
1105+
Return the generators of this ring.
1106+
1107+
EXAMPLES::
1108+
1109+
sage: R.<t> = PowerSeriesRing(ZZ)
1110+
sage: R.gens()
1111+
(t,)
1112+
"""
1113+
return (self.__generator,)
1114+
11001115
def uniformizer(self):
11011116
"""
11021117
Return a uniformizer of this power series ring if it is
@@ -1357,6 +1372,7 @@ def _get_action_(self, other, op, self_is_left):
13571372
return BaseRingFloorDivAction(other, self, is_left=False)
13581373
return super()._get_action_(other, op, self_is_left)
13591374

1375+
13601376
class PowerSeriesRing_over_field(PowerSeriesRing_domain):
13611377
_default_category = CompleteDiscreteValuationRings()
13621378

0 commit comments

Comments
 (0)
Please sign in to comment.