-
-
Notifications
You must be signed in to change notification settings - Fork 654
Completion of polynomial rings and their fraction fields #40635
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
base: develop
Are you sure you want to change the base?
Changes from 7 commits
2368519
573dae0
ce72980
d990b8f
eff3e22
2f06fbc
e6a8942
5f008e6
7468d4a
779cb91
aa9e296
5388244
a5d3d7d
6791145
dede4c3
e31740c
d0bf69c
1177266
b2ee24f
4dea431
0f8b78d
c84ffe6
ee59022
d816dc5
973dffa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -221,12 +221,14 @@ def __classcall__(cls, *args, **kwds): | |||||
'q' | ||||||
""" | ||||||
from .power_series_ring import PowerSeriesRing | ||||||
|
||||||
if 'default_prec' in kwds and kwds['default_prec'] is infinity: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Personal style choice here. |
||||||
from sage.rings.lazy_series_ring import LazyLaurentSeriesRing | ||||||
del kwds['default_prec'] | ||||||
return LazyLaurentSeriesRing(*args, **kwds) | ||||||
if not kwds and len(args) == 1 and isinstance(args[0], (PowerSeriesRing_generic, LazyPowerSeriesRing)): | ||||||
power_series = args[0] | ||||||
else: | ||||||
power_series = PowerSeriesRing(*args, **kwds) | ||||||
|
||||||
return UniqueRepresentation.__classcall__(cls, power_series) | ||||||
|
||||||
def __init__(self, power_series): | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
r""" | ||
Morphisms attached to polynomial rings. | ||
""" | ||
|
||
# ***************************************************************************** | ||
# Copyright (C) 2025 Xavier Caruso <[email protected]> | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 2 of the License, or | ||
# (at your option) any later version. | ||
# http://www.gnu.org/licenses/ | ||
# ***************************************************************************** | ||
|
||
from sage.structure.category_object import normalize_names | ||
from sage.categories.rings import Rings | ||
|
||
from sage.rings.morphism import RingHomomorphism | ||
from sage.rings.integer_ring import ZZ | ||
from sage.rings.infinity import Infinity | ||
from sage.rings.power_series_ring import PowerSeriesRing | ||
from sage.rings.laurent_series_ring import LaurentSeriesRing | ||
|
||
|
||
class MorphismToCompletion(RingHomomorphism): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. feels oddly specific? Can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're probably right. I will try to refactor things differently. |
||
r""" | ||
Morphisms from a polynomial ring (or its fraction field) | ||
to the completion at one place. | ||
|
||
TESTS:: | ||
|
||
sage: A.<t> = GF(5)[] | ||
sage: B.<u> = A.completion(t+1) | ||
sage: f = B.coerce_map_from(A) | ||
sage: type(f) | ||
<class 'sage.rings.polynomial.morphism.MorphismToCompletion'> | ||
|
||
sage: TestSuite(f).run(skip='_test_category') | ||
""" | ||
def __init__(self, domain, place, prec, name, residue_name): | ||
r""" | ||
Initialize this morphism. | ||
|
||
INPUT: | ||
|
||
- ``domain`` -- a polynomial ring of its fraction field | ||
|
||
- ``place`` -- an irreducible polynomial or ``Infinity`` | ||
|
||
- ``prec`` -- an integer or ``Infinity`` | ||
|
||
- ``name`` -- a string, the variable name of the uniformizer | ||
|
||
- ``residue_name`` -- a string, the variable name of the | ||
generator of the residue ring | ||
|
||
TESTS:: | ||
|
||
sage: A.<t> = ZZ[] | ||
sage: B.<u> = A.completion(2*t + 1) | ||
Traceback (most recent call last): | ||
... | ||
NotImplementedError: the leading coefficient of the place is not a unit | ||
|
||
:: | ||
|
||
sage: A.<t> = QQ[] | ||
sage: B.<u,a> = A.completion(x^2 + 2*x + 1) | ||
Traceback (most recent call last): | ||
... | ||
ValueError: place must be Infinity or an irreducible polynomial | ||
""" | ||
if domain.is_field(): | ||
ring = domain.ring() | ||
SeriesRing = LaurentSeriesRing | ||
else: | ||
ring = domain | ||
SeriesRing = PowerSeriesRing | ||
k = base = ring.base_ring() | ||
x = ring.gen() | ||
sparse = ring.is_sparse() | ||
if place is Infinity: | ||
pass | ||
elif place in ring: | ||
place = ring(place) | ||
if place.leading_coefficient().is_unit(): | ||
place = ring(place.monic()) | ||
# We do not check irreducibility; it causes too much troubles: | ||
# it can be long, be not implemented and even sometimes fail | ||
else: | ||
raise NotImplementedError("the leading coefficient of the place is not a unit") | ||
else: | ||
raise ValueError("place must be Infinity or an irreducible polynomial") | ||
self._place = place | ||
if name is None: | ||
raise ValueError("you must specify a variable name") | ||
name = normalize_names(1, name) | ||
if place is Infinity: | ||
codomain = LaurentSeriesRing(base, names=name, default_prec=prec, sparse=sparse) | ||
image = codomain.one() >> 1 | ||
elif place == ring.gen() or place.degree() == 1: # sometimes ring.gen() has not degree 1 | ||
codomain = SeriesRing(base, names=name, default_prec=prec, sparse=sparse) | ||
image = codomain.gen() - place[0] | ||
else: | ||
if residue_name is None: | ||
raise ValueError("you must specify a variable name for the residue field") | ||
residue_name = normalize_names(1, residue_name) | ||
k = base.extension(place, names=residue_name) | ||
codomain = SeriesRing(k, names=name, default_prec=prec, sparse=sparse) | ||
image = codomain.gen() + k.gen() | ||
parent = domain.Hom(codomain, category=Rings()) | ||
RingHomomorphism.__init__(self, parent) | ||
self._image = image | ||
self._k = k | ||
|
||
def _repr_type(self): | ||
r""" | ||
Return a string that describes the type of this morphism. | ||
|
||
EXAMPLES:: | ||
|
||
sage: A.<x> = QQ[] | ||
sage: B.<u> = A.completion(x + 1) | ||
sage: f = B.coerce_map_from(A) | ||
sage: f # indirect doctest | ||
Completion morphism: | ||
From: Univariate Polynomial Ring in x over Rational Field | ||
To: Power Series Ring in u over Rational Field | ||
""" | ||
return "Completion" | ||
|
||
def place(self): | ||
r""" | ||
Return the place at which we completed. | ||
|
||
EXAMPLES:: | ||
|
||
sage: A.<x> = QQ[] | ||
sage: B.<u> = A.completion(x + 1) | ||
sage: f = B.coerce_map_from(A) | ||
sage: f.place() | ||
x + 1 | ||
""" | ||
return self._place | ||
|
||
def _call_(self, P): | ||
r""" | ||
Return the image of ``P`` under this morphism. | ||
|
||
EXAMPLES:: | ||
|
||
sage: A.<x> = QQ[] | ||
sage: B.<u> = A.completion(x + 1) | ||
sage: f = B.coerce_map_from(A) | ||
sage: f(x) # indirect doctest | ||
-1 + u | ||
""" | ||
return P(self._image) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.