subfield#

Various helper functions for computations in number fields.

References

[KoRoTr2015] (1,2)

Pierre-Vincent Koseleff, Fabrice Rouillier, Cuong Tran. On the Sign of a Trigonometric Expression. ISSAC 2015. Proceedings of the 2015 ACM International Symposium on Symbolic and Algebraic Computation. Pages 259–266. DOI: http://dx.doi.org/10.1145/2755996.2756664

flatsurf.geometry.subfield.chebyshev_T(n, c)[source]#

Return the Chebyshev polynomial T_n so that

T_n(2 cos(x)) = 2 cos(n x)

Note

We use the polynomial as defined in [KoRoTr2015], not the Sage version which uses a different normalization.

EXAMPLES:

sage: from flatsurf.geometry.subfield import chebyshev_T, cos_minpoly

sage: x = polygen(ZZ)

sage: chebyshev_T(1, x) - 1 == cos_minpoly(3, x)
True
sage: chebyshev_T(2, x) - chebyshev_T(1, x) + 1 == cos_minpoly(5, x)
True
sage: chebyshev_T(3, x) - chebyshev_T(2, x) + chebyshev_T(1, x) - 1 == cos_minpoly(7, x)
True

sage: cos_minpoly(5, x)(chebyshev_T(3, x)) == cos_minpoly(15, x) * cos_minpoly(5, x)
True
sage: cos_minpoly(3, x)(chebyshev_T(5, x)) == cos_minpoly(15, x) * cos_minpoly(3, x)
True
flatsurf.geometry.subfield.cos_minpoly(n, var='x')[source]#

Return the minimal polynomial of 2 cos pi/n

Done via [KoRoTr2015] Algorithm 3.

EXAMPLES:

sage: from flatsurf.geometry.subfield import cos_minpoly

sage: cos_minpoly(1)
x + 2
sage: cos_minpoly(2)
x
sage: cos_minpoly(3)
x - 1
sage: cos_minpoly(4)
x^2 - 2
sage: cos_minpoly(5)
x^2 - x - 1
sage: cos_minpoly(6)
x^2 - 3
sage: cos_minpoly(8)
x^4 - 4*x^2 + 2
sage: cos_minpoly(9)
x^3 - 3*x - 1
sage: cos_minpoly(10)
x^4 - 5*x^2 + 5

sage: cos_minpoly(90)
x^24 - 24*x^22 + 252*x^20 - 1519*x^18 + 5796*x^16 - 14553*x^14 + 24206*x^12 - 26169*x^10 + 17523*x^8 - 6623*x^6 + 1182*x^4 - 72*x^2 + 1
sage: cos_minpoly(148)
x^72 - 72*x^70 + 2483*x^68 - 54604*x^66 + 860081*x^64 ... - 3511656*x^6 + 77691*x^4 - 684*x^2 + 1
flatsurf.geometry.subfield.cos_minpoly_odd_prime(p, var)[source]#

(-1)^k + (-1)^{k-1} T1 + … + T_k

EXAMPLES:

sage: from flatsurf.geometry.subfield import cos_minpoly_odd_prime

sage: x = polygen(ZZ)

sage: cos_minpoly_odd_prime(3, x)
x - 1
sage: cos_minpoly_odd_prime(5, x)
x^2 - x - 1
sage: cos_minpoly_odd_prime(7, x)
x^3 - x^2 - 2*x + 1
sage: cos_minpoly_odd_prime(11, x)
x^5 - x^4 - 4*x^3 + 3*x^2 + 3*x - 1
flatsurf.geometry.subfield.is_embedded_subfield(K, L, certificate=False)[source]#

Return whether there exists a field morphism from K to L compatible with the embeddings.

EXAMPLES:

sage: from flatsurf.geometry.subfield import is_embedded_subfield

sage: x = polygen(QQ)
sage: y = polygen(QQ, 'y')
sage: z = polygen(QQ, 'z')
sage: p = x^4 - 4*x^2 + 1
sage: emb = AA.polynomial_root(p, RIF(0.5, 0.6))
sage: L = NumberField(p, 'a', embedding=emb)
sage: K1 = NumberField(y^2 - 2, 'sqrt2', embedding=AA(2)**(1/2))
sage: K2 = NumberField(z^2 - 2, 'msqrt2', embedding=-AA(2)**(1/2))
sage: is_embedded_subfield(K1, L)
True
sage: is_embedded_subfield(K1, L, True)
(True, Generic morphism:
   From: Number Field in sqrt2 with defining polynomial y^2 - 2 with sqrt2 = 1.414213562373095?
   To:   Number Field in a with defining polynomial x^4 - 4*x^2 + 1 with a = 0.5176380902050415?
   Defn: sqrt2 -> -a^3 + 3*a)
sage: is_embedded_subfield(K2, L, True)
(True, Generic morphism:
   From: Number Field in msqrt2 with defining polynomial z^2 - 2 with msqrt2 = -1.414213562373095?
   To:   Number Field in a with defining polynomial x^4 - 4*x^2 + 1 with a = 0.5176380902050415?
   Defn: msqrt2 -> a^3 - 3*a)
sage: is_embedded_subfield(K1, K2, True)
(True, Generic morphism:
   From: Number Field in sqrt2 with defining polynomial y^2 - 2 with sqrt2 = 1.414213562373095?
   To:   Number Field in msqrt2 with defining polynomial z^2 - 2 with msqrt2 = -1.414213562373095?
   Defn: sqrt2 -> -msqrt2)
flatsurf.geometry.subfield.number_field_elements_from_algebraics(elts, name='a')[source]#

The native Sage function number_field_elements_from_algebraics currently returns number field without embedding. This function return field with embedding!

EXAMPLES:

sage: from flatsurf.geometry.subfield import number_field_elements_from_algebraics
sage: z = QQbar.zeta(5)
sage: c = z.real()
sage: s = z.imag()
sage: number_field_elements_from_algebraics((c, s))
(Number Field in a with defining polynomial y^4 - 5*y^2 + 5
 with a = 1.902113032590308?, [1/2*a^2 - 3/2, 1/2*a])
sage: number_field_elements_from_algebraics([AA(1), AA(2/3)])
(Rational Field, [1, 2/3])
flatsurf.geometry.subfield.subfield_from_elements(self, alpha, name=None, polred=True, threshold=None)[source]#

Return the subfield generated by the elements alpha.

INPUT:

  • alpha - list of elements in this number field

  • name - a name for the generator of the new number field

  • polred (boolean, default True) - whether to optimize the generator of the newly created field

  • threshold (positive number, default None) - threshold to be passed to the do_polred function

EXAMPLES:

sage: from flatsurf.geometry.subfield import subfield_from_elements

sage: x = polygen(QQ)
sage: poly = x^4 - 4*x^2 + 1
sage: emb = AA.polynomial_root(poly, RIF(0.51, 0.52))
sage: K.<a> = NumberField(poly, embedding=emb)
sage: sqrt2 = -a^3 + 3*a
sage: sqrt3 = -a^2 + 2
sage: assert sqrt2 ** 2 == 2 and sqrt3 ** 2 == 3
sage: L, elts, phi = subfield_from_elements(K, [sqrt2, 1 - sqrt2/3])
sage: L
Number Field in a0 with defining polynomial x^2 - 2 with a0 = 1.414213562373095?
sage: elts
[a0, -1/3*a0 + 1]
sage: phi
Ring morphism:
  From: Number Field in a0 with defining polynomial x^2 - 2 with a0 = 1.414213562373095?
  To:   Number Field in a with defining polynomial x^4 - 4*x^2 + 1 with a = 0.5176380902050415?
  Defn: a0 |--> -a^3 + 3*a
sage: assert phi(elts[0]) == sqrt2
sage: assert phi(elts[1]) == 1 - sqrt2/3

sage: L, elts, phi = subfield_from_elements(K, [1, sqrt3])
sage: assert phi(elts[0]) == 1
sage: assert phi(elts[1]) == sqrt3