snappy 3.1.1__cp38-cp38-win_amd64.whl → 3.2__cp38-cp38-win_amd64.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.cp38-win_amd64.pyd +0 -0
- snappy/SnapPy.cp38-win_amd64.pyd +0 -0
- snappy/SnapPyHP.cp38-win_amd64.pyd +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/additional_classes.rst.txt +40 -40
- snappy/doc/_sources/bugs.rst.txt +14 -14
- snappy/doc/_sources/censuses.rst.txt +51 -51
- snappy/doc/_sources/credits.rst.txt +75 -75
- snappy/doc/_sources/development.rst.txt +259 -239
- snappy/doc/_sources/index.rst.txt +182 -115
- snappy/doc/_sources/installing.rst.txt +247 -264
- snappy/doc/_sources/manifold.rst.txt +6 -6
- snappy/doc/_sources/manifoldhp.rst.txt +46 -46
- snappy/doc/_sources/news.rst.txt +355 -283
- snappy/doc/_sources/other.rst.txt +25 -25
- snappy/doc/_sources/platonic_census.rst.txt +20 -20
- snappy/doc/_sources/plink.rst.txt +102 -102
- snappy/doc/_sources/ptolemy.rst.txt +66 -66
- snappy/doc/_sources/ptolemy_classes.rst.txt +42 -42
- snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -297
- snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -363
- snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -301
- snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -61
- snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -105
- snappy/doc/_sources/screenshots.rst.txt +21 -21
- snappy/doc/_sources/snap.rst.txt +87 -87
- snappy/doc/_sources/snappy.rst.txt +28 -28
- snappy/doc/_sources/spherogram.rst.txt +103 -103
- snappy/doc/_sources/todo.rst.txt +47 -47
- snappy/doc/_sources/triangulation.rst.txt +11 -11
- snappy/doc/_sources/tutorial.rst.txt +49 -49
- snappy/doc/_sources/verify.rst.txt +210 -150
- snappy/doc/_sources/verify_internals.rst.txt +79 -90
- snappy/doc/_static/basic.css +924 -902
- 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 +12 -13
- 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 +199 -199
- snappy/doc/_static/pygments.css +74 -73
- snappy/doc/_static/searchtools.js +125 -71
- snappy/doc/_static/snappy_furo.css +33 -33
- snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -42
- snappy/doc/_static/sphinx_highlight.js +13 -3
- snappy/doc/additional_classes.html +1499 -1330
- snappy/doc/bugs.html +131 -134
- snappy/doc/censuses.html +426 -445
- snappy/doc/credits.html +180 -183
- snappy/doc/development.html +383 -363
- snappy/doc/genindex.html +1330 -1409
- snappy/doc/index.html +261 -206
- snappy/doc/installing.html +345 -363
- snappy/doc/manifold.html +3451 -2839
- snappy/doc/manifoldhp.html +179 -182
- snappy/doc/news.html +387 -329
- snappy/doc/objects.inv +0 -0
- snappy/doc/other.html +160 -162
- snappy/doc/platonic_census.html +374 -377
- snappy/doc/plink.html +209 -212
- snappy/doc/ptolemy.html +253 -255
- snappy/doc/ptolemy_classes.html +1143 -1146
- snappy/doc/ptolemy_examples1.html +408 -410
- snappy/doc/ptolemy_examples2.html +470 -473
- snappy/doc/ptolemy_examples3.html +413 -416
- snappy/doc/ptolemy_examples4.html +194 -197
- snappy/doc/ptolemy_prelim.html +247 -250
- snappy/doc/py-modindex.html +164 -167
- snappy/doc/screenshots.html +140 -142
- snappy/doc/search.html +134 -137
- snappy/doc/searchindex.js +1 -1
- snappy/doc/snap.html +201 -204
- snappy/doc/snappy.html +180 -182
- snappy/doc/spherogram.html +1210 -1213
- snappy/doc/todo.html +165 -168
- snappy/doc/triangulation.html +1583 -1474
- snappy/doc/tutorial.html +158 -161
- snappy/doc/verify.html +329 -275
- snappy/doc/verify_internals.html +1234 -1691
- 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.cp38-win_amd64.pyd +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 +14 -10
- 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-38.pyc +0 -0
- snappy/__pycache__/browser.cpython-38.pyc +0 -0
- snappy/__pycache__/cache.cpython-38.pyc +0 -0
- snappy/__pycache__/database.cpython-38.pyc +0 -0
- snappy/__pycache__/db_utilities.cpython-38.pyc +0 -0
- snappy/__pycache__/decorated_isosig.cpython-38.pyc +0 -0
- snappy/__pycache__/exceptions.cpython-38.pyc +0 -0
- snappy/__pycache__/export_stl.cpython-38.pyc +0 -0
- snappy/__pycache__/filedialog.cpython-38.pyc +0 -0
- snappy/__pycache__/gui.cpython-38.pyc +0 -0
- snappy/__pycache__/horoviewer.cpython-38.pyc +0 -0
- snappy/__pycache__/math_basics.cpython-38.pyc +0 -0
- snappy/__pycache__/matrix.cpython-38.pyc +0 -0
- snappy/__pycache__/number.cpython-38.pyc +0 -0
- snappy/__pycache__/numeric_output_checker.cpython-38.pyc +0 -0
- snappy/__pycache__/pari.cpython-38.pyc +0 -0
- snappy/__pycache__/polyviewer.cpython-38.pyc +0 -0
- snappy/__pycache__/sage_helper.cpython-38.pyc +0 -0
- snappy/__pycache__/version.cpython-38.pyc +0 -0
- snappy/doc/_sources/verify_canon.rst.txt +0 -90
- snappy/doc/_static/jquery-3.6.0.js +0 -10881
- snappy/doc/_static/js/html5shiv-printshiv.min.js +0 -4
- snappy/doc/_static/js/html5shiv.min.js +0 -4
- snappy/doc/_static/underscore-1.13.1.js +0 -2042
- snappy/doc/_static/underscore.js +0 -6
- snappy/doc/verify_canon.html +0 -304
- snappy/drilling/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/constants.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/crush.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/cusps.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/debug.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/epsilons.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/exceptions.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/fixed_points.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/geodesic_info.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/geodesic_tube.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/geometric_structure.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/line.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/moves.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/peripheral_curves.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/perturb.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/quotient_space.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/spatial_dict.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/subdivide.cpython-38.pyc +0 -0
- snappy/drilling/__pycache__/tracing.cpython-38.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-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/barycentric_geometry.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/exceptions.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/hyp_utils.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/link_projection.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/main.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/mcomplex_with_expansion.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/mcomplex_with_link.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/mcomplex_with_memory.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/pl_utils.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/put_in_S3.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/rational_linear_algebra.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/simplify_to_base_tri.cpython-38.pyc +0 -0
- snappy/exterior_to_link/__pycache__/stored_moves.cpython-38.pyc +0 -0
- snappy/hyperboloid/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/manifolds/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/component.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/coordinates.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/fieldExtensions.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/findLoops.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/homology.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/manifoldMethods.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/matrix.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/numericalSolutionsToGroebnerBasis.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/polynomial.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/processComponents.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/processFileBase.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/processFileDispatch.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/processMagmaFile.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/processRurFile.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/ptolemyGeneralizedObstructionClass.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/ptolemyObstructionClass.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/ptolemyVariety.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/ptolemyVarietyPrimeIdealGroebnerBasis.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/rur.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/solutionsToPrimeIdealGroebnerBasis.cpython-38.pyc +0 -0
- snappy/ptolemy/__pycache__/utilities.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/character_varieties.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/fundamental_polyhedron.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/interval_reps.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/kernel_structures.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/mcomplex_base.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/nsagetools.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/polished_reps.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/shapes.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/slice_obs_HKL.cpython-38.pyc +0 -0
- snappy/snap/__pycache__/utilities.cpython-38.pyc +0 -0
- snappy/snap/peripheral/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/snap/peripheral/__pycache__/dual_cellulation.cpython-38.pyc +0 -0
- snappy/snap/peripheral/__pycache__/link.cpython-38.pyc +0 -0
- snappy/snap/peripheral/__pycache__/peripheral.cpython-38.pyc +0 -0
- snappy/snap/peripheral/__pycache__/surface.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/arrow.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/corner.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/edge.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/face.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/files.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/homology.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/linalg.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/mcomplex.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/perm4.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/simplex.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/spun.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/surface.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/tetrahedron.cpython-38.pyc +0 -0
- snappy/snap/t3mlite/__pycache__/vertex.cpython-38.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-38.pyc +0 -0
- snappy/twister/__pycache__/main.cpython-38.pyc +0 -0
- snappy/upper_halfspace/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/upper_halfspace/__pycache__/ideal_point.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/cuspCrossSection.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/cuspTranslations.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/cusp_areas.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/cusp_shapes.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/exceptions.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/interval_newton_shapes_engine.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/interval_tree.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/krawczyk_shapes_engine.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/realAlgebra.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/shapes.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/short_slopes.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/squareExtensions.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/verifyCanonical.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/verifyHyperbolicity.cpython-38.pyc +0 -0
- snappy/verify/__pycache__/volume.cpython-38.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/adjust_torsion.cpython-38.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/closed.cpython-38.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/compute_ptolemys.cpython-38.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/cusped.cpython-38.pyc +0 -0
- snappy/verify/complex_volume/__pycache__/extended_bloch.cpython-38.pyc +0 -0
- snappy/verify/cuspCrossSection.py +0 -1422
- snappy/verify/maximal_cusp_area_matrix/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/verify/maximal_cusp_area_matrix/__pycache__/cusp_tiling_engine.cpython-38.pyc +0 -0
- snappy/verify/maximal_cusp_area_matrix/__pycache__/cusp_translate_engine.cpython-38.pyc +0 -0
- snappy/verify/upper_halfspace/__pycache__/__init__.cpython-38.pyc +0 -0
- snappy/verify/upper_halfspace/__pycache__/extended_matrix.cpython-38.pyc +0 -0
- snappy/verify/upper_halfspace/__pycache__/finite_point.cpython-38.pyc +0 -0
- snappy/verify/upper_halfspace/__pycache__/ideal_point.cpython-38.pyc +0 -0
- snappy-3.1.1.dist-info/RECORD +0 -575
- {snappy-3.1.1.dist-info → snappy-3.2.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
from ..geometric_structure.geodesic.fixed_points import r13_fixed_line_of_psl2c_matrix
|
2
|
+
from ..geometric_structure.geodesic.geodesic_start_point_info import sample_line, GeodesicStartPointInfo
|
3
|
+
from ..geometric_structure.geodesic.line import R13LineWithMatrix
|
4
|
+
from ..hyperboloid.line import R13Line
|
5
|
+
from ..hyperboloid import so13_to_psl2c
|
6
|
+
from ..upper_halfspace import complex_length_of_psl2c_matrix
|
7
|
+
from ..math_basics import lower # type: ignore
|
8
|
+
from ..snap.t3mlite import Mcomplex
|
9
|
+
|
10
|
+
from typing import List, Optional
|
11
|
+
|
12
|
+
class GeodesicInfoBase:
|
13
|
+
"""
|
14
|
+
Basic information about a geodesic, consisting of word and matrix.
|
15
|
+
|
16
|
+
Used intermediately during the computation of the length spectrum.
|
17
|
+
Ordered by (lower bound of) real length.
|
18
|
+
|
19
|
+
After de-duplication, it is converted to the user-facing
|
20
|
+
LengthSpectrumGeodesicInfo.
|
21
|
+
"""
|
22
|
+
def __init__(self,
|
23
|
+
word : List[int],
|
24
|
+
o13_matrix):
|
25
|
+
self.word = word
|
26
|
+
self.o13_matrix = o13_matrix
|
27
|
+
|
28
|
+
self.psl2c_matrix = so13_to_psl2c(self.o13_matrix)
|
29
|
+
self.length = complex_length_of_psl2c_matrix(self.psl2c_matrix)
|
30
|
+
self._key = lower(self.length.real())
|
31
|
+
|
32
|
+
def __lt__(self, other):
|
33
|
+
"""
|
34
|
+
Ordering <.
|
35
|
+
"""
|
36
|
+
return self._key < other._key
|
37
|
+
|
38
|
+
class CoreCurveGeodesicInfo(GeodesicInfoBase):
|
39
|
+
"""
|
40
|
+
Information for a known core curve. That is, we go through each
|
41
|
+
filled cusp and compute this information before starting to compute
|
42
|
+
the length spectrum.
|
43
|
+
|
44
|
+
It contains the index of the corresponding (filled) cusp.
|
45
|
+
"""
|
46
|
+
def __init__(self,
|
47
|
+
word : List[int],
|
48
|
+
o13_matrix,
|
49
|
+
core_curve : int):
|
50
|
+
super().__init__(word, o13_matrix)
|
51
|
+
self.core_curve = core_curve
|
52
|
+
|
53
|
+
class GeodesicKeyInfo(GeodesicInfoBase):
|
54
|
+
"""
|
55
|
+
Information for a geodesic which might potentially a multiple of another
|
56
|
+
geodesic or even a core curve.
|
57
|
+
|
58
|
+
Via geodesic_start_point_info, we can determine whether this geodesic
|
59
|
+
corresponds to a multiple of a core curve.
|
60
|
+
|
61
|
+
Given two geodesics that are not core curves, we can also use this
|
62
|
+
information here to determine whether one is a conjugate of a multiple of
|
63
|
+
the other.
|
64
|
+
|
65
|
+
Also see get_geodesic_key_info_dict and get_geodesic_key_info_set.
|
66
|
+
"""
|
67
|
+
def __init__(self,
|
68
|
+
mcomplex : Mcomplex,
|
69
|
+
word : List[int],
|
70
|
+
o13_matrix):
|
71
|
+
super().__init__(word, o13_matrix)
|
72
|
+
self.mcomplex = mcomplex
|
73
|
+
|
74
|
+
self._r13_line_with_matrix : Optional[R13LineWithMatrix] = None
|
75
|
+
self._info : Optional[GeodesicStartPointInfo] = None
|
76
|
+
|
77
|
+
def r13_line_with_matrix(self) -> R13LineWithMatrix:
|
78
|
+
"""
|
79
|
+
The actual line in H^3 with the matrix corresponding to the
|
80
|
+
geodesic.
|
81
|
+
"""
|
82
|
+
if self._r13_line_with_matrix is None:
|
83
|
+
self._r13_line_with_matrix = (
|
84
|
+
r13_fixed_line_of_psl2c_matrix(self.psl2c_matrix))
|
85
|
+
|
86
|
+
return self._r13_line_with_matrix
|
87
|
+
|
88
|
+
def r13_line(self) -> R13Line:
|
89
|
+
"""
|
90
|
+
The actually line in H^3 corresponding to the geodesic.
|
91
|
+
"""
|
92
|
+
return self.r13_line_with_matrix().r13_line
|
93
|
+
|
94
|
+
def geodesic_start_point_info(self) -> GeodesicStartPointInfo:
|
95
|
+
"""
|
96
|
+
Information to start developing about the geodesic.
|
97
|
+
"""
|
98
|
+
if self._info is None:
|
99
|
+
start_point = sample_line(self.r13_line())
|
100
|
+
|
101
|
+
self._info = GeodesicStartPointInfo(
|
102
|
+
mcomplex=self.mcomplex,
|
103
|
+
word=self.word,
|
104
|
+
trace=self.psl2c_matrix.trace(),
|
105
|
+
unnormalised_start_point = start_point,
|
106
|
+
unnormalised_end_point=self.o13_matrix * start_point,
|
107
|
+
line=self.r13_line_with_matrix())
|
108
|
+
self._info.find_tet_or_core_curve()
|
109
|
+
|
110
|
+
return self._info
|
@@ -0,0 +1,117 @@
|
|
1
|
+
from .geodesic_piece import GeodesicPiece, get_geodesic_piece_dict
|
2
|
+
from .geodesic_info import GeodesicKeyInfo
|
3
|
+
|
4
|
+
from ..tiling.canonical_key_dict import CanonicalKeyDict
|
5
|
+
from ..tiling.dict_based_set import DictBasedSet
|
6
|
+
from ..geometric_structure.geodesic.tiles_for_geodesic import compute_tiles_for_geodesic
|
7
|
+
from ..geometric_structure.geodesic.geodesic_start_point_info import GeodesicStartPointInfo
|
8
|
+
from ..hyperboloid import o13_inverse, r13_to_klein
|
9
|
+
from ..snap.t3mlite import Mcomplex
|
10
|
+
from ..exceptions import InsufficientPrecisionError
|
11
|
+
|
12
|
+
from typing import List, Sequence
|
13
|
+
|
14
|
+
def get_geodesic_key_info_dict(mcomplex : Mcomplex):
|
15
|
+
"""
|
16
|
+
Given a triangulation with a geometric structure, gives an (empty)
|
17
|
+
dictionary where keys are GeodesicKeyInfo's not corresponding to
|
18
|
+
core curves.
|
19
|
+
|
20
|
+
Two keys are regarded the same if they give the same geodesic in the
|
21
|
+
manifold up to multiplicity and orientation of the geodesic.
|
22
|
+
|
23
|
+
Note that the same caveat from get_geodesic_piece_dict about this not
|
24
|
+
being an equivalence relationship applies.
|
25
|
+
|
26
|
+
In particular, it assumed that we insert the primitive geodesic before
|
27
|
+
we insert a multiple of that primitive geodesic.
|
28
|
+
"""
|
29
|
+
return CanonicalKeyDict(
|
30
|
+
get_geodesic_piece_dict(mcomplex),
|
31
|
+
_canonical_keys)
|
32
|
+
|
33
|
+
def get_geodesic_key_info_set(mcomplex : Mcomplex):
|
34
|
+
"""
|
35
|
+
Analogous to get_geodesic_key_info_dict, gives a set where the
|
36
|
+
elements are GeodesicKeyInfo's not corresponding to core curves.
|
37
|
+
|
38
|
+
The same caveats apply.
|
39
|
+
"""
|
40
|
+
return DictBasedSet(get_geodesic_key_info_dict(mcomplex))
|
41
|
+
|
42
|
+
def _canonical_keys(key_info : GeodesicKeyInfo) -> List[GeodesicPiece]:
|
43
|
+
"""
|
44
|
+
To see whether two geodesics are the same, we compute the intersection
|
45
|
+
of the geodesic with each tetrahedron and store the information in
|
46
|
+
GeodesicPiece's.
|
47
|
+
|
48
|
+
If a part of the geodesic is so close to the skeleton that it cannot be
|
49
|
+
decided whether it intersects a tetrahedron or not, we conservatively add
|
50
|
+
the GeodesicPiece. In particular, if a geodesic is going through a face
|
51
|
+
of a tetrahedron, we add the two tetrahedra neighboring that face.
|
52
|
+
|
53
|
+
We obtain the GeodesicPieces by developing a tube about the geodesic until
|
54
|
+
we can verify that the tube has positive radius.
|
55
|
+
"""
|
56
|
+
|
57
|
+
if key_info.geodesic_start_point_info().core_curve_cusp:
|
58
|
+
raise ValueError(
|
59
|
+
"Expected a non-core curve geodesic as key for dictionary of "
|
60
|
+
"GeodesicKeyInfo's.")
|
61
|
+
|
62
|
+
# Note that geodesic_start_point_info might compute a transform of
|
63
|
+
# the given geodesic. This is to ensure that it can find a lifted
|
64
|
+
# tetrahedron in the fundamental domain containing the point about which
|
65
|
+
# we start developing (or a pair of two lifted tetrahedra where one
|
66
|
+
# is in the fundamental domain).
|
67
|
+
|
68
|
+
return list(
|
69
|
+
_compute_geodesic_pieces(
|
70
|
+
key_info.mcomplex,
|
71
|
+
key_info.geodesic_start_point_info(),
|
72
|
+
key_info.length.real()))
|
73
|
+
|
74
|
+
def _compute_geodesic_pieces(
|
75
|
+
mcomplex : Mcomplex,
|
76
|
+
info : GeodesicStartPointInfo,
|
77
|
+
real_length) -> Sequence[GeodesicPiece]:
|
78
|
+
|
79
|
+
g = info.line.o13_matrix
|
80
|
+
|
81
|
+
for tile in compute_tiles_for_geodesic(
|
82
|
+
mcomplex, info, avoid_core_curves = True):
|
83
|
+
if tile.lower_bound_distance > 0:
|
84
|
+
break
|
85
|
+
|
86
|
+
h = tile.lifted_tetrahedron.o13_matrix
|
87
|
+
|
88
|
+
# Compute the matrix corresponding to line given by
|
89
|
+
# tile.inverse_lifted_geometric_object.
|
90
|
+
#
|
91
|
+
# Ideally, compute_tiles_for_geodesic could work with
|
92
|
+
# both types, R13Line and R13LineWithMatrix and do the
|
93
|
+
# appropriate thing.
|
94
|
+
#
|
95
|
+
m0 = o13_inverse(h) * g * h
|
96
|
+
|
97
|
+
# Also compute the inverse
|
98
|
+
m1 = o13_inverse(m0)
|
99
|
+
|
100
|
+
pt0, pt1 = tile.inverse_lifted_geometric_object.points
|
101
|
+
|
102
|
+
# We do not know which of pt0 and pt1 is the attracting fixed point
|
103
|
+
# of m0 or m1.
|
104
|
+
# Check and switch around if necessary.
|
105
|
+
|
106
|
+
if (m0 * pt0)[0] > pt0[0]:
|
107
|
+
pass
|
108
|
+
elif (m0 * pt1)[0] > pt1[0]:
|
109
|
+
pt1, pt0 = pt0, pt1
|
110
|
+
else:
|
111
|
+
raise InsufficientPrecisionError(
|
112
|
+
"Could not determine which fixed point is attracting. "
|
113
|
+
"Increasing the precision should fix this.")
|
114
|
+
|
115
|
+
# Emit a GeodesicPiece for both orientations of the geodesic.
|
116
|
+
for pt, m in ((pt0, m0), (pt1, m1)):
|
117
|
+
yield GeodesicPiece(r13_to_klein(pt), m, real_length)
|
@@ -0,0 +1,143 @@
|
|
1
|
+
from ..tiling.real_hash_dict import RealHashDict
|
2
|
+
from ..hyperboloid import o13_inverse
|
3
|
+
from ..hyperboloid.distances import distance_r13_points
|
4
|
+
from ..snap.t3mlite import Mcomplex
|
5
|
+
from ..exceptions import InsufficientPrecisionError
|
6
|
+
|
7
|
+
from typing import Tuple
|
8
|
+
|
9
|
+
class GeodesicPiece:
|
10
|
+
"""
|
11
|
+
For a hyperbolic manifold given through context, this class stores enough
|
12
|
+
information about a loxodromic Decktransformation of H^3 to determine
|
13
|
+
whether one loxodromic is a positive multiple of another one.
|
14
|
+
|
15
|
+
This can be used as keys in a dictionary constructed with
|
16
|
+
get_geodesic_piece_dict.
|
17
|
+
|
18
|
+
The information consists of the attracting fixed point encoded as 3-vector
|
19
|
+
in S^2 (as boundary of the Klein or Poincare ball model), the associated
|
20
|
+
matrix and the real part of the translation length.
|
21
|
+
|
22
|
+
Note that intervals for the attracing fixed point can be used to verify
|
23
|
+
two loxodromics apart up to multiplicity (and are good for hashing).
|
24
|
+
But we need the matrix to verify that two loxodromics are the same - or
|
25
|
+
that one is a multiple of another.
|
26
|
+
"""
|
27
|
+
|
28
|
+
def __init__(self,
|
29
|
+
klein_endpoint, # 3-vector in S^2
|
30
|
+
o13_matrix,
|
31
|
+
real_length):
|
32
|
+
self.klein_endpoint = klein_endpoint
|
33
|
+
self.o13_matrix = o13_matrix
|
34
|
+
self.real_length = real_length
|
35
|
+
|
36
|
+
def get_geodesic_piece_dict(mcomplex : Mcomplex):
|
37
|
+
"""
|
38
|
+
Returns a dictionary where the keys can be GeodesicPiece's.
|
39
|
+
The GeodesicPiece's have to be for loxodromics coming from the given
|
40
|
+
triangulation with a geometric structure.
|
41
|
+
|
42
|
+
Two keys are regarded as the same if the matrix of one is a multiple
|
43
|
+
of the matrix of the other key.
|
44
|
+
|
45
|
+
Note that this is not quite an equivalence relation: if B and C are
|
46
|
+
multiples of A, then B is not necessarily a multiple of C.
|
47
|
+
|
48
|
+
It is assumed that we insert the primitive matrix before we insert a
|
49
|
+
multiple of that primitive matrix.
|
50
|
+
"""
|
51
|
+
return RealHashDict(
|
52
|
+
_equality_predicate(mcomplex),
|
53
|
+
_hash(mcomplex.RF),
|
54
|
+
_epsilon_inverse,
|
55
|
+
mcomplex.verified)
|
56
|
+
|
57
|
+
_epsilon_inverse = 1024
|
58
|
+
|
59
|
+
def _hash(RF):
|
60
|
+
weights = [ RF(1.2003), RF(0.94533), RF(1.431112) ]
|
61
|
+
|
62
|
+
def result(piece : GeodesicPiece):
|
63
|
+
"""
|
64
|
+
Use attracting fixed point for computing the hash.
|
65
|
+
"""
|
66
|
+
return (piece.klein_endpoint[0] * weights[0] +
|
67
|
+
piece.klein_endpoint[1] * weights[1] +
|
68
|
+
piece.klein_endpoint[2] * weights[2])
|
69
|
+
|
70
|
+
return result
|
71
|
+
|
72
|
+
def _equality_predicate(mcomplex):
|
73
|
+
def unsymmetrized_result(piece_0 : GeodesicPiece,
|
74
|
+
piece_1 : GeodesicPiece) -> bool:
|
75
|
+
"""
|
76
|
+
Check whether the matrix of piece_1 is a multiple of
|
77
|
+
the matrix of piece_0.
|
78
|
+
|
79
|
+
Raise an exception if this could not be decided.
|
80
|
+
"""
|
81
|
+
|
82
|
+
candidate_multiplicity = piece_1.real_length / piece_0.real_length
|
83
|
+
|
84
|
+
multiplicity = _int_or_none(
|
85
|
+
candidate_multiplicity, mcomplex.verified)
|
86
|
+
if multiplicity is None:
|
87
|
+
return False
|
88
|
+
|
89
|
+
# Compute translates of base points.
|
90
|
+
base = mcomplex.R13_baseTetInCenter
|
91
|
+
|
92
|
+
base_0 = base
|
93
|
+
for i in range(multiplicity):
|
94
|
+
base_0 = piece_0.o13_matrix * base_0
|
95
|
+
|
96
|
+
base_1 = piece_1.o13_matrix * base
|
97
|
+
|
98
|
+
# And then use the distance to see whether one matrix is
|
99
|
+
# a multiple of the other.
|
100
|
+
d = distance_r13_points(base_1, base_0)
|
101
|
+
if d < mcomplex.baseTetInRadius:
|
102
|
+
return True
|
103
|
+
if d > mcomplex.baseTetInRadius:
|
104
|
+
return False
|
105
|
+
raise InsufficientPrecisionError(
|
106
|
+
"Could not determine whether two pieces of a geodesic are the "
|
107
|
+
"same.\n"
|
108
|
+
"Distance of images of basepoints: %r.\n"
|
109
|
+
"Base tetrahedron in radius: %r.\n"
|
110
|
+
"Increasing precision should fix this." % (
|
111
|
+
d, mcomplex.baseTetInRadius))
|
112
|
+
|
113
|
+
def result(piece_0 : GeodesicPiece,
|
114
|
+
piece_1 : GeodesicPiece) -> bool:
|
115
|
+
"""
|
116
|
+
Check whether the matrix of piece_0 is a multiple of
|
117
|
+
the matrix of piece_1 or vice versa.
|
118
|
+
"""
|
119
|
+
if piece_0.real_length > piece_1.real_length:
|
120
|
+
return unsymmetrized_result(piece_1, piece_0)
|
121
|
+
else:
|
122
|
+
return unsymmetrized_result(piece_0, piece_1)
|
123
|
+
|
124
|
+
return result
|
125
|
+
|
126
|
+
_is_int_epsilon = 0.001
|
127
|
+
|
128
|
+
def _int_or_none(r, verified) -> Tuple[bool, int]:
|
129
|
+
if verified:
|
130
|
+
if r.floor() < r:
|
131
|
+
return None
|
132
|
+
is_int, r_int = r.is_int()
|
133
|
+
if is_int:
|
134
|
+
return r_int
|
135
|
+
|
136
|
+
raise InsufficientPrecisionError(
|
137
|
+
"When computing multiplicity of geodesic, "
|
138
|
+
"could not determine whether interval contains an integer or not.")
|
139
|
+
else:
|
140
|
+
r_int = r.round()
|
141
|
+
if abs(r_int -r) < _is_int_epsilon:
|
142
|
+
return int(r_int)
|
143
|
+
return None
|
@@ -0,0 +1,182 @@
|
|
1
|
+
from .spine import add_spine
|
2
|
+
|
3
|
+
from ..geometric_structure import add_r13_geometry, add_filling_information
|
4
|
+
from ..geometric_structure.geodesic.add_core_curves import add_r13_core_curves
|
5
|
+
from ..geometric_structure.cusp_neighborhood.complex_cusp_cross_section import ComplexCuspCrossSection
|
6
|
+
from ..geometric_structure.cusp_neighborhood.vertices import scale_vertices_from_horotriangles
|
7
|
+
|
8
|
+
from ..cusps.trig_cusp_area_matrix import triangulation_dependent_cusp_area_matrix_from_cusp_cross_section
|
9
|
+
from ..cusps.cusp_areas_from_matrix import unbiased_cusp_areas_from_cusp_area_matrix
|
10
|
+
from ..tiling.triangle import add_triangles_to_tetrahedra
|
11
|
+
from ..math_basics import correct_min
|
12
|
+
from ..matrix import make_matrix
|
13
|
+
from ..snap.t3mlite import Mcomplex
|
14
|
+
|
15
|
+
from typing import Optional
|
16
|
+
|
17
|
+
def mcomplex_for_len_spec(
|
18
|
+
manifold, bits_prec : Optional[int], verified : bool) -> Mcomplex:
|
19
|
+
"""
|
20
|
+
Convert a SnapPy manifold (wrapping a SnapPea kernel C triangulation) to
|
21
|
+
an Mcomplex (a python triangulation) and a geometric structures to the
|
22
|
+
Mcomplex necessary to compute the length spectrum.
|
23
|
+
|
24
|
+
The basic geometric structures are:
|
25
|
+
- the shapes of the ideal tetrahedra in tet.ShapeParameters
|
26
|
+
- the position of the vertices when developing the fundamental domain
|
27
|
+
in R13 in tet.R13_vertices (scaled to define a cusp neighborhood or
|
28
|
+
tube about a core curve, see later for details)
|
29
|
+
- the O13 face-pairing matrices between the tetrahedra in tet.O13_matrices
|
30
|
+
- to what (possibly trivial) generate a face-pairing belongs
|
31
|
+
in tet.GeneratorsInfo
|
32
|
+
- the plane equations for the faces (with normal facing outward)
|
33
|
+
in tet in tet.R13_planes and tet.R13_unnormalised_planes
|
34
|
+
- ideal triangles for each face in tet.R13_triangles
|
35
|
+
- the (possibly trivial) filling of each cusp as matrix tet.filling_matrix
|
36
|
+
encoding the filling curve as well as a cure parallel to the core curve.
|
37
|
+
- the core curves in tet.core_curve as R13LineWithMatrix
|
38
|
+
|
39
|
+
Furthermore, we also pick disjoint and embedded cusp neighborhoods (for
|
40
|
+
complete cusps) or tubes (for filled cusps) about the core curve for all
|
41
|
+
cusps.
|
42
|
+
|
43
|
+
We always work with horotriangles to truncate tetrahedra. That is, if we
|
44
|
+
have a tube about a core curve, we pick the horotriangles large
|
45
|
+
enough that they are fully outside the tube. Through a scale factor, we
|
46
|
+
also (indirectly) specify the horotriangles small enough that they are
|
47
|
+
fully inside the tube. So for a core curve, the truncated tetrahedra look
|
48
|
+
like a triangular version of the Giant's Causeway in Northern Ireland.
|
49
|
+
|
50
|
+
The picked horotriangles are such that the regions of a
|
51
|
+
tetrahedron they cut off are disjoint and do not cut-off the incenter of
|
52
|
+
the tetrahedron.
|
53
|
+
|
54
|
+
We use the cusp neighborhood choices and horotriangles to compute:
|
55
|
+
- the radius of the tube about the core curve in
|
56
|
+
cusp.core_curve_tube_radius so that if a geodesic goes through a
|
57
|
+
core curve, we can avoid developing the geodesic inside this tube
|
58
|
+
(which would require infinitely many pieces to reach the core curve)
|
59
|
+
by calling replace_piece_in_core_curve_tube.
|
60
|
+
- scale the tet.R13_vertices so that they define the horosphere that
|
61
|
+
cuts the tetrahedron in the picked horotriangle.
|
62
|
+
|
63
|
+
Recall that a spine of the triangulation has the key property that each
|
64
|
+
geodesic that is not a core curve is intersecting the spine.
|
65
|
+
|
66
|
+
We also use the cusp neighborhood choices and horotriangles to compute:
|
67
|
+
- use the tetrahedron's incenter as its spine center tet.spine_center.
|
68
|
+
- compute tet.out_radius, the radius (about the spine center) of a
|
69
|
+
tetrahedron truncated by the smaller horotriangles given by the scale
|
70
|
+
factor.
|
71
|
+
- tet.spine_radius is the radius of a ball about tet.spine_center
|
72
|
+
containing the restriction of the spine to the tetrahedron.
|
73
|
+
- tet.inv_spine_cosh = 1 / cosh(r) where r is the tet.spine_radius
|
74
|
+
- The spine center of the base tetrahedron is stored in
|
75
|
+
mcomplex.spine_center. We regard it as center for the lift of the
|
76
|
+
entire spine to H^3 and restricted to a fundamental domain.
|
77
|
+
mcomplex.spine_radius is the radius of a ball about this spine
|
78
|
+
center that contains the entire spine.
|
79
|
+
"""
|
80
|
+
|
81
|
+
mcomplex = Mcomplex(manifold)
|
82
|
+
|
83
|
+
# Add shapes, vertex positions, face-pairings, plane equations,
|
84
|
+
# generator info
|
85
|
+
add_r13_geometry(mcomplex,
|
86
|
+
manifold,
|
87
|
+
verified=verified, bits_prec=bits_prec)
|
88
|
+
# Add tet.filling_matrix
|
89
|
+
add_filling_information(mcomplex, manifold)
|
90
|
+
# Add tet.core_curve
|
91
|
+
add_r13_core_curves(mcomplex, manifold)
|
92
|
+
# Add ideal triangles in tet.R13_triangles
|
93
|
+
add_triangles_to_tetrahedra(mcomplex)
|
94
|
+
|
95
|
+
# Pick disjoint/embedded cusp neighborhoods and tubes about core curves
|
96
|
+
# avoiding the incenter of each tetrahedron.
|
97
|
+
_add_and_scale_cusp_cross_section(mcomplex)
|
98
|
+
|
99
|
+
# Scale tet.R13_vertices to correspond to the just chosen horotriangles
|
100
|
+
scale_vertices_from_horotriangles(mcomplex)
|
101
|
+
|
102
|
+
# Construct spine.
|
103
|
+
add_spine(mcomplex)
|
104
|
+
|
105
|
+
return mcomplex
|
106
|
+
|
107
|
+
def _add_and_scale_cusp_cross_section(mcomplex : Mcomplex):
|
108
|
+
"""
|
109
|
+
Pick disjoint/embedded cusp neighborhoods and tubes about core curves
|
110
|
+
avoiding the incenter of each tetrahedron.
|
111
|
+
|
112
|
+
Also store scaling factor for a horotriangle to be inside the chosen
|
113
|
+
tube about a core curve in inverse_scale_to_be_inside_tube.
|
114
|
+
"""
|
115
|
+
|
116
|
+
c = ComplexCuspCrossSection(mcomplex)
|
117
|
+
c.add_structures()
|
118
|
+
|
119
|
+
# Develop vertices in C for incomplete cusps.
|
120
|
+
c.add_vertex_positions_to_horotriangles()
|
121
|
+
# The similarities about some point in C. But we want to work with
|
122
|
+
# similarities of C^*, so move.
|
123
|
+
c.move_fixed_point_to_zero()
|
124
|
+
|
125
|
+
c.scale_triangles_to_avoid_standard_tubes()
|
126
|
+
|
127
|
+
_scale_cusp_cross_section(c)
|
128
|
+
|
129
|
+
def _scale_cusp_cross_section(c : ComplexCuspCrossSection):
|
130
|
+
"""
|
131
|
+
Scale horotriangles. That is scale all horotriangles belonging to
|
132
|
+
the same (complete or filled) cusp by the same factor.
|
133
|
+
|
134
|
+
We scale them such that the regions the horotriangles cut off a
|
135
|
+
particular tetrahedron are disjoint and don't cut-off the incenter.
|
136
|
+
|
137
|
+
Also compute the radius of the corresponding tube about the core curve
|
138
|
+
(that is contained inside the the regions we cut off and thus embedded
|
139
|
+
and disjoint from the other tubes or cusp neighborhoods).
|
140
|
+
"""
|
141
|
+
|
142
|
+
# Cusp areas we start with. For a filled cusp, this is the area of the
|
143
|
+
# horotriangles that touch a standard tube about the core curve.
|
144
|
+
original_cusp_areas = c.cusp_areas()
|
145
|
+
# Maximal areas to avoid incenters of the tetrahedra
|
146
|
+
max_areas = [ area * (c.compute_scale_to_avoid_incenter(v) ** 2)
|
147
|
+
for v, area in zip(c.mcomplex.Vertices, original_cusp_areas) ]
|
148
|
+
cusp_area_matrix = (
|
149
|
+
triangulation_dependent_cusp_area_matrix_from_cusp_cross_section(c))
|
150
|
+
# Adjust the diagonal entries so that the incenter of a tetrahedron
|
151
|
+
# cannot be in a cusp neighborhoods/ horotriangles outside a tube about
|
152
|
+
# a core curve.
|
153
|
+
incenter_cusp_area_matrix = _min_matrix(cusp_area_matrix, max_areas)
|
154
|
+
cusp_areas = (
|
155
|
+
unbiased_cusp_areas_from_cusp_area_matrix(incenter_cusp_area_matrix))
|
156
|
+
c.normalize_cusps(cusp_areas)
|
157
|
+
|
158
|
+
# Compute (lower bound) on radius of tubes about core curves that are
|
159
|
+
# embedded/disjoint from the cusp neighborhoods.
|
160
|
+
for i, cusp in enumerate(c.mcomplex.Vertices):
|
161
|
+
if cusp.is_complete:
|
162
|
+
continue
|
163
|
+
cusp_area_scale = cusp_areas[i] / original_cusp_areas[i]
|
164
|
+
cusp_scale = cusp_area_scale.sqrt()
|
165
|
+
cusp.core_curve_tube_radius = cusp_scale.arcsinh()
|
166
|
+
|
167
|
+
def _min_matrix(m, diag_sqrt):
|
168
|
+
"""
|
169
|
+
Compute new matrix by replacing the diagonal.
|
170
|
+
|
171
|
+
A new diagonal entry will be computed by taking the minimum of the
|
172
|
+
old entry and the square of the corresponding entry in diag_sqrt.
|
173
|
+
"""
|
174
|
+
|
175
|
+
n = len(diag_sqrt)
|
176
|
+
|
177
|
+
return make_matrix(
|
178
|
+
[ [
|
179
|
+
m[i,j] if i != j
|
180
|
+
else correct_min([diag_sqrt[i] ** 2, m[i, j]])
|
181
|
+
for j in range(n)]
|
182
|
+
for i in range(n)])
|
@@ -0,0 +1,80 @@
|
|
1
|
+
from ..hyperboloid.distances import (
|
2
|
+
distance_r13_points, lower_bound_distance_r13_point_triangle)
|
3
|
+
|
4
|
+
from ..math_basics import correct_min, correct_max # type: ignore
|
5
|
+
|
6
|
+
from ..snap.t3mlite import simplex, Tetrahedron
|
7
|
+
|
8
|
+
def lower_bound_geodesic_length(
|
9
|
+
lower_bound_distance, inv_spine_cosh):
|
10
|
+
"""
|
11
|
+
This implements a version of Proposition 3.5 of
|
12
|
+
Weeks-Hodgson's Symmetries, Isometries and Length Spectra of Closed
|
13
|
+
Hyperbolic Three-Manifolds. Slightly changing notation, it says:
|
14
|
+
|
15
|
+
To find all closed geodesics of length at most L, it sufficies to
|
16
|
+
find all translates gD such that d(x, gx) <= R where
|
17
|
+
R = 2 arccosh(cosh(r) cosh(L/2)).
|
18
|
+
|
19
|
+
The input is a lower_bound_distance, a lower bound on the radius R of the
|
20
|
+
ball we have covered by tiles, and inv_spine_cosh = 1/cosh(r) where
|
21
|
+
r is a given tetrahedron's spine radius. More precisely, r is the radius
|
22
|
+
with respect to a given's tetrahedron's spine center (typically incenter)
|
23
|
+
of the intersection of the triangulation's spine with the tetrahedron.
|
24
|
+
|
25
|
+
The output is L which has the following property: Any geodesic in M that
|
26
|
+
intersects the given tetrahedron's spine and has length less than L is
|
27
|
+
among the ones we have encountered during tiling so far.
|
28
|
+
|
29
|
+
Note that our R is defined slightly differently, thus we can actually drop
|
30
|
+
the factor of 2 through out:
|
31
|
+
|
32
|
+
R = arccosh(cosh(r) cosh(L))
|
33
|
+
|
34
|
+
We also want an expression in L:
|
35
|
+
|
36
|
+
L = arccosh(cosh(R) / cosh(r))
|
37
|
+
|
38
|
+
And want to conservatively return 0 if this is not well-defined.
|
39
|
+
|
40
|
+
Note that we use the tetrahedron's spine radius here. But since we are
|
41
|
+
interested in geodesics and length bounds intrinsic to the manifold, the
|
42
|
+
length spectrum computation starts a tiling process for each tetrahedron.
|
43
|
+
|
44
|
+
Note that if the geometric structure is complete, every geodesic
|
45
|
+
will intersect the spine. However, for a spun-triangulation, this
|
46
|
+
only applies to geodesics that are not core curves. This is fine
|
47
|
+
since we treat core curves separately when computing the length
|
48
|
+
spectrum.
|
49
|
+
"""
|
50
|
+
|
51
|
+
if lower_bound_distance > 0:
|
52
|
+
q = lower_bound_distance.cosh() * inv_spine_cosh
|
53
|
+
if q > 1:
|
54
|
+
return q.arccosh()
|
55
|
+
RF = lower_bound_distance.parent()
|
56
|
+
return RF(0)
|
57
|
+
|
58
|
+
def lower_bound_distance_r13_point_truncated_tetrahedron(
|
59
|
+
point, tet : Tetrahedron, verified : bool):
|
60
|
+
"""
|
61
|
+
A lower bound for the distance of a point to a truncated tetrahedron.
|
62
|
+
Assuming the point is not inside the truncated tetrahedron.
|
63
|
+
|
64
|
+
The truncated tetrahedron is given as follows: we have the ideal
|
65
|
+
triangles for each face of the underlying ideal tetrahedra. We have
|
66
|
+
a lower bound on the radius of the truncated tetrahedron with respect
|
67
|
+
to its spine center (typically the incenter).
|
68
|
+
"""
|
69
|
+
|
70
|
+
# One lower bound is given by computing the distance of the incenter
|
71
|
+
# and subtracting the radius.
|
72
|
+
d_out = distance_r13_points(point, tet.spine_center) - tet.out_radius
|
73
|
+
# Another lower bound is given by computing the distance to the underlying
|
74
|
+
# ideal tetrahedron. Assuming the point is not in the tetrahedron, it is
|
75
|
+
# given by the distances to the ideal faces.
|
76
|
+
d_faces = correct_min(
|
77
|
+
[ lower_bound_distance_r13_point_triangle(
|
78
|
+
point, tet.R13_triangles[f], verified)
|
79
|
+
for f in simplex.TwoSubsimplices ])
|
80
|
+
return correct_max([d_out, d_faces])
|