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,484 @@
|
|
1
|
+
from .exceptions import CuspDevelopmentExactVerifyError
|
2
|
+
|
3
|
+
from ...math_basics import correct_min, correct_max, lower
|
4
|
+
|
5
|
+
from ...snap import t3mlite as t3m
|
6
|
+
from ...snap.t3mlite import simplex
|
7
|
+
from ...snap.mcomplex_base import *
|
8
|
+
|
9
|
+
from typing import Any, List, Optional
|
10
|
+
|
11
|
+
class HoroTriangleBase:
|
12
|
+
@staticmethod
|
13
|
+
def _make_second(sides, x):
|
14
|
+
"""
|
15
|
+
Cyclically rotate sides = (a,b,c) so that x is the second entry"
|
16
|
+
"""
|
17
|
+
i = (sides.index(x) + 2) % len(sides)
|
18
|
+
return sides[i:]+sides[:i]
|
19
|
+
|
20
|
+
@staticmethod
|
21
|
+
def _sides_and_cross_ratios(tet, vertex, side):
|
22
|
+
sides = simplex.FacesAroundVertexCounterclockwise[vertex]
|
23
|
+
left_side, center_side, right_side = (
|
24
|
+
HoroTriangleBase._make_second(sides, side))
|
25
|
+
z_left = tet.ShapeParameters[left_side & center_side ]
|
26
|
+
z_right = tet.ShapeParameters[center_side & right_side ]
|
27
|
+
return left_side, center_side, right_side, z_left, z_right
|
28
|
+
|
29
|
+
class CuspCrossSectionBase(McomplexEngine):
|
30
|
+
"""
|
31
|
+
Base class for RealCuspCrossSection and ComplexCuspCrossSection.
|
32
|
+
"""
|
33
|
+
|
34
|
+
def add_structures(self, one_cocycle=None):
|
35
|
+
self._add_edge_dict()
|
36
|
+
self._add_cusp_cross_sections(one_cocycle)
|
37
|
+
|
38
|
+
def _add_edge_dict(self):
|
39
|
+
"""
|
40
|
+
Adds a dictionary that maps a pair of vertices to all edges
|
41
|
+
of the triangulation connecting these vertices.
|
42
|
+
The key is a pair (v0, v1) of integers with v0 < v1 that are the
|
43
|
+
indices of the two vertices.
|
44
|
+
"""
|
45
|
+
|
46
|
+
self._edge_dict = {}
|
47
|
+
for edge in self.mcomplex.Edges:
|
48
|
+
vert0, vert1 = edge.Vertices
|
49
|
+
key = tuple(sorted([vert0.Index, vert1.Index]))
|
50
|
+
self._edge_dict.setdefault(key, []).append(edge)
|
51
|
+
|
52
|
+
def _add_cusp_cross_sections(self, one_cocycle):
|
53
|
+
for T in self.mcomplex.Tetrahedra:
|
54
|
+
T.horotriangles = {
|
55
|
+
simplex.V0 : None,
|
56
|
+
simplex.V1 : None,
|
57
|
+
simplex.V2 : None,
|
58
|
+
simplex.V3 : None
|
59
|
+
}
|
60
|
+
for cusp in self.mcomplex.Vertices:
|
61
|
+
self._add_one_cusp_cross_section(cusp, one_cocycle)
|
62
|
+
|
63
|
+
def _add_one_cusp_cross_section(self, cusp, one_cocycle):
|
64
|
+
"""
|
65
|
+
Build a cusp cross section as described in Section 3.6 of the paper
|
66
|
+
|
67
|
+
Asymmetric hyperbolic L-spaces, Heegaard genus, and Dehn filling
|
68
|
+
Nathan M. Dunfield, Neil R. Hoffman, Joan E. Licata
|
69
|
+
http://arxiv.org/abs/1407.7827
|
70
|
+
"""
|
71
|
+
corner0 = cusp.Corners[0]
|
72
|
+
tet0, vert0 = corner0.Tetrahedron, corner0.Subsimplex
|
73
|
+
face0 = simplex.FacesAroundVertexCounterclockwise[vert0][0]
|
74
|
+
tet0.horotriangles[vert0] = self.HoroTriangle(tet0, vert0, face0)
|
75
|
+
active = [(tet0, vert0)]
|
76
|
+
while active:
|
77
|
+
tet0, vert0 = active.pop()
|
78
|
+
for face0 in simplex.FacesAroundVertexCounterclockwise[vert0]:
|
79
|
+
tet1, face1, vert1 = CuspCrossSectionBase._glued_to(
|
80
|
+
tet0, face0, vert0)
|
81
|
+
if tet1.horotriangles[vert1] is None:
|
82
|
+
known_side = (self.HoroTriangle.direction_sign() *
|
83
|
+
tet0.horotriangles[vert0].lengths[face0])
|
84
|
+
if one_cocycle:
|
85
|
+
known_side *= one_cocycle[tet0.Index, face0, vert0]
|
86
|
+
|
87
|
+
tet1.horotriangles[vert1] = self.HoroTriangle(
|
88
|
+
tet1, vert1, face1, known_side)
|
89
|
+
active.append((tet1, vert1))
|
90
|
+
|
91
|
+
@staticmethod
|
92
|
+
def _glued_to(tetrahedron, face, vertex):
|
93
|
+
"""
|
94
|
+
Returns (other tet, other face, other vertex).
|
95
|
+
"""
|
96
|
+
gluing = tetrahedron.Gluing[face]
|
97
|
+
return tetrahedron.Neighbor[face], gluing.image(face), gluing.image(vertex)
|
98
|
+
|
99
|
+
@staticmethod
|
100
|
+
def _cusp_area(cusp):
|
101
|
+
area = 0
|
102
|
+
for corner in cusp.Corners:
|
103
|
+
subsimplex = corner.Subsimplex
|
104
|
+
area += corner.Tetrahedron.horotriangles[subsimplex].area
|
105
|
+
return area
|
106
|
+
|
107
|
+
def cusp_areas(self):
|
108
|
+
"""
|
109
|
+
List of all cusp areas.
|
110
|
+
"""
|
111
|
+
return [ CuspCrossSectionBase._cusp_area(cusp) for cusp in self.mcomplex.Vertices ]
|
112
|
+
|
113
|
+
@staticmethod
|
114
|
+
def _scale_cusp(cusp, scale):
|
115
|
+
for corner in cusp.Corners:
|
116
|
+
subsimplex = corner.Subsimplex
|
117
|
+
corner.Tetrahedron.horotriangles[subsimplex].rescale(scale)
|
118
|
+
|
119
|
+
def scale_cusps(self, scales):
|
120
|
+
"""
|
121
|
+
Scale each cusp by Euclidean dilation by values in given array.
|
122
|
+
"""
|
123
|
+
for cusp, scale in zip(self.mcomplex.Vertices, scales):
|
124
|
+
CuspCrossSectionBase._scale_cusp(cusp, scale)
|
125
|
+
|
126
|
+
def normalize_cusps(self, areas=None):
|
127
|
+
"""
|
128
|
+
Scale cusp so that they have the given target area.
|
129
|
+
Without argument, each cusp is scaled to have area 1.
|
130
|
+
If the argument is a number, scale each cusp to have that area.
|
131
|
+
If the argument is an array, scale each cusp by the respective
|
132
|
+
entry in the array.
|
133
|
+
"""
|
134
|
+
current_areas = self.cusp_areas()
|
135
|
+
if not areas:
|
136
|
+
areas = [ 1 for area in current_areas ]
|
137
|
+
elif not isinstance(areas, list):
|
138
|
+
areas = [ areas for area in current_areas ]
|
139
|
+
scales = [ (area / current_area).sqrt()
|
140
|
+
for area, current_area in zip(areas, current_areas) ]
|
141
|
+
self.scale_cusps(scales)
|
142
|
+
|
143
|
+
def check_cusp_development_exactly(self):
|
144
|
+
"""
|
145
|
+
Check that all side lengths of horo triangles are consistent.
|
146
|
+
If the logarithmic edge equations are fulfilled, this implices
|
147
|
+
that the all cusps are complete and thus the manifold is complete.
|
148
|
+
"""
|
149
|
+
|
150
|
+
for tet0 in self.mcomplex.Tetrahedra:
|
151
|
+
for vert0 in simplex.ZeroSubsimplices:
|
152
|
+
for face0 in simplex.FacesAroundVertexCounterclockwise[vert0]:
|
153
|
+
tet1, face1, vert1 = CuspCrossSectionBase._glued_to(
|
154
|
+
tet0, face0, vert0)
|
155
|
+
side0 = tet0.horotriangles[vert0].lengths[face0]
|
156
|
+
side1 = tet1.horotriangles[vert1].lengths[face1]
|
157
|
+
if not side0 == side1 * self.HoroTriangle.direction_sign():
|
158
|
+
raise CuspDevelopmentExactVerifyError(side0, side1)
|
159
|
+
|
160
|
+
def _testing_check_against_snappea(self, epsilon):
|
161
|
+
# Short-hand
|
162
|
+
ZeroSubs = simplex.ZeroSubsimplices
|
163
|
+
|
164
|
+
# SnapPea kernel results
|
165
|
+
snappea_tilts, snappea_edges = self.manifold._cusp_cross_section_info()
|
166
|
+
|
167
|
+
# Check edge lengths
|
168
|
+
# Iterate through tet
|
169
|
+
for tet, snappea_tet_edges in zip(self.mcomplex.Tetrahedra, snappea_edges):
|
170
|
+
# Iterate through vertices of tet
|
171
|
+
for v, snappea_triangle_edges in zip(ZeroSubs, snappea_tet_edges):
|
172
|
+
# Iterate through faces touching that vertex
|
173
|
+
for f, snappea_triangle_edge in zip(ZeroSubs,
|
174
|
+
snappea_triangle_edges):
|
175
|
+
if v != f:
|
176
|
+
F = simplex.comp(f)
|
177
|
+
length = abs(tet.horotriangles[v].lengths[F])
|
178
|
+
if not abs(length - snappea_triangle_edge) < epsilon:
|
179
|
+
raise ConsistencyWithSnapPeaNumericalVerifyError(
|
180
|
+
snappea_triangle_edge, length)
|
181
|
+
|
182
|
+
@staticmethod
|
183
|
+
def _lower_bound_max_area_triangle_for_std_form(z):
|
184
|
+
"""
|
185
|
+
Imagine an ideal tetrahedron in the upper half space model with
|
186
|
+
vertices at 0, 1, z, and infinity. Pick the lowest (horizontal)
|
187
|
+
horosphere about infinity that intersects the tetrahedron in a
|
188
|
+
triangle, i.e, just touches the face opposite to infinity.
|
189
|
+
This method will return the hyperbolic area of that triangle.
|
190
|
+
|
191
|
+
The result is the same for z, 1/(1-z), and 1 - 1/z.
|
192
|
+
"""
|
193
|
+
|
194
|
+
# First, we check whether the center of the circumcenter of the
|
195
|
+
# triangle containing 0, 1, and z is contained within the triangle.
|
196
|
+
|
197
|
+
# If the center is outside of the triangle, the Euclidean height of the
|
198
|
+
# horosphere is that of the highest point of the three arcs between
|
199
|
+
# 0, 1, and z.
|
200
|
+
# The height is half of the length e of the longest edge of the
|
201
|
+
# triangle.
|
202
|
+
# Given that the Euclidean area of the triangle is given by
|
203
|
+
# A = Im(z) / 2, its hyperbolic area is
|
204
|
+
# A / (e/2)^2 = Im(z) / 2 / (e^2/4) = 2 * Im(z) / e^2
|
205
|
+
#
|
206
|
+
# This is similar to fef_gen.py except that it had a bug in version 1.3
|
207
|
+
# and implemented the last inequality the other way around!
|
208
|
+
#
|
209
|
+
# The center is outside if one of the angles is > pi/2, cover each case
|
210
|
+
#
|
211
|
+
|
212
|
+
# Angle at 0 is > pi/2
|
213
|
+
if z.real() < 0:
|
214
|
+
# So longest edge of the triangle must be opposite of 0
|
215
|
+
return 2 * z.imag() / (abs(z - 1) ** 2)
|
216
|
+
# Angle at 1 is > pi/2
|
217
|
+
if z.real() > 1:
|
218
|
+
# So longest edge of the triangle must be opposite of 1
|
219
|
+
return 2 * z.imag() / (abs(z) ** 2)
|
220
|
+
# Angle at z is > pi/2
|
221
|
+
if abs(2 * z - 1) < 1:
|
222
|
+
# So longest edge of the triangle must be opposite of z
|
223
|
+
return 2 * z.imag()
|
224
|
+
|
225
|
+
# An interval note: the circumcenter might still be in the triangle,
|
226
|
+
# we just were not able to prove it. The area we compute is a lower
|
227
|
+
# bound in any case. Thus, the function is not guaranteed to compute
|
228
|
+
# the maximal area, just a lower bound for it.
|
229
|
+
|
230
|
+
# Now cover the case that the center of the triangle is within the
|
231
|
+
# triangle.
|
232
|
+
|
233
|
+
# The Euclidean area of the above triangle is given by
|
234
|
+
# A = Im(z) / 2
|
235
|
+
# and its Euclidean side lengths are given by
|
236
|
+
# a = 1, b = abs(z), and c = abs(z - 1).
|
237
|
+
#
|
238
|
+
# The Euclidean circumradius r of the triangle is given by the usual
|
239
|
+
# formula
|
240
|
+
# r = a * b * c / (4 * A)
|
241
|
+
#
|
242
|
+
# This is also the Euclidean radius of the circle containing 0, 1, and
|
243
|
+
# z and of the halfsphere above that circle that contains the face
|
244
|
+
# opposite to infinity.
|
245
|
+
# Therefore, r is also the Euclidean height of the above horosphere and
|
246
|
+
# hence, the hyperbolic metric at that height is 1/r.
|
247
|
+
# So the hyperbolic area of the triangle becomes
|
248
|
+
#
|
249
|
+
# A / r^2 = A / (a * b * c / (4 * A))^2 = 16 * A^3 / (a * b * c)^2
|
250
|
+
# = 2 * Im(z)^3 / (abs(z) * abs(z-1)) ^ 2
|
251
|
+
|
252
|
+
return 2 * z.imag() ** 3 / (abs(z) * abs(z - 1)) ** 2
|
253
|
+
|
254
|
+
@staticmethod
|
255
|
+
def _max_area_triangle_to_avoid_incenter(z):
|
256
|
+
abs_z = abs(z)
|
257
|
+
abs_z_minus_one = abs(z - 1)
|
258
|
+
return z.imag() * (1 + abs_z + abs_z_minus_one) / (4 * abs_z * abs_z_minus_one)
|
259
|
+
|
260
|
+
@staticmethod
|
261
|
+
def _compute_area_scale(corner : t3m.Corner, area_function):
|
262
|
+
"""
|
263
|
+
For a tetrahedron and vertex of the tetrahedron, compute how much
|
264
|
+
the cusp neighborhood about the vertex can be scaled so that the cusp
|
265
|
+
triangle is given the by area_function.
|
266
|
+
"""
|
267
|
+
|
268
|
+
tet = corner.Tetrahedron
|
269
|
+
z = tet.ShapeParameters[simplex.E01]
|
270
|
+
return area_function(z) / tet.horotriangles[corner.Subsimplex].area
|
271
|
+
|
272
|
+
@staticmethod
|
273
|
+
def _compute_max_scale(v : t3m.Vertex, max_area_function):
|
274
|
+
area_scales = [
|
275
|
+
CuspCrossSectionBase._compute_area_scale(corner, max_area_function)
|
276
|
+
for corner in v.Corners ]
|
277
|
+
|
278
|
+
return correct_min(area_scales).sqrt()
|
279
|
+
|
280
|
+
def compute_scale_for_std_form(self, v : t3m.Vertex):
|
281
|
+
"""
|
282
|
+
Computes scale for cusp neighborhood about given vertex to ensure
|
283
|
+
that each tetrahedron adjacent to the vertex intersects the the
|
284
|
+
cusp neighborhood in standard form.
|
285
|
+
"""
|
286
|
+
return CuspCrossSectionBase._compute_max_scale(
|
287
|
+
v, CuspCrossSectionBase._lower_bound_max_area_triangle_for_std_form)
|
288
|
+
|
289
|
+
def compute_scale_to_avoid_incenter(self, v : t3m.Vertex):
|
290
|
+
"""
|
291
|
+
Computes scale for cusp neighborhood about given vertex to ensure
|
292
|
+
that the cusp neighborhood avoid the incenter of each tetrahedron.
|
293
|
+
"""
|
294
|
+
return CuspCrossSectionBase._compute_max_scale(
|
295
|
+
v, CuspCrossSectionBase._max_area_triangle_to_avoid_incenter)
|
296
|
+
|
297
|
+
def ensure_std_form(self, allow_scaling_up=False):
|
298
|
+
"""
|
299
|
+
Makes sure that the cusp neighborhoods intersect each tetrahedron
|
300
|
+
in standard form by scaling the cusp neighborhoods down if necessary.
|
301
|
+
"""
|
302
|
+
|
303
|
+
z = self.mcomplex.Tetrahedra[0].ShapeParameters[simplex.E01]
|
304
|
+
RF = z.real().parent()
|
305
|
+
one = RF(1)
|
306
|
+
|
307
|
+
for v in self.mcomplex.Vertices:
|
308
|
+
scale = self.compute_scale_for_std_form(v)
|
309
|
+
if not allow_scaling_up:
|
310
|
+
scale = correct_min([one, scale])
|
311
|
+
CuspCrossSectionBase._scale_cusp(v, scale)
|
312
|
+
|
313
|
+
@staticmethod
|
314
|
+
def _exp_distance_edge_embedding(tet, perm):
|
315
|
+
# Get a face of the tetrahedron adjacent to that edge
|
316
|
+
face3 = simplex.TwoSubsimplices[perm[3]]
|
317
|
+
# At each end of the edge, this tetrahedron gives us one
|
318
|
+
# triangle of a cusp cross-section and the intersection of the
|
319
|
+
# face with the cusp cross-section gives us one edge of the
|
320
|
+
# triangle.
|
321
|
+
# Multiply the two edge lengths. If these are complex edge
|
322
|
+
# lengths, the result is actually the square of a Ptolemy
|
323
|
+
# coordinate (see C. Zickert, The volume and Chern-Simons
|
324
|
+
# invariant of a representation).
|
325
|
+
v0 = simplex.ZeroSubsimplices[perm[0]]
|
326
|
+
length0 = tet.horotriangles[v0].get_real_lengths()[face3]
|
327
|
+
|
328
|
+
v1 = simplex.ZeroSubsimplices[perm[1]]
|
329
|
+
length1 = tet.horotriangles[v1].get_real_lengths()[face3]
|
330
|
+
|
331
|
+
return 1 / (length0 * length1)
|
332
|
+
|
333
|
+
@staticmethod
|
334
|
+
def _exp_distance_edge(edge : t3m.Edge):
|
335
|
+
"""
|
336
|
+
Given an edge, returns the maximal scaling factor of the two cusp
|
337
|
+
neighborhoods at the end of the edges so that the neighborhoods do
|
338
|
+
not intersect in the given edge.
|
339
|
+
"""
|
340
|
+
|
341
|
+
distances = []
|
342
|
+
# Walk around the edge.
|
343
|
+
for i, (tet, perm) in enumerate(edge.embeddings()):
|
344
|
+
d = CuspCrossSectionBase._exp_distance_edge_embedding(tet, perm)
|
345
|
+
|
346
|
+
if i == 0:
|
347
|
+
v0 = simplex.ZeroSubsimplices[perm[0]]
|
348
|
+
v1 = simplex.ZeroSubsimplices[perm[1]]
|
349
|
+
if tet.Class[v0].is_complete and tet.Class[v1].is_complete:
|
350
|
+
# If both cusps are complete, then the horotriangles
|
351
|
+
# of one of the cusp neighborhoods all intersect the edge
|
352
|
+
# in the manifold in the same point. Thus, the distance
|
353
|
+
# we compute is the same, no matter from what tetrahedron
|
354
|
+
# we measure it.
|
355
|
+
return d
|
356
|
+
|
357
|
+
distances.append(d)
|
358
|
+
|
359
|
+
return correct_min(distances)
|
360
|
+
|
361
|
+
@staticmethod
|
362
|
+
def _exp_distance_of_edges(edges: List[t3m.Edge]):
|
363
|
+
"""
|
364
|
+
Implements exp_distance_neighborhoods_measured_along_edges given
|
365
|
+
all edges connecting two cusps in question.
|
366
|
+
"""
|
367
|
+
return correct_min(
|
368
|
+
[ CuspCrossSectionBase._exp_distance_edge(edge)
|
369
|
+
for edge in edges])
|
370
|
+
|
371
|
+
def exp_distance_neighborhoods_measured_along_edges(
|
372
|
+
self, i : int, j : int) -> Optional[Any]:
|
373
|
+
"""
|
374
|
+
Computes the maximal scaling factor of the cusp neighborhoods
|
375
|
+
about cusp i and j such that the two neighborhoods stay disjoint
|
376
|
+
along the edges.
|
377
|
+
|
378
|
+
That is if we scale both cusp i and j, then they are disjoint along
|
379
|
+
edges if the product of the scale factor is less than the maximal
|
380
|
+
scaling factor.
|
381
|
+
|
382
|
+
Note that if i and j are the same, because the scaling factor applies
|
383
|
+
to the same cusp twice, we only can scale the one cusp by a factor
|
384
|
+
sqrt(maximal scaling factor) to stay disjoint along edges.
|
385
|
+
|
386
|
+
This function can return None if no edge between the two given
|
387
|
+
cusps exists.
|
388
|
+
|
389
|
+
Assume two cusp neighborhoods are disjoing along edges. They could
|
390
|
+
still intersect if they are not in standard form.
|
391
|
+
|
392
|
+
Note that this method also works for filled cusps. In this case,
|
393
|
+
the neighborhood is about a core curve in the manifold and consists
|
394
|
+
of the intersections with a tetrahedra by horoballs about its vertices.
|
395
|
+
o
|
396
|
+
When using filled cusps, it is advisable to call
|
397
|
+
scale_triangles_to_avoid_standard_tube first.
|
398
|
+
"""
|
399
|
+
if i > j:
|
400
|
+
i, j = j, i
|
401
|
+
if not (i, j) in self._edge_dict:
|
402
|
+
return None
|
403
|
+
return CuspCrossSectionBase._exp_distance_of_edges(
|
404
|
+
self._edge_dict[(i,j)])
|
405
|
+
|
406
|
+
def ensure_disjoint_on_edges(self):
|
407
|
+
"""
|
408
|
+
Scales the cusp neighborhoods down until they are disjoint when
|
409
|
+
intersected with the edges of the triangulations.
|
410
|
+
|
411
|
+
Given an edge of a triangulation, we can easily compute the signed
|
412
|
+
distance between the two cusp neighborhoods at the ends of the edge
|
413
|
+
measured along that edge. Thus, we can easily check that all the
|
414
|
+
distances measured along all the edges are positive and scale the
|
415
|
+
cusps down if necessary.
|
416
|
+
|
417
|
+
Unfortunately, this is not sufficient to ensure that two cusp
|
418
|
+
neighborhoods are disjoint since there might be a geodesic between
|
419
|
+
the two cusps such that the distance between the two cusps measured
|
420
|
+
along the geodesic is shorter than measured along any edge of the
|
421
|
+
triangulation.
|
422
|
+
|
423
|
+
Thus, it is necessary to call ensure_std_form as well:
|
424
|
+
it will make sure that the cusp neighborhoods are small enough so
|
425
|
+
that they intersect the tetrahedra in "standard" form.
|
426
|
+
Here, "standard" form means that the corresponding horoball about a
|
427
|
+
vertex of a tetrahedron intersects the three faces of the tetrahedron
|
428
|
+
adjacent to the vertex but not the one opposite to the vertex.
|
429
|
+
|
430
|
+
For any geometric triangulation, standard form and positive distance
|
431
|
+
measured along all edges of the triangulation is sufficient for
|
432
|
+
disjoint neighborhoods.
|
433
|
+
|
434
|
+
The SnapPea kernel uses the proto-canonical triangulation associated
|
435
|
+
to the cusp neighborhood to get around this when computing the
|
436
|
+
"reach" and the "stoppers" for the cusps.
|
437
|
+
|
438
|
+
**Remark:** This means that the cusp neighborhoods might be scaled down
|
439
|
+
more than necessary. Related open questions are: given maximal disjoint
|
440
|
+
cusp neighborhoods (maximal in the sense that no neighborhood can be
|
441
|
+
expanded without bumping into another or itself), is there always a
|
442
|
+
geometric triangulation intersecting the cusp neighborhoods in standard
|
443
|
+
form? Is there an easy algorithm to find this triangulation, e.g., by
|
444
|
+
applying a 2-3 move whenever we see a non-standard intersection?
|
445
|
+
"""
|
446
|
+
|
447
|
+
num_cusps = len(self.mcomplex.Vertices)
|
448
|
+
|
449
|
+
# First check for every cusp that its cusp neighborhood does not bump
|
450
|
+
# into itself - at least when measured along the edges of the
|
451
|
+
# triangulation
|
452
|
+
for i in range(num_cusps):
|
453
|
+
# Get all edges
|
454
|
+
if (i,i) in self._edge_dict:
|
455
|
+
dist = CuspCrossSectionBase._exp_distance_of_edges(
|
456
|
+
self._edge_dict[(i,i)])
|
457
|
+
# For verified computations, do not use the seemingly
|
458
|
+
# equivalent dist <= 1. We want to scale down every time
|
459
|
+
# we cannot ensure they are disjoint.
|
460
|
+
if not (dist > 1):
|
461
|
+
scale = dist.sqrt()
|
462
|
+
# Scale the one cusp
|
463
|
+
CuspCrossSectionBase._scale_cusp(self.mcomplex.Vertices[i],
|
464
|
+
scale)
|
465
|
+
|
466
|
+
# Now check for the pairs of two distinct cusps that the corresponding
|
467
|
+
# neighborhoods do not bump into each other - at least when measured
|
468
|
+
# along the edges of the triangulation
|
469
|
+
for i in range(num_cusps):
|
470
|
+
for j in range(i):
|
471
|
+
dist = self.exp_distance_neighborhoods_measured_along_edges(i, j)
|
472
|
+
# Above comment applies
|
473
|
+
if dist is not None:
|
474
|
+
if not (dist > 1):
|
475
|
+
# Scale the two cusps by the same amount
|
476
|
+
# We have choices here, for example, we could only
|
477
|
+
# scale one cusp by dist.
|
478
|
+
scale = dist.sqrt()
|
479
|
+
CuspCrossSectionBase._scale_cusp(self.mcomplex.Vertices[i],
|
480
|
+
scale)
|
481
|
+
CuspCrossSectionBase._scale_cusp(self.mcomplex.Vertices[j],
|
482
|
+
scale)
|
483
|
+
|
484
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class IncompleteCuspError(ValueError):
|
2
|
+
"""
|
3
|
+
Exception raised when trying to construct a CuspCrossSection
|
4
|
+
from a Manifold with Dehn-fillings.
|
5
|
+
"""
|
6
|
+
def __init__(self, manifold):
|
7
|
+
self.manifold = manifold
|
8
|
+
|
9
|
+
def __str__(self):
|
10
|
+
return (('Cannot construct CuspCrossSection from manifold with '
|
11
|
+
'Dehn-fillings: %s') % self.manifold)
|
12
|
+
|
13
|
+
|
14
|
+
class ConsistencyWithSnapPeaNumericalVerifyError(RuntimeError):
|
15
|
+
"""
|
16
|
+
Exception raised when there is a significant numerical difference
|
17
|
+
between the values computed by the SnapPea kernel and by this module
|
18
|
+
for a given quantity.
|
19
|
+
"""
|
20
|
+
def __init__(self, value, snappea_value):
|
21
|
+
self.value = value
|
22
|
+
self.snappea_value = snappea_value
|
23
|
+
|
24
|
+
def __str__(self):
|
25
|
+
return ('Inconsistency between SnapPea kernel and verify: '
|
26
|
+
'%r == %r' % (self.snappea_value, self.value))
|
27
|
+
|
28
|
+
class CuspDevelopmentExactVerifyError(RuntimeError):
|
29
|
+
"""
|
30
|
+
Raised when finding a consistent assignment of side lengths to the
|
31
|
+
Euclidean Horotriangles to form a Euclidean Horotorus for a cusp failed
|
32
|
+
using exact arithmetic.
|
33
|
+
"""
|
34
|
+
|
35
|
+
def __init__(self, value1, value2):
|
36
|
+
self.value1 = value1
|
37
|
+
self.value2 = value2
|
38
|
+
|
39
|
+
def __str__(self):
|
40
|
+
return ('Inconsistency in the side lengths of the Euclidean '
|
41
|
+
'Horotriangles for a cusp: '
|
42
|
+
'%r = %r' % (self.value1, self.value2))
|