passagemath-polyhedra 10.6.31rc3__cp314-cp314-musllinux_1_2_x86_64.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.
Potentially problematic release.
This version of passagemath-polyhedra might be problematic. Click here for more details.
- passagemath_polyhedra-10.6.31rc3.dist-info/METADATA +367 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/METADATA.bak +369 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/RECORD +208 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/WHEEL +5 -0
- passagemath_polyhedra-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_polyhedra.libs/libgcc_s-0cd532bd.so.1 +0 -0
- passagemath_polyhedra.libs/libgmp-0e7fc84e.so.10.5.0 +0 -0
- passagemath_polyhedra.libs/libgomp-8949ffbe.so.1.0.0 +0 -0
- passagemath_polyhedra.libs/libstdc++-5d72f927.so.6.0.33 +0 -0
- sage/all__sagemath_polyhedra.py +50 -0
- sage/game_theory/all.py +8 -0
- sage/game_theory/catalog.py +6 -0
- sage/game_theory/catalog_normal_form_games.py +923 -0
- sage/game_theory/cooperative_game.py +844 -0
- sage/game_theory/matching_game.py +1181 -0
- sage/game_theory/normal_form_game.py +2697 -0
- sage/game_theory/parser.py +275 -0
- sage/geometry/all__sagemath_polyhedra.py +22 -0
- sage/geometry/cone.py +6940 -0
- sage/geometry/cone_catalog.py +847 -0
- sage/geometry/cone_critical_angles.py +1027 -0
- sage/geometry/convex_set.py +1119 -0
- sage/geometry/fan.py +3743 -0
- sage/geometry/fan_isomorphism.py +389 -0
- sage/geometry/fan_morphism.py +1884 -0
- sage/geometry/hasse_diagram.py +202 -0
- sage/geometry/hyperplane_arrangement/affine_subspace.py +390 -0
- sage/geometry/hyperplane_arrangement/all.py +1 -0
- sage/geometry/hyperplane_arrangement/arrangement.py +3895 -0
- sage/geometry/hyperplane_arrangement/check_freeness.py +145 -0
- sage/geometry/hyperplane_arrangement/hyperplane.py +773 -0
- sage/geometry/hyperplane_arrangement/library.py +825 -0
- sage/geometry/hyperplane_arrangement/ordered_arrangement.py +642 -0
- sage/geometry/hyperplane_arrangement/plot.py +520 -0
- sage/geometry/integral_points.py +35 -0
- sage/geometry/integral_points_generic_dense.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/integral_points_generic_dense.pyx +7 -0
- sage/geometry/lattice_polytope.py +5894 -0
- sage/geometry/linear_expression.py +773 -0
- sage/geometry/newton_polygon.py +767 -0
- sage/geometry/point_collection.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/point_collection.pyx +1008 -0
- sage/geometry/polyhedral_complex.py +2616 -0
- sage/geometry/polyhedron/all.py +8 -0
- sage/geometry/polyhedron/backend_cdd.py +460 -0
- sage/geometry/polyhedron/backend_cdd_rdf.py +231 -0
- sage/geometry/polyhedron/backend_field.py +347 -0
- sage/geometry/polyhedron/backend_normaliz.py +2503 -0
- sage/geometry/polyhedron/backend_number_field.py +168 -0
- sage/geometry/polyhedron/backend_polymake.py +765 -0
- sage/geometry/polyhedron/backend_ppl.py +582 -0
- sage/geometry/polyhedron/base.py +1206 -0
- sage/geometry/polyhedron/base0.py +1444 -0
- sage/geometry/polyhedron/base1.py +886 -0
- sage/geometry/polyhedron/base2.py +812 -0
- sage/geometry/polyhedron/base3.py +1845 -0
- sage/geometry/polyhedron/base4.py +1262 -0
- sage/geometry/polyhedron/base5.py +2700 -0
- sage/geometry/polyhedron/base6.py +1741 -0
- sage/geometry/polyhedron/base7.py +997 -0
- sage/geometry/polyhedron/base_QQ.py +1258 -0
- sage/geometry/polyhedron/base_RDF.py +98 -0
- sage/geometry/polyhedron/base_ZZ.py +934 -0
- sage/geometry/polyhedron/base_mutable.py +215 -0
- sage/geometry/polyhedron/base_number_field.py +122 -0
- sage/geometry/polyhedron/cdd_file_format.py +155 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/all.py +1 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +76 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +3859 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pxd +39 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +1038 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pxd +9 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/conversions.pyx +501 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_data_structure.pxd +207 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pxd +102 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +2274 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pxd +370 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/face_list_data_structure.pyx +84 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pxd +31 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +587 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pxd +52 -0
- sage/geometry/polyhedron/combinatorial_polyhedron/polyhedron_face_lattice.pyx +560 -0
- sage/geometry/polyhedron/constructor.py +773 -0
- sage/geometry/polyhedron/double_description.py +753 -0
- sage/geometry/polyhedron/double_description_inhomogeneous.py +564 -0
- sage/geometry/polyhedron/face.py +1060 -0
- sage/geometry/polyhedron/generating_function.py +1810 -0
- sage/geometry/polyhedron/lattice_euclidean_group_element.py +178 -0
- sage/geometry/polyhedron/library.py +3502 -0
- sage/geometry/polyhedron/misc.py +121 -0
- sage/geometry/polyhedron/modules/all.py +1 -0
- sage/geometry/polyhedron/modules/formal_polyhedra_module.py +155 -0
- sage/geometry/polyhedron/palp_database.py +447 -0
- sage/geometry/polyhedron/parent.py +1279 -0
- sage/geometry/polyhedron/plot.py +1986 -0
- sage/geometry/polyhedron/ppl_lattice_polygon.py +556 -0
- sage/geometry/polyhedron/ppl_lattice_polytope.py +1257 -0
- sage/geometry/polyhedron/representation.py +1723 -0
- sage/geometry/pseudolines.py +515 -0
- sage/geometry/relative_interior.py +445 -0
- sage/geometry/toric_plotter.py +1103 -0
- sage/geometry/triangulation/all.py +2 -0
- sage/geometry/triangulation/base.cpython-314-x86_64-linux-musl.so +0 -0
- sage/geometry/triangulation/base.pyx +963 -0
- sage/geometry/triangulation/data.h +147 -0
- sage/geometry/triangulation/data.pxd +4 -0
- sage/geometry/triangulation/element.py +914 -0
- sage/geometry/triangulation/functions.h +10 -0
- sage/geometry/triangulation/functions.pxd +4 -0
- sage/geometry/triangulation/point_configuration.py +2256 -0
- sage/geometry/triangulation/triangulations.h +49 -0
- sage/geometry/triangulation/triangulations.pxd +7 -0
- sage/geometry/voronoi_diagram.py +319 -0
- sage/interfaces/all__sagemath_polyhedra.py +1 -0
- sage/interfaces/polymake.py +2028 -0
- sage/numerical/all.py +13 -0
- sage/numerical/all__sagemath_polyhedra.py +11 -0
- sage/numerical/backends/all.py +1 -0
- sage/numerical/backends/all__sagemath_polyhedra.py +1 -0
- sage/numerical/backends/cvxopt_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/cvxopt_backend.pyx +1006 -0
- sage/numerical/backends/cvxopt_backend_test.py +19 -0
- sage/numerical/backends/cvxopt_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/cvxopt_sdp_backend.pyx +382 -0
- sage/numerical/backends/cvxpy_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/cvxpy_backend.pxd +41 -0
- sage/numerical/backends/cvxpy_backend.pyx +934 -0
- sage/numerical/backends/cvxpy_backend_test.py +13 -0
- sage/numerical/backends/generic_backend_test.py +24 -0
- sage/numerical/backends/interactivelp_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/interactivelp_backend.pxd +36 -0
- sage/numerical/backends/interactivelp_backend.pyx +1231 -0
- sage/numerical/backends/interactivelp_backend_test.py +12 -0
- sage/numerical/backends/logging_backend.py +391 -0
- sage/numerical/backends/matrix_sdp_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/matrix_sdp_backend.pxd +15 -0
- sage/numerical/backends/matrix_sdp_backend.pyx +478 -0
- sage/numerical/backends/ppl_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/ppl_backend.pyx +1126 -0
- sage/numerical/backends/ppl_backend_test.py +13 -0
- sage/numerical/backends/scip_backend.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/backends/scip_backend.pxd +22 -0
- sage/numerical/backends/scip_backend.pyx +1289 -0
- sage/numerical/backends/scip_backend_test.py +13 -0
- sage/numerical/interactive_simplex_method.py +5338 -0
- sage/numerical/knapsack.py +665 -0
- sage/numerical/linear_functions.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/linear_functions.pxd +31 -0
- sage/numerical/linear_functions.pyx +1648 -0
- sage/numerical/linear_tensor.py +470 -0
- sage/numerical/linear_tensor_constraints.py +448 -0
- sage/numerical/linear_tensor_element.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/linear_tensor_element.pxd +6 -0
- sage/numerical/linear_tensor_element.pyx +459 -0
- sage/numerical/mip.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/mip.pxd +40 -0
- sage/numerical/mip.pyx +3667 -0
- sage/numerical/sdp.cpython-314-x86_64-linux-musl.so +0 -0
- sage/numerical/sdp.pxd +39 -0
- sage/numerical/sdp.pyx +1433 -0
- sage/rings/all__sagemath_polyhedra.py +3 -0
- sage/rings/polynomial/all__sagemath_polyhedra.py +10 -0
- sage/rings/polynomial/omega.py +982 -0
- sage/schemes/all__sagemath_polyhedra.py +2 -0
- sage/schemes/toric/all.py +10 -0
- sage/schemes/toric/chow_group.py +1248 -0
- sage/schemes/toric/divisor.py +2082 -0
- sage/schemes/toric/divisor_class.cpython-314-x86_64-linux-musl.so +0 -0
- sage/schemes/toric/divisor_class.pyx +322 -0
- sage/schemes/toric/fano_variety.py +1606 -0
- sage/schemes/toric/homset.py +650 -0
- sage/schemes/toric/ideal.py +451 -0
- sage/schemes/toric/library.py +1322 -0
- sage/schemes/toric/morphism.py +1958 -0
- sage/schemes/toric/points.py +1032 -0
- sage/schemes/toric/sheaf/all.py +1 -0
- sage/schemes/toric/sheaf/constructor.py +302 -0
- sage/schemes/toric/sheaf/klyachko.py +921 -0
- sage/schemes/toric/toric_subscheme.py +905 -0
- sage/schemes/toric/variety.py +3460 -0
- sage/schemes/toric/weierstrass.py +1078 -0
- sage/schemes/toric/weierstrass_covering.py +457 -0
- sage/schemes/toric/weierstrass_higher.py +288 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.info +10 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v03 +0 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v04 +0 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v05 +1 -0
- sage_wheels/share/reflexive_polytopes/Full2d/zzdb.v06 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.info +22 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v04 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v05 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v06 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v07 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v08 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v09 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v10 +0 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v11 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v12 +1 -0
- sage_wheels/share/reflexive_polytopes/Full3d/zzdb.v13 +1 -0
- sage_wheels/share/reflexive_polytopes/reflexive_polytopes_2d +80 -0
- sage_wheels/share/reflexive_polytopes/reflexive_polytopes_3d +37977 -0
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
# sage.doctest: needs sage.geometry.polyhedron sage.graphs sage.libs.singular
|
|
3
|
+
r"""
|
|
4
|
+
Toric ideals
|
|
5
|
+
|
|
6
|
+
A toric ideal (associated to an integer matrix `A`) is an ideal of the
|
|
7
|
+
form
|
|
8
|
+
|
|
9
|
+
.. MATH::
|
|
10
|
+
|
|
11
|
+
I_A = \left<
|
|
12
|
+
x^u - x^v
|
|
13
|
+
: u,v \in \ZZ_\geq^n
|
|
14
|
+
, u-v \in \ker(A)
|
|
15
|
+
\right>
|
|
16
|
+
|
|
17
|
+
In other words, it is an ideal generated by irreducible "binomials",
|
|
18
|
+
that is, differences of monomials without a common factor. Since the
|
|
19
|
+
Buchberger algorithm preserves this property, any Groebner basis is
|
|
20
|
+
then also generated by binomials.
|
|
21
|
+
|
|
22
|
+
EXAMPLES::
|
|
23
|
+
|
|
24
|
+
sage: A = matrix([[1,1,1], [0,1,2]])
|
|
25
|
+
sage: IA = ToricIdeal(A)
|
|
26
|
+
sage: IA.ker()
|
|
27
|
+
Free module of degree 3 and rank 1 over Integer Ring
|
|
28
|
+
User basis matrix:
|
|
29
|
+
[-1 2 -1]
|
|
30
|
+
sage: IA
|
|
31
|
+
Ideal (-z1^2 + z0*z2) of Multivariate Polynomial
|
|
32
|
+
Ring in z0, z1, z2 over Rational Field
|
|
33
|
+
|
|
34
|
+
Here, the "naive" ideal generated by `z_0 z_2 - z_1^2` does already
|
|
35
|
+
equal the toric ideal. But that is not true in general! For example,
|
|
36
|
+
this toric ideal ([Stu1997]_, Example 1.2) is the twisted
|
|
37
|
+
cubic and cannot be generated by `2=\dim \ker(A)` polynomials::
|
|
38
|
+
|
|
39
|
+
sage: A = matrix([[3,2,1,0], [0,1,2,3]])
|
|
40
|
+
sage: IA = ToricIdeal(A)
|
|
41
|
+
sage: IA.ker()
|
|
42
|
+
Free module of degree 4 and rank 2 over Integer Ring
|
|
43
|
+
User basis matrix:
|
|
44
|
+
[-1 1 1 -1]
|
|
45
|
+
[-1 2 -1 0]
|
|
46
|
+
sage: IA
|
|
47
|
+
Ideal (-z1*z2 + z0*z3, -z1^2 + z0*z2, z2^2 - z1*z3) of
|
|
48
|
+
Multivariate Polynomial Ring in z0, z1, z2, z3 over Rational Field
|
|
49
|
+
|
|
50
|
+
The following family of toric ideals is from Example 4.4 of
|
|
51
|
+
[Stu1997]_. One can show that `I_d` is generated by one
|
|
52
|
+
quadric and `d` binomials of degree `d`::
|
|
53
|
+
|
|
54
|
+
sage: def I(d):
|
|
55
|
+
....: return ToricIdeal(matrix([[1,1,1,1,1], [0,1,1,0,0], [0,0,1,1,d]]))
|
|
56
|
+
sage: I(2)
|
|
57
|
+
Ideal (-z3^2 + z0*z4,
|
|
58
|
+
z0*z2 - z1*z3,
|
|
59
|
+
z2*z3 - z1*z4) of
|
|
60
|
+
Multivariate Polynomial Ring in z0, z1, z2, z3, z4 over Rational Field
|
|
61
|
+
sage: I(3)
|
|
62
|
+
Ideal (-z3^3 + z0^2*z4,
|
|
63
|
+
z0*z2 - z1*z3,
|
|
64
|
+
z2*z3^2 - z0*z1*z4,
|
|
65
|
+
z2^2*z3 - z1^2*z4) of
|
|
66
|
+
Multivariate Polynomial Ring in z0, z1, z2, z3, z4 over Rational Field
|
|
67
|
+
sage: I(4)
|
|
68
|
+
Ideal (-z3^4 + z0^3*z4,
|
|
69
|
+
z0*z2 - z1*z3,
|
|
70
|
+
z2*z3^3 - z0^2*z1*z4,
|
|
71
|
+
z2^2*z3^2 - z0*z1^2*z4,
|
|
72
|
+
z2^3*z3 - z1^3*z4) of
|
|
73
|
+
Multivariate Polynomial Ring in z0, z1, z2, z3, z4 over Rational Field
|
|
74
|
+
|
|
75
|
+
Finally, the example in [SH1995b]_ ::
|
|
76
|
+
|
|
77
|
+
sage: A = matrix(ZZ, [ [15, 4, 14, 19, 2, 1, 10, 17],
|
|
78
|
+
....: [18, 11, 13, 5, 16, 16, 8, 19],
|
|
79
|
+
....: [11, 7, 8, 19, 15, 18, 14, 6],
|
|
80
|
+
....: [17, 10, 13, 17, 16, 14, 15, 18] ])
|
|
81
|
+
sage: IA = ToricIdeal(A) # long time
|
|
82
|
+
sage: IA.ngens() # long time
|
|
83
|
+
213
|
|
84
|
+
|
|
85
|
+
TESTS::
|
|
86
|
+
|
|
87
|
+
sage: A = matrix(ZZ, [[1, 1, 0, 0, -1, 0, 0, -1],
|
|
88
|
+
....: [0, 0, 1, 1, 0, -1, -1, 0],
|
|
89
|
+
....: [1, 0, 0, 1, 1, 1, 0, 0],
|
|
90
|
+
....: [1, 0, 0, 1, 0, 0, -1, -1]])
|
|
91
|
+
sage: IA = ToricIdeal(A)
|
|
92
|
+
sage: R = IA.ring()
|
|
93
|
+
sage: R.inject_variables()
|
|
94
|
+
Defining z0, z1, z2, z3, z4, z5, z6, z7
|
|
95
|
+
sage: IA == R.ideal([z4*z6-z5*z7, z2*z5-z3*z6, -z3*z7+z2*z4,
|
|
96
|
+
....: -z2*z6+z1*z7, z1*z4-z3*z6, z0*z7-z3*z6, -z1*z5+z0*z6, -z3*z5+z0*z4,
|
|
97
|
+
....: z0*z2-z1*z3]) # Computed with Maple 12
|
|
98
|
+
True
|
|
99
|
+
|
|
100
|
+
The next example first appeared in Example 12.7 in [Stu1995]_. It is also
|
|
101
|
+
used by the Maple 12 help system as example::
|
|
102
|
+
|
|
103
|
+
sage: A = matrix(ZZ, [[1, 2, 3, 4, 0, 1, 4, 5],
|
|
104
|
+
....: [2, 3, 4, 1, 1, 4, 5, 0],
|
|
105
|
+
....: [3, 4, 1, 2, 4, 5, 0, 1],
|
|
106
|
+
....: [4, 1, 2, 3, 5, 0, 1, 4]])
|
|
107
|
+
sage: IA = ToricIdeal(A, 'z1, z2, z3, z4, z5, z6, z7, z8')
|
|
108
|
+
sage: R = IA.ring()
|
|
109
|
+
sage: R.inject_variables()
|
|
110
|
+
Defining z1, z2, z3, z4, z5, z6, z7, z8
|
|
111
|
+
sage: IA == R.ideal([z4^4-z6*z8^3, z3^4-z5*z7^3, -z4^3+z2*z8^2,
|
|
112
|
+
....: z2*z4-z6*z8, -z4^2*z6+z2^2*z8, -z4*z6^2+z2^3, -z3^3+z1*z7^2,
|
|
113
|
+
....: z1*z3-z5*z7, -z3^2*z5+z1^2*z7, z1^3-z3*z5^2])
|
|
114
|
+
True
|
|
115
|
+
|
|
116
|
+
AUTHORS:
|
|
117
|
+
|
|
118
|
+
- Volker Braun (2011-01-03): Initial version
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
# ****************************************************************************
|
|
122
|
+
# Copyright (C) 2010 Volker Braun <vbraun.name@gmail.com>
|
|
123
|
+
#
|
|
124
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
125
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
126
|
+
# the License, or (at your option) any later version.
|
|
127
|
+
# https://www.gnu.org/licenses/
|
|
128
|
+
# ****************************************************************************
|
|
129
|
+
|
|
130
|
+
# TODO:
|
|
131
|
+
# * Implement the Di Biase & Urbanke algorithm
|
|
132
|
+
# * Implement the Conti & Traverso algorithm (for educational purposes)
|
|
133
|
+
# * Cythonize the Buchberger algorithm for toric ideals
|
|
134
|
+
# * Use the (multiple) weighted homogeneity during Groebner basis computations
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
138
|
+
from sage.misc.misc_c import prod
|
|
139
|
+
from sage.matrix.constructor import matrix
|
|
140
|
+
from sage.rings.integer_ring import ZZ
|
|
141
|
+
from sage.rings.rational_field import QQ
|
|
142
|
+
from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class ToricIdeal(MPolynomialIdeal):
|
|
146
|
+
r"""
|
|
147
|
+
This class represents a toric ideal defined by an integral matrix.
|
|
148
|
+
|
|
149
|
+
INPUT:
|
|
150
|
+
|
|
151
|
+
- ``A`` -- integer matrix; the defining matrix of the toric ideal
|
|
152
|
+
|
|
153
|
+
- ``names`` -- string (optional); names for the variables. By
|
|
154
|
+
default, this is ``'z'`` and the variables will be named ``z0``,
|
|
155
|
+
``z1``, ...
|
|
156
|
+
|
|
157
|
+
- ``base_ring`` -- a ring (default: `\QQ`); the base
|
|
158
|
+
ring of the ideal. A toric ideal uses only coefficients `\pm 1`.
|
|
159
|
+
|
|
160
|
+
- ``polynomial_ring`` -- a polynomial ring (optional); the
|
|
161
|
+
polynomial ring to construct the ideal in
|
|
162
|
+
|
|
163
|
+
You may specify the ambient polynomial ring via the
|
|
164
|
+
``polynomial_ring`` parameter or via the ``names`` and
|
|
165
|
+
``base_ring`` parameter. A :exc:`ValueError` is raised if you
|
|
166
|
+
specify both.
|
|
167
|
+
|
|
168
|
+
- ``algorithm`` -- string (optional); the algorithm to use. For
|
|
169
|
+
now, must be ``'HostenSturmfels'`` which is the algorithm
|
|
170
|
+
proposed by Hosten and Sturmfels in [SH1995b]_.
|
|
171
|
+
|
|
172
|
+
EXAMPLES::
|
|
173
|
+
|
|
174
|
+
sage: A = matrix([[1,1,1], [0,1,2]])
|
|
175
|
+
sage: ToricIdeal(A)
|
|
176
|
+
Ideal (-z1^2 + z0*z2) of Multivariate Polynomial Ring
|
|
177
|
+
in z0, z1, z2 over Rational Field
|
|
178
|
+
|
|
179
|
+
First way of specifying the polynomial ring::
|
|
180
|
+
|
|
181
|
+
sage: ToricIdeal(A, names='x,y,z', base_ring=ZZ)
|
|
182
|
+
Ideal (-y^2 + x*z) of Multivariate Polynomial Ring
|
|
183
|
+
in x, y, z over Integer Ring
|
|
184
|
+
|
|
185
|
+
Second way of specifying the polynomial ring::
|
|
186
|
+
|
|
187
|
+
sage: R.<x,y,z> = ZZ[]
|
|
188
|
+
sage: ToricIdeal(A, polynomial_ring=R)
|
|
189
|
+
Ideal (-y^2 + x*z) of Multivariate Polynomial Ring
|
|
190
|
+
in x, y, z over Integer Ring
|
|
191
|
+
|
|
192
|
+
It is an error to specify both::
|
|
193
|
+
|
|
194
|
+
sage: ToricIdeal(A, names='x,y,z', polynomial_ring=R)
|
|
195
|
+
Traceback (most recent call last):
|
|
196
|
+
...
|
|
197
|
+
ValueError: you must not specify both variable names and a polynomial ring
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
def __init__(self, A,
|
|
201
|
+
names='z', base_ring=QQ,
|
|
202
|
+
polynomial_ring=None,
|
|
203
|
+
algorithm='HostenSturmfels'):
|
|
204
|
+
r"""
|
|
205
|
+
Create an ideal and a multivariate polynomial ring containing it.
|
|
206
|
+
|
|
207
|
+
See the :mod:`module documentation
|
|
208
|
+
<sage.schemes.toric.ideal>` for an introduction to
|
|
209
|
+
toric ideals.
|
|
210
|
+
|
|
211
|
+
INPUT:
|
|
212
|
+
|
|
213
|
+
See the :class:`class-level documentation <ToricIdeal>` for
|
|
214
|
+
input values.
|
|
215
|
+
|
|
216
|
+
EXAMPLES::
|
|
217
|
+
|
|
218
|
+
sage: A = matrix([[1,1,1], [0,1,2]])
|
|
219
|
+
sage: ToricIdeal(A)
|
|
220
|
+
Ideal (-z1^2 + z0*z2) of Multivariate Polynomial Ring
|
|
221
|
+
in z0, z1, z2 over Rational Field
|
|
222
|
+
sage: ToricIdeal(A, names='x', base_ring=GF(101))
|
|
223
|
+
Ideal (-x1^2 + x0*x2) of Multivariate Polynomial Ring
|
|
224
|
+
in x0, x1, x2 over Finite Field of size 101
|
|
225
|
+
sage: ToricIdeal(A, names='x', base_ring=FractionField(QQ['t']))
|
|
226
|
+
Ideal (-x1^2 + x0*x2) of
|
|
227
|
+
Multivariate Polynomial Ring in x0, x1, x2 over
|
|
228
|
+
Fraction Field of Univariate Polynomial Ring in t over Rational Field
|
|
229
|
+
"""
|
|
230
|
+
self._A = matrix(ZZ, A)
|
|
231
|
+
if polynomial_ring:
|
|
232
|
+
if names != 'z' or base_ring is not QQ:
|
|
233
|
+
raise ValueError('you must not specify both variable names and a polynomial ring')
|
|
234
|
+
self._names = [str(g) for g in polynomial_ring.gens()]
|
|
235
|
+
self._base_ring = polynomial_ring.base_ring()
|
|
236
|
+
ring = polynomial_ring
|
|
237
|
+
else:
|
|
238
|
+
self._names = names
|
|
239
|
+
self._base_ring = base_ring
|
|
240
|
+
ring = self._init_ring('degrevlex')
|
|
241
|
+
|
|
242
|
+
if algorithm == 'HostenSturmfels':
|
|
243
|
+
ideal = self._ideal_HostenSturmfels()
|
|
244
|
+
else:
|
|
245
|
+
raise ValueError(f'algorithm = {algorithm} is not known')
|
|
246
|
+
|
|
247
|
+
gens = [ring(x) for x in ideal.gens()]
|
|
248
|
+
MPolynomialIdeal.__init__(self, ring, gens, coerce=False)
|
|
249
|
+
|
|
250
|
+
def A(self):
|
|
251
|
+
"""
|
|
252
|
+
Return the defining matrix.
|
|
253
|
+
|
|
254
|
+
OUTPUT: integer matrix
|
|
255
|
+
|
|
256
|
+
EXAMPLES::
|
|
257
|
+
|
|
258
|
+
sage: A = matrix([[1,1,1], [0,1,2]])
|
|
259
|
+
sage: IA = ToricIdeal(A)
|
|
260
|
+
sage: IA.A()
|
|
261
|
+
[1 1 1]
|
|
262
|
+
[0 1 2]
|
|
263
|
+
"""
|
|
264
|
+
return self._A
|
|
265
|
+
|
|
266
|
+
def ker(self):
|
|
267
|
+
"""
|
|
268
|
+
Return the kernel of the defining matrix.
|
|
269
|
+
|
|
270
|
+
OUTPUT: the kernel of ``self.A()``.
|
|
271
|
+
|
|
272
|
+
EXAMPLES::
|
|
273
|
+
|
|
274
|
+
sage: A = matrix([[1,1,1], [0,1,2]])
|
|
275
|
+
sage: IA = ToricIdeal(A)
|
|
276
|
+
sage: IA.ker()
|
|
277
|
+
Free module of degree 3 and rank 1 over Integer Ring
|
|
278
|
+
User basis matrix: [-1 2 -1]
|
|
279
|
+
"""
|
|
280
|
+
|
|
281
|
+
if '_ker' in self.__dict__:
|
|
282
|
+
return self._ker
|
|
283
|
+
self._ker = self.A().right_kernel(basis='LLL')
|
|
284
|
+
return self._ker
|
|
285
|
+
|
|
286
|
+
def nvariables(self):
|
|
287
|
+
r"""
|
|
288
|
+
Return the number of variables of the ambient polynomial ring.
|
|
289
|
+
|
|
290
|
+
OUTPUT: integer; the number of columns of the defining matrix :meth:`A`
|
|
291
|
+
|
|
292
|
+
EXAMPLES::
|
|
293
|
+
|
|
294
|
+
sage: A = matrix([[1,1,1], [0,1,2]])
|
|
295
|
+
sage: IA = ToricIdeal(A)
|
|
296
|
+
sage: IA.nvariables()
|
|
297
|
+
3
|
|
298
|
+
"""
|
|
299
|
+
return self.A().ncols()
|
|
300
|
+
|
|
301
|
+
def _init_ring(self, term_order):
|
|
302
|
+
r"""
|
|
303
|
+
Construct the ambient polynomial ring.
|
|
304
|
+
|
|
305
|
+
INPUT:
|
|
306
|
+
|
|
307
|
+
- ``term_order`` -- string; the order of the variables, for
|
|
308
|
+
example ``'neglex'`` and ``'degrevlex'``
|
|
309
|
+
|
|
310
|
+
OUTPUT: a polynomial ring with the given term order
|
|
311
|
+
|
|
312
|
+
.. NOTE::
|
|
313
|
+
|
|
314
|
+
Reverse lexicographic ordering is equivalent to negative
|
|
315
|
+
lexicographic order with the reversed list of
|
|
316
|
+
variables. We are using the latter in the implementation
|
|
317
|
+
of the Hosten/Sturmfels algorithm.
|
|
318
|
+
|
|
319
|
+
EXAMPLES::
|
|
320
|
+
|
|
321
|
+
sage: A = matrix([[1,1,1], [0,1,2]])
|
|
322
|
+
sage: IA = ToricIdeal(A)
|
|
323
|
+
sage: R = IA._init_ring('neglex'); R
|
|
324
|
+
Multivariate Polynomial Ring in z0, z1, z2 over Rational Field
|
|
325
|
+
sage: R.term_order()
|
|
326
|
+
Negative lexicographic term order
|
|
327
|
+
sage: R.inject_variables()
|
|
328
|
+
Defining z0, z1, z2
|
|
329
|
+
sage: z0 < z1 and z1 < z2
|
|
330
|
+
True
|
|
331
|
+
"""
|
|
332
|
+
return PolynomialRing(self._base_ring, self._names,
|
|
333
|
+
self.nvariables(), order=term_order)
|
|
334
|
+
|
|
335
|
+
def _naive_ideal(self, ring):
|
|
336
|
+
r"""
|
|
337
|
+
Return the "naive" subideal.
|
|
338
|
+
|
|
339
|
+
INPUT:
|
|
340
|
+
|
|
341
|
+
- ``ring`` -- the ambient ring of the ideal
|
|
342
|
+
|
|
343
|
+
OUTPUT: a subideal of the toric ideal in the polynomial ring ``ring``
|
|
344
|
+
|
|
345
|
+
EXAMPLES::
|
|
346
|
+
|
|
347
|
+
sage: A = matrix([[1,1,1], [0,1,2]])
|
|
348
|
+
sage: IA = ToricIdeal(A)
|
|
349
|
+
sage: IA.ker()
|
|
350
|
+
Free module of degree 3 and rank 1 over Integer Ring
|
|
351
|
+
User basis matrix: [-1 2 -1]
|
|
352
|
+
sage: IA._naive_ideal(IA.ring())
|
|
353
|
+
Ideal (z1^2 - z0*z2) of Multivariate Polynomial Ring in z0, z1, z2 over Rational Field
|
|
354
|
+
"""
|
|
355
|
+
x = ring.gens()
|
|
356
|
+
binomials = []
|
|
357
|
+
for row in self.ker().matrix().rows():
|
|
358
|
+
xpos = prod(x[i]**max(row[i], 0) for i in range(len(x)))
|
|
359
|
+
xneg = prod(x[i]**max(-row[i], 0) for i in range(len(x)))
|
|
360
|
+
binomials.append(xpos - xneg)
|
|
361
|
+
return ring.ideal(binomials)
|
|
362
|
+
|
|
363
|
+
def _ideal_quotient_by_variable(self, ring, ideal, n):
|
|
364
|
+
r"""
|
|
365
|
+
Return the ideal quotient `(J:x_n^\infty)`.
|
|
366
|
+
|
|
367
|
+
INPUT:
|
|
368
|
+
|
|
369
|
+
- ``ring`` -- the ambient polynomial ring in neglex order
|
|
370
|
+
|
|
371
|
+
- ``ideal`` -- the ideal `J`
|
|
372
|
+
|
|
373
|
+
- ``n`` -- integer; the index of the next variable to divide by
|
|
374
|
+
|
|
375
|
+
OUTPUT: the ideal quotient `(J:x_n^\infty)`
|
|
376
|
+
|
|
377
|
+
ALGORITHM:
|
|
378
|
+
|
|
379
|
+
Proposition 4 of [SH1995b]_.
|
|
380
|
+
|
|
381
|
+
EXAMPLES::
|
|
382
|
+
|
|
383
|
+
sage: A = lambda d: matrix([[1,1,1,1,1],[0,1,1,0,0],[0,0,1,1,d]])
|
|
384
|
+
sage: IA = ToricIdeal(A(3))
|
|
385
|
+
sage: R = PolynomialRing(QQ, 5, 'z', order='neglex')
|
|
386
|
+
sage: J0 = IA._naive_ideal(R)
|
|
387
|
+
sage: IA._ideal_quotient_by_variable(R, J0, 0)
|
|
388
|
+
Ideal (z2*z3^2 - z0*z1*z4, z1*z3 - z0*z2,
|
|
389
|
+
z2^2*z3 - z1^2*z4, z1^3*z4 - z0*z2^3)
|
|
390
|
+
of Multivariate Polynomial Ring in z0, z1, z2, z3, z4 over Rational Field
|
|
391
|
+
"""
|
|
392
|
+
N = self.nvariables()
|
|
393
|
+
y = list(ring.gens())
|
|
394
|
+
x = [y[i - n] for i in range(N)]
|
|
395
|
+
y_to_x = dict(zip(x, y))
|
|
396
|
+
x_to_y = dict(zip(y, x))
|
|
397
|
+
# swap variables such that the n-th variable becomes the last one
|
|
398
|
+
J = ideal.subs(y_to_x)
|
|
399
|
+
|
|
400
|
+
# TODO: Can we use the weighted homogeneity with respect to
|
|
401
|
+
# the rows of self.A() when computing the Groebner basis, see
|
|
402
|
+
# [SH1995b]?
|
|
403
|
+
basis = J.groebner_basis()
|
|
404
|
+
|
|
405
|
+
# x_n = y[0] # the cheapest variable in the revlex order
|
|
406
|
+
def subtract(e, power):
|
|
407
|
+
l = list(e)
|
|
408
|
+
return tuple([l[0] - power] + l[1:])
|
|
409
|
+
|
|
410
|
+
def divide_by_x_n(p):
|
|
411
|
+
d_old = p.monomial_coefficients()
|
|
412
|
+
power = min(e[0] for e in d_old)
|
|
413
|
+
d_new = {subtract(exponent, power): coefficient
|
|
414
|
+
for exponent, coefficient in d_old.items()}
|
|
415
|
+
return p.parent()(d_new)
|
|
416
|
+
basis = [divide_by_x_n(b) for b in basis]
|
|
417
|
+
quotient = ring.ideal(basis)
|
|
418
|
+
return quotient.subs(x_to_y)
|
|
419
|
+
|
|
420
|
+
def _ideal_HostenSturmfels(self):
|
|
421
|
+
r"""
|
|
422
|
+
Compute the toric ideal by Hosten and Sturmfels' algorithm.
|
|
423
|
+
|
|
424
|
+
OUTPUT:
|
|
425
|
+
|
|
426
|
+
The toric ideal as an ideal in the polynomial ring
|
|
427
|
+
``self.ring()``.
|
|
428
|
+
|
|
429
|
+
EXAMPLES::
|
|
430
|
+
|
|
431
|
+
sage: A = matrix([[3,2,1,0], [0,1,2,3]])
|
|
432
|
+
sage: IA = ToricIdeal(A); IA
|
|
433
|
+
Ideal (-z1*z2 + z0*z3, -z1^2 + z0*z2, z2^2 - z1*z3)
|
|
434
|
+
of Multivariate Polynomial Ring in z0, z1, z2, z3 over Rational Field
|
|
435
|
+
sage: R = IA.ring()
|
|
436
|
+
sage: IA == IA._ideal_HostenSturmfels()
|
|
437
|
+
True
|
|
438
|
+
|
|
439
|
+
TESTS::
|
|
440
|
+
|
|
441
|
+
sage: I_2x2 = identity_matrix(ZZ, 2)
|
|
442
|
+
sage: ToricIdeal(I_2x2)
|
|
443
|
+
Ideal (0) of Multivariate Polynomial Ring in z0, z1 over Rational Field
|
|
444
|
+
"""
|
|
445
|
+
ring = self._init_ring('neglex')
|
|
446
|
+
J = self._naive_ideal(ring)
|
|
447
|
+
if J.is_zero():
|
|
448
|
+
return J
|
|
449
|
+
for i in range(self.nvariables()):
|
|
450
|
+
J = self._ideal_quotient_by_variable(ring, J, i)
|
|
451
|
+
return J
|