Number theory of hyperbolic 3-manifolds

SnapPy has support for arbitrary-precision computation and for identifying number fields associated to hyperbolic 3-manifolds. While this functionality is less than that of Snap, it is already useful. Except for the first example, one currently needs to use SnapPy inside of Sage to have access to these features. Here’s how to find the tetrahedra shapes to high-precision:

sage: import snappy
sage: M = snappy.Manifold('m004')
sage: M.tetrahedra_shapes('rect', bits_prec=100)
[0.50000000000000000000000000000 + 0.86602540378443864676372317075*I, 0.50000000000000000000000000000 + 0.86602540378443864676372317075*I]
sage: M.tetrahedra_shapes('rect', dec_prec=100)[0]
0.500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +
0.866025403784438646763723170752936183471402626905190314027903489725966508454400018540573093378624288*I

One can also compute the holonomy representation to any precision:

sage: G = M.polished_holonomy(bits_prec=100)
sage: G.SL2C('a')
[0.50000000000000000000000000000 + 0.86602540378443864676372317075*I                                   -1.0000000000000000000000000000*I]
[                                   1.0000000000000000000000000000*I   1.0000000000000000000000000000 - 1.7320508075688772935274463415*I]

You can also try to guess the shapes exactly using an LLL-based algorithm of the type pioneered by Snap:

sage: T = M.tetrahedra_field_gens()
sage: T.find_field(prec=100, degree=10, optimize=True)
(Number Field in z with defining polynomial x^2 - x + 1, <ApproxAN: 0.5 + 0.866025403784*I>, [x, x])

You can do the same for various other fields via the methods trace_field_gens, invariant_trace_field_gens, and holonomy_matrix_entries.

In more complicated examples, one needs to use higher precision and/or degree to actually find the exact values:

sage: N = snappy.Manifold('m004(1,3)')
sage: K = N.trace_field_gens()
sage: K.find_field(prec=100, degree=10, optimize=True)    # Fails, so no output
sage: K.find_field(prec=200, degree=20, optimize=True)[0]
Number Field in z with defining polynomial x^11 - 2*x^10 - 8*x^9 + 16*x^8 + 22*x^7 - 44*x^6 - 25*x^5 + 50*x^4 + 11*x^3 - 22*x^2 - x + 1

We can also compute various hyperbolicly-twisted Alexander polynomials, as described here:

sage: M = snappy.Manifold('5_2')
sage: M.alexander_polynomial()
2*a^2 - 3*a + 2
sage: M.hyperbolic_torsion(bits_prec=100)
(2.3376410213776269870195455729 - 0.56227951206230124389918214504*I)*a^2
- 4.0000000000000000000000000003*a
+ 2.3376410213776269870195455731 - 0.56227951206230124389918214477*I
sage: M.hyperbolic_SLN_torsion(3, 100)   # Dubois-Yamagachi adjoint torsion
(0.40431358073618481197132660504 +
0.75939451500971650241038772223*I)*a^3
+ (2.9032849613891083021420278850 -
4.1185388389935516999882632998*I)*a^2
+ (-2.9032849613891083021420278809 +
4.1185388389935516999882633007*I)*a
- 0.40431358073618481197132661847 - 0.75939451500971650241038771418*I
sage: M.hyperbolic_SLN_torsion(4, 100)   # Why not?
(2.5890988184099251088892745185 + 3.5126610817613336586374292713*I)*a^4
+ (10.357403823939297224437742077 - 13.378446302375451727042633120*I)*a^3
+ (-26.821802363180149782221451472 + 7.0253221635226673172748587283*I)*a^2
+ (10.357403823939297224437738856 - 13.378446302375451727042631346*I)*a
+ 2.5890988184099251088892549440 + 3.5126610817613336586374448040*I

You can find out more about each of these methods using introspection:

sage: M.hyperbolic_torsion?
Definition: M.hyperbolic_torsion(M, bits_prec=100, all_lifts=False, wada_conventions=False, phi=None)
Docstring:
Computes the hyperbolic torsion polynomial as defined in [DFJ].

>>> M = Manifold('K11n42')
>>> M.alexander_polynomial()
1
>>> tau = M.hyperbolic_torsion(bits_prec=200)
>>> tau.degree()
6