snappy 3.3__cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.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.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/SnapPy.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/SnapPy.ico +0 -0
- snappy/SnapPy.png +0 -0
- snappy/SnapPyHP.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/__init__.py +534 -0
- snappy/app.py +604 -0
- snappy/app_menus.py +372 -0
- snappy/browser.py +998 -0
- snappy/cache.py +25 -0
- snappy/canonical.py +249 -0
- snappy/cusps/__init__.py +280 -0
- snappy/cusps/cusp_area_matrix.py +98 -0
- snappy/cusps/cusp_areas_from_matrix.py +96 -0
- snappy/cusps/maximal_cusp_area_matrix.py +136 -0
- snappy/cusps/short_slopes_for_cusp.py +217 -0
- snappy/cusps/test.py +22 -0
- snappy/cusps/trig_cusp_area_matrix.py +63 -0
- snappy/database.py +454 -0
- snappy/db_utilities.py +79 -0
- snappy/decorated_isosig.py +717 -0
- snappy/dev/__init__.py +0 -0
- snappy/dev/extended_ptolemy/__init__.py +8 -0
- snappy/dev/extended_ptolemy/closed.py +106 -0
- snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
- snappy/dev/extended_ptolemy/direct.py +42 -0
- snappy/dev/extended_ptolemy/extended.py +406 -0
- snappy/dev/extended_ptolemy/giac_helper.py +43 -0
- snappy/dev/extended_ptolemy/giac_rur.py +129 -0
- snappy/dev/extended_ptolemy/gluing.py +46 -0
- snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
- snappy/dev/extended_ptolemy/printMatrices.py +70 -0
- snappy/dev/vericlosed/__init__.py +1 -0
- snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
- snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
- snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
- snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
- snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
- snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
- snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
- snappy/dev/vericlosed/orb/__init__.py +1 -0
- snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
- snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
- snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
- snappy/dev/vericlosed/test.py +54 -0
- snappy/dev/vericlosed/truncatedComplex.py +176 -0
- snappy/dev/vericlosed/verificationError.py +58 -0
- snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
- snappy/doc/_images/SnapPy-196.png +0 -0
- snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
- snappy/doc/_images/m125_paper_plane.jpg +0 -0
- snappy/doc/_images/mac.png +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/_images/plink-action.png +0 -0
- snappy/doc/_images/ubuntu.png +0 -0
- snappy/doc/_images/win7.png +0 -0
- snappy/doc/_sources/additional_classes.rst.txt +40 -0
- snappy/doc/_sources/bugs.rst.txt +14 -0
- snappy/doc/_sources/censuses.rst.txt +52 -0
- snappy/doc/_sources/credits.rst.txt +81 -0
- snappy/doc/_sources/development.rst.txt +261 -0
- snappy/doc/_sources/index.rst.txt +215 -0
- snappy/doc/_sources/installing.rst.txt +249 -0
- snappy/doc/_sources/manifold.rst.txt +6 -0
- snappy/doc/_sources/manifoldhp.rst.txt +46 -0
- snappy/doc/_sources/news.rst.txt +425 -0
- snappy/doc/_sources/other.rst.txt +25 -0
- snappy/doc/_sources/platonic_census.rst.txt +20 -0
- snappy/doc/_sources/plink.rst.txt +102 -0
- snappy/doc/_sources/ptolemy.rst.txt +66 -0
- snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
- snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
- snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
- snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
- snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
- snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
- snappy/doc/_sources/screenshots.rst.txt +21 -0
- snappy/doc/_sources/snap.rst.txt +87 -0
- snappy/doc/_sources/snappy.rst.txt +28 -0
- snappy/doc/_sources/spherogram.rst.txt +103 -0
- snappy/doc/_sources/todo.rst.txt +47 -0
- snappy/doc/_sources/triangulation.rst.txt +11 -0
- snappy/doc/_sources/tutorial.rst.txt +49 -0
- snappy/doc/_sources/verify.rst.txt +210 -0
- snappy/doc/_sources/verify_internals.rst.txt +79 -0
- snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
- snappy/doc/_static/SnapPy.ico +0 -0
- snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
- snappy/doc/_static/basic.css +906 -0
- snappy/doc/_static/css/badge_only.css +1 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
- snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
- snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
- snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
- snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
- snappy/doc/_static/css/theme.css +4 -0
- snappy/doc/_static/doctools.js +149 -0
- snappy/doc/_static/documentation_options.js +13 -0
- snappy/doc/_static/file.png +0 -0
- 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/jquery.js +2 -0
- snappy/doc/_static/js/badge_only.js +1 -0
- snappy/doc/_static/js/theme.js +1 -0
- snappy/doc/_static/js/versions.js +228 -0
- snappy/doc/_static/language_data.js +192 -0
- snappy/doc/_static/minus.png +0 -0
- snappy/doc/_static/plus.png +0 -0
- snappy/doc/_static/pygments.css +75 -0
- snappy/doc/_static/searchtools.js +635 -0
- snappy/doc/_static/snappy_furo.css +33 -0
- snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
- snappy/doc/_static/sphinx_highlight.js +154 -0
- snappy/doc/additional_classes.html +1500 -0
- snappy/doc/bugs.html +132 -0
- snappy/doc/censuses.html +453 -0
- snappy/doc/credits.html +184 -0
- snappy/doc/development.html +385 -0
- snappy/doc/doc-latest/additional_classes.html +1500 -0
- snappy/doc/doc-latest/bugs.html +132 -0
- snappy/doc/doc-latest/censuses.html +453 -0
- snappy/doc/doc-latest/credits.html +184 -0
- snappy/doc/doc-latest/development.html +385 -0
- snappy/doc/doc-latest/genindex.html +1349 -0
- snappy/doc/doc-latest/index.html +287 -0
- snappy/doc/doc-latest/installing.html +346 -0
- snappy/doc/doc-latest/manifold.html +3632 -0
- snappy/doc/doc-latest/manifoldhp.html +180 -0
- snappy/doc/doc-latest/news.html +438 -0
- snappy/doc/doc-latest/objects.inv +0 -0
- snappy/doc/doc-latest/other.html +160 -0
- snappy/doc/doc-latest/platonic_census.html +376 -0
- snappy/doc/doc-latest/plink.html +210 -0
- snappy/doc/doc-latest/ptolemy.html +253 -0
- snappy/doc/doc-latest/ptolemy_classes.html +1144 -0
- snappy/doc/doc-latest/ptolemy_examples1.html +409 -0
- snappy/doc/doc-latest/ptolemy_examples2.html +471 -0
- snappy/doc/doc-latest/ptolemy_examples3.html +414 -0
- snappy/doc/doc-latest/ptolemy_examples4.html +195 -0
- snappy/doc/doc-latest/ptolemy_prelim.html +248 -0
- snappy/doc/doc-latest/py-modindex.html +165 -0
- snappy/doc/doc-latest/screenshots.html +141 -0
- snappy/doc/doc-latest/search.html +135 -0
- snappy/doc/doc-latest/searchindex.js +1 -0
- snappy/doc/doc-latest/snap.html +202 -0
- snappy/doc/doc-latest/snappy.html +181 -0
- snappy/doc/doc-latest/spherogram.html +1346 -0
- snappy/doc/doc-latest/todo.html +166 -0
- snappy/doc/doc-latest/triangulation.html +1676 -0
- snappy/doc/doc-latest/tutorial.html +159 -0
- snappy/doc/doc-latest/verify.html +330 -0
- snappy/doc/doc-latest/verify_internals.html +1235 -0
- snappy/doc/genindex.html +1349 -0
- snappy/doc/index.html +287 -0
- snappy/doc/installing.html +346 -0
- snappy/doc/manifold.html +3632 -0
- snappy/doc/manifoldhp.html +180 -0
- snappy/doc/news.html +438 -0
- snappy/doc/objects.inv +0 -0
- snappy/doc/other.html +160 -0
- snappy/doc/platonic_census.html +376 -0
- snappy/doc/plink.html +210 -0
- snappy/doc/ptolemy.html +253 -0
- snappy/doc/ptolemy_classes.html +1144 -0
- snappy/doc/ptolemy_examples1.html +409 -0
- snappy/doc/ptolemy_examples2.html +471 -0
- snappy/doc/ptolemy_examples3.html +414 -0
- snappy/doc/ptolemy_examples4.html +195 -0
- snappy/doc/ptolemy_prelim.html +248 -0
- snappy/doc/py-modindex.html +165 -0
- snappy/doc/screenshots.html +141 -0
- snappy/doc/search.html +135 -0
- snappy/doc/searchindex.js +1 -0
- snappy/doc/snap.html +202 -0
- snappy/doc/snappy.html +181 -0
- snappy/doc/spherogram.html +1346 -0
- snappy/doc/todo.html +166 -0
- snappy/doc/triangulation.html +1676 -0
- snappy/doc/tutorial.html +159 -0
- snappy/doc/verify.html +330 -0
- snappy/doc/verify_internals.html +1235 -0
- snappy/drilling/__init__.py +456 -0
- snappy/drilling/barycentric.py +103 -0
- snappy/drilling/constants.py +5 -0
- snappy/drilling/crush.py +270 -0
- snappy/drilling/cusps.py +125 -0
- snappy/drilling/debug.py +242 -0
- snappy/drilling/epsilons.py +6 -0
- snappy/drilling/exceptions.py +55 -0
- snappy/drilling/moves.py +620 -0
- snappy/drilling/peripheral_curves.py +210 -0
- snappy/drilling/perturb.py +188 -0
- snappy/drilling/shorten.py +36 -0
- snappy/drilling/subdivide.py +274 -0
- snappy/drilling/test.py +23 -0
- snappy/drilling/test_cases.py +132 -0
- snappy/drilling/tracing.py +351 -0
- snappy/exceptions.py +26 -0
- snappy/export_stl.py +120 -0
- snappy/exterior_to_link/__init__.py +2 -0
- snappy/exterior_to_link/barycentric_geometry.py +463 -0
- snappy/exterior_to_link/exceptions.py +6 -0
- snappy/exterior_to_link/geodesic_map.json +14408 -0
- snappy/exterior_to_link/hyp_utils.py +112 -0
- snappy/exterior_to_link/link_projection.py +323 -0
- snappy/exterior_to_link/main.py +198 -0
- snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
- snappy/exterior_to_link/mcomplex_with_link.py +687 -0
- snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
- snappy/exterior_to_link/pl_utils.py +491 -0
- snappy/exterior_to_link/put_in_S3.py +156 -0
- snappy/exterior_to_link/rational_linear_algebra.py +130 -0
- snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
- snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
- snappy/exterior_to_link/stored_moves.py +475 -0
- snappy/exterior_to_link/test.py +31 -0
- snappy/filedialog.py +28 -0
- 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 +691 -0
- snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +480 -0
- snappy/geometric_structure/cusp_neighborhood/exceptions.py +41 -0
- snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +294 -0
- snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +156 -0
- snappy/geometric_structure/cusp_neighborhood/vertices.py +35 -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_representatives.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/geometric_structure/geodesic/fixed_points.py +106 -0
- snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
- 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 +128 -0
- snappy/geometric_structure/test.py +22 -0
- snappy/gui.py +121 -0
- snappy/horoviewer.py +443 -0
- snappy/hyperboloid/__init__.py +212 -0
- snappy/hyperboloid/distances.py +259 -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/info_icon.gif +0 -0
- snappy/infowindow.py +65 -0
- snappy/isometry_signature.py +389 -0
- snappy/len_spec/__init__.py +609 -0
- snappy/len_spec/geodesic_info.py +129 -0
- snappy/len_spec/geodesic_key_info_dict.py +116 -0
- snappy/len_spec/geodesic_piece.py +146 -0
- snappy/len_spec/geometric_structure.py +182 -0
- snappy/len_spec/geometry.py +136 -0
- snappy/len_spec/length_spectrum_geodesic_info.py +185 -0
- snappy/len_spec/spine.py +128 -0
- snappy/len_spec/test.py +24 -0
- snappy/len_spec/test_cases.py +69 -0
- snappy/len_spec/tile.py +276 -0
- snappy/len_spec/word.py +86 -0
- snappy/manifolds/HTWKnots/alternating.gz +0 -0
- snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
- snappy/manifolds/__init__.py +3 -0
- snappy/margulis/__init__.py +332 -0
- snappy/margulis/cusp_neighborhood_neighborhood.py +66 -0
- snappy/margulis/geodesic_neighborhood.py +152 -0
- snappy/margulis/margulis_info.py +21 -0
- snappy/margulis/mu_from_neighborhood_pair.py +175 -0
- snappy/margulis/neighborhood.py +29 -0
- snappy/margulis/test.py +22 -0
- snappy/math_basics.py +187 -0
- snappy/matrix.py +525 -0
- snappy/number.py +657 -0
- snappy/numeric_output_checker.py +345 -0
- snappy/pari.py +41 -0
- snappy/phone_home.py +57 -0
- snappy/polyviewer.py +259 -0
- snappy/ptolemy/__init__.py +17 -0
- snappy/ptolemy/component.py +103 -0
- snappy/ptolemy/coordinates.py +2290 -0
- snappy/ptolemy/fieldExtensions.py +153 -0
- snappy/ptolemy/findLoops.py +473 -0
- snappy/ptolemy/geometricRep.py +59 -0
- snappy/ptolemy/homology.py +165 -0
- snappy/ptolemy/magma/default.magma_template +229 -0
- snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
- snappy/ptolemy/manifoldMethods.py +395 -0
- snappy/ptolemy/matrix.py +350 -0
- snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
- snappy/ptolemy/polynomial.py +856 -0
- snappy/ptolemy/processComponents.py +173 -0
- snappy/ptolemy/processFileBase.py +247 -0
- snappy/ptolemy/processFileDispatch.py +46 -0
- snappy/ptolemy/processMagmaFile.py +392 -0
- snappy/ptolemy/processRurFile.py +150 -0
- snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
- snappy/ptolemy/ptolemyObstructionClass.py +64 -0
- snappy/ptolemy/ptolemyVariety.py +995 -0
- snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
- snappy/ptolemy/reginaWrapper.py +698 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/rur.py +545 -0
- snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
- snappy/ptolemy/test.py +1126 -0
- snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
- snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
- snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
- snappy/ptolemy/utilities.py +236 -0
- 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 +197 -0
- snappy/raytracing/eyeball.py +124 -0
- snappy/raytracing/finite_raytracing_data.py +237 -0
- snappy/raytracing/finite_viewer.py +590 -0
- snappy/raytracing/geodesic_tube_info.py +174 -0
- snappy/raytracing/geodesics.py +246 -0
- snappy/raytracing/geodesics_window.py +258 -0
- snappy/raytracing/gui_utilities.py +293 -0
- snappy/raytracing/hyperboloid_navigation.py +556 -0
- snappy/raytracing/hyperboloid_utilities.py +234 -0
- snappy/raytracing/ideal_raytracing_data.py +592 -0
- snappy/raytracing/inside_viewer.py +974 -0
- snappy/raytracing/pack.py +22 -0
- snappy/raytracing/raytracing_data.py +126 -0
- snappy/raytracing/raytracing_view.py +454 -0
- snappy/raytracing/shaders/Eye.png +0 -0
- snappy/raytracing/shaders/NonGeometric.png +0 -0
- snappy/raytracing/shaders/__init__.py +101 -0
- snappy/raytracing/shaders/fragment.glsl +1744 -0
- snappy/raytracing/test.py +29 -0
- snappy/raytracing/tooltip.py +146 -0
- snappy/raytracing/upper_halfspace_utilities.py +98 -0
- snappy/raytracing/view_scale_controller.py +98 -0
- snappy/raytracing/zoom_slider/__init__.py +263 -0
- snappy/raytracing/zoom_slider/inward.png +0 -0
- snappy/raytracing/zoom_slider/inward18.png +0 -0
- snappy/raytracing/zoom_slider/outward.png +0 -0
- snappy/raytracing/zoom_slider/outward18.png +0 -0
- snappy/raytracing/zoom_slider/test.py +20 -0
- snappy/sage_helper.py +119 -0
- snappy/settings.py +407 -0
- snappy/shell.py +53 -0
- snappy/snap/__init__.py +117 -0
- snappy/snap/character_varieties.py +375 -0
- snappy/snap/find_field.py +372 -0
- snappy/snap/fox_milnor.py +271 -0
- snappy/snap/fundamental_polyhedron.py +569 -0
- snappy/snap/generators.py +39 -0
- snappy/snap/interval_reps.py +81 -0
- snappy/snap/kernel_structures.py +128 -0
- snappy/snap/mcomplex_base.py +18 -0
- snappy/snap/nsagetools.py +716 -0
- snappy/snap/peripheral/__init__.py +1 -0
- snappy/snap/peripheral/dual_cellulation.py +219 -0
- snappy/snap/peripheral/link.py +127 -0
- snappy/snap/peripheral/peripheral.py +159 -0
- snappy/snap/peripheral/surface.py +522 -0
- snappy/snap/peripheral/test.py +35 -0
- snappy/snap/polished_reps.py +335 -0
- snappy/snap/shapes.py +152 -0
- snappy/snap/slice_obs_HKL/__init__.py +194 -0
- snappy/snap/slice_obs_HKL/basics.py +236 -0
- snappy/snap/slice_obs_HKL/direct.py +217 -0
- snappy/snap/slice_obs_HKL/poly_norm.py +212 -0
- snappy/snap/slice_obs_HKL/rep_theory.py +424 -0
- snappy/snap/t3mlite/__init__.py +2 -0
- snappy/snap/t3mlite/arrow.py +243 -0
- snappy/snap/t3mlite/corner.py +22 -0
- snappy/snap/t3mlite/edge.py +172 -0
- snappy/snap/t3mlite/face.py +37 -0
- snappy/snap/t3mlite/files.py +211 -0
- snappy/snap/t3mlite/homology.py +53 -0
- snappy/snap/t3mlite/linalg.py +419 -0
- snappy/snap/t3mlite/mcomplex.py +1499 -0
- snappy/snap/t3mlite/perm4.py +320 -0
- snappy/snap/t3mlite/setup.py +12 -0
- snappy/snap/t3mlite/simplex.py +199 -0
- snappy/snap/t3mlite/spun.py +297 -0
- snappy/snap/t3mlite/surface.py +519 -0
- snappy/snap/t3mlite/test.py +20 -0
- snappy/snap/t3mlite/test_vs_regina.py +86 -0
- snappy/snap/t3mlite/tetrahedron.py +109 -0
- snappy/snap/t3mlite/vertex.py +42 -0
- snappy/snap/test.py +139 -0
- snappy/snap/utilities.py +288 -0
- snappy/test.py +213 -0
- snappy/test_cases.py +263 -0
- snappy/testing.py +131 -0
- snappy/tiling/__init__.py +2 -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/quotient_dict.py +70 -0
- snappy/tiling/real_hash_dict.py +164 -0
- snappy/tiling/test.py +23 -0
- snappy/tiling/tile.py +224 -0
- snappy/tiling/triangle.py +33 -0
- snappy/tkterminal.py +920 -0
- snappy/twister/__init__.py +20 -0
- snappy/twister/main.py +646 -0
- snappy/twister/surfaces/S_0_1 +3 -0
- snappy/twister/surfaces/S_0_2 +3 -0
- snappy/twister/surfaces/S_0_4 +7 -0
- snappy/twister/surfaces/S_0_4_Lantern +8 -0
- snappy/twister/surfaces/S_1 +3 -0
- snappy/twister/surfaces/S_1_1 +4 -0
- snappy/twister/surfaces/S_1_2 +5 -0
- snappy/twister/surfaces/S_1_2_5 +6 -0
- snappy/twister/surfaces/S_2 +6 -0
- snappy/twister/surfaces/S_2_1 +8 -0
- snappy/twister/surfaces/S_2_heeg +10 -0
- snappy/twister/surfaces/S_3 +8 -0
- snappy/twister/surfaces/S_3_1 +10 -0
- snappy/twister/surfaces/S_4_1 +12 -0
- snappy/twister/surfaces/S_5_1 +14 -0
- snappy/twister/surfaces/heeg_fig8 +9 -0
- snappy/twister/twister_core.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/upper_halfspace/__init__.py +146 -0
- snappy/upper_halfspace/ideal_point.py +29 -0
- snappy/verify/__init__.py +13 -0
- snappy/verify/canonical.py +542 -0
- snappy/verify/complex_volume/__init__.py +18 -0
- snappy/verify/complex_volume/adjust_torsion.py +86 -0
- snappy/verify/complex_volume/closed.py +168 -0
- snappy/verify/complex_volume/compute_ptolemys.py +90 -0
- snappy/verify/complex_volume/cusped.py +56 -0
- snappy/verify/complex_volume/extended_bloch.py +201 -0
- snappy/verify/cusp_translations.py +85 -0
- snappy/verify/edge_equations.py +80 -0
- snappy/verify/exceptions.py +254 -0
- snappy/verify/hyperbolicity.py +224 -0
- snappy/verify/interval_newton_shapes_engine.py +523 -0
- snappy/verify/interval_tree.py +400 -0
- snappy/verify/krawczyk_shapes_engine.py +518 -0
- snappy/verify/real_algebra.py +286 -0
- snappy/verify/shapes.py +25 -0
- snappy/verify/square_extensions.py +1005 -0
- snappy/verify/test.py +72 -0
- snappy/verify/volume.py +128 -0
- snappy/version.py +2 -0
- snappy-3.3.dist-info/METADATA +58 -0
- snappy-3.3.dist-info/RECORD +541 -0
- snappy-3.3.dist-info/WHEEL +6 -0
- snappy-3.3.dist-info/entry_points.txt +2 -0
- snappy-3.3.dist-info/top_level.txt +28 -0
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
"""
|
|
2
|
+
|
|
3
|
+
The main HKL tests that use the representation-theoretic perspective,
|
|
4
|
+
based on Lemma 3.5 and Theorem 3.8 of [DG].
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from ...sage_helper import _within_sage
|
|
12
|
+
if _within_sage:
|
|
13
|
+
from ...sage_helper import (ZZ, QQ, GF, PolynomialRing, LaurentPolynomialRing,
|
|
14
|
+
CyclotomicField, vector, matrix, is_power_of_two,
|
|
15
|
+
identity_matrix, block_matrix, gcd,
|
|
16
|
+
VectorSpace, MatrixSpace, ChainComplex,
|
|
17
|
+
prime_range, prime_powers)
|
|
18
|
+
|
|
19
|
+
from ..nsagetools import (MapToFreeAbelianization, compute_torsion,
|
|
20
|
+
fox_derivative_with_involution,
|
|
21
|
+
fox_derivative,
|
|
22
|
+
fast_determinant_of_laurent_poly_matrix,
|
|
23
|
+
last_square_submatrix,
|
|
24
|
+
first_square_submatrix)
|
|
25
|
+
|
|
26
|
+
from .basics import (print_function,
|
|
27
|
+
MatrixRepresentation,
|
|
28
|
+
twisted_alexander_polynomial)
|
|
29
|
+
|
|
30
|
+
from .poly_norm import (poly_involution,
|
|
31
|
+
poly_is_a_norm,
|
|
32
|
+
poly_is_a_norm_in_some_extension)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def poly_to_rep(f):
|
|
36
|
+
"""
|
|
37
|
+
For a polynomial f in F[x], return the matrix corresponding to the
|
|
38
|
+
left action of x on F[x]/(f).
|
|
39
|
+
"""
|
|
40
|
+
assert f.is_monic()
|
|
41
|
+
d = f.degree()
|
|
42
|
+
last_column = [-f[e] for e in range(d)]
|
|
43
|
+
I = identity_matrix(d)
|
|
44
|
+
M = matrix(I.rows()[1:] + [last_column])
|
|
45
|
+
assert M.charpoly() == f
|
|
46
|
+
return M.transpose()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def irreps(p, q):
|
|
50
|
+
"""
|
|
51
|
+
Returns the irreducible representations of the cyclic group C_p
|
|
52
|
+
over the field F_q, where p and q are distinct primes.
|
|
53
|
+
|
|
54
|
+
Each representation is given by a matrix over F_q giving the
|
|
55
|
+
action of the preferred generator of C_p.
|
|
56
|
+
|
|
57
|
+
sage: [M.nrows() for M in irreps(3, 7)]
|
|
58
|
+
[1, 1, 1]
|
|
59
|
+
sage: [M.nrows() for M in irreps(7, 11)]
|
|
60
|
+
[1, 3, 3]
|
|
61
|
+
sage: sum(M.nrows() for M in irreps(157, 13))
|
|
62
|
+
157
|
|
63
|
+
"""
|
|
64
|
+
p, q = ZZ(p), ZZ(q)
|
|
65
|
+
assert q.is_prime() and gcd(p, q) == 1
|
|
66
|
+
R = PolynomialRing(GF(q), 'x')
|
|
67
|
+
x = R.gen()
|
|
68
|
+
polys = [f for f, e in (x**p - 1).factor()]
|
|
69
|
+
polys.sort(key=lambda f:(f.degree(), -f.constant_coefficient()))
|
|
70
|
+
reps = [poly_to_rep(f) for f in polys]
|
|
71
|
+
assert all(A**p == 1 for A in reps)
|
|
72
|
+
assert reps[0] == 1
|
|
73
|
+
return reps
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def cyclic_rep(group, matrix_of_rep):
|
|
77
|
+
"""
|
|
78
|
+
For a group G whose free abelianization is Z, returns the
|
|
79
|
+
representation of G factoring through Z where 1 in Z in turn goes
|
|
80
|
+
to the given matrix_of_rep.
|
|
81
|
+
"""
|
|
82
|
+
A = matrix_of_rep
|
|
83
|
+
epsilon = MapToFreeAbelianization(group)
|
|
84
|
+
assert epsilon.range().rank() == 1
|
|
85
|
+
gens = group.generators()
|
|
86
|
+
rels = group.relators()
|
|
87
|
+
mats = [A**(epsilon(g)[0]) for g in gens]
|
|
88
|
+
rho = MatrixRepresentation(gens, rels, A.parent(), mats)
|
|
89
|
+
rho.epsilon = epsilon
|
|
90
|
+
rho.A = A
|
|
91
|
+
return rho
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def dim_twisted_homology(group, matrix_of_C_p_rep):
|
|
95
|
+
"""
|
|
96
|
+
sage: M = Manifold('K12n813')
|
|
97
|
+
sage: G = M.fundamental_group()
|
|
98
|
+
sage: reps = irreps(3, 7)
|
|
99
|
+
sage: [dim_twisted_homology(G, A) for A in reps]
|
|
100
|
+
[1, 1, 1]
|
|
101
|
+
sage: reps = irreps(3, 5)
|
|
102
|
+
sage: [dim_twisted_homology(G, A) for A in reps]
|
|
103
|
+
[1, 0]
|
|
104
|
+
"""
|
|
105
|
+
rho = cyclic_rep(group, matrix_of_C_p_rep)
|
|
106
|
+
C = rho.twisted_chain_complex()
|
|
107
|
+
H = C.homology()
|
|
108
|
+
if matrix_of_C_p_rep != 1:
|
|
109
|
+
assert H[0].rank() == 0
|
|
110
|
+
else:
|
|
111
|
+
assert H[0].rank() == 1
|
|
112
|
+
return H[1].rank()
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def reps_appearing(knot_exterior, p, q):
|
|
116
|
+
"""
|
|
117
|
+
All irreducible C_p reps appearing in the F_q homology of the
|
|
118
|
+
cyclic branched cover B_p, together with their multiplicities.
|
|
119
|
+
|
|
120
|
+
sage: M = Manifold('K12a169')
|
|
121
|
+
sage: [(A.trace(), e) for A, e in reps_appearing(M, 3, 5)]
|
|
122
|
+
[(4, 1)]
|
|
123
|
+
"""
|
|
124
|
+
M = knot_exterior
|
|
125
|
+
G = M.fundamental_group()
|
|
126
|
+
for A in irreps(p, q)[1:]:
|
|
127
|
+
d = dim_twisted_homology(G, A)
|
|
128
|
+
if d > 0:
|
|
129
|
+
n = A.nrows()
|
|
130
|
+
assert d % n == 0
|
|
131
|
+
yield (A, d//n)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def induced_rep_from_twisted_cocycle(p, rho, chi, cocycle):
|
|
135
|
+
"""
|
|
136
|
+
The main metabelian representation from Section 7 of [HKL] for the
|
|
137
|
+
group of a knot complement, where p is the degree of the branched
|
|
138
|
+
cover, rho is an irreducible cyclic representation acting on the
|
|
139
|
+
F_q vector space V, chi is a homomorpism V -> F_q, and cocycle
|
|
140
|
+
describes the semidirect product extension.
|
|
141
|
+
|
|
142
|
+
We differ from [HKL] in that all actions are on the left, meaning
|
|
143
|
+
that this representation is defined in terms of the convention for the
|
|
144
|
+
semidirect product discussed in::
|
|
145
|
+
|
|
146
|
+
MatrixRepresentation.semidirect_rep_from_twisted_cocycle
|
|
147
|
+
|
|
148
|
+
Here is an example::
|
|
149
|
+
|
|
150
|
+
sage: G = Manifold('K12n132').fundamental_group()
|
|
151
|
+
sage: A = matrix(GF(5), [[0, 4], [1, 4]])
|
|
152
|
+
sage: rho = cyclic_rep(G, A)
|
|
153
|
+
sage: cocycle = (0, 0, 0, 1, 1, 2)
|
|
154
|
+
sage: chi = lambda v: v[0] + 4*v[1]
|
|
155
|
+
sage: rho_ind = induced_rep_from_twisted_cocycle(3, rho, chi, cocycle)
|
|
156
|
+
sage: rho_ind('c').list()
|
|
157
|
+
[0, 0, (-z^3 - z^2 - z - 1), z^2*t^-1, 0, 0, 0, (-z^3 - z^2 - z - 1)*t^-1, 0]
|
|
158
|
+
|
|
159
|
+
Here, we duplicate the calculation of Section 10.2 of [HKL]::
|
|
160
|
+
|
|
161
|
+
sage: M = Manifold('K12a169')
|
|
162
|
+
sage: G = M.fundamental_group()
|
|
163
|
+
sage: A = matrix(GF(5), [[0, 4], [1, 4]])
|
|
164
|
+
sage: rho = cyclic_rep(G, A)
|
|
165
|
+
sage: chi = lambda v:3*v[0]
|
|
166
|
+
sage: alpha = induced_rep_from_twisted_cocycle(3, rho, chi, (0, 0, 1, 0))
|
|
167
|
+
sage: -twisted_alexander_polynomial(alpha, reduced=True)
|
|
168
|
+
4*t^2 + (z^3 + z^2 + 5)*t + 4
|
|
169
|
+
"""
|
|
170
|
+
q = rho.base_ring.order()
|
|
171
|
+
n = rho.dim
|
|
172
|
+
K = CyclotomicField(q, 'z')
|
|
173
|
+
z = K.gen()
|
|
174
|
+
A = rho.A
|
|
175
|
+
R = LaurentPolynomialRing(K, 't')
|
|
176
|
+
t = R.gen()
|
|
177
|
+
MatSp = MatrixSpace(R, p)
|
|
178
|
+
gens = rho.generators
|
|
179
|
+
images = {}
|
|
180
|
+
for s, g in enumerate(gens):
|
|
181
|
+
v = vector(cocycle[s*n:(s+1)*n])
|
|
182
|
+
e = rho.epsilon(g)[0]
|
|
183
|
+
U = MatSp(0)
|
|
184
|
+
for j in range(0, p):
|
|
185
|
+
k, l = (e + j).quo_rem(p)
|
|
186
|
+
U[l, j] = t**k * z**chi(A**(-l) * v)
|
|
187
|
+
images[g] = U
|
|
188
|
+
|
|
189
|
+
e, v = -e, -A**(-e)*v
|
|
190
|
+
V = MatSp(0)
|
|
191
|
+
for j in range(0, p):
|
|
192
|
+
k, l = (e + j).quo_rem(p)
|
|
193
|
+
V[l, j] = t**k * z**chi(A**(-l) * v)
|
|
194
|
+
images[g.swapcase()] = V
|
|
195
|
+
|
|
196
|
+
alpha = MatrixRepresentation(gens, rho.relators, MatSp, images)
|
|
197
|
+
alpha.epsilon = rho.epsilon
|
|
198
|
+
return alpha
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def alex_poly_of_induced_rep(p, knot_exterior, A, chi):
|
|
202
|
+
"""
|
|
203
|
+
When A is the matrix generating an irreducible representation V
|
|
204
|
+
that appears with multiplicity 1 in H_1(B_p, F_q) and chi: V -> F_q
|
|
205
|
+
is a homomorphism, computes the (reduced) twisted alexander
|
|
206
|
+
polynomial of Herald-Kirk-Livingston.
|
|
207
|
+
|
|
208
|
+
Here is the example from Section 10.3 of [HKL]. When comparing
|
|
209
|
+
with the original, note the polynomnial coeffs in Q(zeta_5) are
|
|
210
|
+
not in the usual Q-basis for this field 1, z, z^2, z^3 where z =
|
|
211
|
+
zeta_5::
|
|
212
|
+
|
|
213
|
+
sage: M = Manifold('K12n132')
|
|
214
|
+
sage: A = matrix(GF(5), [[0, 4], [1, 4]])
|
|
215
|
+
sage: chi = lambda v:v[0] + 3*v[1]
|
|
216
|
+
sage: alex = alex_poly_of_induced_rep(3, M, A, chi)
|
|
217
|
+
sage: t = alex.parent().gen()
|
|
218
|
+
sage: quo, rem = alex.quo_rem(t - 1)
|
|
219
|
+
sage: 5*quo/quo.leading_coefficient()
|
|
220
|
+
5*t^3 + (10*z^3 + 14*z^2 + 14*z + 12)*t^2 + (-4*z^2 - 14*z - 2)*t + 5
|
|
221
|
+
|
|
222
|
+
Here is their example 10.6::
|
|
223
|
+
|
|
224
|
+
sage: M = Manifold('K12n224')
|
|
225
|
+
sage: A3, A5 = matrix(GF(7), [[4]]), matrix(GF(7), [[2]])
|
|
226
|
+
sage: A3.charpoly(), A5.charpoly()
|
|
227
|
+
(x + 3, x + 5)
|
|
228
|
+
sage: -alex_poly_of_induced_rep(3, M, A3, lambda v:3*v[0])
|
|
229
|
+
t^4 + (-4*z^4 - 4*z^2 - 4*z - 5)*t^3 + 6*t^2 + (4*z^4 + 4*z^2 + 4*z - 1)*t + 1
|
|
230
|
+
sage: -alex_poly_of_induced_rep(3, M, A5, lambda v:v[0])
|
|
231
|
+
t^4 + (4*z^4 + 4*z^2 + 4*z - 1)*t^3 + 6*t^2 + (-4*z^4 - 4*z^2 - 4*z - 5)*t + 1
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
G = knot_exterior.fundamental_group()
|
|
235
|
+
rho = cyclic_rep(G, A)
|
|
236
|
+
n = rho.dim
|
|
237
|
+
|
|
238
|
+
C = rho.twisted_cochain_complex()
|
|
239
|
+
if C.homology(1).dimension() != n:
|
|
240
|
+
raise ValueError('Multiplicity of V is not 1')
|
|
241
|
+
d0, d1 = C.differential(0), C.differential(1)
|
|
242
|
+
B1 = d0.column_space()
|
|
243
|
+
Z1 = d1.right_kernel()
|
|
244
|
+
cocycle = next(z for z in Z1.basis() if z not in B1)
|
|
245
|
+
alpha = induced_rep_from_twisted_cocycle(p, rho, chi, cocycle)
|
|
246
|
+
ans = twisted_alexander_polynomial(alpha, reduced=True)
|
|
247
|
+
assert poly_involution(ans) == ans
|
|
248
|
+
return ans
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def twisted_alex_polys_are_not_norms(knot_exterior, p, A, ribbon_mode=False, verbose=False):
|
|
253
|
+
"""
|
|
254
|
+
For an irreducible rep rho from the knot group, consider the
|
|
255
|
+
rho-isotypic part of H_1(B_p, F_q). If V is the vector space on
|
|
256
|
+
which rho acts, this function iterates over equivariant maps::
|
|
257
|
+
|
|
258
|
+
psi: H_1(B_p, F_q) --> V
|
|
259
|
+
|
|
260
|
+
as in the start of Section 7 of [HKL] where what we call psi is
|
|
261
|
+
there denoted rho. Such a psi can be given by a cocycle
|
|
262
|
+
representative of a nonzero class in H^1(E, V) where E is knot
|
|
263
|
+
exterior. The particular cocycle representative, as well as
|
|
264
|
+
multiplying [psi] by a nonzero element of F_q, will not change the
|
|
265
|
+
twisted alexander polynomial, so in fact we iterate [psi] over
|
|
266
|
+
P^1(H^1(E, V)).
|
|
267
|
+
|
|
268
|
+
For each [psi], we consider nonzero characters chi: V --> F_q,
|
|
269
|
+
up to scaling. If any of the twisted alexander polynomials
|
|
270
|
+
associated to (psi, chi) is not a norm, then we yield True, and
|
|
271
|
+
otherwise False.
|
|
272
|
+
|
|
273
|
+
When dim V > 1 and q is large, there are a lot of chi to
|
|
274
|
+
examine. Experience shows that for a fixed chi it is very unlikely
|
|
275
|
+
to get a non-norm after encountering many norms; this especially
|
|
276
|
+
true if some prior chi gave all norms. For speed, we limit
|
|
277
|
+
the number of non-norms encountered before giving up on a
|
|
278
|
+
particular chi.
|
|
279
|
+
"""
|
|
280
|
+
print = print_function(verbose)
|
|
281
|
+
|
|
282
|
+
G = knot_exterior.fundamental_group()
|
|
283
|
+
rho = cyclic_rep(G, A)
|
|
284
|
+
n = rho.dim
|
|
285
|
+
C = rho.twisted_cochain_complex()
|
|
286
|
+
F = rho.base_ring
|
|
287
|
+
cohomology_basis = []
|
|
288
|
+
for V, chain in C.homology(1, generators=True):
|
|
289
|
+
assert V.dimension() == 1
|
|
290
|
+
cohomology_basis.append(chain.vector(1))
|
|
291
|
+
|
|
292
|
+
dim = C.homology(1).dimension()
|
|
293
|
+
d0, d1 = C.differential(0), C.differential(1)
|
|
294
|
+
B1 = d0.column_space()
|
|
295
|
+
Z1 = d1.right_kernel()
|
|
296
|
+
assert (dim == len(cohomology_basis) and
|
|
297
|
+
all(v in Z1 for v in cohomology_basis) and
|
|
298
|
+
all(v not in B1 for v in cohomology_basis))
|
|
299
|
+
|
|
300
|
+
non_norms = []
|
|
301
|
+
P1 = [S.basis()[0] for S in VectorSpace(F, dim).subspaces(1)]
|
|
302
|
+
chi_specs = [S.basis()[0] for S in VectorSpace(F, n).subspaces(1)]
|
|
303
|
+
all_norm_phis = 0
|
|
304
|
+
for phi in P1:
|
|
305
|
+
print(11*' ', phi, end='')
|
|
306
|
+
cocycle = sum(a*v for a, v in zip(phi, cohomology_basis))
|
|
307
|
+
norms_seen_for_this_chi = 0
|
|
308
|
+
for chi_spec in chi_specs:
|
|
309
|
+
def chi(v):
|
|
310
|
+
return chi_spec * v
|
|
311
|
+
alpha = induced_rep_from_twisted_cocycle(p, rho, chi, cocycle)
|
|
312
|
+
delta_chi = twisted_alexander_polynomial(alpha, reduced=True)
|
|
313
|
+
assert poly_involution(delta_chi) == delta_chi
|
|
314
|
+
if F.order() == 2 and not ribbon_mode:
|
|
315
|
+
norm = poly_is_a_norm_in_some_extension(delta_chi)
|
|
316
|
+
else:
|
|
317
|
+
norm = poly_is_a_norm(delta_chi)
|
|
318
|
+
print('', not norm, end='')
|
|
319
|
+
if not norm:
|
|
320
|
+
print()
|
|
321
|
+
yield True
|
|
322
|
+
break
|
|
323
|
+
else:
|
|
324
|
+
norms_seen_for_this_chi += 1
|
|
325
|
+
if (len(chi_specs) > 3
|
|
326
|
+
and all_norm_phis >= 2
|
|
327
|
+
and norms_seen_for_this_chi >= 2):
|
|
328
|
+
break
|
|
329
|
+
|
|
330
|
+
if norms_seen_for_this_chi == len(chi_specs):
|
|
331
|
+
all_norm_phis += 1
|
|
332
|
+
|
|
333
|
+
if norm:
|
|
334
|
+
print()
|
|
335
|
+
yield False
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def min_contrib_to_delta(knot_exterior, p, A, e, ribbon_mode=False, verbose=False):
|
|
339
|
+
"""
|
|
340
|
+
If V^e is specified by the matrix A, then this computes the
|
|
341
|
+
quantity delta(V) in Theorem 3.8 of [DG].
|
|
342
|
+
"""
|
|
343
|
+
print = print_function(verbose, indent=12)
|
|
344
|
+
|
|
345
|
+
norm_count = 0
|
|
346
|
+
nonnorm_count = 0
|
|
347
|
+
for nonnorm in twisted_alex_polys_are_not_norms(knot_exterior, p, A, ribbon_mode, verbose):
|
|
348
|
+
if nonnorm:
|
|
349
|
+
nonnorm_count += 1
|
|
350
|
+
else:
|
|
351
|
+
norm_count += 1
|
|
352
|
+
if norm_count > 0 and nonnorm_count > 0:
|
|
353
|
+
break
|
|
354
|
+
|
|
355
|
+
n = A.nrows()
|
|
356
|
+
if norm_count == 0: # strongly obstructed
|
|
357
|
+
print('strongly obstructed')
|
|
358
|
+
return e*n
|
|
359
|
+
if nonnorm_count > 0: # weakly obstructed
|
|
360
|
+
print('weakly obstructed')
|
|
361
|
+
return n
|
|
362
|
+
print('unobstructed')
|
|
363
|
+
return 0
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
def slicing_is_obstructed(knot_exterior, p, q,
|
|
367
|
+
skip_higher_mult=False,
|
|
368
|
+
ribbon_mode=False,
|
|
369
|
+
verbose=False):
|
|
370
|
+
"""
|
|
371
|
+
Applies the tests of Section 3 of [DG] to the F_q homology of the
|
|
372
|
+
branched cover B_p::
|
|
373
|
+
|
|
374
|
+
sage: M = Manifold('K12n813')
|
|
375
|
+
sage: slicing_is_obstructed(M, 2, 3, skip_higher_mult=True, verbose=True)
|
|
376
|
+
dim H_1(cover; F_q) = 2 with rep. structure [(1, 2)]
|
|
377
|
+
rep V_0 of dim 1, multiplicity 2, generator matrix [(2)]
|
|
378
|
+
Skipping as mult > 1 and mode is "basic"
|
|
379
|
+
False
|
|
380
|
+
sage: slicing_is_obstructed(M, 3, 7, verbose=True)
|
|
381
|
+
dim H_1(cover; F_q) = 2 with rep. structure [(1, 1), (1, 1)]
|
|
382
|
+
rep V_0 of dim 1, multiplicity 1, generator matrix [(2)]
|
|
383
|
+
(1) True
|
|
384
|
+
strongly obstructed
|
|
385
|
+
Have delta(V_0) = 1 and sum of delta(V_i)'s is now 1
|
|
386
|
+
rep V_1 of dim 1, multiplicity 1, generator matrix [(4)]
|
|
387
|
+
(1) True
|
|
388
|
+
strongly obstructed
|
|
389
|
+
Have delta(V_1) = 1 and sum of delta(V_i)'s is now 2
|
|
390
|
+
True
|
|
391
|
+
|
|
392
|
+
"""
|
|
393
|
+
print = print_function(verbose, 8)
|
|
394
|
+
|
|
395
|
+
p, q = ZZ(p), ZZ(q)
|
|
396
|
+
if not p.is_prime_power():
|
|
397
|
+
raise ValueError(f'Degree of cover (={p}) is not a prime power')
|
|
398
|
+
if not q.is_prime():
|
|
399
|
+
raise ValueError(f'Field F_{q} is not of prime order')
|
|
400
|
+
|
|
401
|
+
reps = list(reps_appearing(knot_exterior, p, q))
|
|
402
|
+
if len(reps) == 0:
|
|
403
|
+
return False
|
|
404
|
+
|
|
405
|
+
isotypic_dims = [e*A.nrows() for A, e in reps]
|
|
406
|
+
total_dim = sum(isotypic_dims)
|
|
407
|
+
meta = 0
|
|
408
|
+
|
|
409
|
+
print( f'dim H_1(cover; F_q) = {total_dim} with rep. structure {[(A.nrows(), e) for A, e in reps]}')
|
|
410
|
+
for i, (A, e) in enumerate(reps):
|
|
411
|
+
print(f'rep V_{i} of dim {A.nrows()}, multiplicity {e}, generator matrix {list(A)}')
|
|
412
|
+
if e > 1 and skip_higher_mult:
|
|
413
|
+
print(4*' ' + 'Skipping as mult > 1 and mode is "basic"')
|
|
414
|
+
else:
|
|
415
|
+
contrib = min_contrib_to_delta(knot_exterior, p, A, e, ribbon_mode, verbose)
|
|
416
|
+
meta += contrib
|
|
417
|
+
print(4*' ' + f"Have delta(V_{i}) = {contrib} and sum of delta(V_i)'s is now {meta}")
|
|
418
|
+
# Stop if criteria already applies or if it will fail even if
|
|
419
|
+
# all remaining reps are strongly obstructed.
|
|
420
|
+
if (2*meta > total_dim or
|
|
421
|
+
2*(meta + sum(isotypic_dims[i + 1:])) <= total_dim):
|
|
422
|
+
break
|
|
423
|
+
|
|
424
|
+
return 2*meta > total_dim
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# $Id: arrow.py,v 1.3 2003/04/30 19:59:58 t3m Exp $
|
|
2
|
+
# t3m - software for studying triangulated 3-manifolds
|
|
3
|
+
# Copyright (C) 2002 Marc Culler, Nathan Dunfield and others
|
|
4
|
+
#
|
|
5
|
+
# This program is distributed under the terms of the
|
|
6
|
+
# GNU General Public License, version 2 or later, as published by
|
|
7
|
+
# the Free Software Foundation. See the file GPL.txt for details.
|
|
8
|
+
|
|
9
|
+
from .simplex import *
|
|
10
|
+
from .perm4 import Perm4, inv
|
|
11
|
+
|
|
12
|
+
# I have implemented Casson's Arrow as a class whose attributes are
|
|
13
|
+
# "an edge in a face in a tetrahedron". The Edge attribute is the
|
|
14
|
+
# (unoriented) edge opposite to the arrow, if the arrow is thought of
|
|
15
|
+
# as a directed edge. The Face attribute is the face that is disjoint
|
|
16
|
+
# from the directed edge, except that it contains the head vertex,
|
|
17
|
+
# i.e. the Face is the face that is normally associated to the arrow
|
|
18
|
+
# when the arrow is used for gluing faces together.
|
|
19
|
+
|
|
20
|
+
# The eArrow class is an extension of Arrow that is initialized by
|
|
21
|
+
# specifying the head and tail vertices.
|
|
22
|
+
|
|
23
|
+
# I have followed Nathan's convention that a "null arrow" is an arrow
|
|
24
|
+
# whose Tetrahedron attribute is None. If an arrow A represents a
|
|
25
|
+
# boundary face then A.glued() is a null arrow. If either A or B is a
|
|
26
|
+
# Null Arrow then both A.glue(B) and B.glue(A) cause the appropriate
|
|
27
|
+
# Neighbor of the non-None Tetrahedron to be set to None, creating a
|
|
28
|
+
# boundary face. This trick allows deceptively short code to be used
|
|
29
|
+
# in writing the two_to_zero move. NOTE: The Arrow.next method does NOT
|
|
30
|
+
# return a null arrow if the face is a boundary face. It returns None.
|
|
31
|
+
|
|
32
|
+
# Arrows seem to be handy for gluing tetrahedra together without too
|
|
33
|
+
# much fussing about how vertices of a tetrahedron are numbered.
|
|
34
|
+
# I have not tried to figure out how they will break if you try to
|
|
35
|
+
# use them in a non-orientable manifold.
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# For speed, we create a lookup table for all possible gluing permutations
|
|
39
|
+
|
|
40
|
+
_arrow_gluing_dict = {}
|
|
41
|
+
for edge0, face0 in EdgeFacePairs:
|
|
42
|
+
for edge1, face1 in EdgeFacePairs:
|
|
43
|
+
perm = Perm4({FaceIndex[face0]:FaceIndex[flip_face[edge1, face1]],
|
|
44
|
+
FaceIndex[flip_face[edge0, face0]]:FaceIndex[face1]})
|
|
45
|
+
glued_face = perm.image(face0)
|
|
46
|
+
_arrow_gluing_dict[edge0, face0, edge1, face1] = (perm, inv(perm), glued_face)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Another table to speed Arrow.opposite
|
|
50
|
+
|
|
51
|
+
_arrow_opposite_dict = {}
|
|
52
|
+
for edge, face in EdgeFacePairs:
|
|
53
|
+
tail = comp(face)
|
|
54
|
+
head = face & comp(edge)
|
|
55
|
+
new_face = comp(OppTail[(tail, head)])
|
|
56
|
+
new_edge = comp(edge)
|
|
57
|
+
_arrow_opposite_dict[edge, face] = (new_edge, new_face)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# Another table to speed Arrow.next
|
|
61
|
+
|
|
62
|
+
_arrow_next_dict = {}
|
|
63
|
+
for edge, face in EdgeFacePairs:
|
|
64
|
+
for perm in Perm4.S4():
|
|
65
|
+
new_edge = perm.image(edge)
|
|
66
|
+
new_face = flip_face[new_edge, perm.image(face)]
|
|
67
|
+
_arrow_next_dict[perm._index, edge, face] = (new_edge, new_face)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class Arrow:
|
|
71
|
+
|
|
72
|
+
def __init__(self, edge, face, tet):
|
|
73
|
+
self.Edge = edge
|
|
74
|
+
self.Face = face
|
|
75
|
+
self.Tetrahedron = tet
|
|
76
|
+
|
|
77
|
+
def __repr__(self):
|
|
78
|
+
return ('< '+SubsimplexName[self.Edge]+' | ' +
|
|
79
|
+
SubsimplexName[self.Face]+' | '+str(self.Tetrahedron)+' >')
|
|
80
|
+
|
|
81
|
+
def head(self):
|
|
82
|
+
return self.Face & comp(self.Edge)
|
|
83
|
+
|
|
84
|
+
def tail(self):
|
|
85
|
+
return comp(self.Face)
|
|
86
|
+
|
|
87
|
+
# Here are the six edges of the tetrahedron, as seen from the
|
|
88
|
+
# point of view of the arrow.
|
|
89
|
+
def equator(self):
|
|
90
|
+
return self.Tetrahedron.Class[comp(self.Edge)]
|
|
91
|
+
|
|
92
|
+
def axis(self):
|
|
93
|
+
return self.Tetrahedron.Class[self.Edge]
|
|
94
|
+
|
|
95
|
+
def north_head(self):
|
|
96
|
+
return self.Tetrahedron.Class[self.head() | OppTail[self.head(),self.tail()]]
|
|
97
|
+
|
|
98
|
+
def south_head(self):
|
|
99
|
+
return self.Tetrahedron.Class[self.head() | OppTail[self.tail(),self.head()]]
|
|
100
|
+
|
|
101
|
+
def north_tail(self):
|
|
102
|
+
return self.Tetrahedron.Class[self.tail() | OppTail[self.head(),self.tail()]]
|
|
103
|
+
|
|
104
|
+
def south_tail(self):
|
|
105
|
+
return self.Tetrahedron.Class[self.tail() | OppTail[self.tail(),self.head()]]
|
|
106
|
+
|
|
107
|
+
def is_null(self):
|
|
108
|
+
return 1 if self.Tetrahedron is None else 0
|
|
109
|
+
|
|
110
|
+
def face_class(self):
|
|
111
|
+
return self.Tetrahedron.Class[self.Face]
|
|
112
|
+
|
|
113
|
+
# Does NOT create a new arrow.
|
|
114
|
+
def reverse(self):
|
|
115
|
+
self.Face = flip_face[self.Edge, self.Face]
|
|
116
|
+
return self
|
|
117
|
+
|
|
118
|
+
# By successive applications of self.next() you can walk around an edge.
|
|
119
|
+
# The sequence of 1-subsimplices self.Edge are all equivalent.
|
|
120
|
+
# The sequence of 2-subsimplices self.Face are the faces adjacent to the edge.
|
|
121
|
+
# When you hit the boundary, self.next() returns None without changing self.
|
|
122
|
+
# Does NOT create a new arrow.
|
|
123
|
+
def next(self):
|
|
124
|
+
if self.Tetrahedron is not None:
|
|
125
|
+
perm = self.Tetrahedron.Gluing[self.Face]
|
|
126
|
+
tet = self.Tetrahedron.Neighbor[self.Face]
|
|
127
|
+
if tet is None:
|
|
128
|
+
return None
|
|
129
|
+
|
|
130
|
+
# Next line equivalent to:
|
|
131
|
+
# self.Edge = perm.image(self.Edge)
|
|
132
|
+
# self.Face = flip_face[self.Edge, perm.image(self.Face)]
|
|
133
|
+
self.Edge, self.Face = _arrow_next_dict[perm._index, self.Edge, self.Face]
|
|
134
|
+
self.Tetrahedron = tet
|
|
135
|
+
return self
|
|
136
|
+
|
|
137
|
+
# Glues two faces together so that other becomes self.next().
|
|
138
|
+
# Returns None
|
|
139
|
+
def glue(self, other):
|
|
140
|
+
if self.Tetrahedron is None and other.Tetrahedron is None:
|
|
141
|
+
return
|
|
142
|
+
if self.Tetrahedron is None:
|
|
143
|
+
other.reverse().glue(self)
|
|
144
|
+
other.reverse()
|
|
145
|
+
return
|
|
146
|
+
if other.Tetrahedron is None:
|
|
147
|
+
self.Tetrahedron.attach(self.Face, None, (0,1,2,3))
|
|
148
|
+
return
|
|
149
|
+
# We do this manually for speed. The below code is equivalent to
|
|
150
|
+
#
|
|
151
|
+
# self.Tetrahedron.attach(self.Face, other.Tetrahedron,
|
|
152
|
+
# { FaceIndex[self.Face]:FaceIndex[flip_face(other.Edge,other.Face)],
|
|
153
|
+
# FaceIndex[flip_face(self.Edge,self.Face)]:FaceIndex[other.Face] })
|
|
154
|
+
tet0, face0, edge0 = self.Tetrahedron, self.Face, self.Edge
|
|
155
|
+
tet1, face1, edge1 = other.Tetrahedron, other.Face, other.Edge
|
|
156
|
+
perm, inv_perm, glued_face = _arrow_gluing_dict[edge0, face0, edge1, face1]
|
|
157
|
+
tet0.Neighbor[face0] = tet1
|
|
158
|
+
tet0.Gluing[face0] = perm
|
|
159
|
+
tet1.Neighbor[glued_face] = tet0
|
|
160
|
+
tet1.Gluing[glued_face] = inv_perm
|
|
161
|
+
|
|
162
|
+
# Returns a COPY of self.next(), or a null arrow in the case of a boundary
|
|
163
|
+
# face.
|
|
164
|
+
# DOES create a new arrow.
|
|
165
|
+
def glued(self):
|
|
166
|
+
a = self.copy()
|
|
167
|
+
if a.next() is None:
|
|
168
|
+
a.Tetrahedron = None
|
|
169
|
+
return a
|
|
170
|
+
|
|
171
|
+
# Changes the arrow into its opposite.
|
|
172
|
+
# Does NOT create a new arrow.
|
|
173
|
+
def opposite(self):
|
|
174
|
+
# Equivalent to
|
|
175
|
+
# self.Face = comp(OppTail[(self.tail(),self.head())])
|
|
176
|
+
# self.Edge = comp(self.Edge)
|
|
177
|
+
self.Edge, self.Face = _arrow_opposite_dict[self.Edge, self.Face]
|
|
178
|
+
return self
|
|
179
|
+
|
|
180
|
+
# Rotate arrow n/3 turns clockwise about self.head()
|
|
181
|
+
# Does NOT create a new arrow
|
|
182
|
+
def rotate(self, n):
|
|
183
|
+
for i in range(n % 3):
|
|
184
|
+
head = self.head()
|
|
185
|
+
tail = self.tail()
|
|
186
|
+
self.Edge = tail | OppTail[(tail, head)]
|
|
187
|
+
self.Face = self.Edge | head
|
|
188
|
+
return self
|
|
189
|
+
|
|
190
|
+
# DOES create a new arrow.
|
|
191
|
+
def copy(self):
|
|
192
|
+
return Arrow(self.Edge, self.Face, self.Tetrahedron)
|
|
193
|
+
|
|
194
|
+
# Two arrows are equal if their attributes are equal. The
|
|
195
|
+
# null arrows must be handled separately. This also allows
|
|
196
|
+
# comparison with None.
|
|
197
|
+
def __eq__(self, other):
|
|
198
|
+
if other is None:
|
|
199
|
+
return False
|
|
200
|
+
if self.Tetrahedron is None and other.Tetrahedron is None:
|
|
201
|
+
return True
|
|
202
|
+
return (self.Tetrahedron == other.Tetrahedron and
|
|
203
|
+
self.Edge == other.Edge and
|
|
204
|
+
self.Face == other.Face)
|
|
205
|
+
|
|
206
|
+
def __ne__(self, other):
|
|
207
|
+
return not self.__eq__(other)
|
|
208
|
+
|
|
209
|
+
# The arrows associated to a given edge e form a cycle of edges linking
|
|
210
|
+
# e. This function returns a list of the edges in that linking cycle.
|
|
211
|
+
def linking_cycle(self):
|
|
212
|
+
a = self.copy()
|
|
213
|
+
cycle = []
|
|
214
|
+
while 1:
|
|
215
|
+
cycle.append(a.Tetrahedron.Class[OppositeEdge[a.Edge]])
|
|
216
|
+
a.next()
|
|
217
|
+
if a == self:
|
|
218
|
+
break
|
|
219
|
+
return cycle
|
|
220
|
+
|
|
221
|
+
# This function returns a list of those edges that are adjacent to the
|
|
222
|
+
# edge associated to the arrow, and meet it at its tail.
|
|
223
|
+
def radii(self):
|
|
224
|
+
a = self.copy()
|
|
225
|
+
radius_list = []
|
|
226
|
+
while 1:
|
|
227
|
+
a.rotate(2)
|
|
228
|
+
radius_list.append(a.Tetrahedron.Class[OppositeEdge[a.Edge]])
|
|
229
|
+
a.rotate(1).next()
|
|
230
|
+
if a == self:
|
|
231
|
+
break
|
|
232
|
+
return radius_list
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
# This class allows one to initialize an arrow by specifying the head and
|
|
236
|
+
# tail vertices of the directed edge.
|
|
237
|
+
#
|
|
238
|
+
class eArrow(Arrow):
|
|
239
|
+
|
|
240
|
+
def __init__(self, tet, tail, head):
|
|
241
|
+
self.Edge = comp( tail | head )
|
|
242
|
+
self.Face = comp( tail )
|
|
243
|
+
self.Tetrahedron = tet
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# $Id: corner.py,v 1.2 2002/09/20 03:52:16 culler Exp $
|
|
2
|
+
# t3m - software for studying triangulated 3-manifolds
|
|
3
|
+
# Copyright (C) 2002 Marc Culler, Nathan Dunfield and others
|
|
4
|
+
#
|
|
5
|
+
# This program is distributed under the terms of the
|
|
6
|
+
# GNU General Public License, version 2 or later, as published by
|
|
7
|
+
# the Free Software Foundation. See the file GPL.txt for details.
|
|
8
|
+
|
|
9
|
+
from .simplex import SubsimplexName
|
|
10
|
+
|
|
11
|
+
# A Corner is a "subsimplex in a tetrahedron".
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Corner:
|
|
15
|
+
|
|
16
|
+
def __init__(self, tetrahedron, subsimplex):
|
|
17
|
+
self.Tetrahedron = tetrahedron
|
|
18
|
+
self.Subsimplex = subsimplex
|
|
19
|
+
|
|
20
|
+
def __repr__(self):
|
|
21
|
+
return ('<'+SubsimplexName[self.Subsimplex] + ' of ' +
|
|
22
|
+
str(self.Tetrahedron) + '>')
|