3-manifolds / SnapPy

SnapPy is a package for studying the topology and geometry of 3-manifolds, with a focus on hyperbolic structures. It is based on the SnapPea kernel written by Jeff Weeks.
https://snappy.computop.org/
84 stars 39 forks source link

Non-deterministic failure in DTcodec #30

Closed unhyperbolic closed 3 years ago

unhyperbolic commented 3 years ago

The following code

from spherogram.codecs import DTcodec
DTcodec([(20, 22, 24, 26, 28, 10, 8, 6, 4, 2, 18, 16, 14, 12)])

or

DTcodec([(22, 20, 18, 16, 14, 12, 32, 30, 28, 26, 24, 2, 4, 6, 8, 10)])

sometimes succeeds and sometimes fails when trying to unpack marked_arc[:2] in DTFatGraph.bridge stack.

Background: The above DT codes were constructed as follows. Saul and I were trying to construct a family of two bridge knots with

from functools import reduce                                                                              
import operator                                                                                          
C, Id = snappy.RationalTangle(1), snappy.IdentityBraid(1)
x = sigma_1 = C | Id | Id                                                                                
y = sigma_2_inverse = Id | -C | Id                                                                        
def braid(n): return reduce(operator.mul, n*[x, y]).numerator_closure().exterior()
# these manifolds (two-bridge knot complements) are "designed" to have 
# Dirichlet domains with volume and diameter linear both in n - that is, they are "skinny".
# (I wanted to see the geometric convergence of the manifold to the cyclic
# cover of the figure eight knot complement.)
M=braid(7)
M.volume()
19.8015843460970
M.high_precision().dirichlet_domain().view()

which runs into the above problem when calling HP._set_DTcode(DTcodec(DT)) to transfer the DT code from the low to the high precision manifold.

unhyperbolic commented 3 years ago

Another interesting thing: once M.high_precision() has failed with the above error, quitting ipython results in a segfault.

NathanDunfield commented 3 years ago

For me, the failure of

from spherogram.codecs import DTcodec
DTcodec([(20, 22, 24, 26, 28, 10, 8, 6, 4, 2, 18, 16, 14, 12)])

is deterministic, specifically it always fails.

Looking at picture for braid(2) in PLink, I see that it has a trivial twist that can be simplified by a Reidemeister I move. I wonder it DT notation, which is missing 1 extra bit per crossing to really specify the planar embedding, doesn't correctly handle this situation. Or in any event our implementation does not. A simpler example with the same traceback is

DTcodec([(2,6,8,4)])

However, if we specify the flip bits, as given by PLink, I get no error:

DTcodec([(2,6,8,4)], flips=[0,1,1,0])

It must be some issue with how snappy.Triangulation is storing and/or transferring the DT code. In your full example, braid(n) will know the augmented flipped version and should hand that over.

unhyperbolic commented 3 years ago

Thanks. I checked in https://github.com/3-manifolds/SnapPy/commit/40c4909030c5ba22bf093ef35cf7204661cdb079 that fixes our original example.

For a non-prime knot, the DT notation is unaltered when flipping one of the components. I guess a trivial twist can be regarded as an extreme form of this.

NathanDunfield commented 3 years ago

Fixed by 40c4909.