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,596 @@
|
|
1
|
+
from .geometric_structure import mcomplex_for_len_spec
|
2
|
+
from .tile import compute_length_spectrum_tiles, LengthSpectrumTile
|
3
|
+
from .geodesic_info import GeodesicInfoBase, GeodesicKeyInfo, CoreCurveGeodesicInfo
|
4
|
+
from .geodesic_key_info_dict import get_geodesic_key_info_set
|
5
|
+
from .word import simplify_geodesic_word
|
6
|
+
from .length_spectrum_geodesic_info import LengthSpectrumGeodesicInfo
|
7
|
+
|
8
|
+
from ..snap.t3mlite import Mcomplex
|
9
|
+
from ..geometric_structure import word_list_to_psl2c_matrix
|
10
|
+
from ..upper_halfspace import psl2c_to_o13
|
11
|
+
from ..hyperboloid.distances import distance_r13_point_line
|
12
|
+
from ..hyperboloid.line import R13Line
|
13
|
+
from ..SnapPy import list_as_word, inverse_list_word
|
14
|
+
from ..math_basics import lower, correct_max # type: ignore
|
15
|
+
from ..exceptions import InsufficientPrecisionError, NonorientableManifoldError
|
16
|
+
from ..sage_helper import _within_sage, SageNotAvailable
|
17
|
+
|
18
|
+
if _within_sage:
|
19
|
+
from sage.rings.real_mpfi import RealIntervalField
|
20
|
+
|
21
|
+
import heapq
|
22
|
+
|
23
|
+
from typing import Any, Optional, List, Sequence
|
24
|
+
|
25
|
+
_optimization : bool = False
|
26
|
+
|
27
|
+
def length_spectrum_alt_gen(manifold,
|
28
|
+
bits_prec : Optional[int] = None,
|
29
|
+
verified : bool = False
|
30
|
+
) -> Sequence[LengthSpectrumGeodesicInfo]:
|
31
|
+
"""
|
32
|
+
Returns a generator for the geodesics sorted by real length. The method
|
33
|
+
only supports orientable manifolds.
|
34
|
+
|
35
|
+
Here is an example::
|
36
|
+
|
37
|
+
>>> M = Manifold("m202(3,4)(0,0)")
|
38
|
+
>>> spec = M.length_spectrum_alt_gen()
|
39
|
+
>>> next(spec) # doctest: +NUMERIC9
|
40
|
+
Length Core curve Word
|
41
|
+
0.14742465268512 - 1.78287093565202*I Cusp 0 aabcDabcB
|
42
|
+
>>> next(spec) # doctest: +NUMERIC9
|
43
|
+
0.81161414965958 + 2.72911699294426*I - b
|
44
|
+
>>> next(spec) # doctest: +NUMERIC9
|
45
|
+
0.84163270359334 + 2.61245944742151*I - aB
|
46
|
+
|
47
|
+
Note that the shortest geodesic in the above example happens to be the
|
48
|
+
core curve of the filled cusp (Cusp 0).
|
49
|
+
|
50
|
+
Access just the length or word::
|
51
|
+
|
52
|
+
>>> g = next(spec)
|
53
|
+
>>> g.length # doctest: +NUMERIC9
|
54
|
+
0.93461379591349 + 2.70060614107722*I
|
55
|
+
>>> g.word
|
56
|
+
'a'
|
57
|
+
|
58
|
+
The word is given with respect to the unsimplified fundamental group::
|
59
|
+
|
60
|
+
>>> G = M.fundamental_group(simplify_presentation=False)
|
61
|
+
>>> G.complex_length('a') # doctest: +NUMERIC9
|
62
|
+
0.93461379591349 + 2.70060614107722*I
|
63
|
+
|
64
|
+
The method also supports higher precision::
|
65
|
+
|
66
|
+
>>> M = Manifold("m003(-3,1)")
|
67
|
+
>>> spec = M.length_spectrum_alt_gen(bits_prec=100)
|
68
|
+
>>> next(spec).length # doctest: +NUMERIC24
|
69
|
+
0.58460368501798696932015666264 + 2.4953704555604684110903962008*I
|
70
|
+
|
71
|
+
**Performance**
|
72
|
+
|
73
|
+
This method uses a different algorithm than
|
74
|
+
:meth:`length_spectrum <Manifold.length_spectrum>`. In particular,
|
75
|
+
it does not compute the Dirichlet domain. It also allows for
|
76
|
+
:ref:`verified computations <verify-primer>`.
|
77
|
+
It is implemented in python and thus
|
78
|
+
typically slower than :meth:`length_spectrum <Manifold.length_spectrum>`.
|
79
|
+
But there are also some cases where it is significantly faster. In
|
80
|
+
particular, this applies to spun triangulations such as ``m004(21,10)``.
|
81
|
+
|
82
|
+
Here is example where we can help the algorithm by guessing and drilling
|
83
|
+
and filling a short geodesic::
|
84
|
+
|
85
|
+
>>> M = Manifold("o9_00639")
|
86
|
+
|
87
|
+
Over an hour to compute::
|
88
|
+
|
89
|
+
>>> M.high_precision().length_spectrum(0.1) # doctest: +SKIP
|
90
|
+
mult length topology parity
|
91
|
+
1 0.00150226276052 - 2.39996262244127*I circle +
|
92
|
+
|
93
|
+
A couple of minutes to compute::
|
94
|
+
|
95
|
+
>>> spec = M.length_spectrum_alt_gen(bits_prec = 150)
|
96
|
+
>>> next(spec) # doctest: +SKIP
|
97
|
+
Length Word Core curve
|
98
|
+
0.00150226276052 - 2.39996262244127*I a -
|
99
|
+
|
100
|
+
After drilling and filling, less than a second to compute::
|
101
|
+
|
102
|
+
>>> N = M.drill_word('a')
|
103
|
+
>>> N.dehn_fill((1,0),-1) # N is now isometric to o9_00639 but as a surgery m125(0,0)(34,55)
|
104
|
+
>>> spec = N.length_spectrum_alt_gen()
|
105
|
+
>>> next(spec) # doctest: +NUMERIC9
|
106
|
+
Length Core curve Word
|
107
|
+
0.00150226276073 - 2.39996262244128*I Cusp 1 cDcDDcDcDDcDDcDcDDcDcDDcDDcDcDDcDD
|
108
|
+
>>> next(spec).length.real() # doctest: +NUMERIC9
|
109
|
+
0.96218768626877
|
110
|
+
|
111
|
+
**Verified computations**
|
112
|
+
|
113
|
+
The method also supports :ref:`verified computations <verify-primer>`::
|
114
|
+
|
115
|
+
sage: M = Manifold("m019")
|
116
|
+
sage: spec = M.length_spectrum_alt_gen(verified=True, bits_prec=100)
|
117
|
+
sage: next(spec)
|
118
|
+
Length Core curve Word
|
119
|
+
0.43153441294719... + 2.35105908147863...*I - a
|
120
|
+
sage: next(spec)
|
121
|
+
0.88944299721255... - 2.94185904702273...*I - bD
|
122
|
+
|
123
|
+
If :attr:`verified = True` is passed, the algorithm guarantees that the lower
|
124
|
+
bound of the real length is (non-strictly) increasing. In particular, we know
|
125
|
+
that we have found all geodesics less than the following length::
|
126
|
+
|
127
|
+
sage: next(spec).length.real().lower() # doctest: +NUMERIC12
|
128
|
+
0.94135129037387168886341739832
|
129
|
+
|
130
|
+
To illustrate some pitfalls, here is an example of a potential a result
|
131
|
+
of the method:
|
132
|
+
|
133
|
+
+----------------------+-------+
|
134
|
+
| Real length interval | Word |
|
135
|
+
+======================+=======+
|
136
|
+
| ``[1.0, 2.0]`` | ``a`` |
|
137
|
+
+----------------------+-------+
|
138
|
+
| ``[1.2, 1.3]`` | ``b`` |
|
139
|
+
+----------------------+-------+
|
140
|
+
| ``[1.7, 1.8]`` | ``c`` |
|
141
|
+
+----------------------+-------+
|
142
|
+
| ``[3.0, 4.0]`` | ``d`` |
|
143
|
+
+----------------------+-------+
|
144
|
+
|
145
|
+
Note that we cannot say whether geodesic ``a`` is actually the first,
|
146
|
+
second or third shortest geodesic or tied with ``b`` or ``c``. Increasing
|
147
|
+
precision can change (representative words and) the order in which the
|
148
|
+
geodesics are emitted.
|
149
|
+
|
150
|
+
We can say that together ``a``, ``b`` and ``c`` are the three shortest
|
151
|
+
geodesics. Furthermore, we can also say that the systole
|
152
|
+
of the manifold is in ``[1.0, 2.0]`` even though ``a`` itself might not be
|
153
|
+
the shortest geodesic. The latter is true in general:
|
154
|
+
|
155
|
+
**Verified systole**
|
156
|
+
|
157
|
+
It is not necessarily true that the first geodesic returned
|
158
|
+
by the method is the shortest geodesic. Despite this, the interval for
|
159
|
+
the real length of the first geodesic always contains the systole of
|
160
|
+
the manifold::
|
161
|
+
|
162
|
+
sage: M = Manifold("m004")
|
163
|
+
sage: spec = M.length_spectrum_alt_gen(verified=True)
|
164
|
+
sage: g = next(spec) # g might or might not be shortest geodesic
|
165
|
+
sage: systole = g.length.real() # But interval is large enough to contain systole
|
166
|
+
sage: systole # doctest: +NUMERIC6
|
167
|
+
1.08707015?
|
168
|
+
|
169
|
+
:param bits_prec:
|
170
|
+
Precision used for the computation. Increase if computation did
|
171
|
+
not succeed.
|
172
|
+
:param verified:
|
173
|
+
Use :ref:`verified computation <verify-primer>`.
|
174
|
+
:return:
|
175
|
+
A generator to enumerate the geodesics such that the (lower bound
|
176
|
+
of the) real length is non-decreasing.
|
177
|
+
"""
|
178
|
+
|
179
|
+
if not manifold.is_orientable():
|
180
|
+
raise NonorientableManifoldError(
|
181
|
+
"Manifold.length_spectrum_alt_gen", manifold)
|
182
|
+
|
183
|
+
# Triangulation with necessary geometric structures
|
184
|
+
mcomplex : Mcomplex = mcomplex_for_len_spec(
|
185
|
+
manifold,
|
186
|
+
bits_prec=bits_prec, verified=verified)
|
187
|
+
# Needed to know whether we convert a word such as [ 1 ] to
|
188
|
+
# a or to x1.
|
189
|
+
num_generators = len([g for g in mcomplex.GeneratorMatrices.keys()
|
190
|
+
if g > 0])
|
191
|
+
is_first = True
|
192
|
+
|
193
|
+
geodesic : GeodesicInfoBase
|
194
|
+
for geodesic in _length_spectrum_from_mcomplex(mcomplex, manifold):
|
195
|
+
# Convert information to user-friendly form
|
196
|
+
if isinstance(geodesic, CoreCurveGeodesicInfo):
|
197
|
+
core_curve = geodesic.core_curve
|
198
|
+
else:
|
199
|
+
core_curve = None
|
200
|
+
yield LengthSpectrumGeodesicInfo(
|
201
|
+
# _is_first indicates whether to print the header
|
202
|
+
_is_first = is_first,
|
203
|
+
length = geodesic.length,
|
204
|
+
# Convert word to a or x1
|
205
|
+
word = list_as_word(
|
206
|
+
simplify_geodesic_word(geodesic.word),
|
207
|
+
num_generators,
|
208
|
+
verbose_form=False),
|
209
|
+
core_curve = core_curve,
|
210
|
+
parity = 'orientation-preserving',
|
211
|
+
topology = 'circle',
|
212
|
+
multiplicity = 1)
|
213
|
+
is_first = False
|
214
|
+
|
215
|
+
def length_spectrum_alt(manifold,
|
216
|
+
count : Optional[int] = None,
|
217
|
+
max_len : Optional[Any] = None,
|
218
|
+
bits_prec : Optional[int] = None,
|
219
|
+
verified : bool = False
|
220
|
+
) -> List[LengthSpectrumGeodesicInfo]:
|
221
|
+
"""
|
222
|
+
Returns a list of geodesics. How far this list goes can be specified
|
223
|
+
by either a cut-off length or a count. The method only supports
|
224
|
+
orientable manifolds. It is a convenience method for
|
225
|
+
:meth:`~snappy.Manifold.length_spectrum_alt_gen`.
|
226
|
+
We refer the reader to
|
227
|
+
:meth:`~snappy.Manifold.length_spectrum_alt_gen`
|
228
|
+
for further details not covered here.
|
229
|
+
|
230
|
+
**Cut-off length**
|
231
|
+
|
232
|
+
Here is an example where a cut-off length for the geodesics is specified::
|
233
|
+
|
234
|
+
>>> M = Manifold("m202(3,4)(3,4)")
|
235
|
+
>>> M.length_spectrum_alt(max_len = 0.5) # doctest: +SKIP
|
236
|
+
[Length Core curve Word
|
237
|
+
0.14820741547094 - 1.76955170166922*I Cusp 1 bcDc,
|
238
|
+
0.14820741547097 - 1.76955170166923*I Cusp 0 aabcDabcB]
|
239
|
+
|
240
|
+
It also supports :ref:`verified <verify-primer>` computations::
|
241
|
+
|
242
|
+
sage: M.length_spectrum_alt(max_len = 0.5, verified = True, bits_prec = 100) # doctest: +SKIP
|
243
|
+
[Length Core curve Word
|
244
|
+
0.148207415470948? - 1.76955170166924? *I Cusp 0 aabcDabcB,
|
245
|
+
0.14820741547094... - 1.76955170166923...*I Cusp 1 bcDc]
|
246
|
+
|
247
|
+
If :attr:`verified=True`, the returned list is guaranteed to include all
|
248
|
+
geodesics up to the given cut-off length and might include additional
|
249
|
+
geodesics.
|
250
|
+
|
251
|
+
**Count**
|
252
|
+
|
253
|
+
Here is an example where a count is specified::
|
254
|
+
|
255
|
+
>>> M = Manifold("m202(3,4)(3,4)")
|
256
|
+
>>> M.length_spectrum_alt(count = 3) # doctest: +SKIP
|
257
|
+
[Length Core curve Word
|
258
|
+
0.14820741547094 - 1.76955170166922*I Cusp 1 bcDc,
|
259
|
+
0.14820741547097 - 1.76955170166923*I Cusp 0 aabcDabcB,
|
260
|
+
0.79356651781096 + 2.65902431489655*I - aB,
|
261
|
+
0.79356651781096 + 2.65902431489655*I - b]
|
262
|
+
|
263
|
+
Note that the number of geodesics listed might be larger than the given
|
264
|
+
count. In particular, this happens when the same (real) length appears
|
265
|
+
multiple times. If :attr:`verified=True`, the returned list is guaranteed
|
266
|
+
to include the :attr:`count` shortest geodesics and might include additional
|
267
|
+
geodesics.
|
268
|
+
|
269
|
+
**Verified systole**
|
270
|
+
|
271
|
+
Even though, the first reported geodesic might not be the shortest, we
|
272
|
+
obtain an interval containing the systole as follows, also see
|
273
|
+
:meth:`~snappy.Manifold.length_spectrum_alt_gen`::
|
274
|
+
|
275
|
+
sage: M = Manifold("m004")
|
276
|
+
sage: M.length_spectrum_alt(count=1, verified=True, bits_prec=100)[0].length.real() # doctest: +NUMERIC21
|
277
|
+
1.0870701449957390997853?
|
278
|
+
|
279
|
+
:param count:
|
280
|
+
Number of shortest geodesics to list. The actual result might
|
281
|
+
contain additional geodesics. Exactly one of :attr:`count` and
|
282
|
+
:attr:`max_len` has to be specified.
|
283
|
+
:param max_len:
|
284
|
+
Cut-off length for geodesics. The actual result includes all
|
285
|
+
geodesics up to the given length and might include additional
|
286
|
+
geodesics. Exactly one of :attr:`count` and :attr:`max_len` has
|
287
|
+
to be specified.
|
288
|
+
:param bits_prec:
|
289
|
+
Precision used for the computation. Increase if computation did
|
290
|
+
not succeed.
|
291
|
+
:param verified:
|
292
|
+
Use :ref:`verified computation <verify-primer>`.
|
293
|
+
:return:
|
294
|
+
A list of geodesics such that the (lower bound of) the real
|
295
|
+
length is non-decreasing.
|
296
|
+
"""
|
297
|
+
|
298
|
+
has_count = count is not None
|
299
|
+
has_max_len = max_len is not None
|
300
|
+
|
301
|
+
if not (has_count ^ has_max_len):
|
302
|
+
raise ValueError(
|
303
|
+
"Must specify exactly one of count or max_len.")
|
304
|
+
|
305
|
+
if has_max_len:
|
306
|
+
return list(
|
307
|
+
_length_spectrum_alt_max_len(
|
308
|
+
manifold,
|
309
|
+
max_len = max_len,
|
310
|
+
bits_prec = bits_prec,
|
311
|
+
verified = verified))
|
312
|
+
else:
|
313
|
+
return list(
|
314
|
+
_length_spectrum_alt_count(
|
315
|
+
manifold,
|
316
|
+
count = count,
|
317
|
+
bits_prec = bits_prec,
|
318
|
+
verified = verified))
|
319
|
+
|
320
|
+
def _length_spectrum_alt_max_len(
|
321
|
+
manifold, *,
|
322
|
+
max_len : Any,
|
323
|
+
bits_prec : Optional[int],
|
324
|
+
verified : bool):
|
325
|
+
"""
|
326
|
+
Generator to produce all geodesics up to a given length.
|
327
|
+
"""
|
328
|
+
|
329
|
+
if verified:
|
330
|
+
if not _within_sage:
|
331
|
+
raise SageNotAvailable('Sorry, this feature requires using SnapPy inside Sage.')
|
332
|
+
if bits_prec is None:
|
333
|
+
resolved_bits_prec = manifold._precision()
|
334
|
+
else:
|
335
|
+
resolved_bits_prec = bits_prec
|
336
|
+
RIF = RealIntervalField(resolved_bits_prec)
|
337
|
+
resolved_max_len = RIF(max_len)
|
338
|
+
else:
|
339
|
+
# A bit of fudge
|
340
|
+
resolved_max_len = max_len * 1.0000152
|
341
|
+
|
342
|
+
for info in length_spectrum_alt_gen(manifold = manifold,
|
343
|
+
bits_prec = bits_prec,
|
344
|
+
verified = verified):
|
345
|
+
# For verified computation:
|
346
|
+
#
|
347
|
+
# Recall that length_spectrum_alt_gen gives geodesics in the
|
348
|
+
# order such that the lower bound of info.length.real() is
|
349
|
+
# guaranteed to be (not strictly) increasing.
|
350
|
+
#
|
351
|
+
# The inequality checks that the lower bound of info.length.real()
|
352
|
+
# is larger than the given max_len.
|
353
|
+
#
|
354
|
+
# Thus, if true, any further geodesics will have length larger
|
355
|
+
# than max_len.
|
356
|
+
#
|
357
|
+
if info.length.real() > resolved_max_len:
|
358
|
+
break
|
359
|
+
yield info
|
360
|
+
|
361
|
+
def _length_spectrum_alt_count(
|
362
|
+
manifold, *,
|
363
|
+
count : int,
|
364
|
+
bits_prec : Optional[int],
|
365
|
+
verified : bool):
|
366
|
+
"""
|
367
|
+
Generator to return a (potential) superset of geodesics containing
|
368
|
+
the count shortest geodesics.
|
369
|
+
|
370
|
+
In the verified case, this is a bit tricky since the only guarantee
|
371
|
+
we have is that the lower bound of the interval of the length
|
372
|
+
is (non-strictly) increasing.
|
373
|
+
"""
|
374
|
+
|
375
|
+
if not count > 0:
|
376
|
+
# Sanitycheck.
|
377
|
+
return
|
378
|
+
|
379
|
+
for i, info in enumerate(
|
380
|
+
length_spectrum_alt_gen(manifold = manifold,
|
381
|
+
bits_prec = bits_prec,
|
382
|
+
verified = verified)):
|
383
|
+
this_len = info.length.real()
|
384
|
+
|
385
|
+
if i >= count:
|
386
|
+
if verified:
|
387
|
+
# The lower bound of the length of the current geodesic
|
388
|
+
# is larger than the maximum length of any geodesic
|
389
|
+
# encountered so far.
|
390
|
+
# Thus all following geodesics will be longer than any
|
391
|
+
# of geodesic encountered so far.
|
392
|
+
if this_len > max_len:
|
393
|
+
break
|
394
|
+
else:
|
395
|
+
# Add a fudge factor to account for geodesics with
|
396
|
+
# true equal length might have slightly different
|
397
|
+
# length due to numeric noise.
|
398
|
+
if this_len > 1.0000152 * max_len:
|
399
|
+
break
|
400
|
+
|
401
|
+
# Update the maximal length of geodesics encountered so far.
|
402
|
+
if i == 0:
|
403
|
+
max_len = this_len
|
404
|
+
else:
|
405
|
+
max_len = correct_max([max_len, this_len])
|
406
|
+
|
407
|
+
yield info
|
408
|
+
|
409
|
+
def _length_spectrum_from_mcomplex(
|
410
|
+
mcomplex : Mcomplex, manifold) -> Sequence[GeodesicInfoBase]:
|
411
|
+
"""
|
412
|
+
Implements length_spectrum given an Mcomplex constructed with
|
413
|
+
mcomplex_for_len_spec and the SnapPy Manifold.
|
414
|
+
"""
|
415
|
+
|
416
|
+
if mcomplex.verified:
|
417
|
+
epsilon = 0
|
418
|
+
else:
|
419
|
+
# A bit of extra tiling before outputting a geodesic.
|
420
|
+
epsilon = mcomplex.RF(0.0001)
|
421
|
+
|
422
|
+
# A set-like structure holding GeodesicKeyInfo's to record
|
423
|
+
# which geodesics were already emitted.
|
424
|
+
# Two geodesics are regarded as equal if one is a
|
425
|
+
# multiple of another (including inverse) and if they are
|
426
|
+
# conjugates.
|
427
|
+
#
|
428
|
+
# Note that the structure does not work correctly if we add
|
429
|
+
# a multiple of a geodesic to it first. If we add a geodesic
|
430
|
+
# that is not a multiple first though, trying to add a multiple of
|
431
|
+
# that geodesic will be detected and add will return False.
|
432
|
+
#
|
433
|
+
# The structure does not hold geodesics corresponding to
|
434
|
+
# core curves.
|
435
|
+
#
|
436
|
+
visited_geodesics = get_geodesic_key_info_set(mcomplex)
|
437
|
+
|
438
|
+
# A priority queue of geodesics (including those corresponding
|
439
|
+
# to core curves.). The key is the lower bound of the geodesic
|
440
|
+
# length.
|
441
|
+
#
|
442
|
+
# The reason for the queue is this:
|
443
|
+
# When tiling to find geodesics, the geodesics are not emitted in order.
|
444
|
+
# The tiling algorithm does tell us though that we have seen all geodesics
|
445
|
+
# up to a certain length.
|
446
|
+
#
|
447
|
+
# We will add geodesics to the priority queue as we tile.
|
448
|
+
# And we pick off a geodesic g from the top of the priority queue
|
449
|
+
# when we know that we have tiled far enough to see all geodesics that
|
450
|
+
# could be shorter than g.
|
451
|
+
pending_geodesics : Sequence[GeodesicInfoBase] = []
|
452
|
+
|
453
|
+
# Core curves are treated differently. We add them here to the priority
|
454
|
+
# queue explicitly and filter them out when tiling later.
|
455
|
+
for geodesic in _geodesic_key_infos_for_core_curves(
|
456
|
+
mcomplex, manifold):
|
457
|
+
heapq.heappush(pending_geodesics, geodesic)
|
458
|
+
|
459
|
+
# The real length of the last geodesic that we emitted.
|
460
|
+
last_real_length : Optional[Any] = None
|
461
|
+
|
462
|
+
for tile in compute_length_spectrum_tiles(mcomplex):
|
463
|
+
|
464
|
+
# We have tiled far enough to have seen all geodesics up to
|
465
|
+
# this length.
|
466
|
+
#
|
467
|
+
# Note that this comment about tiling only applies to the non-core
|
468
|
+
# curve geodesics. However, we have already added all core curves
|
469
|
+
# explicitly earlier, so we are fine.
|
470
|
+
#
|
471
|
+
r = tile.lower_bound_geodesic_length
|
472
|
+
while (pending_geodesics and
|
473
|
+
pending_geodesics[0].length.real() + epsilon < r):
|
474
|
+
# We can emit the geodesic g from the top of the priority queue
|
475
|
+
# - if we haven't emitted it already earlier.
|
476
|
+
# That is because all geodesics that we have not seen when
|
477
|
+
# tiling this far have length larger than g - or at least its
|
478
|
+
# lower bound is larger than than the lengths of those unseen
|
479
|
+
# geodesics.
|
480
|
+
geodesic : GeodesicInfoBase = heapq.heappop(pending_geodesics)
|
481
|
+
real_length = geodesic.length.real()
|
482
|
+
|
483
|
+
if _optimization:
|
484
|
+
# An optimization. If the geodesic has length less than
|
485
|
+
# what the last one, we know it is a duplicate.
|
486
|
+
if last_real_length is not None:
|
487
|
+
if last_real_length > real_length:
|
488
|
+
continue
|
489
|
+
|
490
|
+
if isinstance(geodesic, GeodesicKeyInfo):
|
491
|
+
# Handle the non-core curve case.
|
492
|
+
line : R13Line = geodesic.r13_line()
|
493
|
+
|
494
|
+
# If this geodesic does not intersect the spine, it is conjugate
|
495
|
+
# to a geodesic that we have already seen earlier, so we can
|
496
|
+
# skip it.
|
497
|
+
#
|
498
|
+
# Note that this also filters out parabolics. For them, the
|
499
|
+
# fixed points coincide and we get a degenerate line. We can
|
500
|
+
# still compute the distance to the spine center and it will
|
501
|
+
# be a very large number or interval with a large number as
|
502
|
+
# lower bound and infinity as upper bound.
|
503
|
+
|
504
|
+
# We first do a quick global check to see whether the spine
|
505
|
+
# intersects a ball containing the spine.
|
506
|
+
if distance_r13_point_line(
|
507
|
+
mcomplex.spine_center, line) > mcomplex.spine_radius:
|
508
|
+
continue
|
509
|
+
|
510
|
+
# And then a similar check per tetrahedron.
|
511
|
+
if all(distance_r13_point_line(
|
512
|
+
tet.spine_center, line) > tet.spine_radius
|
513
|
+
for tet in mcomplex.Tetrahedra):
|
514
|
+
continue
|
515
|
+
|
516
|
+
if mcomplex.verified:
|
517
|
+
# We need to make sure that the intervals are tight enough
|
518
|
+
# that we do not accidentally add a multiple before adding
|
519
|
+
# a primitive.
|
520
|
+
if not real_length.relative_diameter() < 0.125:
|
521
|
+
raise InsufficientPrecisionError(
|
522
|
+
"Interval of real length of geodesic too large. "
|
523
|
+
"Increase precision to fix it.")
|
524
|
+
|
525
|
+
# We also ignore core curves here since they have been
|
526
|
+
# explicitly added earlier.
|
527
|
+
#
|
528
|
+
# Note that this requires computing the start point info
|
529
|
+
# which can be expensive so we do the other checks first.
|
530
|
+
#
|
531
|
+
if geodesic.geodesic_start_point_info().core_curve_cusp:
|
532
|
+
continue
|
533
|
+
|
534
|
+
# Check that we have not visited this geodesic already
|
535
|
+
if not visited_geodesics.add(geodesic):
|
536
|
+
continue
|
537
|
+
# else:
|
538
|
+
# This is a core curve. We already know that they are
|
539
|
+
# de-duplicated (and cannot be parabolics), so no checks
|
540
|
+
# to perform.
|
541
|
+
|
542
|
+
if not real_length > 0:
|
543
|
+
raise InsufficientPrecisionError(
|
544
|
+
"Could not verify that a geodesic is not a parabolic. "
|
545
|
+
"This is most likely due to insufficient precision.")
|
546
|
+
|
547
|
+
if last_real_length is not None:
|
548
|
+
if not lower(last_real_length) <= lower(real_length):
|
549
|
+
raise InsufficientPrecisionError(
|
550
|
+
"Lower bound of new geodesics is less than that of "
|
551
|
+
"already seen geodesics. Re-start length spectrum "
|
552
|
+
"computation with higher precision to see more "
|
553
|
+
"geodesics.")
|
554
|
+
|
555
|
+
last_real_length = real_length
|
556
|
+
|
557
|
+
yield geodesic
|
558
|
+
|
559
|
+
# Geodesic is processed, remove from priority queue.
|
560
|
+
heapq.heappush(
|
561
|
+
pending_geodesics,
|
562
|
+
GeodesicKeyInfo(mcomplex, tile.word, tile.o13_matrix))
|
563
|
+
|
564
|
+
def _geodesic_key_infos_for_core_curves(
|
565
|
+
mcomplex, manifold) -> Sequence[CoreCurveGeodesicInfo]:
|
566
|
+
"""
|
567
|
+
Computes geodesic info for all core curves given Mcomplex constructed
|
568
|
+
with mcomplex_for_len_spec and the SnapPy Manifold.
|
569
|
+
"""
|
570
|
+
|
571
|
+
G = manifold.fundamental_group(False)
|
572
|
+
all_peripheral_words = G.peripheral_curves(as_int_list = True)
|
573
|
+
|
574
|
+
for cusp, peripheral_words in zip(mcomplex.Vertices, all_peripheral_words):
|
575
|
+
if cusp.is_complete:
|
576
|
+
continue
|
577
|
+
|
578
|
+
word = []
|
579
|
+
|
580
|
+
# Add suitable multiples of word corresponding to meridian and longitude
|
581
|
+
for peripheral_word, f in zip(peripheral_words, cusp.filling_matrix[1]):
|
582
|
+
if f == 0:
|
583
|
+
continue
|
584
|
+
if f < 0:
|
585
|
+
peripheral_word = inverse_list_word(peripheral_word)
|
586
|
+
f = -f
|
587
|
+
word += f * peripheral_word
|
588
|
+
|
589
|
+
psl2c_matrix = word_list_to_psl2c_matrix(mcomplex, word)
|
590
|
+
|
591
|
+
o13_matrix = psl2c_to_o13(psl2c_matrix)
|
592
|
+
|
593
|
+
yield CoreCurveGeodesicInfo(
|
594
|
+
word,
|
595
|
+
o13_matrix,
|
596
|
+
core_curve = cusp.Index)
|