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,697 @@
|
|
1
|
+
from .cusp_cross_section_base import CuspCrossSectionBase, HoroTriangleBase
|
2
|
+
from .exceptions import IncompleteCuspError
|
3
|
+
|
4
|
+
from ...snap.kernel_structures import TransferKernelStructuresEngine
|
5
|
+
from ...snap import t3mlite as t3m
|
6
|
+
from ...snap.t3mlite import simplex
|
7
|
+
from ...math_basics import correct_max, correct_min, lower
|
8
|
+
|
9
|
+
# For each vertex, return an edge connected to it
|
10
|
+
_pick_an_edge_for_vertex = {
|
11
|
+
vertex : [ edge
|
12
|
+
for edge in simplex.OneSubsimplices
|
13
|
+
if simplex.is_subset(vertex, edge) ][0]
|
14
|
+
for vertex in simplex.ZeroSubsimplices
|
15
|
+
}
|
16
|
+
|
17
|
+
# For each (vertex, face) pair, pick one of the two edges adjacent
|
18
|
+
# to both the vertex and face
|
19
|
+
_pick_an_edge_for_vertex_and_face = {
|
20
|
+
(vertex, face): [ edge
|
21
|
+
for edge in simplex.OneSubsimplices
|
22
|
+
if (simplex.is_subset(vertex, edge) and
|
23
|
+
simplex.is_subset(edge, face)) ][0]
|
24
|
+
for vertex in simplex.ZeroSubsimplices
|
25
|
+
for face in simplex.TwoSubsimplices
|
26
|
+
if simplex.is_subset(vertex, face)
|
27
|
+
}
|
28
|
+
|
29
|
+
# Given a vertex, cyclically order the three adjacent faces in
|
30
|
+
# clockwise fashion. For each face, return the triple (face, edge, next face)
|
31
|
+
# where edge is adjacent to both faces.
|
32
|
+
_face_edge_face_triples_for_vertex_link = {
|
33
|
+
vertex : [ (faces[i], faces[i] & faces[(i+1) % 3], faces[(i+1) % 3])
|
34
|
+
for i in range(3) ]
|
35
|
+
for vertex, faces in simplex.FacesAroundVertexCounterclockwise.items()
|
36
|
+
}
|
37
|
+
|
38
|
+
class ComplexHoroTriangle:
|
39
|
+
"""
|
40
|
+
A horosphere cross section in the corner of an ideal tetrahedron.
|
41
|
+
The sides of the triangle correspond to faces of the tetrahedron.
|
42
|
+
The lengths stored for the triangle are complex.
|
43
|
+
"""
|
44
|
+
def __init__(self, tet, vertex, known_side, length_of_side=None):
|
45
|
+
left_side, center_side, right_side, z_left, z_right = (
|
46
|
+
HoroTriangleBase._sides_and_cross_ratios(tet, vertex, known_side))
|
47
|
+
|
48
|
+
if length_of_side is None:
|
49
|
+
CF = z_left.parent()
|
50
|
+
L = CF(1)
|
51
|
+
else:
|
52
|
+
L = length_of_side
|
53
|
+
self.lengths = { center_side : L,
|
54
|
+
left_side : - z_left * L,
|
55
|
+
right_side : - L / z_right }
|
56
|
+
absL = abs(L)
|
57
|
+
self.area = absL * absL * z_left.imag() / 2
|
58
|
+
|
59
|
+
self._real_lengths_cache = None
|
60
|
+
|
61
|
+
def get_real_lengths(self):
|
62
|
+
if not self._real_lengths_cache:
|
63
|
+
self._real_lengths_cache = {
|
64
|
+
side : abs(length)
|
65
|
+
for side, length in self.lengths.items() }
|
66
|
+
return self._real_lengths_cache
|
67
|
+
|
68
|
+
def rescale(self, t):
|
69
|
+
"Rescales the triangle by a Euclidean dilation"
|
70
|
+
for face in self.lengths:
|
71
|
+
self.lengths[face] *= t
|
72
|
+
self.area *= t * t
|
73
|
+
|
74
|
+
self._real_lengths_cache = None
|
75
|
+
|
76
|
+
@staticmethod
|
77
|
+
def direction_sign():
|
78
|
+
return -1
|
79
|
+
|
80
|
+
def add_vertex_positions(self, vertex, edge, position):
|
81
|
+
"""
|
82
|
+
Adds a dictionary vertex_positions mapping
|
83
|
+
an edge (such as simplex.E01) to complex position
|
84
|
+
for the vertex of the horotriangle obtained by
|
85
|
+
intersecting the edge with the horosphere.
|
86
|
+
|
87
|
+
Two of these positions are computed from the one given
|
88
|
+
using the complex edge lengths. The given vertex and
|
89
|
+
edge are t3m-style.
|
90
|
+
"""
|
91
|
+
|
92
|
+
self.vertex_positions = {}
|
93
|
+
|
94
|
+
# The three triples
|
95
|
+
# (face, edge adjacent to face and next face, next face)
|
96
|
+
# when going around the vertex counter clockwise
|
97
|
+
vertex_link = _face_edge_face_triples_for_vertex_link[vertex]
|
98
|
+
|
99
|
+
# Find for which of these triples the position is for
|
100
|
+
for i in range(3):
|
101
|
+
if edge == vertex_link[i][1]:
|
102
|
+
break
|
103
|
+
|
104
|
+
# Now go through the triples starting with the one for
|
105
|
+
# which we have given the vertex position
|
106
|
+
for j in range(3):
|
107
|
+
face0, edge, face1 = vertex_link[(i + j) % 3]
|
108
|
+
# Assign vertex position
|
109
|
+
self.vertex_positions[edge] = position
|
110
|
+
# Update vertex position to be for the next
|
111
|
+
# edge using complex edge length
|
112
|
+
position += self.lengths[face1]
|
113
|
+
|
114
|
+
def lift_vertex_positions(self, lifted_position):
|
115
|
+
"""
|
116
|
+
Lift the vertex positions of this triangle. lifted_position is
|
117
|
+
used as a guide what branch of the logarithm to use.
|
118
|
+
|
119
|
+
The lifted position is computed as the log of the vertex
|
120
|
+
position where it is assumed that the fixed point of the
|
121
|
+
holonomy is at the origin. The branch of the logarithm
|
122
|
+
closest to lifted_position is used.
|
123
|
+
"""
|
124
|
+
|
125
|
+
NumericalField = lifted_position.parent()
|
126
|
+
twoPi = 2 * NumericalField.pi()
|
127
|
+
I = NumericalField(1j)
|
128
|
+
|
129
|
+
def adjust_log(z):
|
130
|
+
# Compute log and adjust
|
131
|
+
logZ = z.log()
|
132
|
+
# Add multiplies of 2 * pi * I so that it is close
|
133
|
+
# to lifted_position
|
134
|
+
return logZ + ((lifted_position - logZ) / twoPi).imag().round() * twoPi * I
|
135
|
+
|
136
|
+
self.lifted_vertex_positions = {
|
137
|
+
# Take log of vertex position
|
138
|
+
# (assuming fixed point is at origin).
|
139
|
+
edge: adjust_log(position)
|
140
|
+
for edge, position in self.vertex_positions.items()
|
141
|
+
}
|
142
|
+
|
143
|
+
class ComplexCuspCrossSection(CuspCrossSectionBase):
|
144
|
+
"""
|
145
|
+
Similarly to RealCuspCrossSection with the following differences: it
|
146
|
+
computes the complex edge lengths and the cusp translations (instead
|
147
|
+
of the tilts) and it only works for orientable manifolds.
|
148
|
+
|
149
|
+
The same comment applies about the type of the shapes. The resulting
|
150
|
+
edge lengths and translations will be of the same type as the shapes.
|
151
|
+
|
152
|
+
For shapes corresponding to a non-boundary unipotent representation
|
153
|
+
(in other words, a manifold having an incomplete cusp), a cusp can
|
154
|
+
be developed if an appropriate 1-cocycle is given. The 1-cocycle
|
155
|
+
is a cellular cocycle in the dual of the cusp triangulations and
|
156
|
+
represents an element in H^1(boundary M; C^*) that must match the
|
157
|
+
PSL(2,C) boundary holonomy of the representation.
|
158
|
+
It is encoded as dictionary with key (tet index, t3m face, t3m vertex).
|
159
|
+
"""
|
160
|
+
|
161
|
+
HoroTriangle = ComplexHoroTriangle
|
162
|
+
|
163
|
+
@staticmethod
|
164
|
+
def fromManifoldAndShapes(manifold, shapes, one_cocycle=None):
|
165
|
+
if not one_cocycle:
|
166
|
+
for cusp_info in manifold.cusp_info():
|
167
|
+
if not cusp_info['complete?']:
|
168
|
+
raise IncompleteCuspError(manifold)
|
169
|
+
|
170
|
+
if not manifold.is_orientable():
|
171
|
+
raise ValueError("Non-orientable")
|
172
|
+
|
173
|
+
m = t3m.Mcomplex(manifold)
|
174
|
+
|
175
|
+
t = TransferKernelStructuresEngine(m, manifold)
|
176
|
+
t.reindex_cusps_and_transfer_peripheral_curves()
|
177
|
+
t.add_shapes(shapes)
|
178
|
+
|
179
|
+
if one_cocycle == 'develop':
|
180
|
+
resolved_one_cocycle = None
|
181
|
+
else:
|
182
|
+
resolved_one_cocycle = one_cocycle
|
183
|
+
|
184
|
+
c = ComplexCuspCrossSection(m)
|
185
|
+
c.add_structures(resolved_one_cocycle)
|
186
|
+
|
187
|
+
# For testing against SnapPea kernel data
|
188
|
+
c.manifold = manifold
|
189
|
+
|
190
|
+
return c
|
191
|
+
|
192
|
+
def _dummy_for_testing(self):
|
193
|
+
"""
|
194
|
+
Compare the computed edge lengths and tilts against the one computed by
|
195
|
+
the SnapPea kernel.
|
196
|
+
|
197
|
+
>>> from snappy import Manifold
|
198
|
+
|
199
|
+
Convention of the kernel is to use (3/8) sqrt(3) as area (ensuring that
|
200
|
+
cusp neighborhoods are disjoint).
|
201
|
+
|
202
|
+
>>> cusp_area = 0.649519052838329
|
203
|
+
|
204
|
+
>>> for name in ['m009', 'm015', 't02333']:
|
205
|
+
... M = Manifold(name)
|
206
|
+
... e = ComplexCuspCrossSection.fromManifoldAndShapes(M, M.tetrahedra_shapes('rect'))
|
207
|
+
... e.normalize_cusps(cusp_area)
|
208
|
+
... e._testing_check_against_snappea(1e-10)
|
209
|
+
|
210
|
+
"""
|
211
|
+
|
212
|
+
@staticmethod
|
213
|
+
def _get_translation(vertex, ml):
|
214
|
+
"""
|
215
|
+
Compute the translation corresponding to the meridian (ml = 0) or
|
216
|
+
longitude (ml = 1) of the given cusp.
|
217
|
+
"""
|
218
|
+
|
219
|
+
# Accumulate result
|
220
|
+
result = 0
|
221
|
+
|
222
|
+
# For each triangle of this cusp's cross-section
|
223
|
+
for corner in vertex.Corners:
|
224
|
+
# Get the corresponding tetrahedron
|
225
|
+
tet = corner.Tetrahedron
|
226
|
+
# Get the corresponding vertex of this tetrahedron
|
227
|
+
subsimplex = corner.Subsimplex
|
228
|
+
# Get the three faces of the tetrahedron adjacent to that vertex
|
229
|
+
# Each one intersects the cusp cross-section in an edge of
|
230
|
+
# the triangle.
|
231
|
+
faces = simplex.FacesAroundVertexCounterclockwise[subsimplex]
|
232
|
+
# Get the data for this triangle
|
233
|
+
triangle = tet.horotriangles[subsimplex]
|
234
|
+
|
235
|
+
# Restrict the peripheral curve data to this triangle.
|
236
|
+
# The result consists of four integers, but the one at
|
237
|
+
# subsimplex will always be zero, so effectively, it
|
238
|
+
# is three integers corresponding to the three sides of the
|
239
|
+
# triangle.
|
240
|
+
# Each of these integers tells us how often the peripheral curve
|
241
|
+
# "enters" the triangle from the corresponding side of the
|
242
|
+
# triangle.
|
243
|
+
# Each time the peripheral curve "enters" the triangle through a
|
244
|
+
# side, its contribution to the translation is the vector from the
|
245
|
+
# center of the side to the center of the triangle.
|
246
|
+
curves = tet.PeripheralCurves[ml][0][subsimplex]
|
247
|
+
|
248
|
+
# We know need to compute this contribution to the translation.
|
249
|
+
# Imagine a triangle with complex edge lengths e_0, e_1, e_2 and,
|
250
|
+
# without loss of generality, move it such that its vertices are
|
251
|
+
# at v_0 = 0, v_1 = e_0, v_2 = e_0 + e_1.
|
252
|
+
# The center of the triangle is at
|
253
|
+
# c = (v_0 + v_1 + v_2) / 3 = 2 * e_0 / 3 + e_1 / 3.
|
254
|
+
# The vector from the center of the side corresponding to e_0
|
255
|
+
# to the center of the triangle is given by
|
256
|
+
# c - e_0 / 2 = e_0 / 6 + e_1 / 3
|
257
|
+
#
|
258
|
+
# If the peripheral curves enters the side of the triangle
|
259
|
+
# corresponding to e_i n_i-times, then the total contribution
|
260
|
+
# with respect to that triangle is given by
|
261
|
+
# n_0 * (e_0 / 6 + e_1 / 3)
|
262
|
+
# + n_1 * (e_1 / 6 + e_2 / 3)
|
263
|
+
# + n_2 * (e_2 / 6 + e_0 / 3)
|
264
|
+
# = ( (n_0 + 2 * n_2) * e_0
|
265
|
+
# + (n_1 + 2 * n_0) * e_1
|
266
|
+
# + (n_2 + 2 * n_1) * e_2) / 6
|
267
|
+
#
|
268
|
+
# = (sum_{i=0,1,2} (n_i + 2 * n_{i+2}) * e_i) / 6
|
269
|
+
|
270
|
+
# Implement this sum
|
271
|
+
for i in range(3):
|
272
|
+
# Find the t3m faces corresponding to two edges of this
|
273
|
+
# triangle
|
274
|
+
this_face = faces[ i ]
|
275
|
+
prev_face = faces[(i+2) % 3]
|
276
|
+
|
277
|
+
# n_i + 2 * n_{i+2} in above notation
|
278
|
+
f = curves[this_face] + 2 * curves[prev_face]
|
279
|
+
|
280
|
+
# (n_i + 2 * n_{i+2}) * e_i in above notation
|
281
|
+
result += f * triangle.lengths[this_face]
|
282
|
+
|
283
|
+
return result / 6
|
284
|
+
|
285
|
+
@staticmethod
|
286
|
+
def _compute_translations(vertex):
|
287
|
+
vertex.Translations = [
|
288
|
+
ComplexCuspCrossSection._get_translation(vertex, i)
|
289
|
+
for i in range(2) ]
|
290
|
+
|
291
|
+
def compute_translations(self):
|
292
|
+
for vertex in self.mcomplex.Vertices:
|
293
|
+
ComplexCuspCrossSection._compute_translations(vertex)
|
294
|
+
|
295
|
+
@staticmethod
|
296
|
+
def _get_normalized_translations(vertex):
|
297
|
+
"""
|
298
|
+
Compute the translations corresponding to the merdian and longitude of
|
299
|
+
the given cusp.
|
300
|
+
"""
|
301
|
+
|
302
|
+
m, l = vertex.Translations
|
303
|
+
return m / l * abs(l), abs(l)
|
304
|
+
|
305
|
+
def all_normalized_translations(self):
|
306
|
+
"""
|
307
|
+
Compute the translations corresponding to the meridian and longitude
|
308
|
+
for each cusp.
|
309
|
+
"""
|
310
|
+
|
311
|
+
self.compute_translations()
|
312
|
+
return [ ComplexCuspCrossSection._get_normalized_translations(vertex)
|
313
|
+
for vertex in self.mcomplex.Vertices ]
|
314
|
+
|
315
|
+
@staticmethod
|
316
|
+
def _compute_cusp_shape(vertex : t3m.Vertex):
|
317
|
+
m, l = vertex.Translations
|
318
|
+
return (l / m).conjugate()
|
319
|
+
|
320
|
+
def cusp_shapes(self):
|
321
|
+
"""
|
322
|
+
Compute the cusp shapes as conjugate of the quotient of the translations
|
323
|
+
corresponding to the longitude and meridian for each cusp (SnapPea
|
324
|
+
kernel convention).
|
325
|
+
"""
|
326
|
+
self.compute_translations()
|
327
|
+
return [ ComplexCuspCrossSection._compute_cusp_shape(vertex)
|
328
|
+
for vertex in self.mcomplex.Vertices ]
|
329
|
+
|
330
|
+
def add_vertex_positions_to_horotriangles(self):
|
331
|
+
"""
|
332
|
+
Develops cusp to assign to each horotriangle the positions of its three
|
333
|
+
vertices in the Euclidean plane.
|
334
|
+
|
335
|
+
Note: For a complete cusp, this is defined only up to translating the
|
336
|
+
entire triangle by translations generated by meridian and longitude.
|
337
|
+
|
338
|
+
For an incomplete cusp, this is defined only up to
|
339
|
+
similarities generated by the meridian and longitude. The
|
340
|
+
positions can be moved such that the fixed point of these
|
341
|
+
similarities is at the origin by calling
|
342
|
+
move_fixed_point_to_zero after
|
343
|
+
add_vertex_positions_to_horotriangles.
|
344
|
+
|
345
|
+
Note: This is not working when one_cocycle is passed during the
|
346
|
+
construction of the cusp cross section.
|
347
|
+
"""
|
348
|
+
for cusp in self.mcomplex.Vertices:
|
349
|
+
self._add_one_cusp_vertex_positions(cusp)
|
350
|
+
|
351
|
+
def _add_one_cusp_vertex_positions(self, cusp : t3m.Vertex):
|
352
|
+
"""
|
353
|
+
Procedure is similar to _add_one_cusp_cross_section
|
354
|
+
"""
|
355
|
+
|
356
|
+
corner0 = cusp.Corners[0]
|
357
|
+
tet0, vert0 = corner0.Tetrahedron, corner0.Subsimplex
|
358
|
+
zero = tet0.ShapeParameters[simplex.E01].parent()(0)
|
359
|
+
tet0.horotriangles[vert0].add_vertex_positions(
|
360
|
+
vert0, _pick_an_edge_for_vertex[vert0], zero)
|
361
|
+
|
362
|
+
active = [(tet0, vert0)]
|
363
|
+
|
364
|
+
# Pairs (tet index, vertex) indicating what has already been
|
365
|
+
# visited
|
366
|
+
visited = set()
|
367
|
+
visited.add((tet0.Index, vert0))
|
368
|
+
|
369
|
+
while active:
|
370
|
+
tet0, vert0 = active.pop()
|
371
|
+
for face0 in simplex.FacesAroundVertexCounterclockwise[vert0]:
|
372
|
+
tet1, face1, vert1 = CuspCrossSectionBase._glued_to(
|
373
|
+
tet0, face0, vert0)
|
374
|
+
if not (tet1.Index, vert1) in visited:
|
375
|
+
edge0 = _pick_an_edge_for_vertex_and_face[vert0, face0]
|
376
|
+
edge1 = tet0.Gluing[face0].image(edge0)
|
377
|
+
|
378
|
+
tet1.horotriangles[vert1].add_vertex_positions(
|
379
|
+
vert1,
|
380
|
+
edge1,
|
381
|
+
tet0.horotriangles[vert0].vertex_positions[edge0])
|
382
|
+
|
383
|
+
active.append( (tet1, vert1) )
|
384
|
+
visited.add((tet1.Index, vert1))
|
385
|
+
|
386
|
+
def _debug_show_horotriangles(self, cusp : int =0):
|
387
|
+
from sage.plot.line import line
|
388
|
+
from sage.functions.other import real, imag
|
389
|
+
|
390
|
+
self.add_vertex_positions_to_horotriangles()
|
391
|
+
|
392
|
+
return sum(
|
393
|
+
[ line( [ (real(z0), imag(z0)),
|
394
|
+
(real(z1), imag(z1)) ] )
|
395
|
+
for tet in self.mcomplex.Tetrahedra
|
396
|
+
for V, h in tet.horotriangles.items()
|
397
|
+
for z0 in h.vertex_positions.values()
|
398
|
+
for z1 in h.vertex_positions.values()
|
399
|
+
if tet.Class[V].Index == cusp ])
|
400
|
+
|
401
|
+
def _debug_show_lifted_horotriangles(self, cusp : int =0):
|
402
|
+
from sage.plot.line import line
|
403
|
+
from sage.functions.other import real, imag
|
404
|
+
|
405
|
+
self.add_vertex_positions_to_horotriangles()
|
406
|
+
|
407
|
+
return sum(
|
408
|
+
[ line( [ (real(z0), imag(z0)),
|
409
|
+
(real(z1), imag(z1)) ] )
|
410
|
+
for tet in self.mcomplex.Tetrahedra
|
411
|
+
for V, h in tet.horotriangles.items()
|
412
|
+
for z0 in h.lifted_vertex_positions.values()
|
413
|
+
for z1 in h.lifted_vertex_positions.values()
|
414
|
+
if tet.Class[V].Index == cusp ])
|
415
|
+
|
416
|
+
def move_fixed_point_to_zero(self):
|
417
|
+
"""
|
418
|
+
Determines the fixed point of the holonomies for all
|
419
|
+
incomplete cusps. Then moves the vertex positions of the
|
420
|
+
corresponding cusp triangles so that the fixed point is at the
|
421
|
+
origin.
|
422
|
+
|
423
|
+
It also adds the boolean v.is_complete to all vertices of the
|
424
|
+
triangulation to mark whether the corresponding cusp is
|
425
|
+
complete or not.
|
426
|
+
"""
|
427
|
+
|
428
|
+
# For each cusp
|
429
|
+
for cusp in self.mcomplex.Vertices:
|
430
|
+
if cusp.is_complete:
|
431
|
+
continue
|
432
|
+
# For an incomplete cusp, compute fixed point
|
433
|
+
fixed_pt = self._compute_cusp_fixed_point(cusp)
|
434
|
+
for corner in cusp.Corners:
|
435
|
+
tet, vert = corner.Tetrahedron, corner.Subsimplex
|
436
|
+
trig = tet.horotriangles[vert]
|
437
|
+
# Move all vertex positions so that fixed point
|
438
|
+
# is at origin
|
439
|
+
trig.vertex_positions = {
|
440
|
+
edge : position - fixed_pt
|
441
|
+
for edge, position in trig.vertex_positions.items() }
|
442
|
+
|
443
|
+
def _compute_cusp_fixed_point(self, cusp : t3m.Vertex):
|
444
|
+
"""
|
445
|
+
Compute fixed point for an incomplete cusp.
|
446
|
+
"""
|
447
|
+
|
448
|
+
# Given a horotriangle trig0 with a vertex and edge, let
|
449
|
+
# l0 be the complex position of the vertex and p0 the complex
|
450
|
+
# edge length.
|
451
|
+
# Let trig1 be the horotriangle glued to trig0 along the edge
|
452
|
+
# and the l1 and p1 be the corresponding position and edge length
|
453
|
+
# (traversed the opposite direction) in the other horotriangle.
|
454
|
+
#
|
455
|
+
# Then the similarity is described the complex number z = -l1 / l0
|
456
|
+
# which is one or the holonomy of meridian or longitude (depending
|
457
|
+
# on whether the common edge is inside or on the boundary of a
|
458
|
+
# fundamental domain implicitly chosen when developing the cusp).
|
459
|
+
#
|
460
|
+
# Furthermore, we can compute the fixed point p of the similarity
|
461
|
+
# using p1 - p = z * (p0 - p).
|
462
|
+
|
463
|
+
# Compute z, p0, p1 for each horotriangle, vertex and edge and pick
|
464
|
+
# the one where z is furthest away from one.
|
465
|
+
z, p0, p1 = max(self._compute_cusp_fixed_point_data(cusp),
|
466
|
+
key=lambda d: lower(abs(1 - d[0])))
|
467
|
+
|
468
|
+
# Compute fixed point
|
469
|
+
return (p1 - z * p0) / (1 - z)
|
470
|
+
|
471
|
+
def _compute_cusp_fixed_point_data(self, cusp : t3m.Vertex):
|
472
|
+
"""
|
473
|
+
Compute abs(z-1), z, p0, p1 for each horotriangle, vertex and edge
|
474
|
+
as described in _compute_cusp_fixed_point.
|
475
|
+
"""
|
476
|
+
|
477
|
+
# For each horotriangle
|
478
|
+
for corner in cusp.Corners:
|
479
|
+
tet0, vert0 = corner.Tetrahedron, corner.Subsimplex
|
480
|
+
vertex_link = _face_edge_face_triples_for_vertex_link[vert0]
|
481
|
+
|
482
|
+
# A flag of a horotriangle corresponds to a face and edge
|
483
|
+
# of the tetrahedron.
|
484
|
+
for face0, edge0, other_face in vertex_link:
|
485
|
+
# How that horotriangle is glued to the neighboring one
|
486
|
+
tet1, face1, vert1 = CuspCrossSectionBase._glued_to(
|
487
|
+
tet0, face0, vert0)
|
488
|
+
edge1 = tet0.Gluing[face0].image(edge0)
|
489
|
+
|
490
|
+
# Get horotriangle and the complex vertex position and
|
491
|
+
# edge length
|
492
|
+
trig0 = tet0.horotriangles[vert0]
|
493
|
+
l0 = trig0.lengths[face0]
|
494
|
+
p0 = trig0.vertex_positions[edge0]
|
495
|
+
|
496
|
+
# And for neighbor
|
497
|
+
trig1 = tet1.horotriangles[vert1]
|
498
|
+
l1 = trig1.lengths[face1]
|
499
|
+
p1 = trig1.vertex_positions[edge1]
|
500
|
+
|
501
|
+
# Parameter for similarity
|
502
|
+
z = - l1 / l0
|
503
|
+
yield (z, p0, p1)
|
504
|
+
|
505
|
+
def lift_vertex_positions_of_horotriangles(self):
|
506
|
+
"""
|
507
|
+
After developing an incomplete cusp with
|
508
|
+
add_vertex_positions_to_horotriangles, this function moves the
|
509
|
+
vertex positions first to zero the fixed point (see
|
510
|
+
move_ffixed_point_to_zero) and computes logarithms for all the
|
511
|
+
vertex positions of the horotriangles in the Euclidean plane
|
512
|
+
in a consistent manner. These logarithms are written to a
|
513
|
+
dictionary lifted_vertex_positions on the HoroTriangle's.
|
514
|
+
|
515
|
+
For an incomplete cusp, the respective value in lifted_vertex_positions
|
516
|
+
will be None.
|
517
|
+
|
518
|
+
The three logarithms of the vertex positions of a triangle are only
|
519
|
+
defined up to adding mu Z + lambda Z where mu and lambda are the
|
520
|
+
logarithmic holonomies of the meridian and longitude.
|
521
|
+
"""
|
522
|
+
|
523
|
+
self.move_fixed_point_to_zero()
|
524
|
+
|
525
|
+
for cusp in self.mcomplex.Vertices:
|
526
|
+
self._lift_one_cusp_vertex_positions(cusp)
|
527
|
+
|
528
|
+
def _lift_one_cusp_vertex_positions(self, cusp : t3m.Vertex):
|
529
|
+
# Pick first triangle to develop
|
530
|
+
corner0 = cusp.Corners[0]
|
531
|
+
tet0, vert0 = corner0.Tetrahedron, corner0.Subsimplex
|
532
|
+
trig0 = tet0.horotriangles[vert0]
|
533
|
+
edge0 = _pick_an_edge_for_vertex[vert0]
|
534
|
+
|
535
|
+
if cusp.is_complete:
|
536
|
+
# If cusp is complete, we store None for the logarithms
|
537
|
+
for corner in cusp.Corners:
|
538
|
+
tet0, vert0 = corner.Tetrahedron, corner.Subsimplex
|
539
|
+
tet0.horotriangles[vert0].lifted_vertex_positions = {
|
540
|
+
vert0 | vert1 : None
|
541
|
+
for vert1 in t3m.ZeroSubsimplices
|
542
|
+
if vert0 != vert1 }
|
543
|
+
return
|
544
|
+
|
545
|
+
# Lift first triangle, picking main branch of logarithm for
|
546
|
+
# the first vertex
|
547
|
+
trig0.lift_vertex_positions(trig0.vertex_positions[edge0].log())
|
548
|
+
|
549
|
+
# Procedure similar to _add_one_cusp_cross_section
|
550
|
+
active = [(tet0, vert0)]
|
551
|
+
|
552
|
+
# Pairs (tet index, vertex) indicating what has already been
|
553
|
+
# visited
|
554
|
+
visited = set()
|
555
|
+
|
556
|
+
while active:
|
557
|
+
tet0, vert0 = active.pop()
|
558
|
+
for face0 in simplex.FacesAroundVertexCounterclockwise[vert0]:
|
559
|
+
tet1, face1, vert1 = CuspCrossSectionBase._glued_to(
|
560
|
+
tet0, face0, vert0)
|
561
|
+
if not (tet1.Index, vert1) in visited:
|
562
|
+
edge0 = _pick_an_edge_for_vertex_and_face[vert0, face0]
|
563
|
+
|
564
|
+
# Lift triangle using lifted vertex position of
|
565
|
+
# neighboring triangle as guide (when determining what
|
566
|
+
# branch of logarithm to take).
|
567
|
+
tet1.horotriangles[vert1].lift_vertex_positions(
|
568
|
+
tet0.horotriangles[vert0].lifted_vertex_positions[edge0])
|
569
|
+
|
570
|
+
active.append( (tet1, vert1) )
|
571
|
+
visited.add( (tet1.Index, vert1) )
|
572
|
+
|
573
|
+
def move_lifted_vertex_positions_to_zero_first(self):
|
574
|
+
"""
|
575
|
+
Shift the lifted vertex positions such that the one associated
|
576
|
+
to the first vertex when developing the incomplete cusp is
|
577
|
+
zero. This makes the values we obtain more stable when
|
578
|
+
changing the Dehn-surgery parameters.
|
579
|
+
"""
|
580
|
+
|
581
|
+
for cusp in self.mcomplex.Vertices:
|
582
|
+
if not cusp.is_complete:
|
583
|
+
ComplexCuspCrossSection._move_lifted_vertex_positions_cusp(cusp)
|
584
|
+
|
585
|
+
@staticmethod
|
586
|
+
def _move_lifted_vertex_positions_cusp(cusp : t3m.Vertex):
|
587
|
+
corner0 = cusp.Corners[0]
|
588
|
+
tet0, vert0 = corner0.Tetrahedron, corner0.Subsimplex
|
589
|
+
trig0 = tet0.horotriangles[vert0]
|
590
|
+
edge0 = _pick_an_edge_for_vertex[vert0]
|
591
|
+
|
592
|
+
log0 = trig0.lifted_vertex_positions[edge0]
|
593
|
+
|
594
|
+
for corner in cusp.Corners:
|
595
|
+
tet, vert = corner.Tetrahedron, corner.Subsimplex
|
596
|
+
trig = tet.horotriangles[vert]
|
597
|
+
|
598
|
+
trig.lifted_vertex_positions = {
|
599
|
+
edge: position - log0
|
600
|
+
for edge, position in trig.lifted_vertex_positions.items()
|
601
|
+
}
|
602
|
+
|
603
|
+
def scale_triangles_to_avoid_standard_tubes(self):
|
604
|
+
r"""
|
605
|
+
Scales each horo triangle so that it is guaranteed to be outside of
|
606
|
+
a standard tube about the incompleteness locus from the outside (up
|
607
|
+
to rounding errors, it will touch the tube from the outside). Note
|
608
|
+
that the scale factor is not uniform across the triangles belonging
|
609
|
+
to the same (incomplete) cusp.
|
610
|
+
|
611
|
+
Thus, if we truncated each tetrahedron along the triangle, the
|
612
|
+
tetrahedra would not intersect the standard tube.
|
613
|
+
|
614
|
+
|
615
|
+
\ /
|
616
|
+
\ ---- triangle after calling this method and
|
617
|
+
\ / applying inverse_scale_to_be_inside_tube
|
618
|
+
\ /
|
619
|
+
\ ---- triangle after calling this method
|
620
|
+
\ /
|
621
|
+
\ /
|
622
|
+
45degrees \/
|
623
|
+
----------------------------------
|
624
|
+
|
625
|
+
The resulting neighborhood about the core curve in the filled manifold
|
626
|
+
looks like a triangular version of the Giant's Causeway in Northern
|
627
|
+
Ireland.
|
628
|
+
|
629
|
+
Also stores the inverse of the Euclidean length scale factor
|
630
|
+
in inverse_scale_to_be_inside_tube to make the horo triangle be inside
|
631
|
+
the standard tube (up to rounding error, touch the standard tube from
|
632
|
+
the inside).
|
633
|
+
|
634
|
+
Here, a standard tube is given by a Euclidean cone from zero to
|
635
|
+
infinity in the upper halfspace model with cone angle pi/4.
|
636
|
+
Its hyperbolic radius is given by
|
637
|
+
arcinh(1) = log(1 + sqrt(2)) = 0.881373... .
|
638
|
+
"""
|
639
|
+
|
640
|
+
for cusp in self.mcomplex.Vertices:
|
641
|
+
self._scale_triangles_to_avoid_standard_tube(cusp)
|
642
|
+
|
643
|
+
def _scale_triangles_to_avoid_standard_tube(self, cusp : t3m.Vertex):
|
644
|
+
for corner in cusp.Corners:
|
645
|
+
tet, vert = corner.Tetrahedron, corner.Subsimplex
|
646
|
+
trig = tet.horotriangles[vert]
|
647
|
+
|
648
|
+
if cusp.is_complete:
|
649
|
+
z = tet.ShapeParameters[simplex.E01]
|
650
|
+
RF = z.real().parent()
|
651
|
+
trig.inverse_scale_to_be_inside_tube = RF(1)
|
652
|
+
continue
|
653
|
+
|
654
|
+
vertex_positions = [
|
655
|
+
trig.vertex_positions[edge]
|
656
|
+
for face0, edge, face1
|
657
|
+
in _face_edge_face_triples_for_vertex_link[vert] ]
|
658
|
+
|
659
|
+
min_height = correct_min(
|
660
|
+
[ _lower_bound_distance_origin_line_segment(
|
661
|
+
vertex_positions[0], vertex_positions[1]),
|
662
|
+
_lower_bound_distance_origin_line_segment(
|
663
|
+
vertex_positions[1], vertex_positions[2]),
|
664
|
+
_lower_bound_distance_origin_line_segment(
|
665
|
+
vertex_positions[2], vertex_positions[0]) ])
|
666
|
+
max_height = correct_max( [ abs(p) for p in vertex_positions ] )
|
667
|
+
|
668
|
+
trig.rescale(1 / min_height)
|
669
|
+
|
670
|
+
trig.inverse_scale_to_be_inside_tube = max_height / min_height
|
671
|
+
|
672
|
+
def _lower_bound_distance_origin_line_segment(a, b):
|
673
|
+
"""
|
674
|
+
Given two complex numbers a and b, compute a lower bound for
|
675
|
+
the (Euclidean) distance of the line segment from a to b to 0.
|
676
|
+
"""
|
677
|
+
|
678
|
+
# The similarity
|
679
|
+
# f : z |-> (a - z) / (a - b)
|
680
|
+
# takes a to 0 and b to 1.
|
681
|
+
|
682
|
+
d = a - b
|
683
|
+
|
684
|
+
# The image of f(0).
|
685
|
+
z0 = a / d
|
686
|
+
|
687
|
+
if z0.real() > 1:
|
688
|
+
return abs(b)
|
689
|
+
|
690
|
+
if z0.real() < 0:
|
691
|
+
return abs(a)
|
692
|
+
|
693
|
+
# This is only the distance if we can show that z0.real() >= 0
|
694
|
+
# and z0.real() <= 1.
|
695
|
+
#
|
696
|
+
# But it is still a lower bound for the distance.
|
697
|
+
return abs(z0.imag()) * abs(d)
|