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
snappy/testing.py
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
from .numeric_output_checker import NumericOutputChecker
|
2
|
+
from .sage_helper import _within_sage
|
3
|
+
|
4
|
+
import doctest
|
5
|
+
import getopt
|
6
|
+
import re
|
7
|
+
import sys
|
8
|
+
import types
|
9
|
+
|
10
|
+
# Used for doctesting
|
11
|
+
_gui_status = {}
|
12
|
+
|
13
|
+
try:
|
14
|
+
from snappy.gui import Tk_
|
15
|
+
_gui_status['tk'] = True
|
16
|
+
except ImportError:
|
17
|
+
_gui_status['tk'] = False
|
18
|
+
if _gui_status['tk']:
|
19
|
+
try:
|
20
|
+
import snappy.CyOpenGL
|
21
|
+
_gui_status['cyopengl'] = True
|
22
|
+
except:
|
23
|
+
_gui_status['cyopengl'] = False
|
24
|
+
else:
|
25
|
+
_gui_status['cyopengl'] = False
|
26
|
+
_gui_status['fake_root'] = False
|
27
|
+
|
28
|
+
def cyopengl_works():
|
29
|
+
if not _gui_status['cyopengl']:
|
30
|
+
return False
|
31
|
+
# if we are running the tests from the snappy app the default root will
|
32
|
+
# already exist -- it will be the tkterminal window. Otherwise, we open
|
33
|
+
# a root window here to serve as the master of all of the GUI windows
|
34
|
+
# which get created during testing.
|
35
|
+
if _gui_status['tk'] and not Tk_._default_root:
|
36
|
+
try:
|
37
|
+
root = Tk_.Tk()
|
38
|
+
if sys.platform not in ('linux', 'linux2'):
|
39
|
+
root.withdraw()
|
40
|
+
except:
|
41
|
+
# tkinter loads OK but is not able to get a display.
|
42
|
+
_gui_status['tk'] = _gui_status['cyopengl'] = False
|
43
|
+
return _gui_status['cyopengl']
|
44
|
+
|
45
|
+
|
46
|
+
def tk_root():
|
47
|
+
if _gui_status['tk']:
|
48
|
+
return Tk_._default_root
|
49
|
+
else:
|
50
|
+
return None
|
51
|
+
|
52
|
+
def root_is_fake():
|
53
|
+
return _gui_status['fake_root']
|
54
|
+
|
55
|
+
class DocTestParser(doctest.DocTestParser):
|
56
|
+
use_cyopengl = False
|
57
|
+
use_cymodernopengl = True
|
58
|
+
use_sage = _within_sage
|
59
|
+
|
60
|
+
def parse(self, string, name='<string>'):
|
61
|
+
string = re.subn(
|
62
|
+
r'#doctest: \+CYOPENGL',
|
63
|
+
'' if DocTestParser.use_cyopengl else '#doctest: +SKIP',
|
64
|
+
string)[0]
|
65
|
+
|
66
|
+
string = re.subn(
|
67
|
+
r'#doctest: \+CYMODERNOPENGL',
|
68
|
+
(''
|
69
|
+
if (DocTestParser.use_cyopengl and
|
70
|
+
DocTestParser.use_cymodernopengl)
|
71
|
+
else '#doctest: +SKIP'),
|
72
|
+
string)[0]
|
73
|
+
|
74
|
+
if DocTestParser.use_sage:
|
75
|
+
string = re.subn(r'(\n\s*)sage:|(\A\s*)sage:',
|
76
|
+
r'\g<1>>>>',
|
77
|
+
string)[0]
|
78
|
+
return doctest.DocTestParser.parse(self, string, name)
|
79
|
+
|
80
|
+
if _within_sage:
|
81
|
+
try:
|
82
|
+
from sage.all import PSL, BraidGroup
|
83
|
+
except ImportError:
|
84
|
+
import sage.groups.perm_gps.permgroup_element
|
85
|
+
from sage.groups.perm_gps.permgroup_named import PSL
|
86
|
+
from sage.groups.braid import BraidGroup
|
87
|
+
globs = {'PSL': PSL, 'BraidGroup': BraidGroup}
|
88
|
+
else:
|
89
|
+
globs = {}
|
90
|
+
|
91
|
+
def print_results(module, results):
|
92
|
+
root = tk_root()
|
93
|
+
# Platform specific hacks to make running the tests work.
|
94
|
+
if root and not root_is_fake():
|
95
|
+
if sys.platform in ('linux', 'linux2'):
|
96
|
+
root.deiconify()
|
97
|
+
root.update_idletasks()
|
98
|
+
else:
|
99
|
+
root.update()
|
100
|
+
print(module.__name__ + ':')
|
101
|
+
print(' %s failures out of %s tests.' % (results.failed,
|
102
|
+
results.attempted))
|
103
|
+
|
104
|
+
def doctest_modules(modules, verbose=False, print_info=False, extraglobs={}):
|
105
|
+
finder = doctest.DocTestFinder(parser=DocTestParser())
|
106
|
+
full_extraglobals = globs.copy()
|
107
|
+
full_extraglobals.update(extraglobs)
|
108
|
+
failed, attempted = 0, 0
|
109
|
+
for module in modules:
|
110
|
+
if isinstance(module, types.ModuleType):
|
111
|
+
runner = doctest.DocTestRunner(checker=NumericOutputChecker(), verbose=verbose)
|
112
|
+
for test in finder.find(module, extraglobs=full_extraglobals):
|
113
|
+
runner.run(test)
|
114
|
+
result = runner.summarize()
|
115
|
+
else:
|
116
|
+
result = module(verbose=verbose, print_info=False)
|
117
|
+
failed += result.failed
|
118
|
+
attempted += result.attempted
|
119
|
+
if print_info:
|
120
|
+
print_results(module, result)
|
121
|
+
|
122
|
+
if print_info:
|
123
|
+
print('\nAll doctests:\n %s failures out of %s tests.' % (failed, attempted))
|
124
|
+
return doctest.TestResults(failed, attempted)
|
125
|
+
|
126
|
+
def run_doctests_as_main(run_doctests):
|
127
|
+
optlist, args = getopt.getopt(sys.argv[1:], 'v', ['verbose'])
|
128
|
+
verbose = len(optlist) > 0
|
129
|
+
results = run_doctests(verbose=verbose, print_info=True)
|
130
|
+
sys.exit(results.failed)
|
131
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class CanonicalKeyDict:
|
2
|
+
"""
|
3
|
+
Applies a function to canonize key before looking it up
|
4
|
+
or setting it in the supplied dictionary.
|
5
|
+
|
6
|
+
Note that the function can return a set of multiple
|
7
|
+
canidadates for the canonical key. The look-ups in the
|
8
|
+
dictionary will work correctly, as long as the true canonical
|
9
|
+
key is among the candidates.
|
10
|
+
|
11
|
+
# Modulo 5, canonical representative is 0, 1, ... 4.
|
12
|
+
|
13
|
+
>>> d = CanonicalKeyDict({}, canonical_keys_function = lambda x : x)
|
14
|
+
>>> d.setdefault([1], []).append('A')
|
15
|
+
>>> d.setdefault([2, 7], []).append('B')
|
16
|
+
>>> d.setdefault([1,6], [])
|
17
|
+
['A']
|
18
|
+
>>> d.setdefault([1,6], []).append('C')
|
19
|
+
>>> d.setdefault([1,6], [])
|
20
|
+
['A', 'C']
|
21
|
+
>>> d.setdefault([1], [])
|
22
|
+
['A', 'C']
|
23
|
+
>>> d.setdefault([1, 11], [])
|
24
|
+
['A', 'C']
|
25
|
+
>>> d.setdefault([2], [])
|
26
|
+
['B']
|
27
|
+
"""
|
28
|
+
|
29
|
+
def __init__(self, dictionary, canonical_keys_function):
|
30
|
+
self._dictionary = dictionary
|
31
|
+
self._canonical_keys_function = canonical_keys_function
|
32
|
+
|
33
|
+
# Not implemented because it was not needed so far:
|
34
|
+
# get
|
35
|
+
# __getitem__
|
36
|
+
# __setitem__
|
37
|
+
|
38
|
+
# Note that __setitem__ requires updating all entries in
|
39
|
+
# self._dictionary.
|
40
|
+
# The easiest way to do this is to wrap the value into
|
41
|
+
# wrapped_value = [value], and assign to wrapped_value[0].
|
42
|
+
# This would also allow self.setdefault(key, None).
|
43
|
+
|
44
|
+
def setdefault(self, key, default):
|
45
|
+
if default is None:
|
46
|
+
raise Exception("Implementation reserved default = None for "
|
47
|
+
"internal purposes.")
|
48
|
+
|
49
|
+
computed_keys = self._canonical_keys_function(key)
|
50
|
+
|
51
|
+
for computed_key in computed_keys:
|
52
|
+
value = self._dictionary.get(computed_key)
|
53
|
+
if not value is None:
|
54
|
+
return value
|
55
|
+
|
56
|
+
for computed_key in computed_keys:
|
57
|
+
self._dictionary[computed_key] = default
|
58
|
+
|
59
|
+
return default
|
@@ -0,0 +1,79 @@
|
|
1
|
+
class DictBasedSet:
|
2
|
+
"""
|
3
|
+
This class can be constructed from a dictionary with keys in A.
|
4
|
+
|
5
|
+
The resulting object is a set of A.
|
6
|
+
|
7
|
+
>>> fruit_set = DictBasedSet(dict())
|
8
|
+
>>> fruit_set.add('Apple')
|
9
|
+
True
|
10
|
+
>>> fruit_set.add('Banana')
|
11
|
+
True
|
12
|
+
>>> fruit_set.add('Apple') # Already added earlier
|
13
|
+
False
|
14
|
+
|
15
|
+
"""
|
16
|
+
|
17
|
+
def __init__(self, dictionary):
|
18
|
+
self._dictionary = dictionary
|
19
|
+
|
20
|
+
def add(self, key) -> bool:
|
21
|
+
"""
|
22
|
+
Adds key to set of A.
|
23
|
+
|
24
|
+
Returns true if key was not yet in the set.
|
25
|
+
"""
|
26
|
+
visited = self._dictionary.setdefault(key, [False])
|
27
|
+
if visited[0]:
|
28
|
+
return False
|
29
|
+
visited[0] = True
|
30
|
+
return True
|
31
|
+
|
32
|
+
class DictBasedProductSet:
|
33
|
+
"""
|
34
|
+
This class can be constructed from a dictionary with keys in A.
|
35
|
+
|
36
|
+
The resulting object is a set of AxB.
|
37
|
+
|
38
|
+
Can be combined with RealHashDict or CanonicalKeyDict.
|
39
|
+
|
40
|
+
>>> fruit_number_set = DictBasedProductSet(dict())
|
41
|
+
>>> fruit_number_set.add('Apple', 1)
|
42
|
+
True
|
43
|
+
>>> fruit_number_set.add('Banana', 1)
|
44
|
+
True
|
45
|
+
>>> fruit_number_set.add('Apple', 2)
|
46
|
+
True
|
47
|
+
>>> fruit_number_set.add('Apple', 1) # Already added earlier
|
48
|
+
False
|
49
|
+
|
50
|
+
"""
|
51
|
+
|
52
|
+
def __init__(self, dictionary):
|
53
|
+
self._dictionary = dictionary
|
54
|
+
|
55
|
+
def add(self, key, element) -> bool:
|
56
|
+
"""
|
57
|
+
Adds (key, element) in AxB to set.
|
58
|
+
|
59
|
+
Returns true if (key, element) was not yet in the set.
|
60
|
+
"""
|
61
|
+
|
62
|
+
elements = self._get_elements_for_key(key)
|
63
|
+
if element in elements:
|
64
|
+
return False
|
65
|
+
else:
|
66
|
+
elements.add(element)
|
67
|
+
return True
|
68
|
+
|
69
|
+
def _get_elements_for_key(self, key):
|
70
|
+
"""
|
71
|
+
Could be used for potential future optimization:
|
72
|
+
When going to a neighboring tetrahedron paired through
|
73
|
+
a trivial face-pairing matrix (so it is a tetrahedron within
|
74
|
+
the same copy of the fundamental polyhedron), we can keep
|
75
|
+
a reference to the set returned by _get_elements_for_key
|
76
|
+
and just add the neighboring tetrahedron to this set rather
|
77
|
+
than doing the look-up from scratch.
|
78
|
+
"""
|
79
|
+
return self._dictionary.setdefault(key, set())
|
snappy/tiling/floor.py
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
from ..math_basics import is_RealIntervalFieldElement # type: ignore
|
2
|
+
from ..exceptions import InsufficientPrecisionError # type: ignore
|
3
|
+
|
4
|
+
from typing import Sequence
|
5
|
+
|
6
|
+
def floor_as_integers(x) -> Sequence[int]:
|
7
|
+
"""
|
8
|
+
Computes floor of a number or interval, returning a list of integers
|
9
|
+
if evaluating floor is ambiguous.
|
10
|
+
|
11
|
+
sage: from sage.all import RIF
|
12
|
+
sage: floor_as_integers(RIF(1.8, 1.9))
|
13
|
+
[1]
|
14
|
+
sage: floor_as_integers(RIF(1.9, 2.1))
|
15
|
+
[1, 2]
|
16
|
+
|
17
|
+
>>> from snappy.number import *
|
18
|
+
>>> def to_number(py_float):
|
19
|
+
... return number_to_native_number(SnapPyNumbers(100)(py_float))
|
20
|
+
>>> floor_as_integers(to_number(1.4))
|
21
|
+
[1]
|
22
|
+
>>> floor_as_integers(to_number(2.01))
|
23
|
+
[1, 2]
|
24
|
+
>>> floor_as_integers(to_number(1.99))
|
25
|
+
[1, 2]
|
26
|
+
|
27
|
+
"""
|
28
|
+
|
29
|
+
if is_RealIntervalFieldElement(x):
|
30
|
+
f = x.floor()
|
31
|
+
l = f.lower().round()
|
32
|
+
u = f.upper().round() + 1
|
33
|
+
|
34
|
+
n = u - l
|
35
|
+
if n > 5:
|
36
|
+
raise InsufficientPrecisionError(
|
37
|
+
"Too many integers (%d) in given interval to compute floor. "
|
38
|
+
"Increasing precision should fix it." % n)
|
39
|
+
|
40
|
+
return list(range(l, u))
|
41
|
+
else:
|
42
|
+
f = x.floor()
|
43
|
+
int_f = int(f)
|
44
|
+
d = x - f
|
45
|
+
if d < 0.125:
|
46
|
+
return [ int_f - 1, int_f ]
|
47
|
+
if d > 0.875:
|
48
|
+
return [ int_f, int_f + 1 ]
|
49
|
+
return [ int_f ]
|
@@ -0,0 +1,54 @@
|
|
1
|
+
from .real_hash_dict import RealHashDict
|
2
|
+
from ..hyperboloid import r13_dot
|
3
|
+
from ..exceptions import InsufficientPrecisionError # type: ignore
|
4
|
+
|
5
|
+
def get_hyperboloid_dict(max_neg_prod_equal, min_neg_prod_distinct,
|
6
|
+
verified):
|
7
|
+
RF = max_neg_prod_equal.parent()
|
8
|
+
return RealHashDict(
|
9
|
+
_equality_predicate(max_neg_prod_equal, min_neg_prod_distinct),
|
10
|
+
_hash_function(RF),
|
11
|
+
_compute_epsilon_inverse(RF),
|
12
|
+
verified)
|
13
|
+
|
14
|
+
def _equality_predicate(max_neg_prod_equal, min_neg_prod_distinct):
|
15
|
+
def result(point_0, point_1):
|
16
|
+
neg_inner_product = -r13_dot(point_0, point_1)
|
17
|
+
if neg_inner_product < max_neg_prod_equal:
|
18
|
+
return True
|
19
|
+
if neg_inner_product > min_neg_prod_distinct:
|
20
|
+
return False
|
21
|
+
|
22
|
+
raise InsufficientPrecisionError(
|
23
|
+
"Could neither verify that the two given tiles are "
|
24
|
+
"the same nor that they are distinct.\n"
|
25
|
+
"Neg inner product is: %r.\n"
|
26
|
+
"Max to be same tile: %r.\n"
|
27
|
+
"Min to be distinct tiles: %r." % (
|
28
|
+
neg_inner_product, max_neg_prod_equal, min_neg_prod_distinct))
|
29
|
+
|
30
|
+
return result
|
31
|
+
|
32
|
+
def _hash_function(RF):
|
33
|
+
weights = [ RF(1.2003), RF(0.94553), RF(1.431112), RF(1.2342) ]
|
34
|
+
|
35
|
+
def result(point):
|
36
|
+
return (point[0] * weights[0] +
|
37
|
+
point[1] * weights[1] +
|
38
|
+
point[2] * weights[2] +
|
39
|
+
point[3] * weights[3])
|
40
|
+
|
41
|
+
return result
|
42
|
+
|
43
|
+
_default_epsilon_inverse = 128
|
44
|
+
|
45
|
+
def _compute_epsilon_inverse(RF):
|
46
|
+
result = _default_epsilon_inverse
|
47
|
+
|
48
|
+
p = RF.precision()
|
49
|
+
if p > 53:
|
50
|
+
result *= 2 ** ((p - 53) // 3)
|
51
|
+
|
52
|
+
return result
|
53
|
+
|
54
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
from itertools import count
|
2
|
+
|
3
|
+
class IteratorCache:
|
4
|
+
def __init__(self, iterator):
|
5
|
+
"""
|
6
|
+
Takes an iterator and produces an iterable such that an
|
7
|
+
iterator created from the iterable produces the same iterated
|
8
|
+
values.
|
9
|
+
|
10
|
+
The iterates values, however, are lazily cached so that
|
11
|
+
iterating over another iterator again is faster.
|
12
|
+
|
13
|
+
(Silly) Example:
|
14
|
+
|
15
|
+
>>> squares = IterableCache(iter(i ** 2 for i in range(1000)))
|
16
|
+
>>> iterator0 = iter(squares)
|
17
|
+
>>> next(iterator0)
|
18
|
+
0
|
19
|
+
>>> next(iterator0)
|
20
|
+
1
|
21
|
+
>>> next(iterator0)
|
22
|
+
4
|
23
|
+
>>> iterator1 = iter(squares)
|
24
|
+
>>> next(iterator1) # Cached from previous run
|
25
|
+
0
|
26
|
+
>>> next(iterator1)
|
27
|
+
1
|
28
|
+
>>> next(iterator1)
|
29
|
+
4
|
30
|
+
>>> next(iterator1) # Not cached from previous run
|
31
|
+
9
|
32
|
+
|
33
|
+
"""
|
34
|
+
|
35
|
+
self._iterator = iterator
|
36
|
+
self._cache = []
|
37
|
+
|
38
|
+
def __iter__(self):
|
39
|
+
for i in count():
|
40
|
+
if i == len(self._cache):
|
41
|
+
try:
|
42
|
+
n = next(self._iterator)
|
43
|
+
except StopIteration:
|
44
|
+
break
|
45
|
+
self._cache.append(n)
|
46
|
+
yield self._cache[i]
|
47
|
+
|
48
|
+
def merge_iterators(iterators):
|
49
|
+
"""
|
50
|
+
Merges iterators into one iterable picking the smallest element
|
51
|
+
(using < operator) from the list of next elements for each iterator.
|
52
|
+
"""
|
53
|
+
|
54
|
+
elements = [ [ next(iter), i ]
|
55
|
+
for i, iter in enumerate(iterators) ]
|
56
|
+
|
57
|
+
while True:
|
58
|
+
element, i = min(elements)
|
59
|
+
yield element
|
60
|
+
|
61
|
+
elements[i][0] = next(iterators[i])
|
62
|
+
|
63
|
+
def merge_iterables(iterables):
|
64
|
+
"""
|
65
|
+
Merges iterables into one iterable picking the smallest element
|
66
|
+
(using < operator) from the list of next elements for each iterator.
|
67
|
+
|
68
|
+
Example:
|
69
|
+
|
70
|
+
>>> squares_and_cubes = iter(merge_iterables([
|
71
|
+
... (i ** 2 for i in range(10000)),
|
72
|
+
... (i ** 3 for i in range(10000)) ]))
|
73
|
+
>>> list(islice(squares_and_cubes, 12))
|
74
|
+
[0, 0, 1, 1, 4, 8, 9, 16, 25, 27, 36, 49]
|
75
|
+
|
76
|
+
"""
|
77
|
+
|
78
|
+
return merge_iterators([ iter(i) for i in iterables ])
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from ..snap.t3mlite import Tetrahedron # type: ignore
|
2
|
+
|
3
|
+
# @dataclass - not supported until python 3.7. We support 3.6.
|
4
|
+
|
5
|
+
class LiftedTetrahedron:
|
6
|
+
"""
|
7
|
+
Represents the lift of a tetrahedron in a manifold to the hyperboloid
|
8
|
+
model.
|
9
|
+
|
10
|
+
That is, if a tetrahedron (as part of the fundamental domain) was assigned
|
11
|
+
vertices by calling add_r13_geometry, then the vertices of a
|
12
|
+
LiftedTetrahedron l will be given by l.o13_matrices * tet.R13_vertices[v]
|
13
|
+
where v in snappy.snap.t3mlite.simplex.ZeroSubsimplices.
|
14
|
+
"""
|
15
|
+
|
16
|
+
def __init__(self,
|
17
|
+
tet : Tetrahedron,
|
18
|
+
# An O(1,3)-matrix - since this might be a SageMath class or a
|
19
|
+
# SimpleMatrix, just using Any as type annotation.
|
20
|
+
o13_matrix):
|
21
|
+
self.tet = tet
|
22
|
+
self.o13_matrix = o13_matrix
|
@@ -0,0 +1,54 @@
|
|
1
|
+
from .lifted_tetrahedron import LiftedTetrahedron
|
2
|
+
from .canonical_key_dict import CanonicalKeyDict
|
3
|
+
from .dict_based_set import DictBasedProductSet
|
4
|
+
from .hyperboloid_dict import get_hyperboloid_dict
|
5
|
+
|
6
|
+
from ..hyperboloid import o13_inverse
|
7
|
+
|
8
|
+
class LiftedTetrahedronSet:
|
9
|
+
"""
|
10
|
+
A set of lifted tetrahedra in H^3 or a quotient space of
|
11
|
+
H^3.
|
12
|
+
|
13
|
+
Which space will be used is determined by the dictionary
|
14
|
+
given when LiftedTetrahedronSet is constructed.
|
15
|
+
"""
|
16
|
+
|
17
|
+
def __init__(self, dictionary, base_point, act_on_base_point_by_inverse):
|
18
|
+
self._set = DictBasedProductSet(dictionary)
|
19
|
+
self._base_point = base_point
|
20
|
+
self._act_on_base_point_by_inverse = act_on_base_point_by_inverse
|
21
|
+
|
22
|
+
def add(self, lifted_tetrahedron : LiftedTetrahedron) -> bool:
|
23
|
+
if self._act_on_base_point_by_inverse:
|
24
|
+
m = o13_inverse(lifted_tetrahedron.o13_matrix)
|
25
|
+
else:
|
26
|
+
m = lifted_tetrahedron.o13_matrix
|
27
|
+
|
28
|
+
return self._set.add(
|
29
|
+
m * self._base_point,
|
30
|
+
lifted_tetrahedron.tet.Index)
|
31
|
+
|
32
|
+
def get_lifted_tetrahedron_set(base_point,
|
33
|
+
canonical_keys_function,
|
34
|
+
act_on_base_point_by_inverse,
|
35
|
+
max_neg_prod_equal, min_neg_prod_distinct,
|
36
|
+
verified
|
37
|
+
) -> LiftedTetrahedronSet:
|
38
|
+
"""
|
39
|
+
Returns a set to store lifted tetrahedra in H^3 or a quotient
|
40
|
+
space of H^3.
|
41
|
+
|
42
|
+
The type of geometric object determined which space will be used.
|
43
|
+
|
44
|
+
"""
|
45
|
+
|
46
|
+
d = get_hyperboloid_dict(max_neg_prod_equal, min_neg_prod_distinct,
|
47
|
+
verified)
|
48
|
+
|
49
|
+
if canonical_keys_function:
|
50
|
+
d = CanonicalKeyDict(d, canonical_keys_function)
|
51
|
+
|
52
|
+
return LiftedTetrahedronSet(d, base_point, act_on_base_point_by_inverse)
|
53
|
+
|
54
|
+
|
@@ -0,0 +1,164 @@
|
|
1
|
+
from ..verify.interval_tree import IntervalTree
|
2
|
+
from .floor import floor_as_integers
|
3
|
+
|
4
|
+
# For experimenting how the performance of the IntervalTree compares
|
5
|
+
# to using a python dict.
|
6
|
+
#
|
7
|
+
# Sadly, the IntervalTree is implemented in slow python and not fast
|
8
|
+
# C(++). This is because we do not have access to the mpfi number since
|
9
|
+
# we cannot include .pyd files from SageMath :(
|
10
|
+
#
|
11
|
+
_use_interval_tree = True
|
12
|
+
|
13
|
+
class RealHashDict:
|
14
|
+
"""
|
15
|
+
A dictionary (following python dict API) where we provide for the keys:
|
16
|
+
- a predicate that decides whether two keys are the same
|
17
|
+
- a hash function returning an approximation of a real number
|
18
|
+
|
19
|
+
The use case is, for example, to use as keys points in a metric space
|
20
|
+
that are given by approximate numbers. Two close by approximations are
|
21
|
+
probably the same point.
|
22
|
+
|
23
|
+
The requirements of the hash function has the following requirements:
|
24
|
+
- If it is an interval, it has to contain the true hash value, that is
|
25
|
+
the true value of the hash function evaluated for the true value of
|
26
|
+
the key.
|
27
|
+
- If it is an interval and _use_interval_tree is False, the length of
|
28
|
+
the interval cannot be much larger than 1/epsilon_inverse.
|
29
|
+
- If it is a floating point number, the approximation cannot differ
|
30
|
+
from the true value by more than 1/epsilon_inverse/16.
|
31
|
+
|
32
|
+
Example Z as a discrete subset of R::
|
33
|
+
|
34
|
+
>>> from snappy.number import *
|
35
|
+
>>> def to_number(py_float):
|
36
|
+
... return number_to_native_number(SnapPyNumbers(100)(py_float))
|
37
|
+
|
38
|
+
>>> d = RealHashDict(
|
39
|
+
... # If two floating approximations of integers are close by,
|
40
|
+
... # they must be the same
|
41
|
+
... equality_predicate = lambda x, y: abs(x - y) < to_number(0.5),
|
42
|
+
... # For space with more than 1-dimension, use some function
|
43
|
+
... # involving the other coordinates
|
44
|
+
... hash_function = lambda x : x,
|
45
|
+
... epsilon_inverse = 1024,
|
46
|
+
... verified = False)
|
47
|
+
|
48
|
+
# Keys near 1 should be treated as the same.
|
49
|
+
>>> d[to_number(1.0)] = 'A'
|
50
|
+
>>> d[to_number(1.0000001)] = 'B'
|
51
|
+
>>> d.get(to_number(0.9999999))
|
52
|
+
'B'
|
53
|
+
|
54
|
+
>>> d.setdefault(to_number(10 + 0.1 / 1024), []).append('A')
|
55
|
+
>>> d.get(to_number(10.0))
|
56
|
+
['A']
|
57
|
+
>>> d.setdefault(to_number(10 - 0.1 / 1024), []).append('B')
|
58
|
+
>>> d.get(to_number(10.0000001))
|
59
|
+
['A', 'B']
|
60
|
+
|
61
|
+
sage: from sage.all import RIF
|
62
|
+
sage: def equality_predicate(x, y):
|
63
|
+
... d = abs(x - y)
|
64
|
+
... if d < RIF(0.1):
|
65
|
+
... return True
|
66
|
+
... if d > 0:
|
67
|
+
... return False
|
68
|
+
... raise Exception("Could not determine whether points are the "
|
69
|
+
... "same or not")
|
70
|
+
sage: d = RealHashDict(
|
71
|
+
... equality_predicate = equality_predicate,
|
72
|
+
... hash_function = lambda x : x,
|
73
|
+
... epsilon_inverse = 1024,
|
74
|
+
... verified = True)
|
75
|
+
|
76
|
+
# Keys near 1 should be treated as the same.
|
77
|
+
sage: d[RIF(0.9999999, 1.000001)] = 'A'
|
78
|
+
sage: d[RIF(0.9999998, 1.0000001)] = 'B'
|
79
|
+
sage: d.get(RIF(0.99999997, 1.0000002))
|
80
|
+
'B'
|
81
|
+
|
82
|
+
sage: d.setdefault(RIF(9.9999999, 10.00001), []).append('A')
|
83
|
+
sage: d.get(RIF(10.0))
|
84
|
+
['A']
|
85
|
+
sage: d.setdefault(RIF(9.9999993, 10.00002), []).append('B')
|
86
|
+
sage: d.get(RIF(9.99999999, 10.0000001))
|
87
|
+
['A', 'B']
|
88
|
+
|
89
|
+
sage: from snappy.tiling import real_hash_dict
|
90
|
+
sage: original_use_interval_tree = real_hash_dict._use_interval_tree
|
91
|
+
sage: real_hash_dict._use_interval_tree = True
|
92
|
+
sage: d = RealHashDict(
|
93
|
+
... equality_predicate = equality_predicate,
|
94
|
+
... hash_function = lambda x : x,
|
95
|
+
... epsilon_inverse = 1024,
|
96
|
+
... verified = True)
|
97
|
+
sage: d[RIF(1.0)] = 'A'
|
98
|
+
sage: d[RIF(0.7, 1.3)] = 'B'
|
99
|
+
Traceback (most recent call last):
|
100
|
+
...
|
101
|
+
Exception: Could not determine whether points are the same or not
|
102
|
+
sage: real_hash_dict._use_interval_tree = original_use_interval_tree
|
103
|
+
|
104
|
+
|
105
|
+
"""
|
106
|
+
|
107
|
+
def __init__(self, equality_predicate, hash_function, epsilon_inverse, verified):
|
108
|
+
|
109
|
+
self._equality_predicate = equality_predicate
|
110
|
+
self._hash_function = hash_function
|
111
|
+
|
112
|
+
if verified and _use_interval_tree:
|
113
|
+
self._impl = IntervalTree()
|
114
|
+
else:
|
115
|
+
self._impl = _Dict(epsilon_inverse)
|
116
|
+
|
117
|
+
def get(self, key, default = None):
|
118
|
+
h = self._hash_function(key)
|
119
|
+
|
120
|
+
for other_key, value in self._impl.find(h):
|
121
|
+
if self._equality_predicate(key, other_key):
|
122
|
+
return value
|
123
|
+
|
124
|
+
return default
|
125
|
+
|
126
|
+
# Not implemented because it was not needed yet:
|
127
|
+
# __getitem__
|
128
|
+
|
129
|
+
def __setitem__(self, key, value):
|
130
|
+
h = self._hash_function(key)
|
131
|
+
|
132
|
+
for pair in self._impl.find(h):
|
133
|
+
if self._equality_predicate(key, pair[0]):
|
134
|
+
pair[1] = value
|
135
|
+
return
|
136
|
+
|
137
|
+
self._impl.insert(h, [key, value])
|
138
|
+
|
139
|
+
def setdefault(self, key, default):
|
140
|
+
h = self._hash_function(key)
|
141
|
+
|
142
|
+
for other_key, value in self._impl.find(h):
|
143
|
+
if self._equality_predicate(key, other_key):
|
144
|
+
return value
|
145
|
+
|
146
|
+
self._impl.insert(h, [key, default])
|
147
|
+
|
148
|
+
return default
|
149
|
+
|
150
|
+
class _Dict:
|
151
|
+
def __init__(self, epsilon_inverse):
|
152
|
+
self._epsilon_inverse = epsilon_inverse
|
153
|
+
self._dict = {}
|
154
|
+
|
155
|
+
def insert(self, key, value):
|
156
|
+
for computed_key in self._computed_keys(key):
|
157
|
+
self._dict.setdefault(computed_key, []).append(value)
|
158
|
+
|
159
|
+
def find(self, key):
|
160
|
+
for computed_key in self._computed_keys(key):
|
161
|
+
yield from self._dict.get(computed_key, [])
|
162
|
+
|
163
|
+
def _computed_keys(self, key):
|
164
|
+
return floor_as_integers(key * self._epsilon_inverse)
|