Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move power series to Parent #38741

Merged
merged 3 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions src/sage/rings/multi_power_series_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@
from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_base
from sage.rings.polynomial.term_order import TermOrder
from sage.rings.power_series_ring import PowerSeriesRing, PowerSeriesRing_generic
from sage.rings.ring import CommutativeRing
from sage.structure.nonexact import Nonexact
from sage.structure.parent import Parent

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

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

def ngens(self):
"""
Expand All @@ -1019,6 +1020,18 @@ def ngens(self):
"""
return self._ngens

def gens(self) -> tuple:
"""
Return the generators of this ring.

EXAMPLES::

sage: M = PowerSeriesRing(ZZ, 3, 'v')
sage: M.gens()
(v0, v1, v2)
"""
return tuple(self.gen(i) for i in range(self._ngens))

def prec_ideal(self):
"""
Return the ideal which determines precision; this is the ideal
Expand Down
52 changes: 34 additions & 18 deletions src/sage/rings/power_series_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 + O(x^10)
sage: R.<x> = PowerSeriesRing(QQ, default_prec=15)
sage: sin(x)
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)
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)

An iterated example::

Expand Down Expand Up @@ -139,8 +140,6 @@
from sage.misc.lazy_import import lazy_import
from sage.rings import (
integer,
laurent_series_ring,
laurent_series_ring_element,
power_series_mpoly,
power_series_poly,
power_series_ring_element,
Expand All @@ -153,6 +152,7 @@
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
from sage.structure.category_object import normalize_names
from sage.structure.element import Expression, parent
from sage.structure.parent import Parent
from sage.structure.nonexact import Nonexact
from sage.structure.unique_representation import UniqueRepresentation

Expand Down Expand Up @@ -355,7 +355,7 @@

* :func:`sage.misc.defaults.set_series_precision`
"""
#multivariate case:
# multivariate case:
# examples for first case:
# PowerSeriesRing(QQ,'x,y,z')
# PowerSeriesRing(QQ,['x','y','z'])
Expand All @@ -364,7 +364,7 @@
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)
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:
Expand All @@ -373,7 +373,7 @@
if (isinstance(arg2, str) and
isinstance(names, (int, integer.Integer))):
return _multi_variate(base_ring, num_gens=names, names=arg2,
order=order, default_prec=default_prec, sparse=sparse)
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),
Expand All @@ -385,11 +385,10 @@
elif arg2 is not None:
default_prec = arg2

## too many things (padics, elliptic curves) depend on this behavior,
## so no warning for now.
##
# ## too many things (padics, elliptic curves) depend on this behavior,
# ## so no warning for now.

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

# the following is the original, univariate-only code
Expand Down Expand Up @@ -427,16 +426,17 @@
raise TypeError("base_ring must be a commutative ring")
return R


def _multi_variate(base_ring, num_gens=None, names=None,
order='negdeglex', default_prec=None, sparse=False):
order='negdeglex', default_prec=None, sparse=False):
"""
Construct multivariate power series ring.
"""
if names is None:
raise TypeError("you must specify a variable name or names")

if num_gens is None:
if isinstance(names,str):
if isinstance(names, str):
num_gens = len(names.split(','))
elif isinstance(names, (list, tuple)):
num_gens = len(names)
Expand All @@ -458,6 +458,7 @@
def _single_variate():
pass


def is_PowerSeriesRing(R):
"""
Return ``True`` if this is a *univariate* power series ring. This is in
Expand Down Expand Up @@ -489,7 +490,8 @@
else:
return False

class PowerSeriesRing_generic(UniqueRepresentation, ring.CommutativeRing, Nonexact):

class PowerSeriesRing_generic(UniqueRepresentation, Parent, Nonexact):
"""
A power series ring.
"""
Expand Down Expand Up @@ -592,9 +594,9 @@
else:
raise ValueError('unknown power series implementation: %r' % implementation)

ring.CommutativeRing.__init__(self, base_ring, names=name,
category=getattr(self, '_default_category',
_CommutativeRings))
Parent.__init__(self, base=base_ring, names=name,
category=getattr(self, '_default_category',
_CommutativeRings))
Nonexact.__init__(self, default_prec)
if implementation == 'pari':
self.__generator = self.element_class(self, R.gen().__pari__())
Expand Down Expand Up @@ -832,7 +834,7 @@
elif isinstance(f, LaurentSeries) and f.parent().power_series_ring() is self:
return self(f.power_series(), prec, check=check)
elif isinstance(f, MagmaElement) and str(f.Type()) == 'RngSerPowElt':
v = sage_eval(f.Eltseq())
v = sage_eval(f.Eltseq()) # could use .sage() ?

Check warning on line 837 in src/sage/rings/power_series_ring.py

View check run for this annotation

Codecov / codecov/patch

src/sage/rings/power_series_ring.py#L837

Added line #L837 was not covered by tests
return self(v) * (self.gen(0)**f.Valuation())
elif isinstance(f, FractionFieldElement):
if self.base_ring().has_coerce_map_from(f.parent()):
Expand All @@ -846,7 +848,8 @@
if isinstance(f, SymbolicSeries):
if str(f.default_variable()) == self.variable_name():
return self.element_class(self, f.list(),
f.degree(f.default_variable()), check=check)
f.degree(f.default_variable()),
check=check)
else:
raise TypeError("Can only convert series into ring with same variable name.")
else:
Expand Down Expand Up @@ -1097,6 +1100,18 @@
raise IndexError("generator n>0 not defined")
return self.__generator

def gens(self) -> tuple:
"""
Return the generators of this ring.

EXAMPLES::

sage: R.<t> = PowerSeriesRing(ZZ)
sage: R.gens()
(t,)
"""
return (self.__generator,)

def uniformizer(self):
"""
Return a uniformizer of this power series ring if it is
Expand Down Expand Up @@ -1357,6 +1372,7 @@
return BaseRingFloorDivAction(other, self, is_left=False)
return super()._get_action_(other, op, self_is_left)


class PowerSeriesRing_over_field(PowerSeriesRing_domain):
_default_category = CompleteDiscreteValuationRings()

Expand Down
Loading