passagemath-polyhedra 10.6.37__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.
- passagemath_polyhedra/__init__.py +3 -0
- passagemath_polyhedra-10.6.37.dist-info/METADATA +367 -0
- passagemath_polyhedra-10.6.37.dist-info/METADATA.bak +369 -0
- passagemath_polyhedra-10.6.37.dist-info/RECORD +209 -0
- passagemath_polyhedra-10.6.37.dist-info/WHEEL +5 -0
- passagemath_polyhedra-10.6.37.dist-info/top_level.txt +3 -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 +3905 -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,773 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
r"""
|
|
3
|
+
Hyperplanes
|
|
4
|
+
|
|
5
|
+
.. NOTE::
|
|
6
|
+
|
|
7
|
+
If you want to learn about Sage's hyperplane arrangements then you
|
|
8
|
+
should start with
|
|
9
|
+
:mod:`sage.geometry.hyperplane_arrangement.arrangement`. This
|
|
10
|
+
module is used to represent the individual hyperplanes, but you
|
|
11
|
+
should never construct the classes from this module directly (but
|
|
12
|
+
only via the
|
|
13
|
+
:class:`~sage.geometry.hyperplane_arrangement.arrangement.HyperplaneArrangements`.
|
|
14
|
+
|
|
15
|
+
A linear expression, for example, `3x+3y-5z-7` stands for the
|
|
16
|
+
hyperplane with the equation `x+3y-5z=7`. To create it in Sage, you
|
|
17
|
+
first have to create a
|
|
18
|
+
:class:`~sage.geometry.hyperplane_arrangement.arrangement.HyperplaneArrangements`
|
|
19
|
+
object to define the variables `x`, `y`, `z`::
|
|
20
|
+
|
|
21
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
22
|
+
sage: h = 3*x + 2*y - 5*z - 7; h
|
|
23
|
+
Hyperplane 3*x + 2*y - 5*z - 7
|
|
24
|
+
sage: h.coefficients()
|
|
25
|
+
[-7, 3, 2, -5]
|
|
26
|
+
sage: h.normal()
|
|
27
|
+
(3, 2, -5)
|
|
28
|
+
sage: h.constant_term()
|
|
29
|
+
-7
|
|
30
|
+
sage: h.change_ring(GF(3))
|
|
31
|
+
Hyperplane 0*x + 2*y + z + 2
|
|
32
|
+
sage: h.point()
|
|
33
|
+
(21/38, 7/19, -35/38)
|
|
34
|
+
sage: h.linear_part()
|
|
35
|
+
Vector space of degree 3 and dimension 2 over Rational Field
|
|
36
|
+
Basis matrix:
|
|
37
|
+
[ 1 0 3/5]
|
|
38
|
+
[ 0 1 2/5]
|
|
39
|
+
|
|
40
|
+
Another syntax to create hyperplanes is to specify coefficients and a
|
|
41
|
+
constant term::
|
|
42
|
+
|
|
43
|
+
sage: V = H.ambient_space(); V
|
|
44
|
+
3-dimensional linear space over Rational Field with coordinates x, y, z
|
|
45
|
+
sage: h in V
|
|
46
|
+
True
|
|
47
|
+
sage: V([3, 2, -5], -7)
|
|
48
|
+
Hyperplane 3*x + 2*y - 5*z - 7
|
|
49
|
+
|
|
50
|
+
Or constant term and coefficients together in one list/tuple/iterable::
|
|
51
|
+
|
|
52
|
+
sage: V([-7, 3, 2, -5])
|
|
53
|
+
Hyperplane 3*x + 2*y - 5*z - 7
|
|
54
|
+
sage: v = vector([-7, 3, 2, -5]); v
|
|
55
|
+
(-7, 3, 2, -5)
|
|
56
|
+
sage: V(v)
|
|
57
|
+
Hyperplane 3*x + 2*y - 5*z - 7
|
|
58
|
+
|
|
59
|
+
Note that the constant term comes first, which matches the notation
|
|
60
|
+
for Sage's :func:`~sage.geometry.polyhedron.constructor.Polyhedron` ::
|
|
61
|
+
|
|
62
|
+
sage: Polyhedron(ieqs=[(4,1,2,3)]).Hrepresentation()
|
|
63
|
+
(An inequality (1, 2, 3) x + 4 >= 0,)
|
|
64
|
+
|
|
65
|
+
The difference between hyperplanes as implemented in this module and
|
|
66
|
+
hyperplane arrangements is that:
|
|
67
|
+
|
|
68
|
+
* hyperplane arrangements contain multiple hyperplanes (of course),
|
|
69
|
+
|
|
70
|
+
* linear expressions are a module over the base ring, and these module
|
|
71
|
+
structure is inherited by the hyperplanes.
|
|
72
|
+
|
|
73
|
+
The latter means that you can add and multiply by a scalar::
|
|
74
|
+
|
|
75
|
+
sage: h = 3*x + 2*y - 5*z - 7; h
|
|
76
|
+
Hyperplane 3*x + 2*y - 5*z - 7
|
|
77
|
+
sage: -h
|
|
78
|
+
Hyperplane -3*x - 2*y + 5*z + 7
|
|
79
|
+
sage: h + x
|
|
80
|
+
Hyperplane 4*x + 2*y - 5*z - 7
|
|
81
|
+
sage: h + 7
|
|
82
|
+
Hyperplane 3*x + 2*y - 5*z + 0
|
|
83
|
+
sage: 3*h
|
|
84
|
+
Hyperplane 9*x + 6*y - 15*z - 21
|
|
85
|
+
sage: h * RDF(3)
|
|
86
|
+
Hyperplane 9.0*x + 6.0*y - 15.0*z - 21.0
|
|
87
|
+
|
|
88
|
+
Which you can't do with hyperplane arrangements::
|
|
89
|
+
|
|
90
|
+
sage: arrangement = H(h, x, y, x+y-1); arrangement
|
|
91
|
+
Arrangement <y | x | x + y - 1 | 3*x + 2*y - 5*z - 7>
|
|
92
|
+
sage: arrangement + x
|
|
93
|
+
Traceback (most recent call last):
|
|
94
|
+
...
|
|
95
|
+
TypeError: unsupported operand parent(s) for +:
|
|
96
|
+
'Hyperplane arrangements in 3-dimensional linear space
|
|
97
|
+
over Rational Field with coordinates x, y, z' and
|
|
98
|
+
'Hyperplane arrangements in 3-dimensional linear space
|
|
99
|
+
over Rational Field with coordinates x, y, z'
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
# *****************************************************************************
|
|
103
|
+
# Copyright (C) 2013 David Perkinson <davidp@reed.edu>
|
|
104
|
+
# Volker Braun <vbraun.name@gmail.com>
|
|
105
|
+
#
|
|
106
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
107
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
108
|
+
# the License, or (at your option) any later version.
|
|
109
|
+
# http://www.gnu.org/licenses/
|
|
110
|
+
# *****************************************************************************
|
|
111
|
+
|
|
112
|
+
import sage.geometry.abc
|
|
113
|
+
|
|
114
|
+
from sage.geometry.linear_expression import LinearExpression, LinearExpressionModule
|
|
115
|
+
from sage.misc.cachefunc import cached_method
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class Hyperplane(LinearExpression):
|
|
119
|
+
"""
|
|
120
|
+
A hyperplane.
|
|
121
|
+
|
|
122
|
+
You should always use :class:`AmbientVectorSpace` to construct
|
|
123
|
+
instances of this class.
|
|
124
|
+
|
|
125
|
+
INPUT:
|
|
126
|
+
|
|
127
|
+
- ``parent`` -- the parent :class:`AmbientVectorSpace`
|
|
128
|
+
|
|
129
|
+
- ``coefficients`` -- a vector of coefficients of the linear variables
|
|
130
|
+
|
|
131
|
+
- ``constant`` -- the constant term for the linear expression
|
|
132
|
+
|
|
133
|
+
EXAMPLES::
|
|
134
|
+
|
|
135
|
+
sage: H.<x,y> = HyperplaneArrangements(QQ)
|
|
136
|
+
sage: x+y-1
|
|
137
|
+
Hyperplane x + y - 1
|
|
138
|
+
|
|
139
|
+
sage: ambient = H.ambient_space()
|
|
140
|
+
sage: ambient._element_constructor_(x+y-1)
|
|
141
|
+
Hyperplane x + y - 1
|
|
142
|
+
|
|
143
|
+
For technical reasons, we must allow the degenerate cases of
|
|
144
|
+
an empty space and of a full space::
|
|
145
|
+
|
|
146
|
+
sage: 0*x
|
|
147
|
+
Hyperplane 0*x + 0*y + 0
|
|
148
|
+
sage: 0*x + 1
|
|
149
|
+
Hyperplane 0*x + 0*y + 1
|
|
150
|
+
sage: x + 0 == x + ambient(0) # because coercion requires them
|
|
151
|
+
True
|
|
152
|
+
"""
|
|
153
|
+
def __init__(self, parent, coefficients, constant):
|
|
154
|
+
"""
|
|
155
|
+
Initialize ``self``.
|
|
156
|
+
|
|
157
|
+
TESTS::
|
|
158
|
+
|
|
159
|
+
sage: H.<x,y> = HyperplaneArrangements(QQ)
|
|
160
|
+
sage: x.change_ring(RR)
|
|
161
|
+
Hyperplane 1.00000000000000*x + 0.000000000000000*y + 0.000000000000000
|
|
162
|
+
sage: TestSuite(x+y-1).run()
|
|
163
|
+
"""
|
|
164
|
+
super().__init__(parent, coefficients, constant)
|
|
165
|
+
|
|
166
|
+
def _repr_(self):
|
|
167
|
+
"""
|
|
168
|
+
Return a string representation.
|
|
169
|
+
|
|
170
|
+
OUTPUT: string
|
|
171
|
+
|
|
172
|
+
EXAMPLES::
|
|
173
|
+
|
|
174
|
+
sage: H.<x> = HyperplaneArrangements(QQ)
|
|
175
|
+
sage: x._repr_()
|
|
176
|
+
'Hyperplane x + 0'
|
|
177
|
+
"""
|
|
178
|
+
return 'Hyperplane {0}'.format(self._repr_linear())
|
|
179
|
+
|
|
180
|
+
def _latex_(self):
|
|
181
|
+
r"""
|
|
182
|
+
Return a LaTeX representation.
|
|
183
|
+
|
|
184
|
+
OUTPUT: string
|
|
185
|
+
|
|
186
|
+
EXAMPLES::
|
|
187
|
+
|
|
188
|
+
sage: H.<x> = HyperplaneArrangements(QQ)
|
|
189
|
+
sage: V = H.ambient_space()
|
|
190
|
+
sage: V([2, -3])._latex_()
|
|
191
|
+
'$-3x = -2$'
|
|
192
|
+
|
|
193
|
+
sage: H.<x, y, z> = HyperplaneArrangements(QQ)
|
|
194
|
+
sage: V = H.ambient_space()
|
|
195
|
+
sage: V([-5, 1, 3, 0])._latex_()
|
|
196
|
+
'$x + 3y = 5$'
|
|
197
|
+
sage: V([4, 1, 0, -1])._latex_()
|
|
198
|
+
'$x - z = -4$'
|
|
199
|
+
"""
|
|
200
|
+
linear = self._repr_linear(include_zero=False, include_constant=False, multiplication='')
|
|
201
|
+
s = '{0} = {1}'.format(linear, -self.b())
|
|
202
|
+
return '${0}$'.format(s)
|
|
203
|
+
|
|
204
|
+
def normal(self):
|
|
205
|
+
"""
|
|
206
|
+
Return the normal vector.
|
|
207
|
+
|
|
208
|
+
OUTPUT: a vector over the base ring
|
|
209
|
+
|
|
210
|
+
EXAMPLES::
|
|
211
|
+
|
|
212
|
+
sage: H.<x, y, z> = HyperplaneArrangements(QQ)
|
|
213
|
+
sage: x.normal()
|
|
214
|
+
(1, 0, 0)
|
|
215
|
+
sage: x.A(), x.b()
|
|
216
|
+
((1, 0, 0), 0)
|
|
217
|
+
sage: (x + 2*y + 3*z + 4).normal()
|
|
218
|
+
(1, 2, 3)
|
|
219
|
+
"""
|
|
220
|
+
return self.A()
|
|
221
|
+
|
|
222
|
+
def _normal_pivot(self):
|
|
223
|
+
"""
|
|
224
|
+
Return the index of the largest entry of the normal vector.
|
|
225
|
+
|
|
226
|
+
OUTPUT: integer; the index of the largest entry
|
|
227
|
+
|
|
228
|
+
EXAMPLES::
|
|
229
|
+
|
|
230
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
231
|
+
sage: V = H.ambient_space()
|
|
232
|
+
sage: (x + 3/2*y - 2*z)._normal_pivot()
|
|
233
|
+
2
|
|
234
|
+
|
|
235
|
+
sage: H.<x,y,z> = HyperplaneArrangements(GF(5))
|
|
236
|
+
sage: V = H.ambient_space()
|
|
237
|
+
sage: (x + 3*y - 4*z)._normal_pivot()
|
|
238
|
+
1
|
|
239
|
+
"""
|
|
240
|
+
try:
|
|
241
|
+
values = [abs(x) for x in self.A()]
|
|
242
|
+
except ArithmeticError:
|
|
243
|
+
from sage.rings.real_double import RDF
|
|
244
|
+
values = [abs(RDF(x)) for x in self.A()]
|
|
245
|
+
max_pos = 0
|
|
246
|
+
max_value = values[max_pos]
|
|
247
|
+
for i in range(1, len(values)):
|
|
248
|
+
if values[i] > max_value:
|
|
249
|
+
max_pos = i
|
|
250
|
+
max_value = values[i]
|
|
251
|
+
return max_pos
|
|
252
|
+
|
|
253
|
+
def __contains__(self, q):
|
|
254
|
+
r"""
|
|
255
|
+
Test whether the point ``q`` is in the hyperplane.
|
|
256
|
+
|
|
257
|
+
INPUT:
|
|
258
|
+
|
|
259
|
+
- ``q`` -- point (as a vector, list, or tuple)
|
|
260
|
+
|
|
261
|
+
OUTPUT: boolean
|
|
262
|
+
|
|
263
|
+
EXAMPLES::
|
|
264
|
+
|
|
265
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
266
|
+
sage: h = x + y + z - 1
|
|
267
|
+
sage: (1/3, 1/3, 1/3) in h
|
|
268
|
+
True
|
|
269
|
+
sage: (0,0,0) in h
|
|
270
|
+
False
|
|
271
|
+
"""
|
|
272
|
+
V = self.parent().ambient_vector_space()
|
|
273
|
+
q = V(q)
|
|
274
|
+
return self.A() * q + self._const == 0
|
|
275
|
+
|
|
276
|
+
@cached_method
|
|
277
|
+
def polyhedron(self, **kwds):
|
|
278
|
+
"""
|
|
279
|
+
Return the hyperplane as a polyhedron.
|
|
280
|
+
|
|
281
|
+
OUTPUT: a :func:`~sage.geometry.polyhedron.constructor.Polyhedron` instance
|
|
282
|
+
|
|
283
|
+
EXAMPLES::
|
|
284
|
+
|
|
285
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
286
|
+
sage: h = x + 2*y + 3*z - 4
|
|
287
|
+
sage: P = h.polyhedron(); P
|
|
288
|
+
A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex and 2 lines
|
|
289
|
+
sage: P.Hrepresentation()
|
|
290
|
+
(An equation (1, 2, 3) x - 4 == 0,)
|
|
291
|
+
sage: P.Vrepresentation()
|
|
292
|
+
(A line in the direction (0, 3, -2),
|
|
293
|
+
A line in the direction (3, 0, -1),
|
|
294
|
+
A vertex at (0, 0, 4/3))
|
|
295
|
+
"""
|
|
296
|
+
from sage.geometry.polyhedron.constructor import Polyhedron
|
|
297
|
+
R = kwds.pop('base_ring', None)
|
|
298
|
+
if R is None:
|
|
299
|
+
R = self.parent().base_ring()
|
|
300
|
+
return Polyhedron(eqns=[self.coefficients()], base_ring=R, **kwds)
|
|
301
|
+
|
|
302
|
+
@cached_method
|
|
303
|
+
def linear_part(self):
|
|
304
|
+
r"""
|
|
305
|
+
The linear part of the affine space.
|
|
306
|
+
|
|
307
|
+
OUTPUT:
|
|
308
|
+
|
|
309
|
+
Vector subspace of the ambient vector space, parallel to the
|
|
310
|
+
hyperplane.
|
|
311
|
+
|
|
312
|
+
EXAMPLES::
|
|
313
|
+
|
|
314
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
315
|
+
sage: h = x + 2*y + 3*z - 1
|
|
316
|
+
sage: h.linear_part()
|
|
317
|
+
Vector space of degree 3 and dimension 2 over Rational Field
|
|
318
|
+
Basis matrix:
|
|
319
|
+
[ 1 0 -1/3]
|
|
320
|
+
[ 0 1 -2/3]
|
|
321
|
+
"""
|
|
322
|
+
AA = self.parent().ambient_module()
|
|
323
|
+
from sage.matrix.constructor import matrix
|
|
324
|
+
return matrix(AA.base_ring(), [self.A()]).right_kernel()
|
|
325
|
+
|
|
326
|
+
def linear_part_projection(self, point):
|
|
327
|
+
"""
|
|
328
|
+
Orthogonal projection onto the linear part.
|
|
329
|
+
|
|
330
|
+
INPUT:
|
|
331
|
+
|
|
332
|
+
- ``point`` -- vector of the ambient space, or anything that
|
|
333
|
+
can be converted into one; not necessarily on the
|
|
334
|
+
hyperplane
|
|
335
|
+
|
|
336
|
+
OUTPUT:
|
|
337
|
+
|
|
338
|
+
Coordinate vector of the projection of ``point`` with respect
|
|
339
|
+
to the basis of :meth:`linear_part`. In particular, the length
|
|
340
|
+
of this vector is one less than the ambient space
|
|
341
|
+
dimension.
|
|
342
|
+
|
|
343
|
+
EXAMPLES::
|
|
344
|
+
|
|
345
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
346
|
+
sage: h = x + 2*y + 3*z - 4
|
|
347
|
+
sage: h.linear_part()
|
|
348
|
+
Vector space of degree 3 and dimension 2 over Rational Field
|
|
349
|
+
Basis matrix:
|
|
350
|
+
[ 1 0 -1/3]
|
|
351
|
+
[ 0 1 -2/3]
|
|
352
|
+
sage: p1 = h.linear_part_projection(0); p1
|
|
353
|
+
(0, 0)
|
|
354
|
+
sage: p2 = h.linear_part_projection([3,4,5]); p2
|
|
355
|
+
(8/7, 2/7)
|
|
356
|
+
sage: h.linear_part().basis()
|
|
357
|
+
[(1, 0, -1/3), (0, 1, -2/3)]
|
|
358
|
+
sage: p3 = h.linear_part_projection([1,1,1]); p3
|
|
359
|
+
(4/7, 1/7)
|
|
360
|
+
"""
|
|
361
|
+
point = self.orthogonal_projection(point) - self.point()
|
|
362
|
+
return self.linear_part().coordinate_vector(point)
|
|
363
|
+
|
|
364
|
+
@cached_method
|
|
365
|
+
def point(self):
|
|
366
|
+
"""
|
|
367
|
+
Return the point closest to the origin.
|
|
368
|
+
|
|
369
|
+
OUTPUT:
|
|
370
|
+
|
|
371
|
+
A vector of the ambient vector space. The closest point to the
|
|
372
|
+
origin in the `L^2`-norm.
|
|
373
|
+
|
|
374
|
+
In finite characteristic a random point will be returned if
|
|
375
|
+
the norm of the hyperplane normal vector is zero.
|
|
376
|
+
|
|
377
|
+
EXAMPLES::
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
381
|
+
sage: h = x + 2*y + 3*z - 4
|
|
382
|
+
sage: h.point()
|
|
383
|
+
(2/7, 4/7, 6/7)
|
|
384
|
+
sage: h.point() in h
|
|
385
|
+
True
|
|
386
|
+
|
|
387
|
+
sage: # needs sage.rings.finite_rings
|
|
388
|
+
sage: H.<x,y,z> = HyperplaneArrangements(GF(3))
|
|
389
|
+
sage: h = 2*x + y + z + 1
|
|
390
|
+
sage: h.point()
|
|
391
|
+
(1, 0, 0)
|
|
392
|
+
sage: h.point().base_ring()
|
|
393
|
+
Finite Field of size 3
|
|
394
|
+
|
|
395
|
+
sage: H.<x,y,z> = HyperplaneArrangements(GF(3))
|
|
396
|
+
sage: h = x + y + z + 1
|
|
397
|
+
sage: h.point()
|
|
398
|
+
(2, 0, 0)
|
|
399
|
+
"""
|
|
400
|
+
P = self.parent()
|
|
401
|
+
AA = P.ambient_module()
|
|
402
|
+
R = P.base_ring()
|
|
403
|
+
norm2 = sum(x**2 for x in self.A())
|
|
404
|
+
if norm2 == 0:
|
|
405
|
+
from sage.matrix.constructor import matrix, vector
|
|
406
|
+
solution = matrix(R, self.A()).solve_right(vector(R, [-self.b()]))
|
|
407
|
+
else:
|
|
408
|
+
solution = [-x * self.b() / norm2 for x in self.A()]
|
|
409
|
+
return AA(solution)
|
|
410
|
+
|
|
411
|
+
def dimension(self):
|
|
412
|
+
r"""
|
|
413
|
+
The dimension of the hyperplane.
|
|
414
|
+
|
|
415
|
+
OUTPUT: integer
|
|
416
|
+
|
|
417
|
+
EXAMPLES::
|
|
418
|
+
|
|
419
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
420
|
+
sage: h = x + y + z - 1
|
|
421
|
+
sage: h.dimension()
|
|
422
|
+
2
|
|
423
|
+
"""
|
|
424
|
+
return self.linear_part().dimension()
|
|
425
|
+
|
|
426
|
+
def intersection(self, other):
|
|
427
|
+
r"""
|
|
428
|
+
The intersection of ``self`` with ``other``.
|
|
429
|
+
|
|
430
|
+
INPUT:
|
|
431
|
+
|
|
432
|
+
- ``other`` -- a hyperplane, a polyhedron, or something that
|
|
433
|
+
defines a polyhedron
|
|
434
|
+
|
|
435
|
+
OUTPUT: a polyhedron
|
|
436
|
+
|
|
437
|
+
EXAMPLES::
|
|
438
|
+
|
|
439
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
440
|
+
sage: h = x + y + z - 1
|
|
441
|
+
sage: h.intersection(x - y)
|
|
442
|
+
A 1-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex and 1 line
|
|
443
|
+
sage: h.intersection(polytopes.cube())
|
|
444
|
+
A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 3 vertices
|
|
445
|
+
"""
|
|
446
|
+
from sage.geometry.polyhedron.constructor import Polyhedron
|
|
447
|
+
if not isinstance(other, sage.geometry.abc.Polyhedron):
|
|
448
|
+
try:
|
|
449
|
+
other = other.polyhedron()
|
|
450
|
+
except AttributeError:
|
|
451
|
+
other = Polyhedron(other)
|
|
452
|
+
return self.polyhedron().intersection(other)
|
|
453
|
+
|
|
454
|
+
def orthogonal_projection(self, point):
|
|
455
|
+
"""
|
|
456
|
+
Return the orthogonal projection of a point.
|
|
457
|
+
|
|
458
|
+
INPUT:
|
|
459
|
+
|
|
460
|
+
- ``point`` -- vector of the ambient space, or anything that
|
|
461
|
+
can be converted into one; not necessarily on the
|
|
462
|
+
hyperplane
|
|
463
|
+
|
|
464
|
+
OUTPUT:
|
|
465
|
+
|
|
466
|
+
A vector in the ambient vector space that lies on the
|
|
467
|
+
hyperplane.
|
|
468
|
+
|
|
469
|
+
In finite characteristic, a :exc:`ValueError` is raised if the
|
|
470
|
+
the norm of the hyperplane normal is zero.
|
|
471
|
+
|
|
472
|
+
EXAMPLES::
|
|
473
|
+
|
|
474
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
475
|
+
sage: h = x + 2*y + 3*z - 4
|
|
476
|
+
sage: p1 = h.orthogonal_projection(0); p1
|
|
477
|
+
(2/7, 4/7, 6/7)
|
|
478
|
+
sage: p1 in h
|
|
479
|
+
True
|
|
480
|
+
sage: p2 = h.orthogonal_projection([3,4,5]); p2
|
|
481
|
+
(10/7, 6/7, 2/7)
|
|
482
|
+
sage: p1 in h
|
|
483
|
+
True
|
|
484
|
+
sage: p3 = h.orthogonal_projection([1,1,1]); p3
|
|
485
|
+
(6/7, 5/7, 4/7)
|
|
486
|
+
sage: p3 in h
|
|
487
|
+
True
|
|
488
|
+
"""
|
|
489
|
+
P = self.parent()
|
|
490
|
+
norm2 = sum(x**2 for x in self.A())
|
|
491
|
+
if norm2 == 0:
|
|
492
|
+
raise ValueError('norm of hyperplane normal is zero')
|
|
493
|
+
point = P.ambient_vector_space()(point)
|
|
494
|
+
n = self.normal()
|
|
495
|
+
return point - n * (self.b() + point*n) / norm2
|
|
496
|
+
|
|
497
|
+
def primitive(self, signed=True):
|
|
498
|
+
"""
|
|
499
|
+
Return hyperplane defined by primitive equation.
|
|
500
|
+
|
|
501
|
+
INPUT:
|
|
502
|
+
|
|
503
|
+
- ``signed`` -- boolean (default: ``True``); whether
|
|
504
|
+
to preserve the overall sign
|
|
505
|
+
|
|
506
|
+
OUTPUT:
|
|
507
|
+
|
|
508
|
+
Hyperplane whose linear expression has common factors and
|
|
509
|
+
denominators cleared. That is, the same hyperplane (with the
|
|
510
|
+
same sign) but defined by a rescaled equation. Note that
|
|
511
|
+
different linear expressions must define different hyperplanes
|
|
512
|
+
as comparison is used in caching.
|
|
513
|
+
|
|
514
|
+
If ``signed``, the overall rescaling is by a positive constant
|
|
515
|
+
only.
|
|
516
|
+
|
|
517
|
+
EXAMPLES::
|
|
518
|
+
|
|
519
|
+
sage: H.<x,y> = HyperplaneArrangements(QQ)
|
|
520
|
+
sage: h = -1/3*x + 1/2*y - 1; h
|
|
521
|
+
Hyperplane -1/3*x + 1/2*y - 1
|
|
522
|
+
sage: h.primitive()
|
|
523
|
+
Hyperplane -2*x + 3*y - 6
|
|
524
|
+
sage: h == h.primitive()
|
|
525
|
+
False
|
|
526
|
+
sage: (4*x + 8).primitive()
|
|
527
|
+
Hyperplane x + 0*y + 2
|
|
528
|
+
|
|
529
|
+
sage: (4*x - y - 8).primitive(signed=True) # default
|
|
530
|
+
Hyperplane 4*x - y - 8
|
|
531
|
+
sage: (4*x - y - 8).primitive(signed=False)
|
|
532
|
+
Hyperplane -4*x + y + 8
|
|
533
|
+
|
|
534
|
+
TESTS:
|
|
535
|
+
|
|
536
|
+
Check that :issue:`30078` is fixed::
|
|
537
|
+
|
|
538
|
+
sage: # needs sage.rings.number_field
|
|
539
|
+
sage: R.<sqrt2> = QuadraticField(2)
|
|
540
|
+
sage: H.<x,y> = HyperplaneArrangements(base_ring=R)
|
|
541
|
+
sage: B = H([1,1,0], [2,2,0], [sqrt2,sqrt2,0])
|
|
542
|
+
sage: B
|
|
543
|
+
Arrangement <x + 1>
|
|
544
|
+
|
|
545
|
+
Check that :issue:`30749` is fixed::
|
|
546
|
+
|
|
547
|
+
sage: # needs sage.rings.number_field
|
|
548
|
+
sage: tau = (1+AA(5).sqrt()) / 2
|
|
549
|
+
sage: ncn = [[2*tau+1,2*tau,tau],[2*tau+2,2*tau+1,tau+1]]
|
|
550
|
+
sage: ncn += [[tau+1,tau+1,tau],[2*tau,2*tau,tau],[tau+1,tau+1,1]]
|
|
551
|
+
sage: ncn += [[1,1,1],[1,1,0],[0,1,0],[1,0,0],[tau+1,tau,tau]]
|
|
552
|
+
sage: H = HyperplaneArrangements(AA,names='xyz')
|
|
553
|
+
sage: A = H([[0]+v for v in ncn])
|
|
554
|
+
sage: A.n_regions()
|
|
555
|
+
60
|
|
556
|
+
"""
|
|
557
|
+
from sage.rings.rational_field import QQ
|
|
558
|
+
base_ring = self.parent().base_ring()
|
|
559
|
+
coeffs = self.coefficients()
|
|
560
|
+
# first check if the linear expression even defines a hyperplane
|
|
561
|
+
if self.is_zero():
|
|
562
|
+
raise ValueError('linear expression must be non-constant to define a hyperplane')
|
|
563
|
+
# for scalar adjustment over the base ring QQ,
|
|
564
|
+
# get rid of the denominators and use gcd
|
|
565
|
+
if base_ring is QQ:
|
|
566
|
+
from sage.arith.functions import lcm
|
|
567
|
+
from sage.arith.misc import gcd
|
|
568
|
+
d = lcm(x.denominator() for x in coeffs)
|
|
569
|
+
n = gcd(x.numerator() for x in coeffs)
|
|
570
|
+
adjustment = d/n
|
|
571
|
+
# over other base rings, rescale the coefficients so that
|
|
572
|
+
# the first nonzero of the normal vector is one or negative one
|
|
573
|
+
else:
|
|
574
|
+
for x in coeffs[1:]:
|
|
575
|
+
if not x.is_zero():
|
|
576
|
+
adjustment = x.inverse_of_unit()
|
|
577
|
+
if x < 0: # avoid accidental sign reversal
|
|
578
|
+
adjustment = -adjustment
|
|
579
|
+
break
|
|
580
|
+
# if ``signed`` is not set, adjust the sign
|
|
581
|
+
if not signed:
|
|
582
|
+
for x in coeffs:
|
|
583
|
+
if not x.is_zero():
|
|
584
|
+
if x < 0:
|
|
585
|
+
adjustment = -adjustment
|
|
586
|
+
break
|
|
587
|
+
# return the rescaled hyperplane
|
|
588
|
+
return self.parent(adjustment * self)
|
|
589
|
+
|
|
590
|
+
@cached_method
|
|
591
|
+
def _affine_subspace(self):
|
|
592
|
+
"""
|
|
593
|
+
Return the hyperplane as affine subspace.
|
|
594
|
+
|
|
595
|
+
OUTPUT:
|
|
596
|
+
|
|
597
|
+
The hyperplane as a
|
|
598
|
+
:class:`~sage.geometry.hyperplane_arrangement.affine_subspace.AffineSubspace`.
|
|
599
|
+
|
|
600
|
+
EXAMPLES::
|
|
601
|
+
|
|
602
|
+
sage: H.<x,y> = HyperplaneArrangements(QQ)
|
|
603
|
+
sage: h = -1/3*x + 1/2*y - 1; h
|
|
604
|
+
Hyperplane -1/3*x + 1/2*y - 1
|
|
605
|
+
sage: h._affine_subspace()
|
|
606
|
+
Affine space p + W where:
|
|
607
|
+
p = (-12/13, 18/13)
|
|
608
|
+
W = Vector space of degree 2 and dimension 1 over Rational Field
|
|
609
|
+
Basis matrix:
|
|
610
|
+
[ 1 2/3]
|
|
611
|
+
"""
|
|
612
|
+
from sage.geometry.hyperplane_arrangement.affine_subspace import AffineSubspace
|
|
613
|
+
return AffineSubspace(self.point(), self.linear_part())
|
|
614
|
+
|
|
615
|
+
def plot(self, **kwds):
|
|
616
|
+
"""
|
|
617
|
+
Plot the hyperplane.
|
|
618
|
+
|
|
619
|
+
OUTPUT: a graphics object
|
|
620
|
+
|
|
621
|
+
EXAMPLES::
|
|
622
|
+
|
|
623
|
+
sage: L.<x, y> = HyperplaneArrangements(QQ)
|
|
624
|
+
sage: (x + y - 2).plot() # needs sage.plot sage.symbolic
|
|
625
|
+
Graphics object consisting of 2 graphics primitives
|
|
626
|
+
"""
|
|
627
|
+
from sage.geometry.hyperplane_arrangement.plot import plot_hyperplane
|
|
628
|
+
return plot_hyperplane(self, **kwds)
|
|
629
|
+
|
|
630
|
+
def __or__(self, other):
|
|
631
|
+
"""
|
|
632
|
+
Construct hyperplane arrangement from bitwise or.
|
|
633
|
+
|
|
634
|
+
EXAMPLES::
|
|
635
|
+
|
|
636
|
+
sage: L.<x, y> = HyperplaneArrangements(QQ)
|
|
637
|
+
sage: x | y + 1
|
|
638
|
+
Arrangement <y + 1 | x>
|
|
639
|
+
sage: x | [(0,1), 1]
|
|
640
|
+
Arrangement <y + 1 | x>
|
|
641
|
+
|
|
642
|
+
TESTS::
|
|
643
|
+
|
|
644
|
+
sage: (x | y).parent() is L
|
|
645
|
+
True
|
|
646
|
+
"""
|
|
647
|
+
from sage.geometry.hyperplane_arrangement.arrangement import HyperplaneArrangements
|
|
648
|
+
parent = self.parent()
|
|
649
|
+
arrangement = HyperplaneArrangements(parent.base_ring(), names=parent._names)
|
|
650
|
+
return arrangement(self, other)
|
|
651
|
+
|
|
652
|
+
def to_symmetric_space(self):
|
|
653
|
+
"""
|
|
654
|
+
Return ``self`` considered as an element in the corresponding
|
|
655
|
+
symmetric space.
|
|
656
|
+
|
|
657
|
+
EXAMPLES::
|
|
658
|
+
|
|
659
|
+
sage: L.<x, y> = HyperplaneArrangements(QQ)
|
|
660
|
+
sage: h = -1/3*x + 1/2*y
|
|
661
|
+
sage: h.to_symmetric_space()
|
|
662
|
+
-1/3*x + 1/2*y
|
|
663
|
+
|
|
664
|
+
sage: hp = -1/3*x + 1/2*y - 1
|
|
665
|
+
sage: hp.to_symmetric_space()
|
|
666
|
+
Traceback (most recent call last):
|
|
667
|
+
...
|
|
668
|
+
ValueError: the hyperplane must pass through the origin
|
|
669
|
+
"""
|
|
670
|
+
coeff = self.coefficients()
|
|
671
|
+
if coeff[0] != 0:
|
|
672
|
+
raise ValueError("the hyperplane must pass through the origin")
|
|
673
|
+
S = self.parent().symmetric_space()
|
|
674
|
+
G = S.gens()
|
|
675
|
+
# We skip the first coefficient since it corresponds to the constant term
|
|
676
|
+
return S.sum(G[i]*c for i, c in enumerate(coeff[1:]))
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
class AmbientVectorSpace(LinearExpressionModule):
|
|
680
|
+
"""
|
|
681
|
+
The ambient space for hyperplanes.
|
|
682
|
+
|
|
683
|
+
This class is the parent for the :class:`Hyperplane` instances.
|
|
684
|
+
|
|
685
|
+
TESTS::
|
|
686
|
+
|
|
687
|
+
sage: from sage.geometry.hyperplane_arrangement.hyperplane import AmbientVectorSpace
|
|
688
|
+
sage: V = AmbientVectorSpace(QQ, ('x', 'y'))
|
|
689
|
+
sage: V.change_ring(QQ) is V
|
|
690
|
+
True
|
|
691
|
+
"""
|
|
692
|
+
|
|
693
|
+
Element = Hyperplane
|
|
694
|
+
|
|
695
|
+
def _repr_(self):
|
|
696
|
+
"""
|
|
697
|
+
Return a string representation.
|
|
698
|
+
|
|
699
|
+
OUTPUT: string
|
|
700
|
+
|
|
701
|
+
EXAMPLES::
|
|
702
|
+
|
|
703
|
+
sage: from sage.geometry.hyperplane_arrangement.hyperplane import AmbientVectorSpace
|
|
704
|
+
sage: AmbientVectorSpace(QQ, ('x', 'y'))
|
|
705
|
+
2-dimensional linear space over Rational Field with coordinates x, y
|
|
706
|
+
"""
|
|
707
|
+
return '{0}-dimensional linear space over {3} with coordinate{1} {2}'.format(
|
|
708
|
+
self.dimension(),
|
|
709
|
+
's' if self.ngens() > 1 else '',
|
|
710
|
+
', '.join(self._names),
|
|
711
|
+
self.base_ring())
|
|
712
|
+
|
|
713
|
+
def dimension(self):
|
|
714
|
+
"""
|
|
715
|
+
Return the ambient space dimension.
|
|
716
|
+
|
|
717
|
+
OUTPUT: integer
|
|
718
|
+
|
|
719
|
+
EXAMPLES::
|
|
720
|
+
|
|
721
|
+
sage: M.<x,y> = HyperplaneArrangements(QQ)
|
|
722
|
+
sage: x.parent().dimension()
|
|
723
|
+
2
|
|
724
|
+
sage: x.parent() is M.ambient_space()
|
|
725
|
+
True
|
|
726
|
+
sage: x.dimension()
|
|
727
|
+
1
|
|
728
|
+
"""
|
|
729
|
+
return self.ngens()
|
|
730
|
+
|
|
731
|
+
def change_ring(self, base_ring):
|
|
732
|
+
"""
|
|
733
|
+
Return a ambient vector space with a changed base ring.
|
|
734
|
+
|
|
735
|
+
INPUT:
|
|
736
|
+
|
|
737
|
+
- ``base_ring`` -- a ring; the new base ring
|
|
738
|
+
|
|
739
|
+
OUTPUT: a new :class:`AmbientVectorSpace`
|
|
740
|
+
|
|
741
|
+
EXAMPLES::
|
|
742
|
+
|
|
743
|
+
sage: M.<y> = HyperplaneArrangements(QQ)
|
|
744
|
+
sage: V = M.ambient_space()
|
|
745
|
+
sage: V.change_ring(RR)
|
|
746
|
+
1-dimensional linear space over Real Field with 53 bits of precision with coordinate y
|
|
747
|
+
|
|
748
|
+
TESTS::
|
|
749
|
+
|
|
750
|
+
sage: V.change_ring(QQ) is V
|
|
751
|
+
True
|
|
752
|
+
"""
|
|
753
|
+
return AmbientVectorSpace(base_ring, self._names)
|
|
754
|
+
|
|
755
|
+
def symmetric_space(self):
|
|
756
|
+
r"""
|
|
757
|
+
Construct the symmetric space of ``self``.
|
|
758
|
+
|
|
759
|
+
Consider a hyperplane arrangement `A` in the vector space
|
|
760
|
+
`V = k^n`, for some field `k`. The symmetric space is the
|
|
761
|
+
symmetric algebra `S(V^*)` as the polynomial ring
|
|
762
|
+
`k[x_1, x_2, \ldots, x_n]` where `(x_1, x_2, \ldots, x_n)` is
|
|
763
|
+
a basis for `V`.
|
|
764
|
+
|
|
765
|
+
EXAMPLES::
|
|
766
|
+
|
|
767
|
+
sage: H.<x,y,z> = HyperplaneArrangements(QQ)
|
|
768
|
+
sage: A = H.ambient_space()
|
|
769
|
+
sage: A.symmetric_space()
|
|
770
|
+
Multivariate Polynomial Ring in x, y, z over Rational Field
|
|
771
|
+
"""
|
|
772
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
773
|
+
return PolynomialRing(self.base_ring(), self.variable_names())
|