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

Laurent polynomial/series modularization fixes #35554

Merged
merged 9 commits into from
Jun 3, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -1166,13 +1166,13 @@ def expand(self, alphabet):
TESTS::

sage: type(p.expand(F.gens()))
<class 'sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_mpair'>
<class 'sage.rings.polynomial.laurent_polynomial_mpair.LaurentPolynomial_mpair'>

sage: p = KL.zero()
sage: p.expand(F.gens())
0
sage: type(p.expand(F.gens()))
<class 'sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_mpair'>
<class 'sage.rings.polynomial.laurent_polynomial_mpair.LaurentPolynomial_mpair'>
"""
codomain = alphabet[0].parent()
return codomain.sum(c * prod(X**int(n)
Expand Down
4 changes: 3 additions & 1 deletion src/sage/data_structures/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,12 @@
from sage.arith.misc import divisors
from sage.misc.misc_c import prod
from sage.misc.lazy_attribute import lazy_attribute
from sage.misc.lazy_import import lazy_import
from sage.combinat.integer_vector_weighted import iterator_fast as wt_int_vec_iter
from sage.combinat.sf.sfa import _variables_recursive, _raise_variables
from sage.categories.hopf_algebras_with_basis import HopfAlgebrasWithBasis

lazy_import('sage.combinat.sf.sfa', ['_variables_recursive', '_raise_variables'])


class Stream():
"""
Expand Down
62 changes: 36 additions & 26 deletions src/sage/rings/big_oh.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,25 @@
- `polynomials <../../../polynomial_rings/index.html>`_
"""

import sage.arith.all as arith
from . import laurent_series_ring_element
from sage.rings.puiseux_series_ring_element import PuiseuxSeries
import sage.rings.padics.factory as padics_factory
import sage.rings.padics.padic_generic_element as padic_generic_element
from sage.arith.misc import factor
from sage.misc.lazy_import import lazy_import
lazy_import('sage.rings.padics.factory', ['Qp', 'Zp'])
lazy_import('sage.rings.padics.padic_generic_element', 'pAdicGenericElement')
from sage.rings.polynomial.polynomial_element import Polynomial

try:
from .laurent_series_ring_element import LaurentSeries
except ImportError:
LaurentSeries = ()

try:
from .puiseux_series_ring_element import PuiseuxSeries
except ImportError:
PuiseuxSeries = ()

from . import power_series_ring_element
from . import integer
from . import rational
from sage.rings.polynomial.polynomial_element import Polynomial
from . import multi_power_series_ring_element


Expand Down Expand Up @@ -47,41 +57,42 @@ def O(*x, **kwds):

This is also useful to create `p`-adic numbers::

sage: O(7^6)
sage: O(7^6) # optional - sage.rings.padics
O(7^6)
sage: 1/3 + O(7^6)
sage: 1/3 + O(7^6) # optional - sage.rings.padics
5 + 4*7 + 4*7^2 + 4*7^3 + 4*7^4 + 4*7^5 + O(7^6)

It behaves well with respect to adding negative powers of `p`::

sage: a = O(11^-32); a
sage: a = O(11^-32); a # optional - sage.rings.padics
O(11^-32)
sage: a.parent()
sage: a.parent() # optional - sage.rings.padics
11-adic Field with capped relative precision 20

There are problems if you add a rational with very negative
valuation to an `O`-Term::

sage: 11^-12 + O(11^15)
sage: 11^-12 + O(11^15) # optional - sage.rings.padics
11^-12 + O(11^8)

The reason that this fails is that the constructor doesn't know
the right precision cap to use. If you cast explicitly or use
other means of element creation, you can get around this issue::

sage: K = Qp(11, 30)
sage: K(11^-12) + O(11^15)
sage: K = Qp(11, 30) # optional - sage.rings.padics
sage: K(11^-12) + O(11^15) # optional - sage.rings.padics
11^-12 + O(11^15)
sage: 11^-12 + K(O(11^15))
sage: 11^-12 + K(O(11^15)) # optional - sage.rings.padics
11^-12 + O(11^15)
sage: K(11^-12, absprec = 15)
sage: K(11^-12, absprec=15) # optional - sage.rings.padics
11^-12 + O(11^15)
sage: K(11^-12, 15)
sage: K(11^-12, 15) # optional - sage.rings.padics
11^-12 + O(11^15)

We can also work with `asymptotic expansions`_::

sage: A.<n> = AsymptoticRing(growth_group='QQ^n * n^QQ * log(n)^QQ', coefficient_ring=QQ); A
sage: A.<n> = AsymptoticRing(growth_group='QQ^n * n^QQ * log(n)^QQ', # optional - sage.symbolic
....: coefficient_ring=QQ); A
Asymptotic Ring <QQ^n * n^QQ * log(n)^QQ * Signs^n> over Rational Field
sage: O(n)
O(n)
Expand Down Expand Up @@ -137,9 +148,8 @@ def O(*x, **kwds):
"for the maximal ideal (x)")
return x.parent().completion(x.parent().gen())(0, x.degree(), **kwds)

elif isinstance(x, laurent_series_ring_element.LaurentSeries):
return laurent_series_ring_element.LaurentSeries(x.parent(), 0).\
add_bigoh(x.valuation(), **kwds)
elif isinstance(x, LaurentSeries):
return LaurentSeries(x.parent(), 0).add_bigoh(x.valuation(), **kwds)

elif isinstance(x, PuiseuxSeries):
return x.add_bigoh(x.valuation(), **kwds)
Expand All @@ -148,18 +158,18 @@ def O(*x, **kwds):
# p-adic number
if x <= 0:
raise ArithmeticError("x must be a prime power >= 2")
F = arith.factor(x)
F = factor(x)
if len(F) != 1:
raise ArithmeticError("x must be prime power")
p, r = F[0]
if r >= 0:
return padics_factory.Zp(p, prec=max(r, 20),
type='capped-rel')(0, absprec=r, **kwds)
return Zp(p, prec=max(r, 20),
type='capped-rel')(0, absprec=r, **kwds)
else:
return padics_factory.Qp(p, prec=max(r, 20),
type='capped-rel')(0, absprec=r, **kwds)
return Qp(p, prec=max(r, 20),
type='capped-rel')(0, absprec=r, **kwds)

elif isinstance(x, padic_generic_element.pAdicGenericElement):
elif isinstance(x, pAdicGenericElement):
return x.parent()(0, absprec=x.valuation(), **kwds)
elif hasattr(x, 'O'):
return x.O(**kwds)
Expand Down
6 changes: 5 additions & 1 deletion src/sage/rings/laurent_series_ring.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@

from sage.rings.integer_ring import ZZ

try:
from sage.libs.pari.all import pari_gen
except ImportError:
pari_gen = ()


def is_LaurentSeriesRing(x):
"""
Expand Down Expand Up @@ -483,7 +488,6 @@ def _element_constructor_(self, x, n=0, prec=infinity):
from sage.rings.polynomial.polynomial_element import Polynomial
from sage.rings.polynomial.multi_polynomial import MPolynomial
from sage.structure.element import parent
from sage.libs.pari.all import pari_gen

P = parent(x)
if isinstance(x, self.element_class) and n == 0 and P is self:
Expand Down
4 changes: 2 additions & 2 deletions src/sage/rings/laurent_series_ring_element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1594,8 +1594,8 @@ cdef class LaurentSeries(AlgebraElement):

TESTS::

sage: y = var('y')
sage: f.derivative(y)
sage: y = var('y') # optional - sage.symbolic
sage: f.derivative(y) # optional - sage.symbolic
Traceback (most recent call last):
...
ValueError: cannot differentiate with respect to y
Expand Down
Loading