snappy 3.3__cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- snappy/CyOpenGL.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/SnapPy.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/SnapPy.ico +0 -0
- snappy/SnapPy.png +0 -0
- snappy/SnapPyHP.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/__init__.py +534 -0
- snappy/app.py +604 -0
- snappy/app_menus.py +372 -0
- snappy/browser.py +998 -0
- snappy/cache.py +25 -0
- snappy/canonical.py +249 -0
- snappy/cusps/__init__.py +280 -0
- snappy/cusps/cusp_area_matrix.py +98 -0
- snappy/cusps/cusp_areas_from_matrix.py +96 -0
- snappy/cusps/maximal_cusp_area_matrix.py +136 -0
- snappy/cusps/short_slopes_for_cusp.py +217 -0
- snappy/cusps/test.py +22 -0
- snappy/cusps/trig_cusp_area_matrix.py +63 -0
- snappy/database.py +454 -0
- snappy/db_utilities.py +79 -0
- snappy/decorated_isosig.py +717 -0
- snappy/dev/__init__.py +0 -0
- snappy/dev/extended_ptolemy/__init__.py +8 -0
- snappy/dev/extended_ptolemy/closed.py +106 -0
- snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
- snappy/dev/extended_ptolemy/direct.py +42 -0
- snappy/dev/extended_ptolemy/extended.py +406 -0
- snappy/dev/extended_ptolemy/giac_helper.py +43 -0
- snappy/dev/extended_ptolemy/giac_rur.py +129 -0
- snappy/dev/extended_ptolemy/gluing.py +46 -0
- snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
- snappy/dev/extended_ptolemy/printMatrices.py +70 -0
- snappy/dev/vericlosed/__init__.py +1 -0
- snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
- snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
- snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
- snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
- snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
- snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
- snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
- snappy/dev/vericlosed/orb/__init__.py +1 -0
- snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
- snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
- snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
- snappy/dev/vericlosed/test.py +54 -0
- snappy/dev/vericlosed/truncatedComplex.py +176 -0
- snappy/dev/vericlosed/verificationError.py +58 -0
- snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
- snappy/doc/_images/SnapPy-196.png +0 -0
- snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
- snappy/doc/_images/m125_paper_plane.jpg +0 -0
- snappy/doc/_images/mac.png +0 -0
- snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
- snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
- snappy/doc/_images/plink-action.png +0 -0
- snappy/doc/_images/ubuntu.png +0 -0
- snappy/doc/_images/win7.png +0 -0
- snappy/doc/_sources/additional_classes.rst.txt +40 -0
- snappy/doc/_sources/bugs.rst.txt +14 -0
- snappy/doc/_sources/censuses.rst.txt +52 -0
- snappy/doc/_sources/credits.rst.txt +81 -0
- snappy/doc/_sources/development.rst.txt +261 -0
- snappy/doc/_sources/index.rst.txt +215 -0
- snappy/doc/_sources/installing.rst.txt +249 -0
- snappy/doc/_sources/manifold.rst.txt +6 -0
- snappy/doc/_sources/manifoldhp.rst.txt +46 -0
- snappy/doc/_sources/news.rst.txt +425 -0
- snappy/doc/_sources/other.rst.txt +25 -0
- snappy/doc/_sources/platonic_census.rst.txt +20 -0
- snappy/doc/_sources/plink.rst.txt +102 -0
- snappy/doc/_sources/ptolemy.rst.txt +66 -0
- snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
- snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
- snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
- snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
- snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
- snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
- snappy/doc/_sources/screenshots.rst.txt +21 -0
- snappy/doc/_sources/snap.rst.txt +87 -0
- snappy/doc/_sources/snappy.rst.txt +28 -0
- snappy/doc/_sources/spherogram.rst.txt +103 -0
- snappy/doc/_sources/todo.rst.txt +47 -0
- snappy/doc/_sources/triangulation.rst.txt +11 -0
- snappy/doc/_sources/tutorial.rst.txt +49 -0
- snappy/doc/_sources/verify.rst.txt +210 -0
- snappy/doc/_sources/verify_internals.rst.txt +79 -0
- snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
- snappy/doc/_static/SnapPy.ico +0 -0
- snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
- snappy/doc/_static/basic.css +906 -0
- snappy/doc/_static/css/badge_only.css +1 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
- snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
- snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
- snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
- snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
- snappy/doc/_static/css/theme.css +4 -0
- snappy/doc/_static/doctools.js +149 -0
- snappy/doc/_static/documentation_options.js +13 -0
- snappy/doc/_static/file.png +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
- snappy/doc/_static/jquery.js +2 -0
- snappy/doc/_static/js/badge_only.js +1 -0
- snappy/doc/_static/js/theme.js +1 -0
- snappy/doc/_static/js/versions.js +228 -0
- snappy/doc/_static/language_data.js +192 -0
- snappy/doc/_static/minus.png +0 -0
- snappy/doc/_static/plus.png +0 -0
- snappy/doc/_static/pygments.css +75 -0
- snappy/doc/_static/searchtools.js +635 -0
- snappy/doc/_static/snappy_furo.css +33 -0
- snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
- snappy/doc/_static/sphinx_highlight.js +154 -0
- snappy/doc/additional_classes.html +1500 -0
- snappy/doc/bugs.html +132 -0
- snappy/doc/censuses.html +453 -0
- snappy/doc/credits.html +184 -0
- snappy/doc/development.html +385 -0
- snappy/doc/doc-latest/additional_classes.html +1500 -0
- snappy/doc/doc-latest/bugs.html +132 -0
- snappy/doc/doc-latest/censuses.html +453 -0
- snappy/doc/doc-latest/credits.html +184 -0
- snappy/doc/doc-latest/development.html +385 -0
- snappy/doc/doc-latest/genindex.html +1349 -0
- snappy/doc/doc-latest/index.html +287 -0
- snappy/doc/doc-latest/installing.html +346 -0
- snappy/doc/doc-latest/manifold.html +3632 -0
- snappy/doc/doc-latest/manifoldhp.html +180 -0
- snappy/doc/doc-latest/news.html +438 -0
- snappy/doc/doc-latest/objects.inv +0 -0
- snappy/doc/doc-latest/other.html +160 -0
- snappy/doc/doc-latest/platonic_census.html +376 -0
- snappy/doc/doc-latest/plink.html +210 -0
- snappy/doc/doc-latest/ptolemy.html +253 -0
- snappy/doc/doc-latest/ptolemy_classes.html +1144 -0
- snappy/doc/doc-latest/ptolemy_examples1.html +409 -0
- snappy/doc/doc-latest/ptolemy_examples2.html +471 -0
- snappy/doc/doc-latest/ptolemy_examples3.html +414 -0
- snappy/doc/doc-latest/ptolemy_examples4.html +195 -0
- snappy/doc/doc-latest/ptolemy_prelim.html +248 -0
- snappy/doc/doc-latest/py-modindex.html +165 -0
- snappy/doc/doc-latest/screenshots.html +141 -0
- snappy/doc/doc-latest/search.html +135 -0
- snappy/doc/doc-latest/searchindex.js +1 -0
- snappy/doc/doc-latest/snap.html +202 -0
- snappy/doc/doc-latest/snappy.html +181 -0
- snappy/doc/doc-latest/spherogram.html +1346 -0
- snappy/doc/doc-latest/todo.html +166 -0
- snappy/doc/doc-latest/triangulation.html +1676 -0
- snappy/doc/doc-latest/tutorial.html +159 -0
- snappy/doc/doc-latest/verify.html +330 -0
- snappy/doc/doc-latest/verify_internals.html +1235 -0
- snappy/doc/genindex.html +1349 -0
- snappy/doc/index.html +287 -0
- snappy/doc/installing.html +346 -0
- snappy/doc/manifold.html +3632 -0
- snappy/doc/manifoldhp.html +180 -0
- snappy/doc/news.html +438 -0
- snappy/doc/objects.inv +0 -0
- snappy/doc/other.html +160 -0
- snappy/doc/platonic_census.html +376 -0
- snappy/doc/plink.html +210 -0
- snappy/doc/ptolemy.html +253 -0
- snappy/doc/ptolemy_classes.html +1144 -0
- snappy/doc/ptolemy_examples1.html +409 -0
- snappy/doc/ptolemy_examples2.html +471 -0
- snappy/doc/ptolemy_examples3.html +414 -0
- snappy/doc/ptolemy_examples4.html +195 -0
- snappy/doc/ptolemy_prelim.html +248 -0
- snappy/doc/py-modindex.html +165 -0
- snappy/doc/screenshots.html +141 -0
- snappy/doc/search.html +135 -0
- snappy/doc/searchindex.js +1 -0
- snappy/doc/snap.html +202 -0
- snappy/doc/snappy.html +181 -0
- snappy/doc/spherogram.html +1346 -0
- snappy/doc/todo.html +166 -0
- snappy/doc/triangulation.html +1676 -0
- snappy/doc/tutorial.html +159 -0
- snappy/doc/verify.html +330 -0
- snappy/doc/verify_internals.html +1235 -0
- snappy/drilling/__init__.py +456 -0
- snappy/drilling/barycentric.py +103 -0
- snappy/drilling/constants.py +5 -0
- snappy/drilling/crush.py +270 -0
- snappy/drilling/cusps.py +125 -0
- snappy/drilling/debug.py +242 -0
- snappy/drilling/epsilons.py +6 -0
- snappy/drilling/exceptions.py +55 -0
- snappy/drilling/moves.py +620 -0
- snappy/drilling/peripheral_curves.py +210 -0
- snappy/drilling/perturb.py +188 -0
- snappy/drilling/shorten.py +36 -0
- snappy/drilling/subdivide.py +274 -0
- snappy/drilling/test.py +23 -0
- snappy/drilling/test_cases.py +132 -0
- snappy/drilling/tracing.py +351 -0
- snappy/exceptions.py +26 -0
- snappy/export_stl.py +120 -0
- snappy/exterior_to_link/__init__.py +2 -0
- snappy/exterior_to_link/barycentric_geometry.py +463 -0
- snappy/exterior_to_link/exceptions.py +6 -0
- snappy/exterior_to_link/geodesic_map.json +14408 -0
- snappy/exterior_to_link/hyp_utils.py +112 -0
- snappy/exterior_to_link/link_projection.py +323 -0
- snappy/exterior_to_link/main.py +198 -0
- snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
- snappy/exterior_to_link/mcomplex_with_link.py +687 -0
- snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
- snappy/exterior_to_link/pl_utils.py +491 -0
- snappy/exterior_to_link/put_in_S3.py +156 -0
- snappy/exterior_to_link/rational_linear_algebra.py +130 -0
- snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
- snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
- snappy/exterior_to_link/stored_moves.py +475 -0
- snappy/exterior_to_link/test.py +31 -0
- snappy/filedialog.py +28 -0
- snappy/geometric_structure/__init__.py +212 -0
- snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
- snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +691 -0
- snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +480 -0
- snappy/geometric_structure/cusp_neighborhood/exceptions.py +41 -0
- snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +294 -0
- snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +156 -0
- snappy/geometric_structure/cusp_neighborhood/vertices.py +35 -0
- snappy/geometric_structure/geodesic/__init__.py +0 -0
- snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
- snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
- snappy/geometric_structure/geodesic/canonical_representatives.py +52 -0
- snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
- snappy/geometric_structure/geodesic/constants.py +6 -0
- snappy/geometric_structure/geodesic/exceptions.py +22 -0
- snappy/geometric_structure/geodesic/fixed_points.py +106 -0
- snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
- snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
- snappy/geometric_structure/geodesic/line.py +30 -0
- snappy/geometric_structure/geodesic/multiplicity.py +127 -0
- snappy/geometric_structure/geodesic/tiles_for_geodesic.py +128 -0
- snappy/geometric_structure/test.py +22 -0
- snappy/gui.py +121 -0
- snappy/horoviewer.py +443 -0
- snappy/hyperboloid/__init__.py +212 -0
- snappy/hyperboloid/distances.py +259 -0
- snappy/hyperboloid/horoball.py +19 -0
- snappy/hyperboloid/line.py +35 -0
- snappy/hyperboloid/point.py +9 -0
- snappy/hyperboloid/triangle.py +29 -0
- snappy/info_icon.gif +0 -0
- snappy/infowindow.py +65 -0
- snappy/isometry_signature.py +389 -0
- snappy/len_spec/__init__.py +609 -0
- snappy/len_spec/geodesic_info.py +129 -0
- snappy/len_spec/geodesic_key_info_dict.py +116 -0
- snappy/len_spec/geodesic_piece.py +146 -0
- snappy/len_spec/geometric_structure.py +182 -0
- snappy/len_spec/geometry.py +136 -0
- snappy/len_spec/length_spectrum_geodesic_info.py +185 -0
- snappy/len_spec/spine.py +128 -0
- snappy/len_spec/test.py +24 -0
- snappy/len_spec/test_cases.py +69 -0
- snappy/len_spec/tile.py +276 -0
- snappy/len_spec/word.py +86 -0
- snappy/manifolds/HTWKnots/alternating.gz +0 -0
- snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
- snappy/manifolds/__init__.py +3 -0
- snappy/margulis/__init__.py +332 -0
- snappy/margulis/cusp_neighborhood_neighborhood.py +66 -0
- snappy/margulis/geodesic_neighborhood.py +152 -0
- snappy/margulis/margulis_info.py +21 -0
- snappy/margulis/mu_from_neighborhood_pair.py +175 -0
- snappy/margulis/neighborhood.py +29 -0
- snappy/margulis/test.py +22 -0
- snappy/math_basics.py +187 -0
- snappy/matrix.py +525 -0
- snappy/number.py +657 -0
- snappy/numeric_output_checker.py +345 -0
- snappy/pari.py +41 -0
- snappy/phone_home.py +57 -0
- snappy/polyviewer.py +259 -0
- snappy/ptolemy/__init__.py +17 -0
- snappy/ptolemy/component.py +103 -0
- snappy/ptolemy/coordinates.py +2290 -0
- snappy/ptolemy/fieldExtensions.py +153 -0
- snappy/ptolemy/findLoops.py +473 -0
- snappy/ptolemy/geometricRep.py +59 -0
- snappy/ptolemy/homology.py +165 -0
- snappy/ptolemy/magma/default.magma_template +229 -0
- snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
- snappy/ptolemy/manifoldMethods.py +395 -0
- snappy/ptolemy/matrix.py +350 -0
- snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
- snappy/ptolemy/polynomial.py +856 -0
- snappy/ptolemy/processComponents.py +173 -0
- snappy/ptolemy/processFileBase.py +247 -0
- snappy/ptolemy/processFileDispatch.py +46 -0
- snappy/ptolemy/processMagmaFile.py +392 -0
- snappy/ptolemy/processRurFile.py +150 -0
- snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
- snappy/ptolemy/ptolemyObstructionClass.py +64 -0
- snappy/ptolemy/ptolemyVariety.py +995 -0
- snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
- snappy/ptolemy/reginaWrapper.py +698 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/rur.py +545 -0
- snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
- snappy/ptolemy/test.py +1126 -0
- snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
- snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
- snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
- snappy/ptolemy/utilities.py +236 -0
- snappy/raytracing/__init__.py +64 -0
- snappy/raytracing/additional_horospheres.py +64 -0
- snappy/raytracing/additional_len_spec_choices.py +63 -0
- snappy/raytracing/cohomology_fractal.py +197 -0
- snappy/raytracing/eyeball.py +124 -0
- snappy/raytracing/finite_raytracing_data.py +237 -0
- snappy/raytracing/finite_viewer.py +590 -0
- snappy/raytracing/geodesic_tube_info.py +174 -0
- snappy/raytracing/geodesics.py +246 -0
- snappy/raytracing/geodesics_window.py +258 -0
- snappy/raytracing/gui_utilities.py +293 -0
- snappy/raytracing/hyperboloid_navigation.py +556 -0
- snappy/raytracing/hyperboloid_utilities.py +234 -0
- snappy/raytracing/ideal_raytracing_data.py +592 -0
- snappy/raytracing/inside_viewer.py +974 -0
- snappy/raytracing/pack.py +22 -0
- snappy/raytracing/raytracing_data.py +126 -0
- snappy/raytracing/raytracing_view.py +454 -0
- snappy/raytracing/shaders/Eye.png +0 -0
- snappy/raytracing/shaders/NonGeometric.png +0 -0
- snappy/raytracing/shaders/__init__.py +101 -0
- snappy/raytracing/shaders/fragment.glsl +1744 -0
- snappy/raytracing/test.py +29 -0
- snappy/raytracing/tooltip.py +146 -0
- snappy/raytracing/upper_halfspace_utilities.py +98 -0
- snappy/raytracing/view_scale_controller.py +98 -0
- snappy/raytracing/zoom_slider/__init__.py +263 -0
- snappy/raytracing/zoom_slider/inward.png +0 -0
- snappy/raytracing/zoom_slider/inward18.png +0 -0
- snappy/raytracing/zoom_slider/outward.png +0 -0
- snappy/raytracing/zoom_slider/outward18.png +0 -0
- snappy/raytracing/zoom_slider/test.py +20 -0
- snappy/sage_helper.py +119 -0
- snappy/settings.py +407 -0
- snappy/shell.py +53 -0
- snappy/snap/__init__.py +117 -0
- snappy/snap/character_varieties.py +375 -0
- snappy/snap/find_field.py +372 -0
- snappy/snap/fox_milnor.py +271 -0
- snappy/snap/fundamental_polyhedron.py +569 -0
- snappy/snap/generators.py +39 -0
- snappy/snap/interval_reps.py +81 -0
- snappy/snap/kernel_structures.py +128 -0
- snappy/snap/mcomplex_base.py +18 -0
- snappy/snap/nsagetools.py +716 -0
- snappy/snap/peripheral/__init__.py +1 -0
- snappy/snap/peripheral/dual_cellulation.py +219 -0
- snappy/snap/peripheral/link.py +127 -0
- snappy/snap/peripheral/peripheral.py +159 -0
- snappy/snap/peripheral/surface.py +522 -0
- snappy/snap/peripheral/test.py +35 -0
- snappy/snap/polished_reps.py +335 -0
- snappy/snap/shapes.py +152 -0
- snappy/snap/slice_obs_HKL/__init__.py +194 -0
- snappy/snap/slice_obs_HKL/basics.py +236 -0
- snappy/snap/slice_obs_HKL/direct.py +217 -0
- snappy/snap/slice_obs_HKL/poly_norm.py +212 -0
- snappy/snap/slice_obs_HKL/rep_theory.py +424 -0
- snappy/snap/t3mlite/__init__.py +2 -0
- snappy/snap/t3mlite/arrow.py +243 -0
- snappy/snap/t3mlite/corner.py +22 -0
- snappy/snap/t3mlite/edge.py +172 -0
- snappy/snap/t3mlite/face.py +37 -0
- snappy/snap/t3mlite/files.py +211 -0
- snappy/snap/t3mlite/homology.py +53 -0
- snappy/snap/t3mlite/linalg.py +419 -0
- snappy/snap/t3mlite/mcomplex.py +1499 -0
- snappy/snap/t3mlite/perm4.py +320 -0
- snappy/snap/t3mlite/setup.py +12 -0
- snappy/snap/t3mlite/simplex.py +199 -0
- snappy/snap/t3mlite/spun.py +297 -0
- snappy/snap/t3mlite/surface.py +519 -0
- snappy/snap/t3mlite/test.py +20 -0
- snappy/snap/t3mlite/test_vs_regina.py +86 -0
- snappy/snap/t3mlite/tetrahedron.py +109 -0
- snappy/snap/t3mlite/vertex.py +42 -0
- snappy/snap/test.py +139 -0
- snappy/snap/utilities.py +288 -0
- snappy/test.py +213 -0
- snappy/test_cases.py +263 -0
- snappy/testing.py +131 -0
- snappy/tiling/__init__.py +2 -0
- snappy/tiling/dict_based_set.py +79 -0
- snappy/tiling/floor.py +49 -0
- snappy/tiling/hyperboloid_dict.py +54 -0
- snappy/tiling/iter_utils.py +78 -0
- snappy/tiling/lifted_tetrahedron.py +22 -0
- snappy/tiling/lifted_tetrahedron_set.py +54 -0
- snappy/tiling/quotient_dict.py +70 -0
- snappy/tiling/real_hash_dict.py +164 -0
- snappy/tiling/test.py +23 -0
- snappy/tiling/tile.py +224 -0
- snappy/tiling/triangle.py +33 -0
- snappy/tkterminal.py +920 -0
- snappy/twister/__init__.py +20 -0
- snappy/twister/main.py +646 -0
- snappy/twister/surfaces/S_0_1 +3 -0
- snappy/twister/surfaces/S_0_2 +3 -0
- snappy/twister/surfaces/S_0_4 +7 -0
- snappy/twister/surfaces/S_0_4_Lantern +8 -0
- snappy/twister/surfaces/S_1 +3 -0
- snappy/twister/surfaces/S_1_1 +4 -0
- snappy/twister/surfaces/S_1_2 +5 -0
- snappy/twister/surfaces/S_1_2_5 +6 -0
- snappy/twister/surfaces/S_2 +6 -0
- snappy/twister/surfaces/S_2_1 +8 -0
- snappy/twister/surfaces/S_2_heeg +10 -0
- snappy/twister/surfaces/S_3 +8 -0
- snappy/twister/surfaces/S_3_1 +10 -0
- snappy/twister/surfaces/S_4_1 +12 -0
- snappy/twister/surfaces/S_5_1 +14 -0
- snappy/twister/surfaces/heeg_fig8 +9 -0
- snappy/twister/twister_core.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/upper_halfspace/__init__.py +146 -0
- snappy/upper_halfspace/ideal_point.py +29 -0
- snappy/verify/__init__.py +13 -0
- snappy/verify/canonical.py +542 -0
- snappy/verify/complex_volume/__init__.py +18 -0
- snappy/verify/complex_volume/adjust_torsion.py +86 -0
- snappy/verify/complex_volume/closed.py +168 -0
- snappy/verify/complex_volume/compute_ptolemys.py +90 -0
- snappy/verify/complex_volume/cusped.py +56 -0
- snappy/verify/complex_volume/extended_bloch.py +201 -0
- snappy/verify/cusp_translations.py +85 -0
- snappy/verify/edge_equations.py +80 -0
- snappy/verify/exceptions.py +254 -0
- snappy/verify/hyperbolicity.py +224 -0
- snappy/verify/interval_newton_shapes_engine.py +523 -0
- snappy/verify/interval_tree.py +400 -0
- snappy/verify/krawczyk_shapes_engine.py +518 -0
- snappy/verify/real_algebra.py +286 -0
- snappy/verify/shapes.py +25 -0
- snappy/verify/square_extensions.py +1005 -0
- snappy/verify/test.py +72 -0
- snappy/verify/volume.py +128 -0
- snappy/version.py +2 -0
- snappy-3.3.dist-info/METADATA +58 -0
- snappy-3.3.dist-info/RECORD +541 -0
- snappy-3.3.dist-info/WHEEL +6 -0
- snappy-3.3.dist-info/entry_points.txt +2 -0
- snappy-3.3.dist-info/top_level.txt +28 -0
|
@@ -0,0 +1,698 @@
|
|
|
1
|
+
__all__ = [ 'NTriangulationForPtolemy' ]
|
|
2
|
+
|
|
3
|
+
from regina import NTriangulation, writeXMLFile, readXMLFile
|
|
4
|
+
|
|
5
|
+
import tempfile
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
from . import manifoldMethods
|
|
9
|
+
from . import utilities
|
|
10
|
+
|
|
11
|
+
# This file is mostly reimplementing the functions in
|
|
12
|
+
# addl_code/ptolemy_equations.c for regina triangulations.
|
|
13
|
+
|
|
14
|
+
# See addl_code/ptolemy_equations.c for more comments.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class NTriangulationForPtolemy(NTriangulation):
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
A wrapper of a regina NTriangulation that can be used for
|
|
21
|
+
the ptolemy module.
|
|
22
|
+
|
|
23
|
+
Create a regina triangulation
|
|
24
|
+
|
|
25
|
+
>>> from regina import NExampleTriangulation
|
|
26
|
+
>>> T = NExampleTriangulation.figureEightKnotComplement()
|
|
27
|
+
|
|
28
|
+
Wrap it for the ptolemy module
|
|
29
|
+
|
|
30
|
+
>>> N = NTriangulationForPtolemy(T)
|
|
31
|
+
|
|
32
|
+
Use it like a snappy triangulation to use ptolemy:
|
|
33
|
+
|
|
34
|
+
>>> N.ptolemy_variety(2,'all')
|
|
35
|
+
[Ptolemy Variety for Figure eight knot complement, N = 2, obstruction_class = 0, Ptolemy Variety for Figure eight knot complement, N = 2, obstruction_class = 1]
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, *args, **kwargs):
|
|
40
|
+
"""
|
|
41
|
+
Constructor - takes same arguments as NTriangulation.
|
|
42
|
+
"""
|
|
43
|
+
super().__init__(*args, **kwargs)
|
|
44
|
+
|
|
45
|
+
# Make sure we are oriented
|
|
46
|
+
if not self.isOriented():
|
|
47
|
+
raise Exception("Only oriented triangulations are supported."
|
|
48
|
+
"Use orient method.")
|
|
49
|
+
|
|
50
|
+
# Copy the packet label
|
|
51
|
+
|
|
52
|
+
if args and isinstance(args[0], NTriangulation):
|
|
53
|
+
self.setPacketLabel(args[0].getPacketLabel())
|
|
54
|
+
|
|
55
|
+
def copy(self):
|
|
56
|
+
return NTriangulationForPtolemy(self)
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def from_xml(text):
|
|
60
|
+
"""
|
|
61
|
+
Construct the triangulation from a regina file.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
# Create temporary file and write text to it
|
|
65
|
+
f = tempfile.NamedTemporaryFile(delete=False)
|
|
66
|
+
filename = f.name
|
|
67
|
+
f.write(text)
|
|
68
|
+
f.close()
|
|
69
|
+
|
|
70
|
+
# Read triangulation from it
|
|
71
|
+
T = readXMLFile(filename)
|
|
72
|
+
|
|
73
|
+
if not isinstance(T, NTriangulation):
|
|
74
|
+
raise Exception("Not a regina triangulation")
|
|
75
|
+
|
|
76
|
+
if T.getNumberOfTetrahedra() == 0:
|
|
77
|
+
raise Exception("Regina triangulation empty")
|
|
78
|
+
|
|
79
|
+
# Delete it
|
|
80
|
+
os.unlink(filename)
|
|
81
|
+
|
|
82
|
+
return NTriangulationForPtolemy(T)
|
|
83
|
+
|
|
84
|
+
def ptolemy_obstruction_classes(self):
|
|
85
|
+
"""
|
|
86
|
+
Returns the obstruction classes needed to compute the
|
|
87
|
+
boundary-unipotent pSL(N,C) = SL(N,C) / {+1, -1} representations for
|
|
88
|
+
even N.
|
|
89
|
+
This is a list of a representative cocycle for class in
|
|
90
|
+
H^2(M, boundary M; Z/2). The first element in the list is always
|
|
91
|
+
representing the trivial obstruction class.
|
|
92
|
+
|
|
93
|
+
For example, the figure eight knot complement has two obstruction
|
|
94
|
+
classes:
|
|
95
|
+
|
|
96
|
+
>>> from regina import NExampleTriangulation
|
|
97
|
+
>>> N = NTriangulationForPtolemy(NExampleTriangulation.figureEightKnotComplement())
|
|
98
|
+
>>> c = N.ptolemy_obstruction_classes()
|
|
99
|
+
>>> len(c)
|
|
100
|
+
2
|
|
101
|
+
|
|
102
|
+
See help(Manifold.ptolemy_obstruction_classes()) for more.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
return manifoldMethods.get_ptolemy_obstruction_classes(self)
|
|
106
|
+
|
|
107
|
+
def ptolemy_generalized_obstruction_classes(self, N):
|
|
108
|
+
"""
|
|
109
|
+
Return the obstruction classes needed to compute
|
|
110
|
+
PGL(N,C)-representations for any N.
|
|
111
|
+
|
|
112
|
+
It returns a list with
|
|
113
|
+
a representative cocycle for each element in
|
|
114
|
+
``H^2(M, boundary M; Z/N) / (Z/N)^*``
|
|
115
|
+
where ``(Z/N)^*`` are the units in Z/N.
|
|
116
|
+
The first element in the list always corresponds to the trivial
|
|
117
|
+
obstruction class.
|
|
118
|
+
The generalized ptolemy obstruction classes are thus a generalization
|
|
119
|
+
of the ptolemy obstruction classes that allow to find all
|
|
120
|
+
boundary-unipotent
|
|
121
|
+
PGL(N,C)-representations including those that do not lift to
|
|
122
|
+
boundary-unipotent SL(N,C)-representations for N odd or
|
|
123
|
+
SL(N,C)/{+1,-1}-representations for N even.
|
|
124
|
+
|
|
125
|
+
For example, the figure eight not complement has three obstruction
|
|
126
|
+
classes for N = 4 up to equivalence:
|
|
127
|
+
|
|
128
|
+
>>> from regina import NExampleTriangulation
|
|
129
|
+
>>> N = NTriangulationForPtolemy(NExampleTriangulation.figureEightKnotComplement())
|
|
130
|
+
>>> c = N.ptolemy_generalized_obstruction_classes(4)
|
|
131
|
+
>>> len(c)
|
|
132
|
+
3
|
|
133
|
+
|
|
134
|
+
See help(Manifold.ptolemy_generalized_obstruction_classes()) for more.
|
|
135
|
+
"""
|
|
136
|
+
return (
|
|
137
|
+
manifoldMethods.get_generalized_ptolemy_obstruction_classes(
|
|
138
|
+
self, N))
|
|
139
|
+
|
|
140
|
+
def ptolemy_variety(self, N, obstruction_class=None,
|
|
141
|
+
simplify=True, eliminate_fixed_ptolemys=False):
|
|
142
|
+
"""
|
|
143
|
+
M.ptolemy_variety(N, obstruction_class = None, simplify = True, eliminate_fixed_ptolemys = False)
|
|
144
|
+
|
|
145
|
+
Returns a Ptolemy variety as described in
|
|
146
|
+
|
|
147
|
+
* Stavros Garoufalidis, Dyland Thurston, Christian K. Zickert:
|
|
148
|
+
"The Complex Volume of SL(n,C)-Representations of 3-Manifolds"
|
|
149
|
+
(https://arxiv.org/abs/1111.2828)
|
|
150
|
+
* Stavros Garoufalidis, Matthias Goerner, Christian K. Zickert:
|
|
151
|
+
"Gluing Equations for PGL(n,C)-Representations of 3-Manifolds "
|
|
152
|
+
(https://arxiv.org/abs/1207.6711)
|
|
153
|
+
|
|
154
|
+
The variety can be exported to magma or sage and solved there. The
|
|
155
|
+
solutions can be processed to compute invariants.
|
|
156
|
+
|
|
157
|
+
For example, the figure eight knot complement has two Ptolemy
|
|
158
|
+
varieties for N = 2, one for the representations lifting to SL(2,C)
|
|
159
|
+
and one for the ones that don't:
|
|
160
|
+
|
|
161
|
+
>>> from regina import NExampleTriangulation
|
|
162
|
+
>>> N = NTriangulationForPtolemy(NExampleTriangulation.figureEightKnotComplement())
|
|
163
|
+
>>> c = N.ptolemy_variety(2, 'all')
|
|
164
|
+
>>> len(c)
|
|
165
|
+
2
|
|
166
|
+
|
|
167
|
+
See help(Manifold.ptolemy_variety) for more information
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
return manifoldMethods.get_ptolemy_variety(
|
|
171
|
+
self, N, obstruction_class,
|
|
172
|
+
simplify=simplify,
|
|
173
|
+
eliminate_fixed_ptolemys=eliminate_fixed_ptolemys)
|
|
174
|
+
|
|
175
|
+
def name(self):
|
|
176
|
+
"""
|
|
177
|
+
Returns the packet label for this regina triangulation.
|
|
178
|
+
|
|
179
|
+
>>> from regina import NExampleTriangulation
|
|
180
|
+
>>> N = NTriangulationForPtolemy(NExampleTriangulation.figureEightKnotComplement())
|
|
181
|
+
|
|
182
|
+
>>> N.name()
|
|
183
|
+
'Figure eight knot complement'
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
return self.getPacketLabel()
|
|
187
|
+
|
|
188
|
+
def num_tetrahedra(self):
|
|
189
|
+
"""
|
|
190
|
+
Returns the number of tetrahedra
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
return self.getNumberOfTetrahedra()
|
|
194
|
+
|
|
195
|
+
def _to_string(self):
|
|
196
|
+
"""
|
|
197
|
+
Returns the XML code for the regina package containing
|
|
198
|
+
this triangulation.
|
|
199
|
+
"""
|
|
200
|
+
# Create temporary file and close it immediately
|
|
201
|
+
f = tempfile.NamedTemporaryFile(delete=False)
|
|
202
|
+
filename = f.name
|
|
203
|
+
f.close()
|
|
204
|
+
|
|
205
|
+
# Write XML representation to it
|
|
206
|
+
writeXMLFile(filename, self, False) # not compressed
|
|
207
|
+
|
|
208
|
+
# Read the file content
|
|
209
|
+
f = open(filename, 'rb')
|
|
210
|
+
s = f.read()
|
|
211
|
+
f.close()
|
|
212
|
+
|
|
213
|
+
# Delete it
|
|
214
|
+
os.unlink(filename)
|
|
215
|
+
|
|
216
|
+
return s
|
|
217
|
+
|
|
218
|
+
def _index_of_tetrahedron_face(self, tetrahedron, face):
|
|
219
|
+
r"""
|
|
220
|
+
Helper for computing the homology. We call a generator
|
|
221
|
+
of the simplicial chain C_2(M, \partial M) a face class.
|
|
222
|
+
There are 2 * #tetrahedra faces classes and we need to
|
|
223
|
+
index them and find a representative for each.
|
|
224
|
+
A representative is a pair of (tetrahedron, face).
|
|
225
|
+
|
|
226
|
+
This method returns the index of the face class given
|
|
227
|
+
a representative.
|
|
228
|
+
regina already gives indices to the triangles, so we can
|
|
229
|
+
use that here.
|
|
230
|
+
|
|
231
|
+
In addl_code/ptolemy_equations.c, this was done in
|
|
232
|
+
_fill_tet_face_to_index_data .
|
|
233
|
+
"""
|
|
234
|
+
return self.triangleIndex(tetrahedron.getTriangle(face))
|
|
235
|
+
|
|
236
|
+
@staticmethod
|
|
237
|
+
def _sign_of_tetrahedron_face(tetrahedron, face):
|
|
238
|
+
"""
|
|
239
|
+
Recall the comments from _index_of_tetrahedron_face
|
|
240
|
+
|
|
241
|
+
A regina triangle has two embeddings and thus yields
|
|
242
|
+
two (tetrahedron, face) pairs representing a face class,
|
|
243
|
+
albeit with different signs.
|
|
244
|
+
We assume that the first embedding always represents the
|
|
245
|
+
+ face class and the second one - face class.
|
|
246
|
+
|
|
247
|
+
In addl_code/ptolemy_equations.c, this was done in
|
|
248
|
+
_fill_tet_face_to_index_data . There, the choice was made
|
|
249
|
+
that the pair (tetrahedron, face) with the lower tetrahedron
|
|
250
|
+
index (face index in case tie) represents + face class.
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
triangle = tetrahedron.getTriangle(face)
|
|
254
|
+
embedding = triangle.getEmbedding(0)
|
|
255
|
+
if (tetrahedron == embedding.getTetrahedron() and
|
|
256
|
+
embedding.getFace() == face):
|
|
257
|
+
return +1
|
|
258
|
+
else:
|
|
259
|
+
return -1
|
|
260
|
+
|
|
261
|
+
def _face_class_explanations(self):
|
|
262
|
+
"""
|
|
263
|
+
A list giving for all the face classes a string s_face_tetrahedron.
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
def process_triangle(triangle):
|
|
267
|
+
embedding = triangle.getEmbedding(0)
|
|
268
|
+
face = embedding.getFace()
|
|
269
|
+
tet = self.tetrahedronIndex(embedding.getTetrahedron())
|
|
270
|
+
return "s_%d_%d" % (face, tet)
|
|
271
|
+
|
|
272
|
+
return [ process_triangle(triangle)
|
|
273
|
+
for triangle in self.getTriangles() ]
|
|
274
|
+
|
|
275
|
+
def _ptolemy_equations_identified_face_classes(self):
|
|
276
|
+
"""
|
|
277
|
+
This is reimplementing get_ptolemy_equations_identified_face_classes
|
|
278
|
+
from addl_code/ptolemy_equations.c
|
|
279
|
+
|
|
280
|
+
This function returns an identification structure where s_f_t gets
|
|
281
|
+
identified with -s_g_u if face f of tetrahedron t is glued to face g of
|
|
282
|
+
tetrahedron u.
|
|
283
|
+
|
|
284
|
+
We can represent a 2-cohomology class H^2(M,boundary M) by denoting by
|
|
285
|
+
s_f_t the value the 2-cohomology class takes on the face f of
|
|
286
|
+
tetrahedron t with the orientation being the one induced from the
|
|
287
|
+
orientation of the tetrahedron.
|
|
288
|
+
Because a face class of the triangulation has two representatives
|
|
289
|
+
(tet_index, face_index) and the gluing is orientation-reversing on the
|
|
290
|
+
face, one s will be the negative of another s.
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
def process_embedding(embedding):
|
|
294
|
+
face = embedding.getFace()
|
|
295
|
+
tet = self.tetrahedronIndex(embedding.getTetrahedron())
|
|
296
|
+
return "s_%d_%d" % (face, tet)
|
|
297
|
+
|
|
298
|
+
def process_triangle(triangle):
|
|
299
|
+
# Each triangle means that one s_tet_face gets
|
|
300
|
+
# identified with another -s_tet_face.
|
|
301
|
+
|
|
302
|
+
return (-1, 0,
|
|
303
|
+
process_embedding(triangle.getEmbedding(0)),
|
|
304
|
+
process_embedding(triangle.getEmbedding(1)))
|
|
305
|
+
|
|
306
|
+
# Process each triangle
|
|
307
|
+
return [ process_triangle(triangle)
|
|
308
|
+
for triangle in self.getTriangles() ]
|
|
309
|
+
|
|
310
|
+
def _ptolemy_equations_boundary_map_2(self):
|
|
311
|
+
"""
|
|
312
|
+
This is reimplementing get_ptolemy_equations_boundary_map_2
|
|
313
|
+
from addl_code/ptolemy_equations.c
|
|
314
|
+
|
|
315
|
+
Boundary map C_3 -> C_2 in relative cellular homology H_2(M, boundary M)
|
|
316
|
+
represented as matrix
|
|
317
|
+
|
|
318
|
+
The following map represents the boundary map in the cellular chain
|
|
319
|
+
complex when representing a linear map as a matrix m acting on a column
|
|
320
|
+
vector v by left-multiplication m * v. With right-multiplication acting
|
|
321
|
+
on row vectors, the matrix represents the coboundary map in the cochain
|
|
322
|
+
complex.
|
|
323
|
+
|
|
324
|
+
The basis for C_3 are just the oriented tetrahedra of the triangulation.
|
|
325
|
+
The basis for C_2 are the face classes, see
|
|
326
|
+
_ptolemy_equations_identified_face_classes.
|
|
327
|
+
"""
|
|
328
|
+
|
|
329
|
+
def process_edge(edge):
|
|
330
|
+
|
|
331
|
+
# Process an edge, each column is for one face class,
|
|
332
|
+
row = [ 0 for i in range(self.getNumberOfTriangles()) ]
|
|
333
|
+
|
|
334
|
+
# Go through the edge embeddings
|
|
335
|
+
for edgeEmbedding in edge.getEmbeddings():
|
|
336
|
+
tet = edgeEmbedding.getTetrahedron()
|
|
337
|
+
perm = edgeEmbedding.getVertices()
|
|
338
|
+
|
|
339
|
+
# The oriented edge is identified with the edge
|
|
340
|
+
# going from perm[0] to perm[1] of the tetrahedron.
|
|
341
|
+
# This means that perm[2] and perm[3] are those faces of the
|
|
342
|
+
# tetrahedron that contain this edge.
|
|
343
|
+
for face in [2, 3]:
|
|
344
|
+
# Take orientations into account to compute with what
|
|
345
|
+
# sign this face class contributes.
|
|
346
|
+
sign = (
|
|
347
|
+
perm.sign() * (-1)**face *
|
|
348
|
+
NTriangulationForPtolemy._sign_of_tetrahedron_face(
|
|
349
|
+
tet, perm[face]))
|
|
350
|
+
# Compute the index of the face class
|
|
351
|
+
index = self._index_of_tetrahedron_face(tet, perm[face])
|
|
352
|
+
row[index] += sign
|
|
353
|
+
|
|
354
|
+
return [ x/2 for x in row ]
|
|
355
|
+
|
|
356
|
+
# Build the matrix with explanations
|
|
357
|
+
# For each edge, compute what triangles and thus face classes
|
|
358
|
+
# have it as boundary
|
|
359
|
+
matrix = [ process_edge(edge) for edge in self.getEdges() ]
|
|
360
|
+
row_explanations = [ 'edge_%d' % i
|
|
361
|
+
for i in range(self.getNumberOfEdges()) ]
|
|
362
|
+
column_explanations = self._face_class_explanations()
|
|
363
|
+
|
|
364
|
+
return matrix, row_explanations, column_explanations
|
|
365
|
+
|
|
366
|
+
def _ptolemy_equations_boundary_map_3(self):
|
|
367
|
+
"""
|
|
368
|
+
This is reimplementing get_ptolemy_equations_boundary_map_3
|
|
369
|
+
from addl_code/ptolemy_equations.c
|
|
370
|
+
|
|
371
|
+
Boundary map C_2 -> C_1 in cellular homology represented as matrix.
|
|
372
|
+
|
|
373
|
+
Also see _ptolemy_equations_boundary_map_2.
|
|
374
|
+
"""
|
|
375
|
+
|
|
376
|
+
def process_triangle(triangle):
|
|
377
|
+
row = [ 0 for i in range(self.getNumberOfTetrahedra()) ]
|
|
378
|
+
for i in range(2):
|
|
379
|
+
index = self.tetrahedronIndex(
|
|
380
|
+
triangle.getEmbedding(i).getTetrahedron())
|
|
381
|
+
row[index] += (-1) ** i
|
|
382
|
+
return row
|
|
383
|
+
|
|
384
|
+
matrix = [ process_triangle(triangle)
|
|
385
|
+
for triangle in self.getTriangles() ]
|
|
386
|
+
|
|
387
|
+
row_explanations = self._face_class_explanations()
|
|
388
|
+
|
|
389
|
+
column_explanations = [ 'tet_%d' % i
|
|
390
|
+
for i in range(self.getNumberOfTetrahedra()) ]
|
|
391
|
+
|
|
392
|
+
return matrix, row_explanations, column_explanations
|
|
393
|
+
|
|
394
|
+
def _ptolemy_equations_action_by_decoration_change(self, N):
|
|
395
|
+
"""
|
|
396
|
+
This is reimplementing get_ptolemy_equations_action_by_decoration_change
|
|
397
|
+
from addl_code/ptolemy_equations.c
|
|
398
|
+
|
|
399
|
+
We can change a decoration by multiplying a coset of a cusp by a
|
|
400
|
+
diagonal matrix. Let's let a diagonal matrix SL(n,C) with diagonal
|
|
401
|
+
entries 1 1 ... z 1 ... 1 1/z (z at position j) act on cusp i. It
|
|
402
|
+
changes some Ptolemy coordinate c_p_t by some power z^n.
|
|
403
|
+
This is expressed in the following matrix as the entry in row
|
|
404
|
+
labelled c_p_t and the column labelled diagonal_entry_j_on_cusp_i.
|
|
405
|
+
"""
|
|
406
|
+
matrix = []
|
|
407
|
+
row_explanations = []
|
|
408
|
+
|
|
409
|
+
for tet_index, tet in enumerate(self.getTetrahedra()):
|
|
410
|
+
for pt in utilities.quadruples_with_fixed_sum_iterator(
|
|
411
|
+
N, skipVertices=True):
|
|
412
|
+
|
|
413
|
+
row = (N - 1) * self.getNumberOfVertices() * [ 0 ]
|
|
414
|
+
|
|
415
|
+
for vertex in range(4):
|
|
416
|
+
cusp_index = self.vertexIndex(tet.getVertex(vertex))
|
|
417
|
+
|
|
418
|
+
for diag_entry in range(pt[vertex]):
|
|
419
|
+
column_index = cusp_index * (N-1) + diag_entry
|
|
420
|
+
row[column_index] += 1
|
|
421
|
+
|
|
422
|
+
matrix.append(row)
|
|
423
|
+
row_explanations.append('c_%d%d%d%d' % pt + '_%d' % tet_index)
|
|
424
|
+
|
|
425
|
+
column_explanations = [
|
|
426
|
+
"diagonal_entry_%d_on_cusp_%d" % (diag_entry, cusp_index)
|
|
427
|
+
for cusp_index in range(self.getNumberOfVertices())
|
|
428
|
+
for diag_entry in range(N-1) ]
|
|
429
|
+
|
|
430
|
+
return matrix, row_explanations, column_explanations
|
|
431
|
+
|
|
432
|
+
@staticmethod
|
|
433
|
+
def _compute_sign(ptolemy_index, perm):
|
|
434
|
+
"""
|
|
435
|
+
This is reimplementing _compute_sign
|
|
436
|
+
from addl_code/ptolemy_equations.c
|
|
437
|
+
"""
|
|
438
|
+
|
|
439
|
+
# Following Remark 5.7 of
|
|
440
|
+
# Garoufalidis, Goerner, Zickert:
|
|
441
|
+
# Gluing Equations for PGL(n,C)-Representations of 3-Manifolds
|
|
442
|
+
# https://arxiv.org/abs/1207.6711
|
|
443
|
+
# we discard all even entries and get a permutation called
|
|
444
|
+
# "effective_perm" here.
|
|
445
|
+
effective_perm = []
|
|
446
|
+
for v in range(4):
|
|
447
|
+
if ptolemy_index[v] % 2:
|
|
448
|
+
effective_perm.append(perm[v])
|
|
449
|
+
|
|
450
|
+
# We need to detect whether effective_perm is even or odd
|
|
451
|
+
# It has at most 3 elements, distinguish cases:
|
|
452
|
+
|
|
453
|
+
# Cases of length 0 and 1
|
|
454
|
+
if len(effective_perm) < 2:
|
|
455
|
+
return +1
|
|
456
|
+
|
|
457
|
+
# Case of length 2: either it is a transposition or not
|
|
458
|
+
if len(effective_perm) == 2:
|
|
459
|
+
if effective_perm[0] < effective_perm[1]:
|
|
460
|
+
return +1
|
|
461
|
+
return -1
|
|
462
|
+
|
|
463
|
+
# Case of length 3: even permutations = cyclic permutations
|
|
464
|
+
if len(effective_perm) == 3:
|
|
465
|
+
# Test whether cyclic permutation by i, including identity
|
|
466
|
+
for i in range(3):
|
|
467
|
+
if (effective_perm[i] < effective_perm[(i + 1) % 3]
|
|
468
|
+
< effective_perm[(i + 2) % 3]):
|
|
469
|
+
return +1
|
|
470
|
+
return -1
|
|
471
|
+
|
|
472
|
+
# index is for a face so one number in index is zero and len < 4,
|
|
473
|
+
# we should never reach here
|
|
474
|
+
raise Exception("Should never reach here")
|
|
475
|
+
|
|
476
|
+
def _get_obstruction_on_edge(self, obstruction_class, tet, v0, v1):
|
|
477
|
+
"""
|
|
478
|
+
Reimplements _get_obstruction_on_edge from
|
|
479
|
+
addl_code/ptolemy_equations.c
|
|
480
|
+
"""
|
|
481
|
+
|
|
482
|
+
if v0 > v1:
|
|
483
|
+
return - self._get_obstruction_on_edge(obstruction_class,
|
|
484
|
+
tet, v1, v0)
|
|
485
|
+
|
|
486
|
+
if v1 != v0 + 1:
|
|
487
|
+
return 0
|
|
488
|
+
|
|
489
|
+
s = [ NTriangulationForPtolemy._sign_of_tetrahedron_face(tet, i) *
|
|
490
|
+
obstruction_class[self._index_of_tetrahedron_face(tet, i)]
|
|
491
|
+
for i in range(4) ]
|
|
492
|
+
|
|
493
|
+
if v0 == 0: # v0 = 0, v1 = 1
|
|
494
|
+
return -s[0] - s[1] - s[3]
|
|
495
|
+
if v0 == 1: # v0 = 1, v1 = 2
|
|
496
|
+
return s[0] + s[1]
|
|
497
|
+
if v0 == 2: # v0 = 2, v1 = 3
|
|
498
|
+
return -s[1]
|
|
499
|
+
|
|
500
|
+
raise Exception("Should not get here")
|
|
501
|
+
|
|
502
|
+
def _get_obstruction_on_edge_with_other_tet(self, obstruction_class,
|
|
503
|
+
tet, face, v0, v1):
|
|
504
|
+
"""
|
|
505
|
+
Reimplements _get_obstruction_on_edge_with_other_tet from
|
|
506
|
+
addl_code/ptolemy_equations.c
|
|
507
|
+
"""
|
|
508
|
+
other_tet = tet.getAdjacentTetrahedron(face)
|
|
509
|
+
gluing = tet.getAdjacentTetrahedronGluing(face)
|
|
510
|
+
other_v0 = gluing[v0]
|
|
511
|
+
other_v1 = gluing[v1]
|
|
512
|
+
|
|
513
|
+
return (
|
|
514
|
+
self._get_obstruction_on_edge(obstruction_class,
|
|
515
|
+
tet, v0, v1) -
|
|
516
|
+
self._get_obstruction_on_edge(obstruction_class,
|
|
517
|
+
other_tet, other_v0, other_v1))
|
|
518
|
+
|
|
519
|
+
def _get_obstruction_on_edges(self, obstruction_class, tet, face, N):
|
|
520
|
+
"""
|
|
521
|
+
This reimplements _get_obstruction_on_edges from
|
|
522
|
+
addl_code/ptolemy_equations.c
|
|
523
|
+
"""
|
|
524
|
+
v0 = (face + 1) % 4
|
|
525
|
+
v1 = (face + 2) % 4
|
|
526
|
+
v2 = (face + 3) % 4
|
|
527
|
+
|
|
528
|
+
e01 = self._get_obstruction_on_edge_with_other_tet(obstruction_class,
|
|
529
|
+
tet, face, v0, v1)
|
|
530
|
+
e02 = self._get_obstruction_on_edge_with_other_tet(obstruction_class,
|
|
531
|
+
tet, face, v0, v2)
|
|
532
|
+
e12 = self._get_obstruction_on_edge_with_other_tet(obstruction_class,
|
|
533
|
+
tet, face, v1, v2)
|
|
534
|
+
|
|
535
|
+
assert (e01 + e12 - e02) % N == 0
|
|
536
|
+
|
|
537
|
+
return e01, e02
|
|
538
|
+
|
|
539
|
+
@staticmethod
|
|
540
|
+
def _get_power_from_obstruction_class(face, e01, e02, ptolemy_index):
|
|
541
|
+
"""
|
|
542
|
+
This reimplements _get_power_from_obstruction_class
|
|
543
|
+
from addl_code/ptolemy_equations.c
|
|
544
|
+
|
|
545
|
+
Let face face of a tetrahedron be glued to some other face. This
|
|
546
|
+
will identify two Ptolemy coordinates up to a sign and an N-th root
|
|
547
|
+
of unity (for an PSL(N,C)-representation. I.e., we get an equation
|
|
548
|
+
between Ptolemy coordinates of the form
|
|
549
|
+
(+/-) u^p c_index_t = c_index'_t'
|
|
550
|
+
where u is the N-th root of unity, c_index_t is the Ptolemy coordinate
|
|
551
|
+
on the given face and c_index'_t' on the face that it glued to the
|
|
552
|
+
given face.
|
|
553
|
+
_compute_sign will give the sign (+/-) based on the index and the
|
|
554
|
+
face gluing permutation.
|
|
555
|
+
_get_power_from_obstruction_class will give p given the face, the
|
|
556
|
+
Ptolemy index and the edge cocycle that assigns e01 to the edge 01
|
|
557
|
+
and e02 to the edge e02 that is determined through the cohomology
|
|
558
|
+
obstruction class by _get_obstruction_on_edges.
|
|
559
|
+
"""
|
|
560
|
+
|
|
561
|
+
v1 = (face + 2) % 4
|
|
562
|
+
v2 = (face + 3) % 4
|
|
563
|
+
return ptolemy_index[v1] * e01 + ptolemy_index[v2] * e02
|
|
564
|
+
|
|
565
|
+
def _ptolemy_equations_identified_coordinates(self, N,
|
|
566
|
+
obstruction_class=None):
|
|
567
|
+
|
|
568
|
+
identifications = []
|
|
569
|
+
|
|
570
|
+
# For each triangle
|
|
571
|
+
for triangle in self.getTriangles():
|
|
572
|
+
embedding = triangle.getEmbedding(0)
|
|
573
|
+
# Compute the (tetrahedron, face) building that triangle
|
|
574
|
+
tet = embedding.getTetrahedron()
|
|
575
|
+
tet_index = self.tetrahedronIndex(tet)
|
|
576
|
+
face = embedding.getFace()
|
|
577
|
+
# Get the face gluing for that tetrahedron and face
|
|
578
|
+
gluing = tet.getAdjacentTetrahedronGluing(face)
|
|
579
|
+
# Get the other (tetrahedron, face) that is glued to it
|
|
580
|
+
# and that face gluing
|
|
581
|
+
other_tet = tet.getAdjacentTetrahedron(face)
|
|
582
|
+
other_tet_index = self.tetrahedronIndex(other_tet)
|
|
583
|
+
other_gluing = gluing.inverse()
|
|
584
|
+
|
|
585
|
+
# Find a lift of the obstruction class to the edges.
|
|
586
|
+
if obstruction_class:
|
|
587
|
+
e01, e02 = self._get_obstruction_on_edges(obstruction_class,
|
|
588
|
+
tet, face, N)
|
|
589
|
+
|
|
590
|
+
# Iterate through all the integral points on the face
|
|
591
|
+
for triple in utilities.triples_with_fixed_sum_iterator(
|
|
592
|
+
N, skipVertices=True):
|
|
593
|
+
# The face integral points are obtained by inserting a 0
|
|
594
|
+
ptolemy_index = triple[0:face] + (0,) + triple[face:]
|
|
595
|
+
# Get the corresponding integral point on the other tetrahedron
|
|
596
|
+
other_ptolemy_index = tuple(
|
|
597
|
+
[ptolemy_index[other_gluing[v]] for v in range(4)])
|
|
598
|
+
|
|
599
|
+
# Compute the sign for the identification
|
|
600
|
+
sign = NTriangulationForPtolemy._compute_sign(
|
|
601
|
+
ptolemy_index, gluing)
|
|
602
|
+
|
|
603
|
+
# When identifying and there is an obstruction class,
|
|
604
|
+
# determine the power of the root of unity necessary
|
|
605
|
+
# in the identification
|
|
606
|
+
if obstruction_class:
|
|
607
|
+
power = (NTriangulationForPtolemy.
|
|
608
|
+
_get_power_from_obstruction_class(face, e01, e02,
|
|
609
|
+
ptolemy_index))
|
|
610
|
+
else:
|
|
611
|
+
power = 0
|
|
612
|
+
|
|
613
|
+
# Get the two corresponding Ptolemy coordinates
|
|
614
|
+
ptolemy = ('c_%d%d%d%d' % ptolemy_index +
|
|
615
|
+
'_%d' % tet_index)
|
|
616
|
+
other_ptolemy = ('c_%d%d%d%d' % other_ptolemy_index +
|
|
617
|
+
'_%d' % other_tet_index)
|
|
618
|
+
|
|
619
|
+
# Identify them
|
|
620
|
+
identifications.append((sign, power, ptolemy, other_ptolemy))
|
|
621
|
+
|
|
622
|
+
return identifications
|
|
623
|
+
|
|
624
|
+
def _choose_generators(self, *args, **kwargs):
|
|
625
|
+
"""
|
|
626
|
+
Not necessary. We call maximalForestInDualSkeleton instead in
|
|
627
|
+
_choose_generators_info.
|
|
628
|
+
"""
|
|
629
|
+
pass
|
|
630
|
+
|
|
631
|
+
def _choose_generators_info(self):
|
|
632
|
+
"""
|
|
633
|
+
Provides information about the choices mades when regina computed the
|
|
634
|
+
simplified fundamental group in a structure similar to SnapPy.
|
|
635
|
+
"""
|
|
636
|
+
|
|
637
|
+
# maximalForestInDualSkeleton was not exposed in earlier regina
|
|
638
|
+
# versions
|
|
639
|
+
if not hasattr(self, 'maximalForestInDualSkeleton'):
|
|
640
|
+
raise Exception("Version of regina does not have python wrapping "
|
|
641
|
+
"for maximalForestInDualSkeleton")
|
|
642
|
+
|
|
643
|
+
# Every triangle belonging to the spanning tree is not a generator
|
|
644
|
+
non_generator_triangles = self.maximalForestInDualSkeleton()
|
|
645
|
+
|
|
646
|
+
# All other triangles are
|
|
647
|
+
generator_triangles = [triangle for triangle in self.getTriangles()
|
|
648
|
+
if triangle not in non_generator_triangles]
|
|
649
|
+
|
|
650
|
+
def get_neighbors(tet):
|
|
651
|
+
"""
|
|
652
|
+
Given a tetrahedron, return the indices of the 4 neighboring
|
|
653
|
+
tetrahedra
|
|
654
|
+
"""
|
|
655
|
+
return [ self.tetrahedronIndex(tet.getAdjacentTetrahedron(face))
|
|
656
|
+
for face in range(4) ]
|
|
657
|
+
|
|
658
|
+
def get_gluings(tet):
|
|
659
|
+
"""
|
|
660
|
+
Given a tetrahedron, return the four face gluings.
|
|
661
|
+
"""
|
|
662
|
+
return [ tet.getAdjacentTetrahedronGluing(face)
|
|
663
|
+
for face in range(4) ]
|
|
664
|
+
|
|
665
|
+
def get_generator(tet, face):
|
|
666
|
+
"""
|
|
667
|
+
Given a tetrahedron and a face (0, ..., 3), return whether it
|
|
668
|
+
corresponds to an inbound or outbound generator.
|
|
669
|
+
"""
|
|
670
|
+
# Get corresponding triangle
|
|
671
|
+
triangle = tet.getTriangle(face)
|
|
672
|
+
if triangle not in generator_triangles:
|
|
673
|
+
# Not a generator, return 0
|
|
674
|
+
return 0
|
|
675
|
+
# Get the index of the generator, first generator is indexed 1
|
|
676
|
+
# so that a negative index can correspond to the inverse
|
|
677
|
+
# generator
|
|
678
|
+
gen = generator_triangles.index(triangle) + 1
|
|
679
|
+
# regina uses embedding 0 of the triangle as outbound generator
|
|
680
|
+
canonical_embed = triangle.getEmbedding(0)
|
|
681
|
+
if (canonical_embed.getTetrahedron() == tet and
|
|
682
|
+
canonical_embed.getFace() == face):
|
|
683
|
+
return gen
|
|
684
|
+
else:
|
|
685
|
+
return -gen
|
|
686
|
+
|
|
687
|
+
def get_generators(tet):
|
|
688
|
+
"""
|
|
689
|
+
Given a tetrahedron, return for each face which inbound
|
|
690
|
+
or outbound generator it belongs to.
|
|
691
|
+
"""
|
|
692
|
+
return [ get_generator(tet, face) for face in range(4) ]
|
|
693
|
+
|
|
694
|
+
return [ { 'index' : index,
|
|
695
|
+
'neighbors' : get_neighbors(tet),
|
|
696
|
+
'gluings' : get_gluings(tet),
|
|
697
|
+
'generators' : get_generators(tet) }
|
|
698
|
+
for index, tet in enumerate(self.getTetrahedra()) ]
|