Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 9bb1d9b

Browse files
committed
34212: log embedding for number fields
1 parent cd1e2b1 commit 9bb1d9b

File tree

2 files changed

+122
-31
lines changed

2 files changed

+122
-31
lines changed

src/sage/rings/number_field/number_field.py

+60-26
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
from sage.misc.functional import is_odd, lift
129129

130130
from sage.misc.misc_c import prod
131-
from sage.rings.infinity import Infinity
131+
from sage.rings.all import Infinity
132132
from sage.categories.number_fields import NumberFields
133133

134134
import sage.rings.ring
@@ -156,7 +156,9 @@
156156

157157
_NumberFields = NumberFields()
158158

159-
159+
from sage.categories.homset import Hom
160+
from sage.categories.sets_cat import Sets
161+
from sage.modules.free_module import VectorSpace
160162
from sage.rings.number_field.morphism import RelativeNumberFieldHomomorphism_from_abs
161163

162164

@@ -1635,7 +1637,7 @@ def construction(self):
16351637
16361638
"""
16371639
from sage.categories.pushout import AlgebraicExtensionFunctor
1638-
from sage.rings.rational_field import QQ
1640+
from sage.all import QQ
16391641
names = self.variable_names()
16401642
polys = []
16411643
embeddings = []
@@ -1765,12 +1767,6 @@ def _element_constructor_(self, x, check=True):
17651767
2*I + 1
17661768
sage: QQi(vector((RR(1), RR(2))))
17671769
2*I + 1
1768-
1769-
Check that :trac:`34059` is fixed::
1770-
1771-
sage: K.<a> = NumberField(x)
1772-
sage: K([1]).parent()
1773-
Number Field in a with defining polynomial x
17741770
"""
17751771
if isinstance(x, number_field_element.NumberFieldElement):
17761772
K = x.parent()
@@ -1826,7 +1822,10 @@ def _element_constructor_(self, x, check=True):
18261822
if len(x) != self.relative_degree():
18271823
raise ValueError("Length must be equal to the degree of this number field")
18281824
base = self.base_ring()
1829-
return sum(base(c) * g for c, g in zip(x, self.gen(0).powers(len(x))))
1825+
result = base(x[0])
1826+
for i in range(1, self.relative_degree()):
1827+
result += base(x[i])*self.gen(0)**i
1828+
return result
18301829
return self._convert_non_number_field_element(x)
18311830

18321831
def _convert_non_number_field_element(self, x):
@@ -3293,8 +3292,7 @@ def algebraic_closure(self):
32933292
sage: K.algebraic_closure()
32943293
Algebraic Field
32953294
"""
3296-
from sage.rings.qqbar import QQbar
3297-
return QQbar
3295+
return sage.rings.all.QQbar
32983296

32993297
@cached_method
33003298
def conductor(self, check_abelian=True):
@@ -4211,7 +4209,7 @@ def _pari_absolute_structure(self):
42114209
- ``beta`` is the image of `x \bmod g` under the inverse
42124210
isomorphism `\phi^{-1}\colon K[x]/(g) \to K[x]/(f)`
42134211
4214-
EXAMPLES:
4212+
EXAMPLES::
42154213
42164214
If `f` is monic and integral, the result satisfies ``g = f``
42174215
and ``alpha = beta = x``::
@@ -6811,7 +6809,7 @@ def regulator(self, proof=None):
68116809
try:
68126810
return self.__regulator
68136811
except AttributeError:
6814-
from sage.rings.real_mpfr import RealField
6812+
from sage.rings.all import RealField
68156813
k = self.pari_bnf(proof)
68166814
self.__regulator = RealField(53)(k.bnf_get_reg())
68176815
return self.__regulator
@@ -8120,8 +8118,7 @@ def _coerce_from_other_number_field(self, x):
81208118

81218119
# Do not use CDF or RDF because of constraints on the
81228120
# exponent of floating-point numbers
8123-
from sage.rings.complex_mpfr import ComplexField
8124-
from sage.rings.real_mpfr import RealField
8121+
from sage.rings.all import RealField, ComplexField
81258122
CC = ComplexField(53)
81268123
RR = RealField(53)
81278124

@@ -8923,7 +8920,7 @@ def free_module(self, base=None, basis=None, map=True):
89238920
if base is None:
89248921
base = QQ
89258922
elif base is self:
8926-
return super().free_module(base=base, basis=basis, map=map)
8923+
return super(NumberField_absolute, self).free_module(base=base, basis=basis, map=map)
89278924
if basis is not None or base is not QQ:
89288925
raise NotImplementedError
89298926
V = QQ**self.degree()
@@ -9297,6 +9294,45 @@ def minkowski_embedding(self, B=None, prec=None):
92979294

92989295
return sage.matrix.all.matrix(d)
92999296

9297+
def logarithmic_embedding(self, prec=53):
9298+
"""
9299+
Return the morphism of ``self`` under the logarithmic embedding
9300+
in the category Set.
9301+
9302+
The logarithmic embedding is defined as a map from the number field ``self`` to `\RR^n`.
9303+
9304+
It is defined under Definition 4.9.6 in [Cohen1993]_.
9305+
9306+
INPUT:
9307+
9308+
- ``prec`` -- desired floating point precision.
9309+
9310+
OUTPUT:
9311+
9312+
- a tuple of real numbers.
9313+
9314+
EXAMPLES::
9315+
9316+
sage: CF.<a> = CyclotomicField(97)
9317+
sage: f = CF.logarithmic_embedding()
9318+
sage: f(0)
9319+
(-1)
9320+
sage: f(7)
9321+
(1.94591014905531)
9322+
9323+
::
9324+
9325+
sage: K.<a> = NumberField(x^3 + 5)
9326+
sage: f = K.logarithmic_embedding()
9327+
sage: f(0)
9328+
(-1)
9329+
sage: f(7)
9330+
(1.94591014905531)
9331+
"""
9332+
log_map = self(0)._logarithmic_embedding_helper(prec)
9333+
log_hom = Hom(self, VectorSpace(QQ, len(log_map(0))), Sets())
9334+
return log_hom(log_map)
9335+
93009336
def places(self, all_complex=False, prec=None):
93019337
r"""
93029338
Return the collection of all infinite places of self.
@@ -9374,9 +9410,8 @@ def places(self, all_complex=False, prec=None):
93749410
C = sage.rings.complex_double.CDF
93759411

93769412
elif prec == Infinity:
9377-
from sage.rings.qqbar import AA, QQbar
9378-
R = AA
9379-
C = QQbar
9413+
R = sage.rings.all.AA
9414+
C = sage.rings.all.QQbar
93809415

93819416
else:
93829417
R = sage.rings.real_mpfr.RealField(prec)
@@ -9673,8 +9708,7 @@ def relativize(self, alpha, names, structure=None):
96739708
# step 1: construct the abstract field generated by alpha.w
96749709
# step 2: make a relative extension of it.
96759710
# step 3: construct isomorphisms
9676-
from sage.matrix.constructor import matrix
9677-
from sage.modules.free_module_element import vector
9711+
from sage.all import vector, matrix
96789712

96799713
from sage.categories.map import is_Map
96809714
if is_Map(alpha):
@@ -9684,7 +9718,7 @@ def relativize(self, alpha, names, structure=None):
96849718
L = alpha.domain()
96859719
alpha = alpha(L.gen()) # relativize over phi's domain
96869720
if L is QQ:
9687-
from sage.rings.polynomial.polynomial_ring import polygen
9721+
from sage.rings.all import polygen
96889722
f = polygen(QQ)
96899723
else:
96909724
f = L.defining_polynomial() # = alpha.minpoly()
@@ -10040,13 +10074,13 @@ def hilbert_symbol(self, a, b, P = None):
1004010074
return pari(self).nfhilbert(a, b)
1004110075

1004210076
from sage.categories.map import Map
10043-
from sage.categories.rings import Rings
10077+
from sage.categories.all import Rings
1004410078
if isinstance(P, Map) and P.category_for().is_subcategory(Rings()):
1004510079
# P is a morphism of Rings
1004610080
if P.domain() is not self:
1004710081
raise ValueError("Domain of P (=%s) should be self (=%s) in self.hilbert_symbol" % (P, self))
1004810082
codom = P.codomain()
10049-
from sage.rings.qqbar import AA, QQbar
10083+
from sage.rings.all import (AA, QQbar)
1005010084
if isinstance(codom, (sage.rings.abc.ComplexField, sage.rings.abc.ComplexDoubleField, sage.rings.abc.ComplexIntervalField)) or \
1005110085
codom is QQbar:
1005210086
if P(self.gen()).imag() == 0:
@@ -11420,7 +11454,7 @@ def embeddings(self, K):
1142011454
v = []
1142111455
except AttributeError:
1142211456
# zeta not defined
11423-
return super().embeddings(K)
11457+
return super(NumberField_cyclotomic, self).embeddings(K)
1142411458
else:
1142511459
X = [m for m in range(n) if arith.gcd(m,n) == 1]
1142611460
v = [self.hom([z**i], check=False) for i in X]

src/sage/rings/number_field/number_field_element.pyx

+62-5
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ ZZ = sage.rings.integer_ring.ZZ
8686
Integer_sage = sage.rings.integer.Integer
8787

8888
from sage.rings.real_mpfi import RealInterval
89+
from sage.rings.real_mpfr import RealField
8990

9091
from sage.rings.complex_mpfr import ComplexField
9192
from sage.rings.cc import CC
@@ -2948,11 +2949,7 @@ cdef class NumberFieldElement(FieldElement):
29482949
from .number_field import NumberField_cyclotomic
29492950
if isinstance(K, NumberField_cyclotomic):
29502951
# solution by radicals may be difficult, but we have a closed form
2951-
from sage.functions.log import exp
2952-
from sage.rings.complex_mpfr import ComplexField
2953-
from sage.rings.imaginary_unit import I
2954-
from sage.rings.real_mpfr import RR
2955-
from sage.symbolic.constants import pi
2952+
from sage.all import exp, I, pi, ComplexField, RR
29562953
CC = ComplexField(53)
29572954
two_pi_i = 2 * pi * I
29582955
k = ( K._n()*CC(K.gen()).log() / CC(two_pi_i) ).real().round() # n ln z / (2 pi i)
@@ -4121,6 +4118,66 @@ cdef class NumberFieldElement(FieldElement):
41214118
"""
41224119
return (self.global_height_non_arch(prec)+self.global_height_arch(prec))/self.number_field().absolute_degree()
41234120

4121+
def _logarithmic_embedding_helper(self, prec=53):
4122+
"""
4123+
Return the image of ``self`` under the logarithmic embedding.
4124+
4125+
The logarithmic embedding is defined as a map from the number field ``self`` to `\RR^n`.
4126+
4127+
It is defined under Definition 4.9.6 in [Cohen1993]_.
4128+
4129+
INPUT:
4130+
4131+
- ``prec`` -- desired floating point precision.
4132+
4133+
OUTPUT:
4134+
4135+
- a function.
4136+
4137+
EXAMPLES::
4138+
4139+
sage: CF.<a> = CyclotomicField(97)
4140+
sage: log_map = CF(0)._logarithmic_embedding_helper()
4141+
sage: log_map(0)
4142+
(-1)
4143+
sage: log_map(7)
4144+
(1.94591014905531)
4145+
4146+
::
4147+
4148+
sage: F.<a> = NumberField(x^3 + 5)
4149+
sage: K.<b> = F.extension(x^2 + 2)
4150+
sage: log_map = K(0)._logarithmic_embedding_helper()
4151+
sage: log_map(0)
4152+
(-1, -1)
4153+
sage: log_map(7)
4154+
(1.94591014905531, 3.89182029811063)
4155+
"""
4156+
def closure_map(x):
4157+
"""
4158+
The function closure of the logarithmic embedding.
4159+
"""
4160+
K = self.base_ring()
4161+
K_embeddings = K.places(prec)
4162+
r1, r2 = K.signature()
4163+
r = r1 + r2 - 1
4164+
4165+
Reals = RealField(prec)
4166+
4167+
if x == 0:
4168+
return vector([-1 for _ in range(r + 1)])
4169+
4170+
x_logs = []
4171+
for i in range(r1):
4172+
sigma = K_embeddings[i]
4173+
x_logs.append(Reals(abs(sigma(x))).log())
4174+
for i in range(r1, r + 1):
4175+
tau = K_embeddings[i]
4176+
x_logs.append(2 * Reals(abs(tau(x))).log())
4177+
4178+
return vector(x_logs)
4179+
return closure_map
4180+
41244181
def numerator_ideal(self):
41254182
"""
41264183
Return the numerator ideal of this number field element.

0 commit comments

Comments
 (0)