From f22aa1fc3d216b712a9e00f826cc9e83281c6f43 Mon Sep 17 00:00:00 2001 From: Matthias Goerner <1239022+unhyperbolic@users.noreply.github.com> Date: Wed, 10 Sep 2025 18:41:39 -0700 Subject: [PATCH 1/3] Testing SnapPy with snappy.Triangulation and snappy.Manifold. --- cython/core/manifold.pyx | 9 --------- cython/core/triangulation.pyx | 6 ------ python/test.py | 24 ++++++++++++++++++++++-- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/cython/core/manifold.pyx b/cython/core/manifold.pyx index be7c0949..4ff982c3 100644 --- a/cython/core/manifold.pyx +++ b/cython/core/manifold.pyx @@ -1627,15 +1627,6 @@ cdef class Manifold(Triangulation): return ans - def is_isometric_to(self, - Manifold other, - return_isometries : bool = False): - """ - This is only here to make the tests that use SnapPy.Manifold work. - """ - return self._is_isometric_to( - other, return_isometries = return_isometries) - def is_two_bridge(self) -> bool: """ If the manifold is the complement of a two-bridge knot or link diff --git a/cython/core/triangulation.pyx b/cython/core/triangulation.pyx index 0f4a1346..2706227c 100644 --- a/cython/core/triangulation.pyx +++ b/cython/core/triangulation.pyx @@ -1020,12 +1020,6 @@ cdef class Triangulation(): free_isometry_list(isometries) return result - def isomorphisms_to(self, Triangulation other not None): - """ - This is only here to make the tests that use SnapPy.Triangulation work. - """ - return self._isomorphisms_to(other) - def __dealloc__(self): if self.c_triangulation is not NULL: free_triangulation(self.c_triangulation) diff --git a/python/test.py b/python/test.py index b4854983..bdcbf21d 100644 --- a/python/test.py +++ b/python/test.py @@ -73,12 +73,32 @@ def additional_doctests(verbose=False, print_info=True): extraglobs = globs) additional_doctests.__name__ = 'snappy.' +def run_SnapPy_doctests(verbose=False, print_info=True): + globs = {'Triangulation' : snappy.Triangulation, + 'Manifold' : snappy.Manifold} + return doctest_modules( + [ snappy.SnapPy ], + verbose=verbose, + print_info=print_info, + extraglobs=globs) +run_SnapPy_doctests.__name__ = 'snappy.SnapPy' + +def run_SnapPyHP_doctests(verbose=False, print_info=True): + globs = {'Triangulation' : snappy.TriangulationHP, + 'Manifold' : snappy.ManifoldHP} + return doctest_modules( + [ snappy.SnapPyHP ], + verbose=verbose, + print_info=print_info, + extraglobs = globs) +run_SnapPyHP_doctests.__name__ = 'snappy.SnapPyHP' + modules = [ snappy.exterior_to_link.test.run_doctests, snappy.numeric_output_checker.run_doctests, snappy.number, - snappy.SnapPy, - snappy.SnapPyHP, + run_SnapPy_doctests, + run_SnapPyHP_doctests, snappy.database, additional_doctests, snappy, From e19bc18919858f85b44ab2142a63be048638f0c0 Mon Sep 17 00:00:00 2001 From: Matthias Goerner <1239022+unhyperbolic@users.noreply.github.com> Date: Wed, 10 Sep 2025 18:41:46 -0700 Subject: [PATCH 2/3] For Triangulation(HP) and Manifold(HP), use common subclass rather than monkey-patching. --- python/__init__.py | 84 +++++++++++++----------------------- python/isometry_signature.py | 2 +- 2 files changed, 32 insertions(+), 54 deletions(-) diff --git a/python/__init__.py b/python/__init__.py index 0b83e916..5b9987af 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -28,12 +28,36 @@ from typing import Union, Tuple, List, Optional +from . import exterior_to_link +from . import verify +from . import margulis +from . import len_spec +from . import cusps +from . cusps import cusp_area_matrix +from . import raytracing +from . import isometry_signature + +class TriangulationMixIn: + exterior_to_link = exterior_to_link.exterior_to_link + +class ManifoldMixIn: + verify_hyperbolicity = verify.verify_hyperbolicity + margulis = margulis.margulis + length_spectrum_alt_gen = len_spec.length_spectrum_alt_gen + length_spectrum_alt = len_spec.length_spectrum_alt + isometry_signature = isometry_signature.isometry_signature + cusp_area_matrix = cusp_area_matrix.cusp_area_matrix + cusp_areas = cusps.cusp_areas + short_slopes = cusps.short_slopes + cusp_translations = cusps.cusp_translations + inside_view = raytracing.inside_view + # Subclass to be able to monkey-patch -class Triangulation(SnapPy.Triangulation): +class Triangulation(SnapPy.Triangulation, TriangulationMixIn): __doc__ = SnapPy.Triangulation.__doc__ # Subclass to be able to monkey-patch -class TriangulationHP(SnapPyHP.Triangulation): +class TriangulationHP(SnapPyHP.Triangulation, TriangulationMixIn): __doc__ = SnapPyHP.Triangulation.__doc__ # We want Manifold to be a subclass of Triangulation. @@ -42,7 +66,7 @@ class TriangulationHP(SnapPyHP.Triangulation): # in the presence of a diamond pattern seem to work just # fine. In particular, we do not double allocate the underlying # C structures. -class Manifold(SnapPy.Manifold, Triangulation): +class Manifold(SnapPy.Manifold, Triangulation, ManifoldMixIn): __doc__ = SnapPy.Manifold.__doc__ def identify(self, extends_to_link=False): @@ -98,7 +122,7 @@ def low_precision(self): # We want ManifoldHP to be a subclass of TriangulationHP. # See comment about Manifold and the diamond pattern. -class ManifoldHP(SnapPyHP.Manifold, TriangulationHP): +class ManifoldHP(SnapPyHP.Manifold, TriangulationHP, ManifoldMixIn): __doc__ = SnapPyHP.Manifold.__doc__ def low_precision(self): @@ -234,56 +258,16 @@ def isomorphisms_to(self, resolved_other) isomorphisms_to.__doc__ = SnapPy.Triangulation._isomorphisms_to.__doc__ -Triangulation.isomorphisms_to = isomorphisms_to -TriangulationHP.isomorphisms_to = isomorphisms_to +TriangulationMixIn.isomorphisms_to = isomorphisms_to from . import snap -snap.add_methods(Manifold) -snap.add_methods(ManifoldHP) -snap.add_methods(Triangulation, hyperbolic=False) -snap.add_methods(TriangulationHP, hyperbolic=False) - -from . import exterior_to_link -Triangulation.exterior_to_link = exterior_to_link.exterior_to_link -TriangulationHP.exterior_to_link = exterior_to_link.exterior_to_link - -from . import verify -Manifold.verify_hyperbolicity = verify.verify_hyperbolicity -ManifoldHP.verify_hyperbolicity = verify.verify_hyperbolicity - -from . import margulis -Manifold.margulis = margulis.margulis -ManifoldHP.margulis = margulis.margulis - -from . import len_spec -Manifold.length_spectrum_alt_gen = len_spec.length_spectrum_alt_gen -ManifoldHP.length_spectrum_alt_gen = len_spec.length_spectrum_alt_gen -Manifold.length_spectrum_alt = len_spec.length_spectrum_alt -ManifoldHP.length_spectrum_alt = len_spec.length_spectrum_alt +snap.add_methods(ManifoldMixIn) +snap.add_methods(TriangulationMixIn, hyperbolic=False) from . import canonical Manifold.canonical_retriangulation = canonical.canonical_retriangulation ManifoldHP.canonical_retriangulation = canonical.canonical_retriangulation_hp -from . import isometry_signature - -Manifold.isometry_signature = isometry_signature.isometry_signature -ManifoldHP.isometry_signature = isometry_signature.isometry_signature - -from .cusps import cusp_area_matrix - -Manifold.cusp_area_matrix = cusp_area_matrix.cusp_area_matrix -ManifoldHP.cusp_area_matrix = cusp_area_matrix.cusp_area_matrix - -from . import cusps - -Manifold.cusp_areas = cusps.cusp_areas -ManifoldHP.cusp_areas = cusps.cusp_areas -Manifold.short_slopes = cusps.short_slopes -ManifoldHP.short_slopes = cusps.short_slopes -Manifold.cusp_translations = cusps.cusp_translations -ManifoldHP.cusp_translations = cusps.cusp_translations - def complex_volume(manifold, verified_modulo_2_torsion=False, bits_prec=None): """ @@ -349,12 +333,6 @@ def complex_volume(manifold, verified_modulo_2_torsion=False, drilling._add_methods(Manifold) drilling._add_methods(ManifoldHP, high_precision=True) -from . import raytracing - -Manifold.inside_view = raytracing.inside_view -ManifoldHP.inside_view = raytracing.inside_view - - def all_translations(self, verified=False, bits_prec=None): """ Returns the (complex) Euclidean translations of the meridian diff --git a/python/isometry_signature.py b/python/isometry_signature.py index 92c2e1d8..f3bfe9b3 100644 --- a/python/isometry_signature.py +++ b/python/isometry_signature.py @@ -1,4 +1,3 @@ -from . import Triangulation, TriangulationHP, ManifoldHP from . import verify from .sage_helper import _within_sage from .math_basics import is_RealIntervalFieldElement @@ -376,6 +375,7 @@ def drill_manifold_precisions( raise err def compute_meridian_slopes(isosig, tri): + from . import Triangulation isosig_tri = Triangulation(isosig, remove_finite_vertices=False) # Do not call isosig_tri.set_peripheral_curves('combinatorial') # here. From 83355079e78bc6ec76fcef427cca5268f54e581f Mon Sep 17 00:00:00 2001 From: Matthias Goerner <1239022+unhyperbolic@users.noreply.github.com> Date: Wed, 10 Sep 2025 22:03:27 -0700 Subject: [PATCH 3/3] Unrolling snap.add_methods --- python/__init__.py | 18 ++++++++++++++---- python/snap/__init__.py | 16 ---------------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/python/__init__.py b/python/__init__.py index 5b9987af..5f93cd55 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -36,9 +36,15 @@ from . cusps import cusp_area_matrix from . import raytracing from . import isometry_signature +from . import snap +from .snap import nsagetools, slice_obs_HKL, fox_milnor class TriangulationMixIn: exterior_to_link = exterior_to_link.exterior_to_link + alexander_polynomial = nsagetools.alexander_polynomial + homological_longitude = nsagetools.homological_longitude + slice_obstruction_HKL = slice_obs_HKL.slice_obstruction_HKL + fox_milnor_test = fox_milnor.fox_milnor_test class ManifoldMixIn: verify_hyperbolicity = verify.verify_hyperbolicity @@ -51,6 +57,14 @@ class ManifoldMixIn: short_slopes = cusps.short_slopes cusp_translations = cusps.cusp_translations inside_view = raytracing.inside_view + polished_holonomy = snap.polished_holonomy + tetrahedra_field_gens = snap.tetrahedra_field_gens + trace_field_gens = snap.trace_field_gens + invariant_trace_field_gens = snap.invariant_trace_field_gens + holonomy_matrix_entries = snap.holonomy_matrix_entries + hyperbolic_torsion = nsagetools.hyperbolic_torsion + hyperbolic_adjoint_torsion = nsagetools.hyperbolic_adjoint_torsion + hyperbolic_SLN_torsion = nsagetools.hyperbolic_SLN_torsion # Subclass to be able to monkey-patch class Triangulation(SnapPy.Triangulation, TriangulationMixIn): @@ -260,10 +274,6 @@ def isomorphisms_to(self, isomorphisms_to.__doc__ = SnapPy.Triangulation._isomorphisms_to.__doc__ TriangulationMixIn.isomorphisms_to = isomorphisms_to -from . import snap -snap.add_methods(ManifoldMixIn) -snap.add_methods(TriangulationMixIn, hyperbolic=False) - from . import canonical Manifold.canonical_retriangulation = canonical.canonical_retriangulation ManifoldHP.canonical_retriangulation = canonical.canonical_retriangulation_hp diff --git a/python/snap/__init__.py b/python/snap/__init__.py index 6eb74d49..f03bacd9 100644 --- a/python/snap/__init__.py +++ b/python/snap/__init__.py @@ -99,19 +99,3 @@ def func(prec): match_kernel=match_kernel) return sum( [G.SL2C(g).list() for g in G.generators()], []) return ListOfApproximateAlgebraicNumbers(func) - - -def add_methods(mfld_class, hyperbolic=True): - mfld_class.alexander_polynomial = nsagetools.alexander_polynomial - mfld_class.homological_longitude = nsagetools.homological_longitude - mfld_class.slice_obstruction_HKL = slice_obs_HKL.slice_obstruction_HKL - mfld_class.fox_milnor_test = fox_milnor.fox_milnor_test - if hyperbolic: - mfld_class.polished_holonomy = polished_holonomy - mfld_class.tetrahedra_field_gens = tetrahedra_field_gens - mfld_class.trace_field_gens = trace_field_gens - mfld_class.invariant_trace_field_gens = invariant_trace_field_gens - mfld_class.holonomy_matrix_entries = holonomy_matrix_entries - mfld_class.hyperbolic_torsion = nsagetools.hyperbolic_torsion - mfld_class.hyperbolic_adjoint_torsion = nsagetools.hyperbolic_adjoint_torsion - mfld_class.hyperbolic_SLN_torsion = nsagetools.hyperbolic_SLN_torsion