snappy 3.1.1__cp311-cp311-macosx_11_0_arm64.whl → 3.2__cp311-cp311-macosx_11_0_arm64.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-311-darwin.so +0 -0
- snappy/SnapPy.cpython-311-darwin.so +0 -0
- snappy/SnapPyHP.cpython-311-darwin.so +0 -0
- snappy/__init__.py +299 -402
- snappy/app.py +70 -20
- snappy/browser.py +18 -17
- snappy/canonical.py +249 -0
- snappy/{verify/cusp_shapes.py → cusps/__init__.py} +8 -18
- snappy/cusps/cusp_area_matrix.py +101 -0
- snappy/{verify/cusp_areas.py → cusps/cusp_areas_from_matrix.py} +23 -39
- snappy/cusps/maximal_cusp_area_matrix.py +136 -0
- snappy/cusps/test.py +21 -0
- snappy/cusps/trig_cusp_area_matrix.py +63 -0
- snappy/database.py +10 -9
- snappy/decorated_isosig.py +337 -114
- snappy/dev/extended_ptolemy/complexVolumesClosed.py +40 -7
- snappy/dev/extended_ptolemy/extended.py +3 -3
- snappy/dev/extended_ptolemy/phc_wrapper.py +10 -10
- snappy/dev/vericlosed/oneVertexTruncatedComplex.py +1 -1
- snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
- snappy/doc/_images/m125_paper_plane.jpg +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/_sources/development.rst.txt +66 -46
- snappy/doc/_sources/index.rst.txt +72 -5
- snappy/doc/_sources/installing.rst.txt +145 -162
- snappy/doc/_sources/news.rst.txt +73 -1
- snappy/doc/_sources/ptolemy_examples1.rst.txt +8 -7
- snappy/doc/_sources/ptolemy_examples3.rst.txt +2 -2
- snappy/doc/_sources/triangulation.rst.txt +2 -2
- snappy/doc/_sources/verify.rst.txt +89 -29
- snappy/doc/_sources/verify_internals.rst.txt +5 -16
- snappy/doc/_static/basic.css +23 -1
- snappy/doc/_static/css/badge_only.css +1 -1
- snappy/doc/_static/css/theme.css +1 -1
- snappy/doc/_static/doctools.js +1 -1
- snappy/doc/_static/documentation_options.js +2 -3
- 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/js/versions.js +228 -0
- snappy/doc/_static/language_data.js +2 -2
- snappy/doc/_static/pygments.css +1 -0
- snappy/doc/_static/searchtools.js +125 -71
- snappy/doc/_static/sphinx_highlight.js +13 -3
- snappy/doc/additional_classes.html +291 -122
- snappy/doc/bugs.html +17 -20
- snappy/doc/censuses.html +34 -53
- snappy/doc/credits.html +18 -21
- snappy/doc/development.html +88 -68
- snappy/doc/genindex.html +66 -145
- snappy/doc/index.html +86 -31
- snappy/doc/installing.html +164 -182
- snappy/doc/manifold.html +1168 -556
- snappy/doc/manifoldhp.html +18 -21
- snappy/doc/news.html +91 -33
- snappy/doc/objects.inv +0 -0
- snappy/doc/other.html +20 -22
- snappy/doc/platonic_census.html +31 -34
- snappy/doc/plink.html +19 -22
- snappy/doc/ptolemy.html +20 -22
- snappy/doc/ptolemy_classes.html +102 -105
- snappy/doc/ptolemy_examples1.html +34 -36
- snappy/doc/ptolemy_examples2.html +28 -31
- snappy/doc/ptolemy_examples3.html +26 -29
- snappy/doc/ptolemy_examples4.html +20 -23
- snappy/doc/ptolemy_prelim.html +25 -28
- snappy/doc/py-modindex.html +16 -19
- snappy/doc/screenshots.html +22 -24
- snappy/doc/search.html +15 -18
- snappy/doc/searchindex.js +1 -1
- snappy/doc/snap.html +18 -21
- snappy/doc/snappy.html +18 -20
- snappy/doc/spherogram.html +84 -87
- snappy/doc/todo.html +17 -20
- snappy/doc/triangulation.html +324 -215
- snappy/doc/tutorial.html +17 -20
- snappy/doc/verify.html +100 -46
- snappy/doc/verify_internals.html +106 -563
- snappy/drilling/__init__.py +153 -235
- snappy/drilling/barycentric.py +103 -0
- snappy/drilling/constants.py +0 -2
- snappy/drilling/crush.py +56 -130
- snappy/drilling/cusps.py +12 -6
- snappy/drilling/debug.py +2 -1
- snappy/drilling/exceptions.py +7 -40
- snappy/drilling/moves.py +302 -243
- snappy/drilling/perturb.py +63 -37
- snappy/drilling/shorten.py +36 -0
- snappy/drilling/subdivide.py +0 -5
- snappy/drilling/test.py +23 -0
- snappy/drilling/test_cases.py +126 -0
- snappy/drilling/tracing.py +9 -37
- snappy/exceptions.py +18 -5
- snappy/exterior_to_link/barycentric_geometry.py +2 -4
- snappy/exterior_to_link/main.py +8 -7
- snappy/exterior_to_link/mcomplex_with_link.py +2 -2
- snappy/exterior_to_link/rational_linear_algebra.py +1 -1
- snappy/exterior_to_link/rational_linear_algebra_wrapped.py +1 -1
- snappy/exterior_to_link/test.py +21 -33
- 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 +697 -0
- snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +484 -0
- snappy/geometric_structure/cusp_neighborhood/exceptions.py +42 -0
- snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +298 -0
- snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +159 -0
- snappy/geometric_structure/cusp_neighborhood/vertices.py +32 -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_keys.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/{drilling → geometric_structure/geodesic}/fixed_points.py +34 -9
- snappy/{drilling/geodesic_info.py → geometric_structure/geodesic/geodesic_start_point_info.py} +139 -180
- 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 +101 -0
- snappy/geometric_structure/test.py +22 -0
- snappy/gui.py +23 -13
- snappy/horoviewer.py +7 -7
- snappy/hyperboloid/__init__.py +96 -31
- snappy/hyperboloid/distances.py +245 -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/isometry_signature.py +382 -0
- snappy/len_spec/__init__.py +596 -0
- snappy/len_spec/geodesic_info.py +110 -0
- snappy/len_spec/geodesic_key_info_dict.py +117 -0
- snappy/len_spec/geodesic_piece.py +143 -0
- snappy/len_spec/geometric_structure.py +182 -0
- snappy/len_spec/geometry.py +80 -0
- snappy/len_spec/length_spectrum_geodesic_info.py +170 -0
- snappy/len_spec/spine.py +206 -0
- snappy/len_spec/test.py +24 -0
- snappy/len_spec/test_cases.py +69 -0
- snappy/len_spec/tile.py +275 -0
- snappy/len_spec/word.py +86 -0
- snappy/math_basics.py +39 -13
- snappy/matrix.py +52 -9
- snappy/number.py +12 -6
- snappy/numeric_output_checker.py +2 -3
- snappy/pari.py +8 -4
- snappy/phone_home.py +2 -1
- snappy/polyviewer.py +8 -8
- snappy/ptolemy/__init__.py +1 -1
- snappy/ptolemy/component.py +2 -2
- snappy/ptolemy/coordinates.py +25 -25
- snappy/ptolemy/findLoops.py +9 -9
- snappy/ptolemy/manifoldMethods.py +27 -29
- snappy/ptolemy/polynomial.py +50 -57
- snappy/ptolemy/processFileBase.py +60 -0
- snappy/ptolemy/ptolemyVariety.py +109 -41
- snappy/ptolemy/reginaWrapper.py +4 -4
- snappy/ptolemy/rur.py +1 -1
- snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +9 -9
- snappy/ptolemy/test.py +99 -54
- snappy/ptolemy/utilities.py +1 -1
- 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 +0 -3
- snappy/raytracing/eyeball.py +123 -0
- snappy/raytracing/finite_raytracing_data.py +17 -17
- snappy/raytracing/finite_viewer.py +15 -15
- snappy/raytracing/geodesic_tube_info.py +93 -63
- snappy/raytracing/geodesics.py +94 -64
- snappy/raytracing/geodesics_window.py +56 -34
- snappy/raytracing/gui_utilities.py +21 -6
- snappy/raytracing/hyperboloid_navigation.py +29 -4
- snappy/raytracing/hyperboloid_utilities.py +73 -73
- snappy/raytracing/ideal_raytracing_data.py +121 -91
- snappy/raytracing/inside_viewer.py +199 -66
- snappy/raytracing/pack.py +22 -0
- snappy/raytracing/raytracing_data.py +37 -25
- snappy/raytracing/raytracing_view.py +70 -65
- snappy/raytracing/shaders/Eye.png +0 -0
- snappy/raytracing/shaders/NonGeometric.png +0 -0
- snappy/raytracing/shaders/__init__.py +39 -3
- snappy/raytracing/shaders/fragment.glsl +451 -133
- snappy/raytracing/test.py +29 -0
- snappy/raytracing/tooltip.py +146 -0
- snappy/raytracing/upper_halfspace_utilities.py +42 -9
- snappy/sage_helper.py +67 -134
- snappy/settings.py +90 -77
- snappy/shell.py +2 -0
- snappy/snap/character_varieties.py +2 -2
- snappy/snap/find_field.py +4 -3
- snappy/snap/fundamental_polyhedron.py +2 -2
- snappy/snap/kernel_structures.py +5 -1
- snappy/snap/nsagetools.py +9 -8
- snappy/snap/peripheral/dual_cellulation.py +4 -3
- snappy/snap/peripheral/peripheral.py +2 -2
- snappy/snap/peripheral/surface.py +5 -5
- snappy/snap/peripheral/test.py +1 -1
- snappy/snap/polished_reps.py +8 -8
- snappy/snap/slice_obs_HKL.py +16 -14
- snappy/snap/t3mlite/arrow.py +3 -3
- snappy/snap/t3mlite/edge.py +3 -3
- snappy/snap/t3mlite/homology.py +2 -2
- snappy/snap/t3mlite/mcomplex.py +3 -3
- snappy/snap/t3mlite/simplex.py +12 -0
- snappy/snap/t3mlite/spun.py +18 -17
- snappy/snap/t3mlite/test_vs_regina.py +4 -4
- snappy/snap/test.py +37 -53
- snappy/snap/utilities.py +4 -5
- snappy/test.py +121 -138
- snappy/test_cases.py +263 -0
- snappy/testing.py +131 -0
- snappy/tiling/__init__.py +2 -0
- snappy/tiling/canonical_key_dict.py +59 -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/real_hash_dict.py +164 -0
- snappy/tiling/test.py +23 -0
- snappy/tiling/tile.py +215 -0
- snappy/tiling/triangle.py +33 -0
- snappy/tkterminal.py +113 -84
- snappy/twister/main.py +1 -7
- snappy/twister/twister_core.cpython-311-darwin.so +0 -0
- snappy/upper_halfspace/__init__.py +78 -17
- snappy/verify/__init__.py +3 -7
- snappy/verify/{verifyCanonical.py → canonical.py} +78 -70
- snappy/verify/complex_volume/adjust_torsion.py +1 -2
- snappy/verify/complex_volume/closed.py +13 -13
- snappy/verify/complex_volume/cusped.py +6 -6
- snappy/verify/complex_volume/extended_bloch.py +5 -8
- snappy/verify/{cuspTranslations.py → cusp_translations.py} +1 -1
- snappy/verify/edge_equations.py +80 -0
- snappy/verify/exceptions.py +0 -55
- snappy/verify/{verifyHyperbolicity.py → hyperbolicity.py} +3 -3
- snappy/verify/interval_newton_shapes_engine.py +7 -5
- snappy/verify/interval_tree.py +5 -5
- snappy/verify/krawczyk_shapes_engine.py +17 -18
- snappy/verify/maximal_cusp_area_matrix/__init__.py +7 -74
- snappy/verify/maximal_cusp_area_matrix/cusp_tiling_engine.py +3 -4
- snappy/verify/maximal_cusp_area_matrix/cusp_translate_engine.py +1 -1
- snappy/verify/{realAlgebra.py → real_algebra.py} +1 -1
- snappy/verify/shapes.py +5 -3
- snappy/verify/short_slopes.py +39 -41
- snappy/verify/{squareExtensions.py → square_extensions.py} +14 -11
- snappy/verify/test.py +57 -60
- snappy/verify/upper_halfspace/extended_matrix.py +1 -1
- snappy/verify/upper_halfspace/finite_point.py +3 -4
- snappy/verify/upper_halfspace/ideal_point.py +9 -9
- snappy/verify/volume.py +2 -2
- snappy/version.py +2 -2
- {snappy-3.1.1.dist-info → snappy-3.2.dist-info}/METADATA +26 -11
- snappy-3.2.dist-info/RECORD +503 -0
- {snappy-3.1.1.dist-info → snappy-3.2.dist-info}/WHEEL +1 -1
- {snappy-3.1.1.dist-info → snappy-3.2.dist-info}/top_level.txt +6 -1
- snappy/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/__pycache__/browser.cpython-311.pyc +0 -0
- snappy/__pycache__/cache.cpython-311.pyc +0 -0
- snappy/__pycache__/database.cpython-311.pyc +0 -0
- snappy/__pycache__/db_utilities.cpython-311.pyc +0 -0
- snappy/__pycache__/decorated_isosig.cpython-311.pyc +0 -0
- snappy/__pycache__/exceptions.cpython-311.pyc +0 -0
- snappy/__pycache__/export_stl.cpython-311.pyc +0 -0
- snappy/__pycache__/filedialog.cpython-311.pyc +0 -0
- snappy/__pycache__/gui.cpython-311.pyc +0 -0
- snappy/__pycache__/horoviewer.cpython-311.pyc +0 -0
- snappy/__pycache__/infowindow.cpython-311.pyc +0 -0
- snappy/__pycache__/math_basics.cpython-311.pyc +0 -0
- snappy/__pycache__/matrix.cpython-311.pyc +0 -0
- snappy/__pycache__/number.cpython-311.pyc +0 -0
- snappy/__pycache__/numeric_output_checker.cpython-311.pyc +0 -0
- snappy/__pycache__/pari.cpython-311.pyc +0 -0
- snappy/__pycache__/polyviewer.cpython-311.pyc +0 -0
- snappy/__pycache__/sage_helper.cpython-311.pyc +0 -0
- snappy/__pycache__/version.cpython-311.pyc +0 -0
- snappy/doc/_sources/verify_canon.rst.txt +0 -90
- snappy/doc/_static/js/html5shiv-printshiv.min.js +0 -4
- snappy/doc/_static/js/html5shiv.min.js +0 -4
- snappy/doc/verify_canon.html +0 -304
- snappy/drilling/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/constants.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/crush.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/cusps.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/debug.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/epsilons.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/exceptions.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/fixed_points.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/geodesic_info.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/geodesic_tube.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/geometric_structure.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/line.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/moves.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/peripheral_curves.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/perturb.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/quotient_space.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/spatial_dict.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/subdivide.cpython-311.pyc +0 -0
- snappy/drilling/__pycache__/tracing.cpython-311.pyc +0 -0
- snappy/drilling/geodesic_tube.py +0 -441
- snappy/drilling/geometric_structure.py +0 -366
- snappy/drilling/line.py +0 -122
- snappy/drilling/quotient_space.py +0 -94
- snappy/drilling/spatial_dict.py +0 -128
- snappy/exterior_to_link/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/barycentric_geometry.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/exceptions.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/hyp_utils.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/link_projection.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/main.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/mcomplex_with_expansion.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/mcomplex_with_link.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/mcomplex_with_memory.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/pl_utils.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/put_in_S3.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/rational_linear_algebra.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/simplify_to_base_tri.cpython-311.pyc +0 -0
- snappy/exterior_to_link/__pycache__/stored_moves.cpython-311.pyc +0 -0
- snappy/hyperboloid/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/manifolds/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/component.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/coordinates.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/fieldExtensions.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/findLoops.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/homology.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/manifoldMethods.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/matrix.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/numericalSolutionsToGroebnerBasis.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/polynomial.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/processComponents.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/processFileBase.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/processFileDispatch.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/processMagmaFile.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/processRurFile.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/ptolemyGeneralizedObstructionClass.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/ptolemyObstructionClass.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/ptolemyVariety.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/ptolemyVarietyPrimeIdealGroebnerBasis.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/rur.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/solutionsToPrimeIdealGroebnerBasis.cpython-311.pyc +0 -0
- snappy/ptolemy/__pycache__/utilities.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/finite_raytracing_data.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/gui_utilities.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/hyperboloid_navigation.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/hyperboloid_utilities.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/ideal_raytracing_data.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/inside_viewer.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/raytracing_data.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/raytracing_view.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/upper_halfspace_utilities.cpython-311.pyc +0 -0
- snappy/raytracing/__pycache__/view_scale_controller.cpython-311.pyc +0 -0
- snappy/raytracing/zoom_slider/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/character_varieties.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/fundamental_polyhedron.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/interval_reps.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/kernel_structures.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/mcomplex_base.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/nsagetools.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/polished_reps.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/shapes.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/slice_obs_HKL.cpython-311.pyc +0 -0
- snappy/snap/__pycache__/utilities.cpython-311.pyc +0 -0
- snappy/snap/peripheral/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/snap/peripheral/__pycache__/dual_cellulation.cpython-311.pyc +0 -0
- snappy/snap/peripheral/__pycache__/link.cpython-311.pyc +0 -0
- snappy/snap/peripheral/__pycache__/peripheral.cpython-311.pyc +0 -0
- snappy/snap/peripheral/__pycache__/surface.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/arrow.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/corner.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/edge.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/face.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/files.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/homology.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/linalg.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/mcomplex.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/perm4.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/simplex.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/spun.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/surface.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/tetrahedron.cpython-311.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/vertex.cpython-311.pyc +0 -0
- snappy/togl/__init__.py +0 -3
- snappy/togl/darwin-tk8.6/Togl2.1/LICENSE +0 -28
- snappy/togl/darwin-tk8.6/Togl2.1/libTogl2.1.dylib +0 -0
- snappy/togl/darwin-tk8.6/Togl2.1/pkgIndex.tcl +0 -5
- snappy/togl/darwin-tk8.7/Togl2.1/LICENSE +0 -28
- snappy/togl/darwin-tk8.7/Togl2.1/libTogl2.1.dylib +0 -0
- snappy/togl/darwin-tk8.7/Togl2.1/pkgIndex.tcl +0 -5
- snappy/togl/linux2-x86_64-tk8.6/Togl2.1/LICENSE +0 -28
- snappy/togl/linux2-x86_64-tk8.6/Togl2.1/libTogl2.1.so +0 -0
- snappy/togl/linux2-x86_64-tk8.6/Togl2.1/pkgIndex.tcl +0 -5
- snappy/togl/win32VC-tk8.6/Togl2.1/LICENSE +0 -28
- snappy/togl/win32VC-tk8.6/Togl2.1/Togl21.dll +0 -0
- snappy/togl/win32VC-tk8.6/Togl2.1/Togl21.lib +0 -0
- snappy/togl/win32VC-tk8.6/Togl2.1/pkgIndex.tcl +0 -6
- snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/LICENSE +0 -28
- snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/Togl21.dll +0 -0
- snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/Togl21.lib +0 -0
- snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/pkgIndex.tcl +0 -6
- snappy/twister/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/twister/__pycache__/main.cpython-311.pyc +0 -0
- snappy/upper_halfspace/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/upper_halfspace/__pycache__/ideal_point.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/cuspCrossSection.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/cuspTranslations.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/cusp_areas.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/cusp_shapes.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/exceptions.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/interval_newton_shapes_engine.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/interval_tree.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/krawczyk_shapes_engine.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/realAlgebra.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/shapes.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/short_slopes.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/squareExtensions.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/verifyCanonical.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/verifyHyperbolicity.cpython-311.pyc +0 -0
- snappy/verify/__pycache__/volume.cpython-311.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/adjust_torsion.cpython-311.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/closed.cpython-311.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/compute_ptolemys.cpython-311.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/cusped.cpython-311.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/extended_bloch.cpython-311.pyc +0 -0
- snappy/verify/cuspCrossSection.py +0 -1422
- snappy/verify/maximal_cusp_area_matrix/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/verify/maximal_cusp_area_matrix/__pycache__/cusp_tiling_engine.cpython-311.pyc +0 -0
- snappy/verify/maximal_cusp_area_matrix/__pycache__/cusp_translate_engine.cpython-311.pyc +0 -0
- snappy/verify/upper_halfspace/__pycache__/__init__.cpython-311.pyc +0 -0
- snappy/verify/upper_halfspace/__pycache__/extended_matrix.cpython-311.pyc +0 -0
- snappy/verify/upper_halfspace/__pycache__/finite_point.cpython-311.pyc +0 -0
- snappy/verify/upper_halfspace/__pycache__/ideal_point.cpython-311.pyc +0 -0
- snappy-3.1.1.dist-info/RECORD +0 -585
- {snappy-3.1.1.dist-info → snappy-3.2.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,298 @@
|
|
1
|
+
from .cusp_cross_section_base import CuspCrossSectionBase, HoroTriangleBase
|
2
|
+
from .exceptions import IncompleteCuspError, ConsistencyWithSnapPeaNumericalVerifyError
|
3
|
+
|
4
|
+
from ...snap.kernel_structures import TransferKernelStructuresEngine
|
5
|
+
from ...snap import t3mlite as t3m
|
6
|
+
from ...snap.t3mlite import simplex
|
7
|
+
|
8
|
+
class RealHoroTriangle:
|
9
|
+
"""
|
10
|
+
A horosphere cross section in the corner of an ideal tetrahedron.
|
11
|
+
The sides of the triangle correspond to faces of the tetrahedron.
|
12
|
+
The lengths stored for the triangle are real.
|
13
|
+
"""
|
14
|
+
def __init__(self, tet, vertex, known_side, length_of_side=None):
|
15
|
+
left_side, center_side, right_side, z_left, z_right = (
|
16
|
+
HoroTriangleBase._sides_and_cross_ratios(tet, vertex, known_side))
|
17
|
+
|
18
|
+
if length_of_side is None:
|
19
|
+
RF = z_left.real().parent()
|
20
|
+
L = RF(1)
|
21
|
+
else:
|
22
|
+
L = length_of_side
|
23
|
+
|
24
|
+
self.lengths = { center_side : L,
|
25
|
+
left_side : abs(z_left) * L,
|
26
|
+
right_side : L / abs(z_right) }
|
27
|
+
a, b, c = self.lengths.values()
|
28
|
+
self.area = L * L * z_left.imag() / 2
|
29
|
+
|
30
|
+
# Below is the usual formula for circumradius
|
31
|
+
self.circumradius = a * b * c / (4 * self.area)
|
32
|
+
|
33
|
+
def rescale(self, t):
|
34
|
+
"Rescales the triangle by a Euclidean dilation"
|
35
|
+
for face in self.lengths:
|
36
|
+
self.lengths[face] *= t
|
37
|
+
self.circumradius *= t
|
38
|
+
self.area *= t * t
|
39
|
+
|
40
|
+
def get_real_lengths(self):
|
41
|
+
return self.lengths
|
42
|
+
|
43
|
+
@staticmethod
|
44
|
+
def direction_sign():
|
45
|
+
return +1
|
46
|
+
|
47
|
+
class RealCuspCrossSection(CuspCrossSectionBase):
|
48
|
+
"""
|
49
|
+
A t3m triangulation with real edge lengths of cusp cross sections built
|
50
|
+
from a cusped (possibly non-orientable) SnapPy manifold M with a hyperbolic
|
51
|
+
structure specified by shapes. It can scale the cusps to areas that can be
|
52
|
+
specified or scale them such that they are disjoint.
|
53
|
+
It can also compute the "tilts" used in the Tilt Theorem, see
|
54
|
+
``canonize_part_1.c``.
|
55
|
+
|
56
|
+
The computations are agnostic about the type of numbers provided as shapes
|
57
|
+
as long as they provide ``+``, ``-``, ``*``, ``/``, ``conjugate()``,
|
58
|
+
``im()``, ``abs()``, ``sqrt()``.
|
59
|
+
Shapes can be a numerical type such as ComplexIntervalField or an exact
|
60
|
+
type (supporting sqrt) such as QQbar.
|
61
|
+
|
62
|
+
The resulting edge lengths and tilts will be of the type returned by
|
63
|
+
applying the above operations to the shapes. For example, if the shapes
|
64
|
+
are in ComplexIntervalField, the edge lengths and tilts are elements in
|
65
|
+
RealIntervalField.
|
66
|
+
|
67
|
+
**Remark:** The real edge lengths could also be obtained from the complex
|
68
|
+
edge lengths computed by ``ComplexCuspCrossSection``, but this has two
|
69
|
+
drawbacks. The times at which we apply ``abs`` or ``sqrt`` during the
|
70
|
+
development and rescaling of the cusps would be different. Though this
|
71
|
+
gives the same values, the resulting representation of these values by an
|
72
|
+
exact number type (such as the ones in ``squareExtension.py``) might be
|
73
|
+
prohibitively more complicated. Furthermore, ``ComplexCuspCrossSection``
|
74
|
+
does not work for non-orientable manifolds (it does not implement working
|
75
|
+
in a cusp's double-cover like the SnapPea kernel does).
|
76
|
+
|
77
|
+
Original source:
|
78
|
+
Asymmetric hyperbolic L-spaces, Heegaard genus, and Dehn filling
|
79
|
+
Nathan M. Dunfield, Neil R. Hoffman, Joan E. Licata
|
80
|
+
http://arxiv.org/abs/1407.7827
|
81
|
+
"""
|
82
|
+
|
83
|
+
HoroTriangle = RealHoroTriangle
|
84
|
+
|
85
|
+
@staticmethod
|
86
|
+
def fromManifoldAndShapes(manifold, shapes):
|
87
|
+
"""
|
88
|
+
**Examples:**
|
89
|
+
|
90
|
+
Initialize from shapes provided from the floats returned by
|
91
|
+
tetrahedra_shapes. The tilts appear to be negative but are not
|
92
|
+
verified by interval arithmetics::
|
93
|
+
|
94
|
+
>>> from snappy import Manifold
|
95
|
+
>>> M = Manifold("m004")
|
96
|
+
>>> M.canonize()
|
97
|
+
>>> shapes = M.tetrahedra_shapes('rect')
|
98
|
+
>>> e = RealCuspCrossSection.fromManifoldAndShapes(M, shapes)
|
99
|
+
>>> e.normalize_cusps()
|
100
|
+
>>> e.compute_tilts()
|
101
|
+
>>> tilts = e.read_tilts()
|
102
|
+
>>> for tilt in tilts:
|
103
|
+
... print('%.8f' % tilt)
|
104
|
+
-0.31020162
|
105
|
+
-0.31020162
|
106
|
+
-0.31020162
|
107
|
+
-0.31020162
|
108
|
+
-0.31020162
|
109
|
+
-0.31020162
|
110
|
+
-0.31020162
|
111
|
+
-0.31020162
|
112
|
+
|
113
|
+
Use verified intervals:
|
114
|
+
|
115
|
+
sage: from snappy.verify import *
|
116
|
+
sage: M = Manifold("m004")
|
117
|
+
sage: M.canonize()
|
118
|
+
sage: shapes = M.tetrahedra_shapes('rect', intervals=True)
|
119
|
+
|
120
|
+
Verify that the tetrahedra shapes form a complete manifold:
|
121
|
+
|
122
|
+
sage: check_logarithmic_gluing_equations_and_positively_oriented_tets(M,shapes)
|
123
|
+
sage: e = RealCuspCrossSection.fromManifoldAndShapes(M, shapes)
|
124
|
+
sage: e.normalize_cusps()
|
125
|
+
sage: e.compute_tilts()
|
126
|
+
|
127
|
+
|
128
|
+
Tilts are verified to be negative:
|
129
|
+
|
130
|
+
sage: [tilt < 0 for tilt in e.read_tilts()]
|
131
|
+
[True, True, True, True, True, True, True, True]
|
132
|
+
|
133
|
+
Setup necessary things in Sage:
|
134
|
+
|
135
|
+
sage: from sage.rings.qqbar import QQbar
|
136
|
+
sage: from sage.rings.rational_field import RationalField
|
137
|
+
sage: from sage.rings.polynomial.polynomial_ring import polygen
|
138
|
+
sage: from sage.rings.real_mpfi import RealIntervalField
|
139
|
+
sage: from sage.rings.complex_interval_field import ComplexIntervalField
|
140
|
+
sage: x = polygen(RationalField())
|
141
|
+
sage: RIF = RealIntervalField()
|
142
|
+
sage: CIF = ComplexIntervalField()
|
143
|
+
|
144
|
+
sage: M = Manifold("m412")
|
145
|
+
sage: M.canonize()
|
146
|
+
|
147
|
+
Make our own exact shapes using Sage. They are the root of the given
|
148
|
+
polynomial isolated by the given interval.
|
149
|
+
|
150
|
+
sage: r=QQbar.polynomial_root(x**2-x+1,CIF(RIF(0.49,0.51),RIF(0.86,0.87)))
|
151
|
+
sage: shapes = 5 * [r]
|
152
|
+
sage: e=RealCuspCrossSection.fromManifoldAndShapes(M, shapes)
|
153
|
+
sage: e.normalize_cusps()
|
154
|
+
|
155
|
+
The following three lines verify that we have shapes giving a complete
|
156
|
+
hyperbolic structure. The last one uses complex interval arithmetics.
|
157
|
+
|
158
|
+
sage: from snappy.verify import edge_equations
|
159
|
+
sage: edge_equations.check_polynomial_edge_equations_exactly(e.mcomplex)
|
160
|
+
sage: e.check_cusp_development_exactly()
|
161
|
+
sage: edge_equations.check_logarithmic_edge_equations_and_positivity(e.mcomplex, CIF)
|
162
|
+
|
163
|
+
Because we use exact types, we can verify that each tilt is either
|
164
|
+
negative or exactly zero.
|
165
|
+
|
166
|
+
sage: e.compute_tilts()
|
167
|
+
sage: [(tilt < 0, tilt == 0) for tilt in e.read_tilts()]
|
168
|
+
[(True, False), (True, False), (False, True), (True, False), (True, False), (True, False), (True, False), (False, True), (True, False), (True, False), (True, False), (False, True), (False, True), (False, True), (False, True), (False, True), (True, False), (True, False), (False, True), (True, False)]
|
169
|
+
|
170
|
+
Some are exactly zero, so the canonical cell decomposition has
|
171
|
+
non-tetrahedral cells. In fact, the one cell is a cube. We can obtain
|
172
|
+
the retriangulation of the canonical cell decomposition as follows:
|
173
|
+
|
174
|
+
sage: e.compute_tilts()
|
175
|
+
sage: opacities = [tilt < 0 for tilt in e.read_tilts()]
|
176
|
+
sage: N = M._canonical_retriangulation()
|
177
|
+
sage: N.num_tetrahedra()
|
178
|
+
12
|
179
|
+
|
180
|
+
The manifold m412 has 8 isometries, the above code certified that using
|
181
|
+
exact arithmetic:
|
182
|
+
sage: len(N.isomorphisms_to(N))
|
183
|
+
8
|
184
|
+
"""
|
185
|
+
for cusp_info in manifold.cusp_info():
|
186
|
+
if not cusp_info['complete?']:
|
187
|
+
raise IncompleteCuspError(manifold)
|
188
|
+
|
189
|
+
m = t3m.Mcomplex(manifold)
|
190
|
+
|
191
|
+
t = TransferKernelStructuresEngine(m, manifold)
|
192
|
+
t.reindex_cusps_and_transfer_peripheral_curves()
|
193
|
+
t.add_shapes(shapes)
|
194
|
+
|
195
|
+
c = RealCuspCrossSection(m)
|
196
|
+
c.add_structures()
|
197
|
+
|
198
|
+
# For testing against SnapPea kernel data
|
199
|
+
c.manifold = manifold
|
200
|
+
|
201
|
+
return c
|
202
|
+
|
203
|
+
@staticmethod
|
204
|
+
def _tet_tilt(tet : t3m.Tetrahedron, face : int):
|
205
|
+
"The tilt of the face of the tetrahedron."
|
206
|
+
|
207
|
+
v = simplex.comp(face)
|
208
|
+
|
209
|
+
ans = 0
|
210
|
+
for w in simplex.ZeroSubsimplices:
|
211
|
+
if v == w:
|
212
|
+
c_w = 1
|
213
|
+
else:
|
214
|
+
z = tet.ShapeParameters[v | w]
|
215
|
+
c_w = -z.real() / abs(z)
|
216
|
+
R_w = tet.horotriangles[w].circumradius
|
217
|
+
ans += c_w * R_w
|
218
|
+
return ans
|
219
|
+
|
220
|
+
@staticmethod
|
221
|
+
def _face_tilt(face : t3m.Face):
|
222
|
+
"""
|
223
|
+
Tilt of a face in the triangulation: this is the sum of
|
224
|
+
the two tilts of the two faces of the two tetrahedra that are
|
225
|
+
glued. The argument is a simplex.Face.
|
226
|
+
"""
|
227
|
+
|
228
|
+
return sum([ RealCuspCrossSection._tet_tilt(corner.Tetrahedron,
|
229
|
+
corner.Subsimplex)
|
230
|
+
for corner in face.Corners ])
|
231
|
+
|
232
|
+
def compute_tilts(self):
|
233
|
+
"""
|
234
|
+
Computes all tilts. They are written to the instances of
|
235
|
+
simplex.Face and can be accessed as
|
236
|
+
[ face.Tilt for face in crossSection.Faces].
|
237
|
+
"""
|
238
|
+
|
239
|
+
for face in self.mcomplex.Faces:
|
240
|
+
face.Tilt = RealCuspCrossSection._face_tilt(face)
|
241
|
+
|
242
|
+
def read_tilts(self):
|
243
|
+
"""
|
244
|
+
After compute_tilts() has been called, put the tilt values into an
|
245
|
+
array containing the tilt of face 0, 1, 2, 3 of the first tetrahedron,
|
246
|
+
... of the second tetrahedron, ....
|
247
|
+
"""
|
248
|
+
|
249
|
+
def index_of_face_corner(corner):
|
250
|
+
face_index = simplex.comp(corner.Subsimplex).bit_length() - 1
|
251
|
+
return 4 * corner.Tetrahedron.Index + face_index
|
252
|
+
|
253
|
+
tilts = (4 * len(self.mcomplex.Tetrahedra)) * [ None ]
|
254
|
+
|
255
|
+
# For each face of the triangulation
|
256
|
+
for face in self.mcomplex.Faces:
|
257
|
+
for corner in face.Corners:
|
258
|
+
tilts[index_of_face_corner(corner)] = face.Tilt
|
259
|
+
|
260
|
+
return tilts
|
261
|
+
|
262
|
+
def _testing_check_against_snappea(self, epsilon):
|
263
|
+
"""
|
264
|
+
Compare the computed edge lengths and tilts against the one computed by
|
265
|
+
the SnapPea kernel.
|
266
|
+
|
267
|
+
>>> from snappy import Manifold
|
268
|
+
|
269
|
+
Convention of the kernel is to use (3/8) sqrt(3) as area (ensuring that
|
270
|
+
cusp neighborhoods are disjoint).
|
271
|
+
|
272
|
+
>>> cusp_area = 0.649519052838329
|
273
|
+
|
274
|
+
>>> for name in ['m009', 'm015', 't02333']:
|
275
|
+
... M = Manifold(name)
|
276
|
+
... e = RealCuspCrossSection.fromManifoldAndShapes(M, M.tetrahedra_shapes('rect'))
|
277
|
+
... e.normalize_cusps(cusp_area)
|
278
|
+
... e._testing_check_against_snappea(1e-10)
|
279
|
+
|
280
|
+
"""
|
281
|
+
|
282
|
+
CuspCrossSectionBase._testing_check_against_snappea(self, epsilon)
|
283
|
+
|
284
|
+
# Short-hand
|
285
|
+
TwoSubs = simplex.TwoSubsimplices
|
286
|
+
|
287
|
+
# SnapPea kernel results
|
288
|
+
snappea_tilts, snappea_edges = self.manifold._cusp_cross_section_info()
|
289
|
+
|
290
|
+
# Check tilts
|
291
|
+
# Iterate through tet
|
292
|
+
for tet, snappea_tet_tilts in zip(self.mcomplex.Tetrahedra, snappea_tilts):
|
293
|
+
# Iterate through vertices of tet
|
294
|
+
for f, snappea_tet_tilt in zip(TwoSubs, snappea_tet_tilts):
|
295
|
+
tilt = RealCuspCrossSection._tet_tilt(tet, f)
|
296
|
+
if not abs(snappea_tet_tilt - tilt) < epsilon:
|
297
|
+
raise ConsistencyWithSnapPeaNumericalVerifyError(
|
298
|
+
snappea_tet_tilt, tilt)
|
@@ -0,0 +1,159 @@
|
|
1
|
+
from .exceptions import IncompleteCuspError
|
2
|
+
from .real_cusp_cross_section import RealCuspCrossSection
|
3
|
+
from .vertices import scale_vertices_from_horotriangles
|
4
|
+
from .. import add_r13_geometry
|
5
|
+
|
6
|
+
from ...hyperboloid.horoball import R13Horoball
|
7
|
+
from ...tiling.tile import Tile, compute_tiles
|
8
|
+
from ...tiling.triangle import add_triangles_to_tetrahedra
|
9
|
+
from ...tiling.lifted_tetrahedron import LiftedTetrahedron
|
10
|
+
from ...tiling.lifted_tetrahedron_set import (LiftedTetrahedronSet,
|
11
|
+
get_lifted_tetrahedron_set)
|
12
|
+
from ...tiling.iter_utils import IteratorCache
|
13
|
+
from ...snap.t3mlite import Mcomplex, Vertex, Corner
|
14
|
+
from ...matrix import make_identity_matrix
|
15
|
+
from ...math_basics import correct_min
|
16
|
+
|
17
|
+
|
18
|
+
from typing import Sequence
|
19
|
+
|
20
|
+
def mcomplex_for_tiling_cusp_neighborhoods(
|
21
|
+
manifold, bits_prec : int, verified : bool) -> Mcomplex:
|
22
|
+
"""
|
23
|
+
Computes mcomplex such that each vertex has a function
|
24
|
+
tiles() returning a stream of tiles to cover the space
|
25
|
+
H^3 / peripheral group of corresponding cusp.
|
26
|
+
"""
|
27
|
+
|
28
|
+
|
29
|
+
for cusp_info in manifold.cusp_info():
|
30
|
+
if not cusp_info['complete?']:
|
31
|
+
raise IncompleteCuspError(manifold)
|
32
|
+
|
33
|
+
# Convert SnapPea kernel triangulation to python triangulation
|
34
|
+
# snappy.snap.t3mlite.Mcomplex
|
35
|
+
mcomplex = Mcomplex(manifold)
|
36
|
+
|
37
|
+
# Add vertices in hyperboloid model and other geometric information
|
38
|
+
add_r13_geometry(mcomplex,
|
39
|
+
manifold,
|
40
|
+
verified=verified, bits_prec=bits_prec)
|
41
|
+
|
42
|
+
add_triangles_to_tetrahedra(mcomplex)
|
43
|
+
|
44
|
+
add_cusp_cross_section(mcomplex)
|
45
|
+
scale_vertices_from_horotriangles(mcomplex)
|
46
|
+
|
47
|
+
for v in mcomplex.Vertices:
|
48
|
+
v._tiles = None
|
49
|
+
def tiles(v=v, verified=verified):
|
50
|
+
if v._tiles is None:
|
51
|
+
v._tiles = IteratorCache(
|
52
|
+
compute_tiles_for_cusp_neighborhood(
|
53
|
+
v, verified))
|
54
|
+
return v._tiles
|
55
|
+
v.tiles = tiles
|
56
|
+
|
57
|
+
return mcomplex
|
58
|
+
|
59
|
+
def compute_tiles_for_cusp_neighborhood(
|
60
|
+
v : Vertex, verified : bool) -> Sequence[Tile]:
|
61
|
+
"""
|
62
|
+
If suitable structures have been added to an Mcomplex
|
63
|
+
(add_r13_geometry, add_triangles_to_tetrahedra), returns
|
64
|
+
a stream of tiles to cover the space
|
65
|
+
H^3 / peripheral group of cusp corresponding to given
|
66
|
+
vertex.
|
67
|
+
"""
|
68
|
+
|
69
|
+
corner = v.Corners[0]
|
70
|
+
|
71
|
+
horoball_defining_vec = corner.Tetrahedron.R13_vertices[corner.Subsimplex]
|
72
|
+
RF = horoball_defining_vec[0].parent()
|
73
|
+
|
74
|
+
# Lowest non-zero value expected is
|
75
|
+
# 2 * (v.lower_bound_embedding_scale ** 2)
|
76
|
+
#
|
77
|
+
# Divide by half so that we have some margin.
|
78
|
+
|
79
|
+
min_neg_prod_distinct = (v.lower_bound_embedding_scale ** 2)
|
80
|
+
|
81
|
+
if verified:
|
82
|
+
max_neg_prod_equal = min_neg_prod_distinct
|
83
|
+
else:
|
84
|
+
max_neg_prod_equal = _compute_prod_epsilon(RF)
|
85
|
+
|
86
|
+
initial_lifted_tetrahedron = LiftedTetrahedron(
|
87
|
+
corner.Tetrahedron, make_identity_matrix(ring=RF, n=4))
|
88
|
+
|
89
|
+
lifted_tetrahedron_set : LiftedTetrahedronSet = (
|
90
|
+
get_lifted_tetrahedron_set(
|
91
|
+
base_point=horoball_defining_vec,
|
92
|
+
act_on_base_point_by_inverse=True,
|
93
|
+
max_neg_prod_equal=max_neg_prod_equal,
|
94
|
+
min_neg_prod_distinct=min_neg_prod_distinct,
|
95
|
+
canonical_keys_function=None,
|
96
|
+
verified=verified))
|
97
|
+
|
98
|
+
return compute_tiles(
|
99
|
+
geometric_object=R13Horoball(horoball_defining_vec),
|
100
|
+
visited_lifted_tetrahedra=lifted_tetrahedron_set,
|
101
|
+
initial_lifted_tetrahedra=[ initial_lifted_tetrahedron ],
|
102
|
+
verified=verified)
|
103
|
+
|
104
|
+
def add_cusp_cross_section(mcomplex : Mcomplex):
|
105
|
+
"""
|
106
|
+
Adds cross section to all cusps. Recall that a cusp cross
|
107
|
+
section corresponds to a choice of horoballs about the vertices
|
108
|
+
corresponding to the cusp. Scales the defining light-like vectors
|
109
|
+
of the vertices of the tetrahedra such that they correspond to
|
110
|
+
these horoballs.
|
111
|
+
"""
|
112
|
+
|
113
|
+
c = RealCuspCrossSection(mcomplex)
|
114
|
+
c.add_structures(None)
|
115
|
+
|
116
|
+
# Save cusp cross section for later
|
117
|
+
mcomplex.real_cusp_cross_section = c
|
118
|
+
|
119
|
+
for i, (v, area) in enumerate(
|
120
|
+
zip(mcomplex.Vertices, c.cusp_areas())):
|
121
|
+
# Area of cusp
|
122
|
+
v.cusp_area = area
|
123
|
+
# A cusp intersects the triangulation in standard form
|
124
|
+
# if for each tetrahedron, the corresponding horoball
|
125
|
+
# intersects the tetrahedron in three but not four faces.
|
126
|
+
#
|
127
|
+
# We store here how much the cusp can be scaled before it
|
128
|
+
# is no longer in standard form.
|
129
|
+
v.scale_for_std_form = (
|
130
|
+
c.compute_scale_for_std_form(v))
|
131
|
+
v.exp_self_distance_along_edges = (
|
132
|
+
c.exp_distance_neighborhoods_measured_along_edges(i, i))
|
133
|
+
# v.lower_bound_embedding_scale: lower bound on how much
|
134
|
+
# we can scale the cusp to stay embedded.
|
135
|
+
if v.exp_self_distance_along_edges is None:
|
136
|
+
v.lower_bound_embedding_scale = v.scale_for_std_form
|
137
|
+
else:
|
138
|
+
v.lower_bound_embedding_scale = correct_min(
|
139
|
+
[ v.scale_for_std_form,
|
140
|
+
v.exp_self_distance_along_edges.sqrt() ])
|
141
|
+
|
142
|
+
def _compute_prod_epsilon(RF):
|
143
|
+
p = RF.precision()
|
144
|
+
|
145
|
+
# We try to be a factor of at least several magnitudes smaller than
|
146
|
+
# 1/_compute_epsilon_inverse(RF) in hyperboloid_dict.py.
|
147
|
+
#
|
148
|
+
# This factor will even grow larger as the precision increases.
|
149
|
+
#
|
150
|
+
# That way, we will hopefully fail in _equality_predicate
|
151
|
+
# in hyperboloid_dict rather than failing by not hashing together
|
152
|
+
# lifted tetrahedra that should be the same but are not recognised
|
153
|
+
# as such because of numerical error.
|
154
|
+
|
155
|
+
result = RF(1e-8)
|
156
|
+
if p > 53:
|
157
|
+
result *= RF(0.5) ** ((p - 53) / 2)
|
158
|
+
|
159
|
+
return result
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from ...hyperboloid import r13_dot
|
2
|
+
from ...snap.t3mlite import simplex
|
3
|
+
|
4
|
+
def scale_vertices_from_horotriangles(mcomplex):
|
5
|
+
"""
|
6
|
+
Scales the R13 vertices of each tetrahedron so that
|
7
|
+
each defines a horosphere that intersects the tetrahedron
|
8
|
+
in a triangle congruent to the horo triangles coming
|
9
|
+
from a cusp cross section.
|
10
|
+
"""
|
11
|
+
|
12
|
+
for tet in mcomplex.Tetrahedra:
|
13
|
+
_scale_vertices_tet(tet)
|
14
|
+
|
15
|
+
def _scale_vertices_tet(tet):
|
16
|
+
R13_vertex_products = {
|
17
|
+
v0 | v1 : r13_dot(pt0, pt1)
|
18
|
+
for v0, pt0 in tet.R13_vertices.items()
|
19
|
+
for v1, pt1 in tet.R13_vertices.items()
|
20
|
+
if v0 > v1 }
|
21
|
+
|
22
|
+
for v0 in simplex.ZeroSubsimplices:
|
23
|
+
v1, v2, _ = simplex.VerticesOfFaceCounterclockwise[simplex.comp(v0)]
|
24
|
+
|
25
|
+
length_on_cusp = tet.horotriangles[v0].get_real_lengths()[v0 | v1 | v2]
|
26
|
+
length_on_horosphere = (
|
27
|
+
-2 * R13_vertex_products[v1 | v2] / (
|
28
|
+
R13_vertex_products[v0 | v1] *
|
29
|
+
R13_vertex_products[v0 | v2])).sqrt()
|
30
|
+
s = length_on_horosphere / length_on_cusp
|
31
|
+
|
32
|
+
tet.R13_vertices[v0] = s * tet.R13_vertices[v0]
|
File without changes
|
@@ -0,0 +1,152 @@
|
|
1
|
+
from .fixed_points import r13_fixed_line_of_psl2c_matrix
|
2
|
+
from .line import R13LineWithMatrix
|
3
|
+
from .. import word_list_to_psl2c_matrix
|
4
|
+
from .. import Filling
|
5
|
+
from ...upper_halfspace import sl2c_inverse # type: ignore
|
6
|
+
from ...snap.t3mlite import Mcomplex, Vertex, Tetrahedron, simplex
|
7
|
+
|
8
|
+
from collections import deque
|
9
|
+
|
10
|
+
from typing import Tuple, Sequence, Optional
|
11
|
+
|
12
|
+
def add_r13_core_curves(
|
13
|
+
mcomplex : Mcomplex,
|
14
|
+
manifold):
|
15
|
+
|
16
|
+
for tet in mcomplex.Tetrahedra:
|
17
|
+
# Dict, keys are a subset of simplex.ZeroSubsimplices
|
18
|
+
#
|
19
|
+
# If a vertex of a tet corresponds to a filled cusp, this dictionary
|
20
|
+
# will contain the appropriate lift of the core curve in the
|
21
|
+
# hyperboloid model.
|
22
|
+
tet.core_curves = { }
|
23
|
+
|
24
|
+
# For each cusp, a pair of words for the meridian and longitude as
|
25
|
+
# sequence of non-zero integers.
|
26
|
+
#
|
27
|
+
# Only computed when needed.
|
28
|
+
all_peripheral_words : Optional[Sequence[Sequence[Sequence[int]]]] = None
|
29
|
+
for v, info in zip(mcomplex.Vertices, manifold.cusp_info()):
|
30
|
+
if v.filling_matrix[0] != (0,0):
|
31
|
+
if all_peripheral_words is None:
|
32
|
+
# Make the SnapPea kernel compute peripheral curves the first
|
33
|
+
# time when we need them.
|
34
|
+
G = manifold.fundamental_group(False)
|
35
|
+
all_peripheral_words = G.peripheral_curves(as_int_list=True)
|
36
|
+
# Note that a cusp only determines the words for the meridian
|
37
|
+
# and longitude only up to conjugacy, we need to pick a lift of the
|
38
|
+
# cusp and a path from the basepoint to the lift.
|
39
|
+
#
|
40
|
+
# Similarly, the lift of the core curve of a filled cusp to the
|
41
|
+
# hyperboloid model depends on a lift of a cusp a path from the
|
42
|
+
# basepoint to the lift.
|
43
|
+
#
|
44
|
+
# We compute the lift for each vertex of each tetrahedron in the
|
45
|
+
# fundamental domain corresponding to the cusp (with the path
|
46
|
+
# connecting the basepoint to the vertex being the one contained
|
47
|
+
# in the fundamental domain).
|
48
|
+
#
|
49
|
+
# Starting with the one choice the SnapPea kernel did and computing
|
50
|
+
# the resulting lift of the core curve, we need to transfer it
|
51
|
+
# to the other choices of vertices of tetrahedra corresponding to
|
52
|
+
# the cusp by "developing" the cusp.
|
53
|
+
#
|
54
|
+
_develop_core_curve_cusp(
|
55
|
+
mcomplex,
|
56
|
+
v,
|
57
|
+
_compute_core_curve(
|
58
|
+
mcomplex,
|
59
|
+
all_peripheral_words[v.Index],
|
60
|
+
v.filling_matrix[1]))
|
61
|
+
|
62
|
+
|
63
|
+
###############################################################################
|
64
|
+
# Helpers
|
65
|
+
|
66
|
+
def _compute_core_curve(
|
67
|
+
mcomplex : Mcomplex,
|
68
|
+
peripheral_words : Sequence[Sequence[int]],
|
69
|
+
core_curve_coefficients : Filling) -> R13LineWithMatrix:
|
70
|
+
"""
|
71
|
+
Compute core curve given words for meridian and longitude and
|
72
|
+
the integers determining a curve (as sum of a multiple of meridian
|
73
|
+
and longitude) that is parallel to the core curve.
|
74
|
+
"""
|
75
|
+
|
76
|
+
result = mcomplex.GeneratorMatrices[0]
|
77
|
+
|
78
|
+
for word, f in zip(peripheral_words, core_curve_coefficients):
|
79
|
+
if f != 0:
|
80
|
+
m = word_list_to_psl2c_matrix(mcomplex, word)
|
81
|
+
if f < 0:
|
82
|
+
m = sl2c_inverse(m)
|
83
|
+
for i in range(abs(f)):
|
84
|
+
result = result * m
|
85
|
+
|
86
|
+
return r13_fixed_line_of_psl2c_matrix(result)
|
87
|
+
|
88
|
+
def _find_standard_basepoint(mcomplex : Mcomplex,
|
89
|
+
vertex : Vertex) -> Tuple[Tetrahedron, int]:
|
90
|
+
"""
|
91
|
+
Reimplements find_standard_basepoint in fundamental_group.c.
|
92
|
+
|
93
|
+
That is, it finds the same tetrahedron and vertex of that tetrahedron
|
94
|
+
in the fundamental domain that the SnapPea kernel used to compute the
|
95
|
+
words for the meridian and longitude of the given cusp.
|
96
|
+
|
97
|
+
The SnapPea kernel picks the first vertex it finds where the meridian
|
98
|
+
and longitude intersect.
|
99
|
+
"""
|
100
|
+
|
101
|
+
# Traverse tets and their vertices in the same order the SnapPea kernel
|
102
|
+
# does
|
103
|
+
for tet in mcomplex.Tetrahedra:
|
104
|
+
for v in simplex.ZeroSubsimplices:
|
105
|
+
# Only consider vertices corresponding to the given cusp
|
106
|
+
if tet.Class[v] is vertex:
|
107
|
+
for f in simplex.TwoSubsimplices:
|
108
|
+
# Check that the meridian and longitude both
|
109
|
+
# go through the same leg of the spine of the cusp
|
110
|
+
# triangle.
|
111
|
+
#
|
112
|
+
# Note that we only support orientable manifolds,
|
113
|
+
# so we only consider the 0-sheet of the orientation
|
114
|
+
# double-cover of the cusp triangulation.
|
115
|
+
if (tet.PeripheralCurves[0][0][v][f] != 0 and
|
116
|
+
tet.PeripheralCurves[1][0][v][f] != 0):
|
117
|
+
return tet, v
|
118
|
+
|
119
|
+
raise Exception("Could not find basepoint for cusp. This is a bug.")
|
120
|
+
|
121
|
+
|
122
|
+
def _develop_core_curve_cusp(
|
123
|
+
mcomplex : Mcomplex,
|
124
|
+
v : Vertex,
|
125
|
+
core_curve : R13LineWithMatrix) -> None:
|
126
|
+
"""
|
127
|
+
Given the core curve computed from the SnapPea kernel's given
|
128
|
+
words for the meridian and longitude for the given cusp,
|
129
|
+
compute the lift of the core curve for all vertices of the
|
130
|
+
tetrahedra corresponding to the given cusp.
|
131
|
+
"""
|
132
|
+
|
133
|
+
# Start with the tet and vertex that the SnapPea kernel used
|
134
|
+
# to compute the words.
|
135
|
+
tet, vertex = _find_standard_basepoint(mcomplex, v)
|
136
|
+
|
137
|
+
tet.core_curves[vertex] = core_curve
|
138
|
+
pending_tet_verts = deque([ (tet, vertex, core_curve) ])
|
139
|
+
|
140
|
+
# Breadth-first traversal of cusp triangles to compute appropriate
|
141
|
+
# transform of core curve.
|
142
|
+
while pending_tet_verts:
|
143
|
+
tet, vertex, core_curve = pending_tet_verts.popleft()
|
144
|
+
for f in simplex.FacesAroundVertexCounterclockwise[vertex]:
|
145
|
+
new_tet = tet.Neighbor[f]
|
146
|
+
new_vertex = tet.Gluing[f].image(vertex)
|
147
|
+
if new_vertex in new_tet.core_curves:
|
148
|
+
continue
|
149
|
+
new_core_curve = core_curve.transformed(tet.O13_matrices[f])
|
150
|
+
new_tet.core_curves[new_vertex] = new_core_curve
|
151
|
+
pending_tet_verts.append(
|
152
|
+
(new_tet, new_vertex, new_core_curve))
|