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

Commit

Permalink
#18836: mvoe refine_embedding function into NumberField class
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnCremona committed Jul 9, 2015
1 parent 6bc31bd commit 450209d
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 151 deletions.
3 changes: 1 addition & 2 deletions src/sage/rings/number_field/galois_group.py
Expand Up @@ -27,7 +27,6 @@
from sage.misc.cachefunc import cached_method
from sage.libs.pari.all import pari
from sage.rings.infinity import infinity
from sage.rings.number_field.number_field import refine_embedding
from sage.rings.number_field.morphism import NumberFieldHomomorphism_im_gens

class GaloisGroup_v1(SageObject):
Expand Down Expand Up @@ -427,7 +426,7 @@ def complex_conjugation(self, P=None):
raise ValueError("No default complex embedding specified")
P = Q

P = refine_embedding(P, infinity)
P = self.number_field().refine_embedding(P, infinity)

if not self.number_field().is_galois():
raise TypeError("Extension is not Galois")
Expand Down
279 changes: 138 additions & 141 deletions src/sage/rings/number_field/number_field.py
Expand Up @@ -8369,6 +8369,144 @@ def elements_of_bounded_height(self,bound,precision=53,LLL=False):
else:
return bdd_height(self, bound, precision, LLL)

def refine_embedding(self, e, prec=None):
r"""
Increase precision of a real or complex embedding.
INPUT:
- ``e`` - an embedding of a number field into either
RR or CC (with some precision)
- ``prec`` - (default None) the desired precision; if None,
current precision is doubled; if Infinity, the equivalent
embedding into either ``QQbar`` or ``AA`` is returned.
EXAMPLES::
sage: K = CyclotomicField(3)
sage: e10 = K.complex_embedding(10)
sage: e10.codomain().precision()
10
sage: e25 = K.refine_embedding(e10, prec=25)
sage: e25.codomain().precision()
25
An example where we extend a real embedding into ``AA``::
sage: K.<a> = NumberField(x^3-2)
sage: K.signature()
(1, 1)
sage: e = K.embeddings(RR)[0]; e
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Real Field with 53 bits of precision
Defn: a |--> 1.25992104989487
sage: e = K.refine_embedding(e,Infinity); e
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Algebraic Real Field
Defn: a |--> 1.259921049894873?
Now we can obtain arbitrary precision values with no trouble::
sage: RealField(150)(e(a))
1.2599210498948731647672106072782283505702515
sage: _^3
2.0000000000000000000000000000000000000000000
sage: RealField(200)(e(a^2-3*a+7))
4.8076379022835799804500738174376232086807389337953290695624
Complex embeddings can be extended into ``QQbar``::
sage: e = K.embeddings(CC)[0]; e
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Complex Field with 53 bits of precision
Defn: a |--> -0.62996052494743... - 1.09112363597172*I
sage: e = K.refine_embedding(e,Infinity); e
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Algebraic Field
Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I
sage: ComplexField(200)(e(a))
-0.62996052494743658238360530363911417528512573235075399004099 - 1.0911236359717214035600726141898088813258733387403009407036*I
sage: e(a)^3
2
Embeddings into lazy fields work::
sage: L = CyclotomicField(7)
sage: x = L.specified_complex_embedding(); x
Generic morphism:
From: Cyclotomic Field of order 7 and degree 6
To: Complex Lazy Field
Defn: zeta7 -> 0.623489801858734? + 0.781831482468030?*I
sage: L.refine_embedding(x, 300)
Ring morphism:
From: Cyclotomic Field of order 7 and degree 6
To: Complex Field with 300 bits of precision
Defn: zeta7 |--> 0.623489801858733530525004884004239810632274730896402105365549439096853652456487284575942507 + 0.781831482468029808708444526674057750232334518708687528980634958045091731633936441700868007*I
sage: L.refine_embedding(x, infinity)
Ring morphism:
From: Cyclotomic Field of order 7 and degree 6
To: Algebraic Field
Defn: zeta7 |--> 0.6234898018587335? + 0.7818314824680299?*I
When the old embedding is into the real lazy field,
then only real embeddings should be considered.
See :trac:`17495`::
sage: R.<x> = QQ[]
sage: K.<a> = NumberField(x^3 + x - 1, embedding=0.68)
sage: K.refine_embedding(K.specified_complex_embedding(), 100)
Ring morphism:
From: Number Field in a with defining polynomial x^3 + x - 1
To: Real Field with 100 bits of precision
Defn: a |--> 0.68232780382801932736948373971
sage: K.refine_embedding(K.specified_complex_embedding(), Infinity)
Ring morphism:
From: Number Field in a with defining polynomial x^3 + x - 1
To: Algebraic Real Field
Defn: a |--> 0.6823278038280193?
"""
if not self is e.domain():
raise ValueError("wrong domain in refine_embedding")
RC = e.codomain()
if RC in (sage.rings.qqbar.AA, sage.rings.qqbar.QQbar):
return e
if RC in (RLF, CLF):
prec_old = e.gen_image().approx().prec()
old_root = e(self.gen()).approx()
else:
prec_old = RC.precision()
old_root = e(self.gen())

if prec is None:
prec = 2*prec_old
elif prec_old >= prec:
return e

# We first compute all the embeddings at the new precision:
if sage.rings.real_mpfr.is_RealField(RC) or RC in (RDF, RLF):
if prec == Infinity:
elist = self.embeddings(sage.rings.qqbar.AA)
else:
elist = self.real_embeddings(prec)
else:
if prec == Infinity:
elist = self.embeddings(sage.rings.qqbar.QQbar)
else:
elist = self.complex_embeddings(prec)

# Now we determine which is an extension of the old one; this
# relies on the fact that coercing a high-precision root into a
# field with lower precision will equal the lower-precision root!
diffs = [(RC(ee(self.gen()))-old_root).abs() for ee in elist]
return elist[min(izip(diffs,count()))[1]]


class NumberField_cyclotomic(NumberField_absolute):
"""
Create a cyclotomic extension of the rational field.
Expand Down Expand Up @@ -10041,144 +10179,3 @@ def put_natural_embedding_first(v):
v[i] = v[0]
v[0] = phi
return



def refine_embedding(e, prec=None):
r"""
Given an embedding from a number field to either `\RR` or
`\CC`, returns an equivalent embedding with higher precision.
INPUT:
- ``e`` - an embedding of a number field into either
RR or CC (with some precision)
- ``prec`` - (default None) the desired precision; if None,
current precision is doubled; if Infinity, the equivalent
embedding into either ``QQbar`` or ``AA`` is returned.
EXAMPLES::
sage: from sage.rings.number_field.number_field import refine_embedding
sage: K = CyclotomicField(3)
sage: e10 = K.complex_embedding(10)
sage: e10.codomain().precision()
10
sage: e25 = refine_embedding(e10, prec=25)
sage: e25.codomain().precision()
25
An example where we extend a real embedding into ``AA``::
sage: K.<a> = NumberField(x^3-2)
sage: K.signature()
(1, 1)
sage: e = K.embeddings(RR)[0]; e
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Real Field with 53 bits of precision
Defn: a |--> 1.25992104989487
sage: e = refine_embedding(e,Infinity); e
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Algebraic Real Field
Defn: a |--> 1.259921049894873?
Now we can obtain arbitrary precision values with no trouble::
sage: RealField(150)(e(a))
1.2599210498948731647672106072782283505702515
sage: _^3
2.0000000000000000000000000000000000000000000
sage: RealField(200)(e(a^2-3*a+7))
4.8076379022835799804500738174376232086807389337953290695624
Complex embeddings can be extended into ``QQbar``::
sage: e = K.embeddings(CC)[0]; e
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Complex Field with 53 bits of precision
Defn: a |--> -0.62996052494743... - 1.09112363597172*I
sage: e = refine_embedding(e,Infinity); e
Ring morphism:
From: Number Field in a with defining polynomial x^3 - 2
To: Algebraic Field
Defn: a |--> -0.6299605249474365? - 1.091123635971722?*I
sage: ComplexField(200)(e(a))
-0.62996052494743658238360530363911417528512573235075399004099 - 1.0911236359717214035600726141898088813258733387403009407036*I
sage: e(a)^3
2
Embeddings into lazy fields work::
sage: L = CyclotomicField(7)
sage: x = L.specified_complex_embedding(); x
Generic morphism:
From: Cyclotomic Field of order 7 and degree 6
To: Complex Lazy Field
Defn: zeta7 -> 0.623489801858734? + 0.781831482468030?*I
sage: refine_embedding(x, 300)
Ring morphism:
From: Cyclotomic Field of order 7 and degree 6
To: Complex Field with 300 bits of precision
Defn: zeta7 |--> 0.623489801858733530525004884004239810632274730896402105365549439096853652456487284575942507 + 0.781831482468029808708444526674057750232334518708687528980634958045091731633936441700868007*I
sage: refine_embedding(x, infinity)
Ring morphism:
From: Cyclotomic Field of order 7 and degree 6
To: Algebraic Field
Defn: zeta7 |--> 0.6234898018587335? + 0.7818314824680299?*I
When the old embedding is into the real lazy field,
then only real embeddings should be considered.
See :trac:`17495`::
sage: R.<x> = QQ[]
sage: K.<a> = NumberField(x^3 + x - 1, embedding=0.68)
sage: from sage.rings.number_field.number_field import refine_embedding
sage: refine_embedding(K.specified_complex_embedding(), 100)
Ring morphism:
From: Number Field in a with defining polynomial x^3 + x - 1
To: Real Field with 100 bits of precision
Defn: a |--> 0.68232780382801932736948373971
sage: refine_embedding(K.specified_complex_embedding(), Infinity)
Ring morphism:
From: Number Field in a with defining polynomial x^3 + x - 1
To: Algebraic Real Field
Defn: a |--> 0.6823278038280193?
"""
K = e.domain()
RC = e.codomain()
if RC in (sage.rings.qqbar.AA, sage.rings.qqbar.QQbar):
return e
if RC in (RLF, CLF):
prec_old = e.gen_image().approx().prec()
old_root = e(K.gen()).approx()
else:
prec_old = RC.precision()
old_root = e(K.gen())

if prec is None:
prec = 2*prec_old
elif prec_old >= prec:
return e

# We first compute all the embeddings at the new precision:
if sage.rings.real_mpfr.is_RealField(RC) or RC in (RDF, RLF):
if prec == Infinity:
elist = K.embeddings(sage.rings.qqbar.AA)
else:
elist = K.real_embeddings(prec)
else:
if prec == Infinity:
elist = K.embeddings(sage.rings.qqbar.QQbar)
else:
elist = K.complex_embeddings(prec)

# Now we determine which is an extension of the old one; this
# relies on the fact that coercing a high-precision root into a
# field with lower precision will equal the lower-precision root!
diffs = [(RC(ee(K.gen()))-old_root).abs() for ee in elist]
return elist[min(izip(diffs,count()))[1]]
2 changes: 1 addition & 1 deletion src/sage/rings/number_field/number_field_element.pyx
Expand Up @@ -2315,7 +2315,7 @@ cdef class NumberFieldElement(FieldElement):
return self.polynomial()(gen_image)
else:
# Convert the embedding to an embedding into AA or QQbar
embedding = number_field.refine_embedding(embedding, infinity)
embedding = K.refine_embedding(embedding, infinity)
a = embedding(self).radical_expression()
if a.parent() == SR:
return a
Expand Down
8 changes: 3 additions & 5 deletions src/sage/schemes/elliptic_curves/ell_point.py
Expand Up @@ -2768,14 +2768,13 @@ def archimedean_local_height(self, v=None, prec=None, weighted=False):
h /= K.degree()
return h

from sage.rings.number_field.number_field import refine_embedding
prec_v = v.codomain().prec()
if prec is None:
prec = prec_v
if K is rings.QQ:
vv = K.embeddings(rings.RealField(max(2*prec, prec_v)))[0]
else:
vv = refine_embedding(v, 2*prec) # vv.prec() = max(2*prec, prec_v)
vv = K.refine_embedding(v, 2*prec) #vv.prec() = max(2*prec, prec_v)
b2, b4, b6, b8 = [vv(b) for b in E.b_invariants()]
H = max(4, abs(b2), 2*abs(b4), 2*abs(b6), abs(b8))
# The following comes from Silverman Theorem 4.2. Silverman
Expand Down Expand Up @@ -3144,7 +3143,6 @@ def elliptic_logarithm(self, embedding=None, precision=100,
0.70448375537782208460499649302 - 0.79246725643650979858266018068*I
"""
from sage.rings.number_field.number_field import refine_embedding
from sage.rings.all import RealField, ComplexField, QQ

# Check the trivial case:
Expand All @@ -3171,7 +3169,7 @@ def elliptic_logarithm(self, embedding=None, precision=100,
prec = emb.codomain().precision()
# if the precision parameter is greater, refine the embedding:
if precision > prec:
emb = refine_embedding(emb, precision)
emb = K.refine_embedding(emb, precision)

L = E.period_lattice(emb)

Expand Down Expand Up @@ -3203,7 +3201,7 @@ def elliptic_logarithm(self, embedding=None, precision=100,
# the curve, and the point
working_prec = 2*working_prec
if not rational:
emb = refine_embedding(emb, working_prec)
emb = K.refine_embedding(emb, working_prec)
ai = [emb(a) for a in E.a_invariants()]
E_work = EllipticCurve(ai) # defined over RR
pt_pari = pari([emb(x), emb(y)])
Expand Down
3 changes: 1 addition & 2 deletions src/sage/schemes/elliptic_curves/period_lattice.py
Expand Up @@ -107,7 +107,6 @@
from sage.rings.complex_field import is_ComplexField
from sage.rings.real_mpfr import RealNumber as RealNumber
from sage.rings.complex_number import ComplexNumber as ComplexNumber
from sage.rings.number_field.number_field import refine_embedding
from sage.rings.infinity import Infinity
from sage.schemes.elliptic_curves.constructor import EllipticCurve
from sage.misc.cachefunc import cached_method
Expand Down Expand Up @@ -209,7 +208,7 @@ def __init__(self, E, embedding=None):
embs = K.embeddings(QQbar)
embedding = embs[0]
else:
embedding = refine_embedding(embedding,Infinity)
embedding = K.refine_embedding(embedding,Infinity)
real = embedding(K.gen()).imag().is_zero()

self.embedding = embedding
Expand Down

0 comments on commit 450209d

Please sign in to comment.