passagemath-groups 10.6.45__cp314-cp314-macosx_13_0_arm64.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.
- passagemath_groups/.dylibs/libgap.10.dylib +0 -0
- passagemath_groups/.dylibs/libgmp.10.dylib +0 -0
- passagemath_groups/.dylibs/libreadline.8.2.dylib +0 -0
- passagemath_groups/.dylibs/libz.1.3.1.dylib +0 -0
- passagemath_groups/__init__.py +3 -0
- passagemath_groups-10.6.45.dist-info/METADATA +113 -0
- passagemath_groups-10.6.45.dist-info/RECORD +40 -0
- passagemath_groups-10.6.45.dist-info/WHEEL +6 -0
- passagemath_groups-10.6.45.dist-info/top_level.txt +3 -0
- sage/all__sagemath_groups.py +21 -0
- sage/geometry/all__sagemath_groups.py +1 -0
- sage/geometry/palp_normal_form.cpython-314-darwin.so +0 -0
- sage/geometry/palp_normal_form.pyx +401 -0
- sage/groups/abelian_gps/all.py +25 -0
- sage/groups/all.py +5 -0
- sage/groups/all__sagemath_groups.py +32 -0
- sage/groups/artin.py +1074 -0
- sage/groups/braid.py +3806 -0
- sage/groups/cactus_group.py +1001 -0
- sage/groups/cubic_braid.py +2052 -0
- sage/groups/finitely_presented.py +1896 -0
- sage/groups/finitely_presented_catalog.py +27 -0
- sage/groups/finitely_presented_named.py +592 -0
- sage/groups/fqf_orthogonal.py +579 -0
- sage/groups/free_group.py +944 -0
- sage/groups/group_exp.py +360 -0
- sage/groups/group_semidirect_product.py +504 -0
- sage/groups/kernel_subgroup.py +231 -0
- sage/groups/lie_gps/all.py +1 -0
- sage/groups/lie_gps/catalog.py +8 -0
- sage/groups/lie_gps/nilpotent_lie_group.py +945 -0
- sage/groups/misc_gps/all.py +1 -0
- sage/groups/misc_gps/misc_groups.py +11 -0
- sage/groups/misc_gps/misc_groups_catalog.py +33 -0
- sage/groups/raag.py +866 -0
- sage/groups/semimonomial_transformations/all.py +1 -0
- sage/groups/semimonomial_transformations/semimonomial_transformation.cpython-314-darwin.so +0 -0
- sage/groups/semimonomial_transformations/semimonomial_transformation.pxd +9 -0
- sage/groups/semimonomial_transformations/semimonomial_transformation.pyx +346 -0
- sage/groups/semimonomial_transformations/semimonomial_transformation_group.py +512 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: passagemath-groups
|
|
3
|
+
Version: 10.6.45
|
|
4
|
+
Summary: passagemath: Groups and Invariant Theory
|
|
5
|
+
Author-email: The Sage Developers <sage-support@googlegroups.com>
|
|
6
|
+
Maintainer: Matthias Köppe, passagemath contributors
|
|
7
|
+
License-Expression: GPL-2.0-or-later
|
|
8
|
+
Project-URL: release notes, https://github.com/passagemath/passagemath/releases
|
|
9
|
+
Project-URL: repo (upstream), https://github.com/sagemath/sage
|
|
10
|
+
Project-URL: repo, https://github.com/passagemath/passagemath
|
|
11
|
+
Project-URL: documentation, https://passagemath.org/docs/latest
|
|
12
|
+
Project-URL: homepage (upstream), https://www.sagemath.org
|
|
13
|
+
Project-URL: discourse, https://passagemath.discourse.group
|
|
14
|
+
Project-URL: tracker (upstream), https://github.com/sagemath/sage/issues
|
|
15
|
+
Project-URL: tracker, https://github.com/passagemath/passagemath/issues
|
|
16
|
+
Classifier: Development Status :: 6 - Mature
|
|
17
|
+
Classifier: Intended Audience :: Education
|
|
18
|
+
Classifier: Intended Audience :: Science/Research
|
|
19
|
+
Classifier: Operating System :: POSIX
|
|
20
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
21
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
22
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
28
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
29
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
30
|
+
Requires-Python: <3.15,>=3.10
|
|
31
|
+
Description-Content-Type: text/x-rst
|
|
32
|
+
Requires-Dist: passagemath-categories~=10.6.45.0
|
|
33
|
+
Requires-Dist: passagemath-gap~=10.6.45.0
|
|
34
|
+
Requires-Dist: passagemath-modules~=10.6.45.0
|
|
35
|
+
Provides-Extra: test
|
|
36
|
+
Requires-Dist: passagemath-repl; extra == "test"
|
|
37
|
+
Provides-Extra: coxeter3
|
|
38
|
+
Requires-Dist: passagemath-coxeter3; extra == "coxeter3"
|
|
39
|
+
Provides-Extra: gap
|
|
40
|
+
Provides-Extra: additive
|
|
41
|
+
Provides-Extra: affine
|
|
42
|
+
Provides-Extra: lie
|
|
43
|
+
Provides-Extra: matrix
|
|
44
|
+
Provides-Extra: permutation
|
|
45
|
+
Provides-Extra: presentation
|
|
46
|
+
Provides-Extra: representations
|
|
47
|
+
Requires-Dist: passagemath-combinat; extra == "representations"
|
|
48
|
+
Provides-Extra: semigroups
|
|
49
|
+
Requires-Dist: passagemath-combinat; extra == "semigroups"
|
|
50
|
+
Provides-Extra: standard
|
|
51
|
+
Requires-Dist: passagemath-groups[additive,matrix,representations,semigroups]; extra == "standard"
|
|
52
|
+
|
|
53
|
+
=====================================================================
|
|
54
|
+
passagemath: Groups and Invariant Theory
|
|
55
|
+
=====================================================================
|
|
56
|
+
|
|
57
|
+
`passagemath <https://github.com/passagemath/passagemath>`__ is open
|
|
58
|
+
source mathematical software in Python, released under the GNU General
|
|
59
|
+
Public Licence GPLv2+.
|
|
60
|
+
|
|
61
|
+
It is a fork of `SageMath <https://www.sagemath.org/>`__, which has been
|
|
62
|
+
developed 2005-2025 under the motto “Creating a Viable Open Source
|
|
63
|
+
Alternative to Magma, Maple, Mathematica, and MATLAB”.
|
|
64
|
+
|
|
65
|
+
The passagemath fork uses the motto "Creating a Free Passage Between the
|
|
66
|
+
Scientific Python Ecosystem and Mathematical Software Communities."
|
|
67
|
+
It was created in October 2024 with the following goals:
|
|
68
|
+
|
|
69
|
+
- providing modularized installation with pip,
|
|
70
|
+
- establishing first-class membership in the scientific Python
|
|
71
|
+
ecosystem,
|
|
72
|
+
- giving `clear attribution of upstream
|
|
73
|
+
projects <https://groups.google.com/g/sage-devel/c/6HO1HEtL1Fs/m/G002rPGpAAAJ>`__,
|
|
74
|
+
- providing independently usable Python interfaces to upstream
|
|
75
|
+
libraries,
|
|
76
|
+
- offering `platform portability and integration testing
|
|
77
|
+
services <https://github.com/passagemath/passagemath/issues/704>`__
|
|
78
|
+
to upstream projects,
|
|
79
|
+
- inviting collaborations with upstream projects,
|
|
80
|
+
- `building a professional, respectful, inclusive
|
|
81
|
+
community <https://groups.google.com/g/sage-devel/c/xBzaINHWwUQ>`__,
|
|
82
|
+
- `empowering Sage users to participate in the scientific Python ecosystem
|
|
83
|
+
<https://github.com/passagemath/passagemath/issues/248>`__ by publishing packages,
|
|
84
|
+
- developing a port to `Pyodide <https://pyodide.org/en/stable/>`__ for
|
|
85
|
+
serverless deployment with Javascript,
|
|
86
|
+
- developing a native Windows port.
|
|
87
|
+
|
|
88
|
+
`Full documentation <https://passagemath.org/docs/latest/html/en/index.html>`__ is
|
|
89
|
+
available online.
|
|
90
|
+
|
|
91
|
+
passagemath attempts to support and provides binary wheels suitable for
|
|
92
|
+
all major Linux distributions and recent versions of macOS.
|
|
93
|
+
|
|
94
|
+
Binary wheels for native Windows (x86_64) are are available for a subset of
|
|
95
|
+
the passagemath distributions. Use of the full functionality of passagemath
|
|
96
|
+
on Windows currently requires the use of Windows Subsystem for Linux (WSL)
|
|
97
|
+
or virtualization.
|
|
98
|
+
|
|
99
|
+
The supported Python versions in the passagemath 10.6.x series are 3.10.x-3.14.x.
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
About this pip-installable distribution package
|
|
103
|
+
-----------------------------------------------
|
|
104
|
+
|
|
105
|
+
This pip-installable package ``passagemath-groups`` a distribution of a part of the Sage Library. It provides a small subset of the modules of the Sage library ("sagelib", ``passagemath-standard``) for computations with groups.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
What is included
|
|
109
|
+
----------------
|
|
110
|
+
|
|
111
|
+
* `Groups <https://passagemath.org/docs/latest/html/en/reference/groups/index.html>`_
|
|
112
|
+
|
|
113
|
+
* see https://github.com/passagemath/passagemath/blob/main/pkgs/sagemath-groups/MANIFEST.in
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
passagemath_groups/__init__.py,sha256=5UZ7CmaoJ-o6uzVDPDwTWpJ_EciPneedoip6lmUDqGw,86
|
|
2
|
+
passagemath_groups/.dylibs/libreadline.8.2.dylib,sha256=oLjNdTQR_N5PDS6c2WerKvqEIlN0hKMKR2-5mzbhBbw,298136
|
|
3
|
+
passagemath_groups/.dylibs/libz.1.3.1.dylib,sha256=htZ7pcm2d0F-f27a2iBxdfsizce4BO1n9c1CCN--bIM,119008
|
|
4
|
+
passagemath_groups/.dylibs/libgap.10.dylib,sha256=vHOrEqH2jIkB51MjHgsjSf58pa-KrhPv94HapFToVgg,2474368
|
|
5
|
+
passagemath_groups/.dylibs/libgmp.10.dylib,sha256=pnapXfr84Tlt7j4SDSGfqzzuIEGe5xLWUaKFZNxqkJA,446592
|
|
6
|
+
passagemath_groups-10.6.45.dist-info/RECORD,,
|
|
7
|
+
passagemath_groups-10.6.45.dist-info/WHEEL,sha256=3XbQBqanlgszXxeTyPSvYjuhSUOgjmWM5CtfEUkpneA,153
|
|
8
|
+
passagemath_groups-10.6.45.dist-info/top_level.txt,sha256=ys0qYvxqpJEW3rVwKsO59n9kNFe6uNUAiVduBEf6o7Y,25
|
|
9
|
+
passagemath_groups-10.6.45.dist-info/METADATA,sha256=Vp74oTeAsZnd1KU_lnTOQQ3XBOUO4AATJafSFxVXAfU,5177
|
|
10
|
+
sage/all__sagemath_groups.py,sha256=JOSY5oJmS67eaWpSs14SBcD7be6NMKH05esJQj8sNOI,525
|
|
11
|
+
sage/groups/finitely_presented.py,sha256=hLccjNjrj880fFeiLu9W7Z7Xz1HewuyJTVKNWrUsVMI,70042
|
|
12
|
+
sage/groups/fqf_orthogonal.py,sha256=8cx71JJorwsFoSPzVLBg1rI_dA9dfGeWDqA6GAuqRh8,20181
|
|
13
|
+
sage/groups/free_group.py,sha256=iMxfq5y8gA91i7XdpCmlL2N-5s2h_oYYohITmhMpVXo,29468
|
|
14
|
+
sage/groups/all__sagemath_groups.py,sha256=g4HxEDA-YDJcTYHqA5pGLBIy7gpzg-BEVb2Jn7mTJD8,1147
|
|
15
|
+
sage/groups/artin.py,sha256=CQHII1jKlBJZ_3GEyH-D22lS06prmIYcagTE7eg_RKc,41353
|
|
16
|
+
sage/groups/finitely_presented_named.py,sha256=dKB2M78fw5W7RTHCGy-VB_X9co9UbFcQQYSdBr945Rc,20597
|
|
17
|
+
sage/groups/all.py,sha256=ia6P1nJW_QxBEPMNKdT6ZE8v7J0z8qlMbX2uD3lBJU8,229
|
|
18
|
+
sage/groups/raag.py,sha256=WbkPRhwCopLc2PtJ_Zcy_QASzsHcsp84_fM1x_dUcWw,28842
|
|
19
|
+
sage/groups/cubic_braid.py,sha256=LEStrE9YiJAb5acsybhoQhth5fh-wbtn7uLjYyLoO1o,86974
|
|
20
|
+
sage/groups/group_semidirect_product.py,sha256=7XqgwRR8i-KAWQdRXE8uoNbYDG-mDTqFw2uyqhDGCwY,17910
|
|
21
|
+
sage/groups/cactus_group.py,sha256=O0FTBvGw8y3nRSR1aGPn5FdEv3jILG7QK_g_lZYdLPc,32895
|
|
22
|
+
sage/groups/braid.py,sha256=6LyEbj9KCOyR7v1HhHWYyd62XqGSHcIOQVQF_TuWCXk,140495
|
|
23
|
+
sage/groups/finitely_presented_catalog.py,sha256=Ylc_cx0Sv6eKH9J-n4xotqWK0Hc4pNrwZ3iRPe-gh1s,1251
|
|
24
|
+
sage/groups/group_exp.py,sha256=KjhnaTnqnNKvBmYZJEbUge2-RydGSkued1JFXSLzeoo,11190
|
|
25
|
+
sage/groups/kernel_subgroup.py,sha256=hZVsh5UYfq6MPxekXwlRuQyPuHq0Fk6SlNnN-5Yja6A,7706
|
|
26
|
+
sage/groups/lie_gps/catalog.py,sha256=O5ub0bmV3z8tvJEFjxhgjIz4Zff8rJksOe5VQp0py0o,363
|
|
27
|
+
sage/groups/lie_gps/all.py,sha256=-vXQHOTG46Zum7Q6k0kcJO43yJo09AIX-El8fzXA7eI,45
|
|
28
|
+
sage/groups/lie_gps/nilpotent_lie_group.py,sha256=6VEgyU0U4ERif179dC1JWBdxO1PM6ZJ4d7Rc7dLkZmY,32506
|
|
29
|
+
sage/groups/misc_gps/misc_groups.py,sha256=W2eH0XFqltL2-g7suj4vS8-klTYW4bTFmoWJ6ciR0-s,346
|
|
30
|
+
sage/groups/misc_gps/all.py,sha256=-vXQHOTG46Zum7Q6k0kcJO43yJo09AIX-El8fzXA7eI,45
|
|
31
|
+
sage/groups/misc_gps/misc_groups_catalog.py,sha256=TbpMPXGhwFpeOMlXdwdIGItBLV0XSvfN4oQRbKbMK9o,1627
|
|
32
|
+
sage/groups/abelian_gps/all.py,sha256=yQQEiBWy_vtucLyFb_q1OIqgiC_DIE9KUzNWpdGTa4A,906
|
|
33
|
+
sage/groups/semimonomial_transformations/semimonomial_transformation.pyx,sha256=9j9eS_uZYdCUQrTJDs4VhpO_7SeSzXdnzh0cACFNtkk,11298
|
|
34
|
+
sage/groups/semimonomial_transformations/all.py,sha256=-vXQHOTG46Zum7Q6k0kcJO43yJo09AIX-El8fzXA7eI,45
|
|
35
|
+
sage/groups/semimonomial_transformations/semimonomial_transformation_group.py,sha256=QflEYRK_oDUf8axx4kwcUR4aMOQNmE_faY1lzOdrAvQ,18312
|
|
36
|
+
sage/groups/semimonomial_transformations/semimonomial_transformation.pxd,sha256=wivg7LyXn_ZMrADRUmabPEYNitTRZCvs2htLN3E0v9g,297
|
|
37
|
+
sage/groups/semimonomial_transformations/semimonomial_transformation.cpython-314-darwin.so,sha256=FO_oCcCc0t7HkVlpnuvncX8SDKK4RbANOrni8XZIoWU,151280
|
|
38
|
+
sage/geometry/all__sagemath_groups.py,sha256=-vXQHOTG46Zum7Q6k0kcJO43yJo09AIX-El8fzXA7eI,45
|
|
39
|
+
sage/geometry/palp_normal_form.pyx,sha256=HfDpZHxffoxG2pxTrXO0ucRlEDZcrtzHBoZ0CoHm5lI,17498
|
|
40
|
+
sage/geometry/palp_normal_form.cpython-314-darwin.so,sha256=TtWcy0Hb_OjQ5WJi3cmKx6Myz5zWlcbGrweCOGLcKo4,201256
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-groups
|
|
2
|
+
# delvewheel: patch
|
|
3
|
+
r"""
|
|
4
|
+
Top level of the distribution package sagemath-groups
|
|
5
|
+
|
|
6
|
+
This distribution makes the following feature available::
|
|
7
|
+
|
|
8
|
+
sage: from sage.features.sagemath import *
|
|
9
|
+
sage: sage__groups().is_present()
|
|
10
|
+
FeatureTestResult('sage.groups', True)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from .all__sagemath_gap import *
|
|
14
|
+
from .all__sagemath_modules import *
|
|
15
|
+
|
|
16
|
+
try: # extra
|
|
17
|
+
from sage.all__sagemath_combinat import *
|
|
18
|
+
except ImportError:
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
from sage.groups.all__sagemath_groups import *
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-groups
|
|
Binary file
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-groups
|
|
2
|
+
# sage.doctest: needs sage.geometry.polyhedron sage.groups
|
|
3
|
+
r"""
|
|
4
|
+
PALP normal form of vertices of a lattice polytope
|
|
5
|
+
"""
|
|
6
|
+
# ****************************************************************************
|
|
7
|
+
# Copyright (C) 2013 Jan Keitel
|
|
8
|
+
# 2014 Volker Braun
|
|
9
|
+
# 2018 Christian Stump
|
|
10
|
+
# 2019 Vincent Delecroix
|
|
11
|
+
# 2019 Jonathan Kliem
|
|
12
|
+
# 2021 Michael Orlitzky
|
|
13
|
+
# 2018-2022 Frédéric Chapoton
|
|
14
|
+
# 2023 Luze Xu
|
|
15
|
+
# 2023 Matthias Koeppe
|
|
16
|
+
#
|
|
17
|
+
# This program is free software: you can redistribute it and/or modify
|
|
18
|
+
# it under the terms of the GNU General Public License as published by
|
|
19
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
20
|
+
# (at your option) any later version.
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
# ****************************************************************************
|
|
23
|
+
|
|
24
|
+
from sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement
|
|
25
|
+
from sage.groups.perm_gps.permgroup_named import SymmetricGroup
|
|
26
|
+
from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
|
|
27
|
+
from sage.matrix.special import column_matrix
|
|
28
|
+
from sage.structure.element import Matrix
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _palp_PM_max(Matrix_integer_dense PM, check=False):
|
|
32
|
+
r"""
|
|
33
|
+
Compute the permutation normal form of the vertex facet pairing matrix.
|
|
34
|
+
|
|
35
|
+
The permutation normal form of a matrix is defined as the lexicographic
|
|
36
|
+
maximum under all permutations of its rows and columns. For more
|
|
37
|
+
more detail, see also
|
|
38
|
+
:meth:`~sage.matrix.matrix2.Matrix.permutation_normal_form`.
|
|
39
|
+
|
|
40
|
+
Instead of using the generic method for computing the permutation
|
|
41
|
+
normal form, this method uses the PALP algorithm to compute
|
|
42
|
+
the permutation normal form and its automorphisms concurrently.
|
|
43
|
+
|
|
44
|
+
INPUT:
|
|
45
|
+
|
|
46
|
+
- ``check`` -- boolean (default: ``False``); whether to return
|
|
47
|
+
the permutations leaving the maximal vertex-facet pairing
|
|
48
|
+
matrix invariant
|
|
49
|
+
|
|
50
|
+
OUTPUT:
|
|
51
|
+
|
|
52
|
+
A matrix or a tuple of a matrix and a dict whose values are the
|
|
53
|
+
permutation group elements corresponding to the permutations
|
|
54
|
+
that permute :meth:`vertices` such that the vertex-facet pairing
|
|
55
|
+
matrix is maximal.
|
|
56
|
+
|
|
57
|
+
EXAMPLES::
|
|
58
|
+
|
|
59
|
+
sage: o = lattice_polytope.cross_polytope(2)
|
|
60
|
+
sage: PM = o.vertex_facet_pairing_matrix()
|
|
61
|
+
sage: PM_max = PM.permutation_normal_form()
|
|
62
|
+
sage: PM_max == o._palp_PM_max()
|
|
63
|
+
True
|
|
64
|
+
|
|
65
|
+
sage: # needs polytopes_db
|
|
66
|
+
sage: P2 = ReflexivePolytope(2, 0)
|
|
67
|
+
sage: PM_max, permutations = P2._palp_PM_max(check=True)
|
|
68
|
+
sage: PM_max
|
|
69
|
+
[3 0 0]
|
|
70
|
+
[0 3 0]
|
|
71
|
+
[0 0 3]
|
|
72
|
+
sage: list(permutations.values())
|
|
73
|
+
[[(1,2,3), (1,2,3)],
|
|
74
|
+
[(1,3,2), (1,3,2)],
|
|
75
|
+
[(1,3), (1,3)],
|
|
76
|
+
[(1,2), (1,2)],
|
|
77
|
+
[(), ()],
|
|
78
|
+
[(2,3), (2,3)]]
|
|
79
|
+
sage: PM_max.automorphisms_of_rows_and_columns()
|
|
80
|
+
[((), ()),
|
|
81
|
+
((1,2,3), (1,2,3)),
|
|
82
|
+
((1,3,2), (1,3,2)),
|
|
83
|
+
((2,3), (2,3)),
|
|
84
|
+
((1,2), (1,2)),
|
|
85
|
+
((1,3), (1,3))]
|
|
86
|
+
sage: PMs = (i._palp_PM_max(check=True)
|
|
87
|
+
....: for i in ReflexivePolytopes(2))
|
|
88
|
+
sage: results = (len(i) == len(j.automorphisms_of_rows_and_columns())
|
|
89
|
+
....: for j, i in PMs)
|
|
90
|
+
sage: all(results) # long time
|
|
91
|
+
True
|
|
92
|
+
|
|
93
|
+
TESTS:
|
|
94
|
+
|
|
95
|
+
Check that a bug introduced in :issue:`35997` is fixed::
|
|
96
|
+
|
|
97
|
+
sage: from sage.geometry.palp_normal_form import _palp_PM_max, _palp_canonical_order
|
|
98
|
+
sage: P = Polyhedron([(-4,-6),(-4,-5),(0,0),(1,0),(5,6)])
|
|
99
|
+
sage: PM = P.slack_matrix().transpose()
|
|
100
|
+
sage: _palp_PM_max(PM)
|
|
101
|
+
[9 5 4 0 0]
|
|
102
|
+
[6 0 6 5 0]
|
|
103
|
+
[1 5 0 0 4]
|
|
104
|
+
[0 6 0 1 6]
|
|
105
|
+
[0 0 3 5 3]
|
|
106
|
+
sage: PM_max, permutations = _palp_PM_max(PM, check=True)
|
|
107
|
+
sage: _palp_canonical_order(P.vertices(), PM_max, permutations)
|
|
108
|
+
([(1, 0), (0, 0), (2, 4), (1, 5), (-1, 1)], (1,2,3))
|
|
109
|
+
"""
|
|
110
|
+
cdef int n_v = PM.ncols()
|
|
111
|
+
cdef int n_f = PM.nrows()
|
|
112
|
+
S_v = SymmetricGroup(n_v)
|
|
113
|
+
S_f = SymmetricGroup(n_f)
|
|
114
|
+
|
|
115
|
+
cdef int n_s = 1
|
|
116
|
+
cdef dict permutations = {0: [S_f.one(), S_v.one()]}
|
|
117
|
+
cdef int j, k, m, d
|
|
118
|
+
cdef int element, max_element
|
|
119
|
+
|
|
120
|
+
for j in range(n_v):
|
|
121
|
+
max_element = PM.get_unsafe_int(0, (<PermutationGroupElement> permutations[0][1])(j + 1) - 1)
|
|
122
|
+
m = 0
|
|
123
|
+
for i in range(j + 1, n_v):
|
|
124
|
+
element = PM.get_unsafe_int(0, (<PermutationGroupElement> permutations[0][1])(i + 1) - 1)
|
|
125
|
+
if element > max_element:
|
|
126
|
+
max_element = element
|
|
127
|
+
m = i - j
|
|
128
|
+
if m > 0:
|
|
129
|
+
permutations[0][1] = (<PermutationGroupElement> permutations[0][1])._transpose_left(j + 1, m + j + 1)
|
|
130
|
+
|
|
131
|
+
cdef first_row_index = 0
|
|
132
|
+
|
|
133
|
+
# Arrange other rows one by one and compare with first row
|
|
134
|
+
for k in range(1, n_f):
|
|
135
|
+
# Error for k == 1 already!
|
|
136
|
+
permutations[n_s] = [S_f.one(), S_v.one()]
|
|
137
|
+
max_element = PM.get_unsafe_int(k, (<PermutationGroupElement> permutations[n_s][1])(1) - 1)
|
|
138
|
+
m = 0
|
|
139
|
+
for j in range(1, n_v):
|
|
140
|
+
element = PM.get_unsafe_int(k, (<PermutationGroupElement> permutations[n_s][1])(j + 1) - 1)
|
|
141
|
+
if element > max_element:
|
|
142
|
+
max_element = element
|
|
143
|
+
m = j
|
|
144
|
+
if m > 0:
|
|
145
|
+
permutations[n_s][1] = (<PermutationGroupElement> permutations[n_s][1])._transpose_left(1, m + 1)
|
|
146
|
+
d = (PM.get_unsafe_int(k, (<PermutationGroupElement> permutations[n_s][1])(1) - 1)
|
|
147
|
+
- PM.get_unsafe_int(first_row_index, (<PermutationGroupElement> permutations[0][1])(1) - 1))
|
|
148
|
+
if d < 0:
|
|
149
|
+
# The largest elt of this row is smaller than largest elt
|
|
150
|
+
# in 1st row, so nothing to do
|
|
151
|
+
continue
|
|
152
|
+
# otherwise:
|
|
153
|
+
for i in range(1, n_v):
|
|
154
|
+
max_element = PM.get_unsafe_int(k, (<PermutationGroupElement> permutations[n_s][1])(i + 1) - 1)
|
|
155
|
+
m = i
|
|
156
|
+
for j in range(i + 1, n_v):
|
|
157
|
+
element = PM.get_unsafe_int(k, (<PermutationGroupElement> permutations[n_s][1])(j + 1) - 1)
|
|
158
|
+
if element > max_element:
|
|
159
|
+
max_element = element
|
|
160
|
+
m = j
|
|
161
|
+
if m > i:
|
|
162
|
+
permutations[n_s][1] = (<PermutationGroupElement> permutations[n_s][1])._transpose_left(i + 1, m + 1)
|
|
163
|
+
if d == 0:
|
|
164
|
+
d = (PM.get_unsafe_int(k, (<PermutationGroupElement> permutations[n_s][1])(i+1) - 1)
|
|
165
|
+
- PM.get_unsafe_int(first_row_index, (<PermutationGroupElement> permutations[0][1])(i + 1) - 1))
|
|
166
|
+
if d < 0:
|
|
167
|
+
break
|
|
168
|
+
if d < 0:
|
|
169
|
+
# This row is smaller than 1st row, so nothing to do
|
|
170
|
+
del permutations[n_s]
|
|
171
|
+
continue
|
|
172
|
+
permutations[n_s][0] = (<PermutationGroupElement> permutations[n_s][0])._transpose_left(1, k + 1)
|
|
173
|
+
if d == 0:
|
|
174
|
+
# This row is the same, so we have a symmetry!
|
|
175
|
+
n_s += 1
|
|
176
|
+
else:
|
|
177
|
+
# This row is larger, so it becomes the first row and
|
|
178
|
+
# the symmetries reset.
|
|
179
|
+
first_row_index = k
|
|
180
|
+
permutations = {0: permutations[n_s]}
|
|
181
|
+
n_s = 1
|
|
182
|
+
permutations = {k: permutations[k] for k in permutations if k < n_s}
|
|
183
|
+
|
|
184
|
+
cdef tuple b = tuple(PM.get_unsafe_int((<PermutationGroupElement> permutations[0][0])(1) - 1,
|
|
185
|
+
(<PermutationGroupElement> permutations[0][1])(j+1) - 1)
|
|
186
|
+
for j in range(n_v))
|
|
187
|
+
# Work out the restrictions the current permutations
|
|
188
|
+
# place on other permutations as a automorphisms
|
|
189
|
+
# of the first row
|
|
190
|
+
# The array is such that:
|
|
191
|
+
# S = [i, 1, ..., 1 (ith), j, i+1, ..., i+1 (jth), k ... ]
|
|
192
|
+
# describes the "symmetry blocks"
|
|
193
|
+
cdef list S = list(range(1, n_v + 1))
|
|
194
|
+
for i in range(1, n_v):
|
|
195
|
+
if b[i-1] == b[i]:
|
|
196
|
+
S[i] = S[i-1]
|
|
197
|
+
S[S[i]-1] += 1
|
|
198
|
+
else:
|
|
199
|
+
S[i] = i + 1
|
|
200
|
+
|
|
201
|
+
cdef int l, cf, ccf, n_s_bar, d1, v0, vc, vj
|
|
202
|
+
cdef list l_r
|
|
203
|
+
|
|
204
|
+
# We determine the other rows of PM_max in turn by use of perms and
|
|
205
|
+
# aut on previous rows.
|
|
206
|
+
for l in range(1, n_f - 1):
|
|
207
|
+
n_s = len(permutations)
|
|
208
|
+
n_s_bar = n_s
|
|
209
|
+
cf = 0
|
|
210
|
+
l_r = [0]*n_v
|
|
211
|
+
# Search for possible local permutations based off previous
|
|
212
|
+
# global permutations.
|
|
213
|
+
for k in range(n_s_bar - 1, -1, -1):
|
|
214
|
+
# number of local permutations associated with current global
|
|
215
|
+
n_p = 0
|
|
216
|
+
ccf = cf
|
|
217
|
+
permutations_bar = {0: list(permutations[k])}
|
|
218
|
+
# We look for the line with the maximal entry in the first
|
|
219
|
+
# subsymmetry block, i.e. we are allowed to swap elements
|
|
220
|
+
# between 0 and S(0)
|
|
221
|
+
for s in range(l, n_f):
|
|
222
|
+
for j in range(1, S[0]):
|
|
223
|
+
v0 = PM.get_unsafe_int((<PermutationGroupElement> permutations_bar[n_p][0])(s+1) - 1,
|
|
224
|
+
(<PermutationGroupElement> permutations_bar[n_p][1])(1) - 1)
|
|
225
|
+
vj = PM.get_unsafe_int((<PermutationGroupElement> permutations_bar[n_p][0])(s+1) - 1,
|
|
226
|
+
(<PermutationGroupElement> permutations_bar[n_p][1])(j+1) - 1)
|
|
227
|
+
if v0 < vj:
|
|
228
|
+
permutations_bar[n_p][1] = (<PermutationGroupElement> permutations_bar[n_p][1])._transpose_left(1, j + 1)
|
|
229
|
+
if ccf == 0:
|
|
230
|
+
l_r[0] = PM.get_unsafe_int((<PermutationGroupElement> permutations_bar[n_p][0])(s+1) - 1,
|
|
231
|
+
(<PermutationGroupElement> permutations_bar[n_p][1])(1) - 1)
|
|
232
|
+
if s != l:
|
|
233
|
+
permutations_bar[n_p][0] = (<PermutationGroupElement> permutations_bar[n_p][0])._transpose_left(l + 1, s + 1)
|
|
234
|
+
n_p += 1
|
|
235
|
+
ccf = 1
|
|
236
|
+
permutations_bar[n_p] = list(permutations[k])
|
|
237
|
+
else:
|
|
238
|
+
d1 = PM.get_unsafe_int((<PermutationGroupElement> permutations_bar[n_p][0])(s+1) - 1,
|
|
239
|
+
(<PermutationGroupElement> permutations_bar[n_p][1])(1) - 1)
|
|
240
|
+
d = d1 - l_r[0]
|
|
241
|
+
if d < 0:
|
|
242
|
+
# We move to the next line
|
|
243
|
+
continue
|
|
244
|
+
elif d==0:
|
|
245
|
+
# Maximal values agree, so possible symmetry
|
|
246
|
+
if s != l:
|
|
247
|
+
permutations_bar[n_p][0] = (<PermutationGroupElement> permutations_bar[n_p][0])._transpose_left(l + 1, s + 1)
|
|
248
|
+
n_p += 1
|
|
249
|
+
permutations_bar[n_p] = list(permutations[k])
|
|
250
|
+
else:
|
|
251
|
+
# We found a greater maximal value for first entry.
|
|
252
|
+
# It becomes our new reference:
|
|
253
|
+
l_r[0] = d1
|
|
254
|
+
if s != l:
|
|
255
|
+
permutations_bar[n_p][0] = (<PermutationGroupElement> permutations_bar[n_p][0])._transpose_left(l + 1, s + 1)
|
|
256
|
+
# Forget previous work done
|
|
257
|
+
cf = 0
|
|
258
|
+
permutations_bar = {0: list(permutations_bar[n_p])}
|
|
259
|
+
n_p = 1
|
|
260
|
+
permutations_bar[n_p] = list(permutations[k])
|
|
261
|
+
n_s = k + 1
|
|
262
|
+
# Check if the permutations found just now work
|
|
263
|
+
# with other elements
|
|
264
|
+
for c in range(1, n_v):
|
|
265
|
+
h = S[c]
|
|
266
|
+
ccf = cf
|
|
267
|
+
# Now let us find out where the end of the
|
|
268
|
+
# next symmetry block is:
|
|
269
|
+
if h < c + 1:
|
|
270
|
+
h = S[h - 1]
|
|
271
|
+
s = n_p
|
|
272
|
+
# Check through this block for each possible permutation
|
|
273
|
+
while s > 0:
|
|
274
|
+
s -= 1
|
|
275
|
+
# Find the largest value in this symmetry block
|
|
276
|
+
for j in range(c + 1, h):
|
|
277
|
+
vc = PM.get_unsafe_int((<PermutationGroupElement> permutations_bar[s][0])(l+1) - 1,
|
|
278
|
+
(<PermutationGroupElement> permutations_bar[s][1])(c+1) - 1)
|
|
279
|
+
vj = PM.get_unsafe_int((<PermutationGroupElement> permutations_bar[s][0])(l+1) - 1,
|
|
280
|
+
(<PermutationGroupElement> permutations_bar[s][1])(j+1) - 1)
|
|
281
|
+
if vc < vj:
|
|
282
|
+
permutations_bar[s][1] = (<PermutationGroupElement> permutations_bar[s][1])._transpose_left(c + 1, j + 1)
|
|
283
|
+
if ccf == 0:
|
|
284
|
+
# Set reference and carry on to next permutation
|
|
285
|
+
l_r[c] = PM.get_unsafe_int((<PermutationGroupElement> permutations_bar[s][0])(l+1) - 1,
|
|
286
|
+
(<PermutationGroupElement> permutations_bar[s][1])(c+1) - 1)
|
|
287
|
+
ccf = 1
|
|
288
|
+
else:
|
|
289
|
+
d1 = PM.get_unsafe_int((<PermutationGroupElement> permutations_bar[s][0])(l+1) - 1,
|
|
290
|
+
(<PermutationGroupElement> permutations_bar[s][1])(c+1) - 1)
|
|
291
|
+
d = d1 - l_r[c]
|
|
292
|
+
if d < 0:
|
|
293
|
+
n_p -= 1
|
|
294
|
+
if s < n_p:
|
|
295
|
+
permutations_bar[s] = list(permutations_bar[n_p])
|
|
296
|
+
elif d > 0:
|
|
297
|
+
# The current case leads to a smaller matrix,
|
|
298
|
+
# hence this case becomes our new reference
|
|
299
|
+
l_r[c] = d1
|
|
300
|
+
cf = 0
|
|
301
|
+
n_p = s + 1
|
|
302
|
+
n_s = k + 1
|
|
303
|
+
# Update permutations
|
|
304
|
+
if (n_s - 1) > k:
|
|
305
|
+
permutations[k] = list(permutations[n_s - 1])
|
|
306
|
+
n_s -= 1
|
|
307
|
+
for s in range(n_p):
|
|
308
|
+
permutations[n_s] = list(permutations_bar[s])
|
|
309
|
+
n_s += 1
|
|
310
|
+
cf = n_s
|
|
311
|
+
permutations = {k: permutations[k] for k in permutations if k < n_s}
|
|
312
|
+
# If the automorphisms are not already completely restricted,
|
|
313
|
+
# update them
|
|
314
|
+
if S != list(range(1, n_v + 1)):
|
|
315
|
+
# Take the old automorphisms and update by
|
|
316
|
+
# the restrictions the last worked out
|
|
317
|
+
# row imposes.
|
|
318
|
+
c = 0
|
|
319
|
+
M = tuple(PM.get_unsafe_int((<PermutationGroupElement> permutations[0][0])(l+1) - 1,
|
|
320
|
+
(<PermutationGroupElement> permutations[0][1])(j+1) - 1)
|
|
321
|
+
for j in range(n_v))
|
|
322
|
+
while c < n_v:
|
|
323
|
+
s = S[c] + 1
|
|
324
|
+
S[c] = c + 1
|
|
325
|
+
c += 1
|
|
326
|
+
while c < (s - 1):
|
|
327
|
+
if M[c] == M[c - 1]:
|
|
328
|
+
S[c] = S[c - 1]
|
|
329
|
+
S[S[c] - 1] += 1
|
|
330
|
+
else:
|
|
331
|
+
S[c] = c + 1
|
|
332
|
+
c += 1
|
|
333
|
+
# Now we have the perms, we construct PM_max using one of them
|
|
334
|
+
PM_max = PM.with_permuted_rows_and_columns(*permutations[0])
|
|
335
|
+
if check:
|
|
336
|
+
return (PM_max, permutations)
|
|
337
|
+
else:
|
|
338
|
+
return PM_max
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def _palp_canonical_order(vertices, PM_max, permutations):
|
|
342
|
+
r"""
|
|
343
|
+
Compute the PALP normal form of vertices of a lattice polytope
|
|
344
|
+
using auxiliary data computed elsewhere.
|
|
345
|
+
|
|
346
|
+
This is a helper function for
|
|
347
|
+
:meth:`~sage.geometry.lattice_polytope.LatticePolytopeClass.normal_form`
|
|
348
|
+
and should not be called directly.
|
|
349
|
+
|
|
350
|
+
Given an iterable of vertices, the maximal vertex-facet pairing matrix
|
|
351
|
+
and the permutations realizing this matrix, apply the last part of the
|
|
352
|
+
PALP algorithm and return the normal form.
|
|
353
|
+
|
|
354
|
+
INPUT:
|
|
355
|
+
|
|
356
|
+
- ``vertices`` -- iterable of iterables; the vertices
|
|
357
|
+
|
|
358
|
+
- ``PM_max`` -- the maximal vertex-facet pairing matrix
|
|
359
|
+
|
|
360
|
+
- ``permutation`` -- the permutations of the vertices yielding ``PM_max``
|
|
361
|
+
|
|
362
|
+
OUTPUT: the PALP normal form as an iterable of integer vectors
|
|
363
|
+
|
|
364
|
+
TESTS::
|
|
365
|
+
|
|
366
|
+
sage: L = lattice_polytope.cross_polytope(2)
|
|
367
|
+
sage: V = L.vertices()
|
|
368
|
+
sage: PM_max, permutations = L._palp_PM_max(check=True)
|
|
369
|
+
sage: from sage.geometry.lattice_polytope import _palp_canonical_order
|
|
370
|
+
sage: _palp_canonical_order(V, PM_max, permutations)
|
|
371
|
+
(M( 1, 0),
|
|
372
|
+
M( 0, 1),
|
|
373
|
+
M( 0, -1),
|
|
374
|
+
M(-1, 0)
|
|
375
|
+
in 2-d lattice M, (1,3,2,4))
|
|
376
|
+
"""
|
|
377
|
+
n_v = PM_max.ncols()
|
|
378
|
+
S_v = SymmetricGroup(n_v)
|
|
379
|
+
p_c = S_v.one()
|
|
380
|
+
M_max = [max(row[j] for row in PM_max.rows()) for j in range(n_v)]
|
|
381
|
+
S_max = sum(PM_max)
|
|
382
|
+
for i in range(n_v):
|
|
383
|
+
k = i
|
|
384
|
+
for j in range(i + 1, n_v):
|
|
385
|
+
if M_max[j] < M_max[k] or \
|
|
386
|
+
(M_max[j] == M_max[k] and S_max[j] < S_max[k]):
|
|
387
|
+
k = j
|
|
388
|
+
if not k == i:
|
|
389
|
+
M_max[i], M_max[k] = M_max[k], M_max[i]
|
|
390
|
+
S_max[i], S_max[k] = S_max[k], S_max[i]
|
|
391
|
+
p_c = p_c._transpose_left(1 + i, 1 + k)
|
|
392
|
+
# Create array of possible NFs.
|
|
393
|
+
permutations = [p_c * l[1] for l in permutations.values()]
|
|
394
|
+
if isinstance(vertices, Matrix):
|
|
395
|
+
Vmatrix = vertices
|
|
396
|
+
else:
|
|
397
|
+
Vmatrix = column_matrix(vertices)
|
|
398
|
+
Vs = [(Vmatrix.with_permuted_columns(sig).hermite_form(), sig)
|
|
399
|
+
for sig in permutations]
|
|
400
|
+
Vmin = min(Vs, key=lambda x: x[0])
|
|
401
|
+
return Vmin[0].columns(), Vmin[1]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-groups
|
|
2
|
+
"""
|
|
3
|
+
all.py -- export of abelian groups to Sage
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# *****************************************************************************
|
|
7
|
+
#
|
|
8
|
+
# Sage: Open Source Mathematical Software
|
|
9
|
+
#
|
|
10
|
+
# Copyright (C) 2006 William Stein <wstein@gmail.com>
|
|
11
|
+
#
|
|
12
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
13
|
+
#
|
|
14
|
+
# This code is distributed in the hope that it will be useful,
|
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
17
|
+
# General Public License for more details.
|
|
18
|
+
#
|
|
19
|
+
# The full text of the GPL is available at:
|
|
20
|
+
#
|
|
21
|
+
# https://www.gnu.org/licenses/
|
|
22
|
+
# *****************************************************************************
|
|
23
|
+
|
|
24
|
+
from sage.groups.abelian_gps.all__sagemath_modules import *
|
|
25
|
+
from sage.groups.abelian_gps.all__sagemath_gap import *
|