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,773 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-polyhedra
|
|
2
|
+
"""
|
|
3
|
+
Linear Expressions
|
|
4
|
+
|
|
5
|
+
A linear expression is just a linear polynomial in some (fixed)
|
|
6
|
+
variables (allowing a nonzero constant term). This class only implements
|
|
7
|
+
linear expressions for others to use.
|
|
8
|
+
|
|
9
|
+
EXAMPLES::
|
|
10
|
+
|
|
11
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
12
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ); L
|
|
13
|
+
Module of linear expressions in variables x, y, z over Rational Field
|
|
14
|
+
sage: x + 2*y + 3*z + 4
|
|
15
|
+
x + 2*y + 3*z + 4
|
|
16
|
+
sage: L(4)
|
|
17
|
+
0*x + 0*y + 0*z + 4
|
|
18
|
+
|
|
19
|
+
You can also pass coefficients and a constant term to construct linear
|
|
20
|
+
expressions::
|
|
21
|
+
|
|
22
|
+
sage: L([1, 2, 3], 4)
|
|
23
|
+
x + 2*y + 3*z + 4
|
|
24
|
+
sage: L([(1, 2, 3), 4])
|
|
25
|
+
x + 2*y + 3*z + 4
|
|
26
|
+
sage: L([4, 1, 2, 3]) # note: constant is first in single-tuple notation
|
|
27
|
+
x + 2*y + 3*z + 4
|
|
28
|
+
|
|
29
|
+
The linear expressions are a module over the base ring, so you can
|
|
30
|
+
add them and multiply them with scalars::
|
|
31
|
+
|
|
32
|
+
sage: m = x + 2*y + 3*z + 4
|
|
33
|
+
sage: 2*m
|
|
34
|
+
2*x + 4*y + 6*z + 8
|
|
35
|
+
sage: m+m
|
|
36
|
+
2*x + 4*y + 6*z + 8
|
|
37
|
+
sage: m-m
|
|
38
|
+
0*x + 0*y + 0*z + 0
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
from sage.structure.parent import Parent
|
|
42
|
+
from sage.structure.richcmp import richcmp
|
|
43
|
+
from sage.structure.element import ModuleElement
|
|
44
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
45
|
+
from sage.misc.cachefunc import cached_method
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class LinearExpression(ModuleElement):
|
|
49
|
+
"""
|
|
50
|
+
A linear expression.
|
|
51
|
+
|
|
52
|
+
A linear expression is just a linear polynomial in some (fixed)
|
|
53
|
+
variables.
|
|
54
|
+
|
|
55
|
+
EXAMPLES::
|
|
56
|
+
|
|
57
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
58
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
59
|
+
sage: m = L([1, 2, 3], 4); m
|
|
60
|
+
x + 2*y + 3*z + 4
|
|
61
|
+
sage: m2 = L([(1, 2, 3), 4]); m2
|
|
62
|
+
x + 2*y + 3*z + 4
|
|
63
|
+
sage: m3 = L([4, 1, 2, 3]); m3 # note: constant is first in single-tuple notation
|
|
64
|
+
x + 2*y + 3*z + 4
|
|
65
|
+
sage: m == m2
|
|
66
|
+
True
|
|
67
|
+
sage: m2 == m3
|
|
68
|
+
True
|
|
69
|
+
sage: L.zero()
|
|
70
|
+
0*x + 0*y + 0*z + 0
|
|
71
|
+
sage: a = L([12, 2/3, -1], -2)
|
|
72
|
+
sage: a - m
|
|
73
|
+
11*x - 4/3*y - 4*z - 6
|
|
74
|
+
sage: LZ.<x,y,z> = LinearExpressionModule(ZZ)
|
|
75
|
+
sage: a - LZ([2, -1, 3], 1)
|
|
76
|
+
10*x + 5/3*y - 4*z - 3
|
|
77
|
+
"""
|
|
78
|
+
def __init__(self, parent, coefficients, constant, check=True):
|
|
79
|
+
"""
|
|
80
|
+
Initialize ``self``.
|
|
81
|
+
|
|
82
|
+
TESTS::
|
|
83
|
+
|
|
84
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
85
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
86
|
+
sage: linear = L([1, 2, 3], 4) # indirect doctest
|
|
87
|
+
sage: linear.parent() is L
|
|
88
|
+
True
|
|
89
|
+
|
|
90
|
+
sage: TestSuite(linear).run()
|
|
91
|
+
"""
|
|
92
|
+
super().__init__(parent)
|
|
93
|
+
self._coeffs = coefficients
|
|
94
|
+
self._const = constant
|
|
95
|
+
if check:
|
|
96
|
+
if self._coeffs.parent() is not self.parent().ambient_module():
|
|
97
|
+
raise ValueError("coefficients are not in the ambient module")
|
|
98
|
+
if not self._coeffs.is_immutable():
|
|
99
|
+
raise ValueError("coefficients are not immutable")
|
|
100
|
+
if self._const.parent() is not self.parent().base_ring():
|
|
101
|
+
raise ValueError("the constant is not in the base ring")
|
|
102
|
+
|
|
103
|
+
def A(self):
|
|
104
|
+
"""
|
|
105
|
+
Return the coefficient vector.
|
|
106
|
+
|
|
107
|
+
OUTPUT: the coefficient vector of the linear expression
|
|
108
|
+
|
|
109
|
+
EXAMPLES::
|
|
110
|
+
|
|
111
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
112
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
113
|
+
sage: linear = L([1, 2, 3], 4); linear
|
|
114
|
+
x + 2*y + 3*z + 4
|
|
115
|
+
sage: linear.A()
|
|
116
|
+
(1, 2, 3)
|
|
117
|
+
sage: linear.b()
|
|
118
|
+
4
|
|
119
|
+
"""
|
|
120
|
+
return self._coeffs
|
|
121
|
+
|
|
122
|
+
def b(self):
|
|
123
|
+
"""
|
|
124
|
+
Return the constant term.
|
|
125
|
+
|
|
126
|
+
OUTPUT: the constant term of the linear expression
|
|
127
|
+
|
|
128
|
+
EXAMPLES::
|
|
129
|
+
|
|
130
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
131
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
132
|
+
sage: linear = L([1, 2, 3], 4); linear
|
|
133
|
+
x + 2*y + 3*z + 4
|
|
134
|
+
sage: linear.A()
|
|
135
|
+
(1, 2, 3)
|
|
136
|
+
sage: linear.b()
|
|
137
|
+
4
|
|
138
|
+
"""
|
|
139
|
+
return self._const
|
|
140
|
+
|
|
141
|
+
constant_term = b
|
|
142
|
+
|
|
143
|
+
def coefficients(self):
|
|
144
|
+
"""
|
|
145
|
+
Return all coefficients.
|
|
146
|
+
|
|
147
|
+
OUTPUT:
|
|
148
|
+
|
|
149
|
+
The constant (as first entry) and coefficients of the linear
|
|
150
|
+
terms (as subsequent entries) in a list.
|
|
151
|
+
|
|
152
|
+
EXAMPLES::
|
|
153
|
+
|
|
154
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
155
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
156
|
+
sage: linear = L([1, 2, 3], 4); linear
|
|
157
|
+
x + 2*y + 3*z + 4
|
|
158
|
+
sage: linear.coefficients()
|
|
159
|
+
[4, 1, 2, 3]
|
|
160
|
+
"""
|
|
161
|
+
return [self._const] + list(self._coeffs)
|
|
162
|
+
|
|
163
|
+
dense_coefficient_list = coefficients
|
|
164
|
+
|
|
165
|
+
def monomial_coefficients(self, copy=True):
|
|
166
|
+
"""
|
|
167
|
+
Return a dictionary whose keys are indices of basis elements in
|
|
168
|
+
the support of ``self`` and whose values are the corresponding
|
|
169
|
+
coefficients.
|
|
170
|
+
|
|
171
|
+
INPUT:
|
|
172
|
+
|
|
173
|
+
- ``copy`` -- ignored
|
|
174
|
+
|
|
175
|
+
EXAMPLES::
|
|
176
|
+
|
|
177
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
178
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
179
|
+
sage: linear = L([1, 2, 3], 4)
|
|
180
|
+
sage: sorted(linear.monomial_coefficients().items(), key=lambda x: str(x[0]))
|
|
181
|
+
[(0, 1), (1, 2), (2, 3), ('b', 4)]
|
|
182
|
+
"""
|
|
183
|
+
zero = self.parent().base_ring().zero()
|
|
184
|
+
d = {i: v for i, v in enumerate(self._coeffs) if v != zero}
|
|
185
|
+
if self._const != zero:
|
|
186
|
+
d['b'] = self._const
|
|
187
|
+
return d
|
|
188
|
+
|
|
189
|
+
def _repr_vector(self, variable='x'):
|
|
190
|
+
"""
|
|
191
|
+
Return a string representation.
|
|
192
|
+
|
|
193
|
+
INPUT:
|
|
194
|
+
|
|
195
|
+
- ``variable`` -- string; the name of the variable vector
|
|
196
|
+
|
|
197
|
+
EXAMPLES::
|
|
198
|
+
|
|
199
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
200
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
201
|
+
sage: L([1, 2, 3], 4)._repr_vector()
|
|
202
|
+
'(1, 2, 3) x + 4 = 0'
|
|
203
|
+
sage: L([-1, -2, -3], -4)._repr_vector('u')
|
|
204
|
+
'(-1, -2, -3) u - 4 = 0'
|
|
205
|
+
"""
|
|
206
|
+
atomic_repr = self.parent().base_ring()._repr_option('element_is_atomic')
|
|
207
|
+
constant = repr(self._const)
|
|
208
|
+
if not atomic_repr:
|
|
209
|
+
constant = '({0})'.format(constant)
|
|
210
|
+
constant = '+ {0}'.format(constant).replace('+ -', '- ')
|
|
211
|
+
return '{0} {1} {2} = 0'.format(repr(self._coeffs), variable, constant)
|
|
212
|
+
|
|
213
|
+
def _repr_linear(self, include_zero=True, include_constant=True, multiplication='*'):
|
|
214
|
+
"""
|
|
215
|
+
Return a representation as a linear polynomial.
|
|
216
|
+
|
|
217
|
+
INPUT:
|
|
218
|
+
|
|
219
|
+
- ``include_zero`` -- whether to include terms with zero
|
|
220
|
+
coefficient
|
|
221
|
+
|
|
222
|
+
- ``include_constant`` -- whether to include the constant
|
|
223
|
+
term
|
|
224
|
+
|
|
225
|
+
- ``multiplication`` -- string (default: ``'*'``); the
|
|
226
|
+
multiplication symbol to use
|
|
227
|
+
|
|
228
|
+
OUTPUT: string
|
|
229
|
+
|
|
230
|
+
EXAMPLES::
|
|
231
|
+
|
|
232
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
233
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
234
|
+
sage: L([1, 2, 3], 4)._repr_linear()
|
|
235
|
+
'x + 2*y + 3*z + 4'
|
|
236
|
+
sage: L([-1, -2, -3], -4)._repr_linear()
|
|
237
|
+
'-x - 2*y - 3*z - 4'
|
|
238
|
+
sage: L([0, 0, 0], 1)._repr_linear()
|
|
239
|
+
'0*x + 0*y + 0*z + 1'
|
|
240
|
+
sage: L([0, 0, 0], 0)._repr_linear()
|
|
241
|
+
'0*x + 0*y + 0*z + 0'
|
|
242
|
+
|
|
243
|
+
sage: R.<u,v> = QQ[]
|
|
244
|
+
sage: L.<x,y,z> = LinearExpressionModule(R)
|
|
245
|
+
sage: L([-u+v+1, -3*u-2, 3], -4*u+v)._repr_linear()
|
|
246
|
+
'(-u + v + 1)*x + (-3*u - 2)*y + 3*z - 4*u + v'
|
|
247
|
+
|
|
248
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
249
|
+
sage: L([1, 0, 3], 0)._repr_linear()
|
|
250
|
+
'x + 0*y + 3*z + 0'
|
|
251
|
+
sage: L([1, 0, 3], 0)._repr_linear(include_zero=False)
|
|
252
|
+
'x + 3*z'
|
|
253
|
+
sage: L([1, 0, 3], 1)._repr_linear(include_constant=False, multiplication='.')
|
|
254
|
+
'x + 0.y + 3.z'
|
|
255
|
+
sage: L([1, 0, 3], 1)._repr_linear(include_zero=False, include_constant=False)
|
|
256
|
+
'x + 3*z'
|
|
257
|
+
sage: L([0, 0, 0], 0)._repr_linear(include_zero=False)
|
|
258
|
+
'0'
|
|
259
|
+
"""
|
|
260
|
+
atomic_repr = self.parent().base_ring()._repr_option('element_is_atomic')
|
|
261
|
+
names = [multiplication + n for n in self.parent()._names]
|
|
262
|
+
terms = list(zip(self._coeffs, names))
|
|
263
|
+
if include_constant:
|
|
264
|
+
terms += [(self._const, '')]
|
|
265
|
+
if not include_zero:
|
|
266
|
+
terms = [t for t in terms if t[0] != 0]
|
|
267
|
+
if len(terms) == 0:
|
|
268
|
+
return '0'
|
|
269
|
+
summands = []
|
|
270
|
+
for coeff, name in terms:
|
|
271
|
+
coeff = str(coeff)
|
|
272
|
+
if not atomic_repr and name != '' and any(c in coeff for c in ['+', '-']):
|
|
273
|
+
coeff = '({0})'.format(coeff)
|
|
274
|
+
summands.append(coeff + name)
|
|
275
|
+
s = ' ' + ' + '.join(summands)
|
|
276
|
+
s = s.replace(' + -', ' - ')
|
|
277
|
+
s = s.replace(' 1' + multiplication, ' ')
|
|
278
|
+
s = s.replace(' -1' + multiplication, ' -')
|
|
279
|
+
return s[1:]
|
|
280
|
+
|
|
281
|
+
_repr_ = _repr_linear
|
|
282
|
+
|
|
283
|
+
def _add_(self, other):
|
|
284
|
+
"""
|
|
285
|
+
Add two linear expressions.
|
|
286
|
+
|
|
287
|
+
EXAMPLES::
|
|
288
|
+
|
|
289
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
290
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
291
|
+
sage: a = L([1, 2, 3], 4)
|
|
292
|
+
sage: b = L([-1, 3, -3], 0)
|
|
293
|
+
sage: a + b
|
|
294
|
+
0*x + 5*y + 0*z + 4
|
|
295
|
+
sage: a - b
|
|
296
|
+
2*x - y + 6*z + 4
|
|
297
|
+
"""
|
|
298
|
+
const = self._const + other._const
|
|
299
|
+
coeffs = self._coeffs + other._coeffs
|
|
300
|
+
coeffs.set_immutable()
|
|
301
|
+
return self.__class__(self.parent(), coeffs, const)
|
|
302
|
+
|
|
303
|
+
def _lmul_(self, scalar):
|
|
304
|
+
"""
|
|
305
|
+
Multiply a linear expression by a scalar.
|
|
306
|
+
|
|
307
|
+
EXAMPLES::
|
|
308
|
+
|
|
309
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
310
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
311
|
+
sage: a = L([1, 2, 3], 4); a
|
|
312
|
+
x + 2*y + 3*z + 4
|
|
313
|
+
sage: 2 * a
|
|
314
|
+
2*x + 4*y + 6*z + 8
|
|
315
|
+
sage: a * 2
|
|
316
|
+
2*x + 4*y + 6*z + 8
|
|
317
|
+
sage: -a
|
|
318
|
+
-x - 2*y - 3*z - 4
|
|
319
|
+
sage: RDF(1) * a
|
|
320
|
+
1.0*x + 2.0*y + 3.0*z + 4.0
|
|
321
|
+
|
|
322
|
+
TESTS::
|
|
323
|
+
|
|
324
|
+
sage: a._lmul_(2)
|
|
325
|
+
2*x + 4*y + 6*z + 8
|
|
326
|
+
"""
|
|
327
|
+
const = scalar * self._const
|
|
328
|
+
coeffs = scalar * self._coeffs
|
|
329
|
+
coeffs.set_immutable()
|
|
330
|
+
return self.__class__(self.parent(), coeffs, const)
|
|
331
|
+
|
|
332
|
+
def _acted_upon_(self, scalar, self_on_left):
|
|
333
|
+
"""
|
|
334
|
+
Action by scalars that do not live in the base ring.
|
|
335
|
+
|
|
336
|
+
EXAMPLES::
|
|
337
|
+
|
|
338
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
339
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
340
|
+
sage: a = x + 2*y + 3*z + 4
|
|
341
|
+
sage: a * RDF(3)
|
|
342
|
+
3.0*x + 6.0*y + 9.0*z + 12.0
|
|
343
|
+
"""
|
|
344
|
+
base_ring = scalar.base_ring()
|
|
345
|
+
parent = self.parent().change_ring(base_ring)
|
|
346
|
+
changed = parent(self)
|
|
347
|
+
return changed._rmul_(scalar)
|
|
348
|
+
|
|
349
|
+
def change_ring(self, base_ring):
|
|
350
|
+
"""
|
|
351
|
+
Change the base ring of this linear expression.
|
|
352
|
+
|
|
353
|
+
INPUT:
|
|
354
|
+
|
|
355
|
+
- ``base_ring`` -- a ring; the new base ring
|
|
356
|
+
|
|
357
|
+
OUTPUT: a new linear expression over the new base ring
|
|
358
|
+
|
|
359
|
+
EXAMPLES::
|
|
360
|
+
|
|
361
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
362
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
363
|
+
sage: a = x + 2*y + 3*z + 4; a
|
|
364
|
+
x + 2*y + 3*z + 4
|
|
365
|
+
sage: a.change_ring(RDF)
|
|
366
|
+
1.0*x + 2.0*y + 3.0*z + 4.0
|
|
367
|
+
"""
|
|
368
|
+
P = self.parent()
|
|
369
|
+
if P.base_ring() is base_ring:
|
|
370
|
+
return self
|
|
371
|
+
return P.change_ring(base_ring)(self)
|
|
372
|
+
|
|
373
|
+
def __hash__(self):
|
|
374
|
+
r"""
|
|
375
|
+
TESTS::
|
|
376
|
+
|
|
377
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
378
|
+
sage: L.<x> = LinearExpressionModule(QQ)
|
|
379
|
+
sage: hash(L([0,1])) == hash((1,))
|
|
380
|
+
True
|
|
381
|
+
"""
|
|
382
|
+
return hash(self._coeffs) ^ hash(self._const)
|
|
383
|
+
|
|
384
|
+
def _richcmp_(self, other, op):
|
|
385
|
+
"""
|
|
386
|
+
Compare two linear expressions.
|
|
387
|
+
|
|
388
|
+
INPUT:
|
|
389
|
+
|
|
390
|
+
- ``other`` -- another linear expression (will be enforced by
|
|
391
|
+
the coercion framework)
|
|
392
|
+
|
|
393
|
+
EXAMPLES::
|
|
394
|
+
|
|
395
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
396
|
+
sage: L.<x> = LinearExpressionModule(QQ)
|
|
397
|
+
sage: x == L([0, 1])
|
|
398
|
+
True
|
|
399
|
+
sage: x == x + 1
|
|
400
|
+
False
|
|
401
|
+
|
|
402
|
+
sage: M.<x> = LinearExpressionModule(ZZ)
|
|
403
|
+
sage: L.gen(0) == M.gen(0) # because there is a conversion
|
|
404
|
+
True
|
|
405
|
+
sage: L.gen(0) == L(M.gen(0)) # this is the conversion
|
|
406
|
+
True
|
|
407
|
+
|
|
408
|
+
sage: x == 'test'
|
|
409
|
+
False
|
|
410
|
+
"""
|
|
411
|
+
return richcmp((self._coeffs, self._const),
|
|
412
|
+
(other._coeffs, other._const), op)
|
|
413
|
+
|
|
414
|
+
def evaluate(self, point):
|
|
415
|
+
"""
|
|
416
|
+
Evaluate the linear expression.
|
|
417
|
+
|
|
418
|
+
INPUT:
|
|
419
|
+
|
|
420
|
+
- ``point`` -- list/tuple/iterable of coordinates; the
|
|
421
|
+
coordinates of a point
|
|
422
|
+
|
|
423
|
+
OUTPUT: the linear expression `Ax + b` evaluated at the point `x`
|
|
424
|
+
|
|
425
|
+
EXAMPLES::
|
|
426
|
+
|
|
427
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
428
|
+
sage: L.<x,y> = LinearExpressionModule(QQ)
|
|
429
|
+
sage: ex = 2*x + 3* y + 4
|
|
430
|
+
sage: ex.evaluate([1,1])
|
|
431
|
+
9
|
|
432
|
+
sage: ex([1,1]) # syntactic sugar
|
|
433
|
+
9
|
|
434
|
+
sage: ex([pi, e]) # needs sage.symbolic
|
|
435
|
+
2*pi + 3*e + 4
|
|
436
|
+
"""
|
|
437
|
+
try:
|
|
438
|
+
point = self.parent().ambient_module()(point)
|
|
439
|
+
except TypeError:
|
|
440
|
+
from sage.matrix.constructor import vector
|
|
441
|
+
point = vector(point)
|
|
442
|
+
return self._coeffs * point + self._const
|
|
443
|
+
|
|
444
|
+
__call__ = evaluate
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
class LinearExpressionModule(Parent, UniqueRepresentation):
|
|
448
|
+
"""
|
|
449
|
+
The module of linear expressions.
|
|
450
|
+
|
|
451
|
+
This is the module of linear polynomials which is the parent for
|
|
452
|
+
linear expressions.
|
|
453
|
+
|
|
454
|
+
EXAMPLES::
|
|
455
|
+
|
|
456
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
457
|
+
sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z'))
|
|
458
|
+
sage: L
|
|
459
|
+
Module of linear expressions in variables x, y, z over Rational Field
|
|
460
|
+
sage: L.an_element()
|
|
461
|
+
x + 0*y + 0*z + 0
|
|
462
|
+
"""
|
|
463
|
+
Element = LinearExpression
|
|
464
|
+
|
|
465
|
+
def __init__(self, base_ring, names=tuple()):
|
|
466
|
+
"""
|
|
467
|
+
Initialize ``self``.
|
|
468
|
+
|
|
469
|
+
TESTS::
|
|
470
|
+
|
|
471
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
472
|
+
sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z'))
|
|
473
|
+
sage: type(L)
|
|
474
|
+
<class 'sage.geometry.linear_expression.LinearExpressionModule_with_category'>
|
|
475
|
+
sage: L.base_ring()
|
|
476
|
+
Rational Field
|
|
477
|
+
|
|
478
|
+
sage: TestSuite(L).run()
|
|
479
|
+
|
|
480
|
+
sage: L = LinearExpressionModule(QQ)
|
|
481
|
+
sage: TestSuite(L).run() # needs sage.rings.real_interval_field
|
|
482
|
+
"""
|
|
483
|
+
from sage.categories.modules import Modules
|
|
484
|
+
super().__init__(base_ring, category=Modules(base_ring).WithBasis().FiniteDimensional())
|
|
485
|
+
self._names = names
|
|
486
|
+
|
|
487
|
+
@cached_method
|
|
488
|
+
def basis(self):
|
|
489
|
+
"""
|
|
490
|
+
Return a basis of ``self``.
|
|
491
|
+
|
|
492
|
+
EXAMPLES::
|
|
493
|
+
|
|
494
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
495
|
+
sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z'))
|
|
496
|
+
sage: list(L.basis())
|
|
497
|
+
[x + 0*y + 0*z + 0,
|
|
498
|
+
0*x + y + 0*z + 0,
|
|
499
|
+
0*x + 0*y + z + 0,
|
|
500
|
+
0*x + 0*y + 0*z + 1]
|
|
501
|
+
"""
|
|
502
|
+
from sage.sets.family import Family
|
|
503
|
+
gens = self.gens()
|
|
504
|
+
d = dict(enumerate(gens))
|
|
505
|
+
d['b'] = self.element_class(self, self.ambient_module().zero(),
|
|
506
|
+
self.base_ring().one())
|
|
507
|
+
return Family(list(range(len(gens))) + ['b'], lambda i: d[i])
|
|
508
|
+
|
|
509
|
+
@cached_method
|
|
510
|
+
def ngens(self):
|
|
511
|
+
"""
|
|
512
|
+
Return the number of linear variables.
|
|
513
|
+
|
|
514
|
+
OUTPUT: integer
|
|
515
|
+
|
|
516
|
+
EXAMPLES::
|
|
517
|
+
|
|
518
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
519
|
+
sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z'))
|
|
520
|
+
sage: L.ngens()
|
|
521
|
+
3
|
|
522
|
+
"""
|
|
523
|
+
return len(self._names)
|
|
524
|
+
|
|
525
|
+
@cached_method
|
|
526
|
+
def gens(self) -> tuple:
|
|
527
|
+
"""
|
|
528
|
+
Return the generators of ``self``.
|
|
529
|
+
|
|
530
|
+
OUTPUT: a tuple of linear expressions, one for each linear variable
|
|
531
|
+
|
|
532
|
+
EXAMPLES::
|
|
533
|
+
|
|
534
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
535
|
+
sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z'))
|
|
536
|
+
sage: L.gens()
|
|
537
|
+
(x + 0*y + 0*z + 0, 0*x + y + 0*z + 0, 0*x + 0*y + z + 0)
|
|
538
|
+
"""
|
|
539
|
+
from sage.matrix.constructor import identity_matrix
|
|
540
|
+
identity = identity_matrix(self.base_ring(), self.ngens())
|
|
541
|
+
return tuple(self(e, 0) for e in identity.rows())
|
|
542
|
+
|
|
543
|
+
def gen(self, i):
|
|
544
|
+
"""
|
|
545
|
+
Return the `i`-th generator.
|
|
546
|
+
|
|
547
|
+
INPUT:
|
|
548
|
+
|
|
549
|
+
- ``i`` -- integer
|
|
550
|
+
|
|
551
|
+
OUTPUT: a linear expression
|
|
552
|
+
|
|
553
|
+
EXAMPLES::
|
|
554
|
+
|
|
555
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
556
|
+
sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z'))
|
|
557
|
+
sage: L.gen(0)
|
|
558
|
+
x + 0*y + 0*z + 0
|
|
559
|
+
"""
|
|
560
|
+
return self.gens()[i]
|
|
561
|
+
|
|
562
|
+
def _element_constructor_(self, arg0, arg1=None):
|
|
563
|
+
"""
|
|
564
|
+
The element constructor.
|
|
565
|
+
|
|
566
|
+
This is part of the Sage parent/element framework.
|
|
567
|
+
|
|
568
|
+
TESTS::
|
|
569
|
+
|
|
570
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
571
|
+
sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z'))
|
|
572
|
+
|
|
573
|
+
Construct from coefficients and constant term::
|
|
574
|
+
|
|
575
|
+
sage: L._element_constructor_([1, 2, 3], 4)
|
|
576
|
+
x + 2*y + 3*z + 4
|
|
577
|
+
sage: L._element_constructor_(vector(ZZ, [1, 2, 3]), 4)
|
|
578
|
+
x + 2*y + 3*z + 4
|
|
579
|
+
|
|
580
|
+
Construct constant linear expression term::
|
|
581
|
+
|
|
582
|
+
sage: L._element_constructor_(4)
|
|
583
|
+
0*x + 0*y + 0*z + 4
|
|
584
|
+
|
|
585
|
+
Construct from list/tuple/iterable::
|
|
586
|
+
|
|
587
|
+
sage: L._element_constructor_(vector([4, 1, 2, 3]))
|
|
588
|
+
x + 2*y + 3*z + 4
|
|
589
|
+
|
|
590
|
+
Construct from a pair ``(coefficients, constant)``::
|
|
591
|
+
|
|
592
|
+
sage: L([(1, 2, 3), 4])
|
|
593
|
+
x + 2*y + 3*z + 4
|
|
594
|
+
|
|
595
|
+
Construct from linear expression::
|
|
596
|
+
|
|
597
|
+
sage: M = LinearExpressionModule(ZZ, ('u', 'v', 'w'))
|
|
598
|
+
sage: m = M([1, 2, 3], 4)
|
|
599
|
+
sage: L._element_constructor_(m)
|
|
600
|
+
x + 2*y + 3*z + 4
|
|
601
|
+
"""
|
|
602
|
+
R = self.base_ring()
|
|
603
|
+
if arg1 is None:
|
|
604
|
+
if arg0 in R:
|
|
605
|
+
const = arg0
|
|
606
|
+
coeffs = self.ambient_module().zero()
|
|
607
|
+
elif isinstance(arg0, LinearExpression):
|
|
608
|
+
# Construct from linear expression
|
|
609
|
+
const = arg0.b()
|
|
610
|
+
coeffs = arg0.A()
|
|
611
|
+
elif isinstance(arg0, (list, tuple)) and len(arg0) == 2 and isinstance(arg0[0], (list, tuple)):
|
|
612
|
+
# Construct from pair
|
|
613
|
+
coeffs = arg0[0]
|
|
614
|
+
const = arg0[1]
|
|
615
|
+
else:
|
|
616
|
+
# Construct from list/tuple/iterable::
|
|
617
|
+
try:
|
|
618
|
+
arg0 = arg0.dense_coefficient_list()
|
|
619
|
+
except AttributeError:
|
|
620
|
+
arg0 = list(arg0)
|
|
621
|
+
const = arg0[0]
|
|
622
|
+
coeffs = arg0[1:]
|
|
623
|
+
else:
|
|
624
|
+
# arg1 is not None, construct from coefficients and constant term
|
|
625
|
+
coeffs = list(arg0)
|
|
626
|
+
const = arg1
|
|
627
|
+
coeffs = self.ambient_module()(coeffs)
|
|
628
|
+
coeffs.set_immutable()
|
|
629
|
+
const = R(const)
|
|
630
|
+
return self.element_class(self, coeffs, const)
|
|
631
|
+
|
|
632
|
+
def random_element(self):
|
|
633
|
+
"""
|
|
634
|
+
Return a random element.
|
|
635
|
+
|
|
636
|
+
EXAMPLES::
|
|
637
|
+
|
|
638
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
639
|
+
sage: L.<x,y,z> = LinearExpressionModule(QQ)
|
|
640
|
+
sage: L.random_element() in L
|
|
641
|
+
True
|
|
642
|
+
"""
|
|
643
|
+
A = self.ambient_module().random_element()
|
|
644
|
+
b = self.base_ring().random_element()
|
|
645
|
+
return self(A, b)
|
|
646
|
+
|
|
647
|
+
@cached_method
|
|
648
|
+
def ambient_module(self):
|
|
649
|
+
"""
|
|
650
|
+
Return the ambient module.
|
|
651
|
+
|
|
652
|
+
.. SEEALSO::
|
|
653
|
+
|
|
654
|
+
:meth:`ambient_vector_space`
|
|
655
|
+
|
|
656
|
+
OUTPUT:
|
|
657
|
+
|
|
658
|
+
The domain of the linear expressions as a free module over the
|
|
659
|
+
base ring.
|
|
660
|
+
|
|
661
|
+
EXAMPLES::
|
|
662
|
+
|
|
663
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
664
|
+
sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z'))
|
|
665
|
+
sage: L.ambient_module()
|
|
666
|
+
Vector space of dimension 3 over Rational Field
|
|
667
|
+
sage: M = LinearExpressionModule(ZZ, ('r', 's'))
|
|
668
|
+
sage: M.ambient_module()
|
|
669
|
+
Ambient free module of rank 2 over the principal ideal domain Integer Ring
|
|
670
|
+
sage: M.ambient_vector_space()
|
|
671
|
+
Vector space of dimension 2 over Rational Field
|
|
672
|
+
"""
|
|
673
|
+
from sage.modules.free_module import FreeModule
|
|
674
|
+
return FreeModule(self.base_ring(), self.ngens())
|
|
675
|
+
|
|
676
|
+
@cached_method
|
|
677
|
+
def ambient_vector_space(self):
|
|
678
|
+
"""
|
|
679
|
+
Return the ambient vector space.
|
|
680
|
+
|
|
681
|
+
.. SEEALSO::
|
|
682
|
+
|
|
683
|
+
:meth:`ambient_module`
|
|
684
|
+
|
|
685
|
+
OUTPUT:
|
|
686
|
+
|
|
687
|
+
The vector space (over the fraction field of the base ring)
|
|
688
|
+
where the linear expressions live.
|
|
689
|
+
|
|
690
|
+
EXAMPLES::
|
|
691
|
+
|
|
692
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
693
|
+
sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z'))
|
|
694
|
+
sage: L.ambient_vector_space()
|
|
695
|
+
Vector space of dimension 3 over Rational Field
|
|
696
|
+
sage: M = LinearExpressionModule(ZZ, ('r', 's'))
|
|
697
|
+
sage: M.ambient_module()
|
|
698
|
+
Ambient free module of rank 2 over the principal ideal domain Integer Ring
|
|
699
|
+
sage: M.ambient_vector_space()
|
|
700
|
+
Vector space of dimension 2 over Rational Field
|
|
701
|
+
"""
|
|
702
|
+
from sage.modules.free_module import VectorSpace
|
|
703
|
+
field = self.base_ring().fraction_field()
|
|
704
|
+
return VectorSpace(field, self.ngens())
|
|
705
|
+
|
|
706
|
+
def _coerce_map_from_(self, P):
|
|
707
|
+
"""
|
|
708
|
+
Return whether there is a coercion.
|
|
709
|
+
|
|
710
|
+
TESTS::
|
|
711
|
+
|
|
712
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
713
|
+
sage: L.<x> = LinearExpressionModule(QQ)
|
|
714
|
+
sage: M.<y> = LinearExpressionModule(ZZ)
|
|
715
|
+
sage: L.coerce_map_from(M)
|
|
716
|
+
Coercion map:
|
|
717
|
+
From: Module of linear expressions in variable y over Integer Ring
|
|
718
|
+
To: Module of linear expressions in variable x over Rational Field
|
|
719
|
+
sage: M.coerce_map_from(L)
|
|
720
|
+
|
|
721
|
+
sage: M.coerce_map_from(ZZ)
|
|
722
|
+
Coercion map:
|
|
723
|
+
From: Integer Ring
|
|
724
|
+
To: Module of linear expressions in variable y over Integer Ring
|
|
725
|
+
sage: M.coerce_map_from(QQ)
|
|
726
|
+
"""
|
|
727
|
+
if self.base().has_coerce_map_from(P):
|
|
728
|
+
return True
|
|
729
|
+
try:
|
|
730
|
+
return self.ngens() == P.ngens() and \
|
|
731
|
+
self.base().has_coerce_map_from(P.base())
|
|
732
|
+
except AttributeError:
|
|
733
|
+
pass
|
|
734
|
+
return super()._coerce_map_from_(P)
|
|
735
|
+
|
|
736
|
+
def _repr_(self):
|
|
737
|
+
"""
|
|
738
|
+
Return a string representation.
|
|
739
|
+
|
|
740
|
+
OUTPUT: string
|
|
741
|
+
|
|
742
|
+
EXAMPLES::
|
|
743
|
+
|
|
744
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
745
|
+
sage: L.<x> = LinearExpressionModule(QQ); L
|
|
746
|
+
Module of linear expressions in variable x over Rational Field
|
|
747
|
+
"""
|
|
748
|
+
return 'Module of linear expressions in variable{2} {0} over {1}'.format(
|
|
749
|
+
', '.join(self._names), self.base_ring(), 's' if self.ngens() > 1 else '')
|
|
750
|
+
|
|
751
|
+
def change_ring(self, base_ring):
|
|
752
|
+
"""
|
|
753
|
+
Return a new module with a changed base ring.
|
|
754
|
+
|
|
755
|
+
INPUT:
|
|
756
|
+
|
|
757
|
+
- ``base_ring`` -- a ring; the new base ring
|
|
758
|
+
|
|
759
|
+
OUTPUT: a new linear expression over the new base ring
|
|
760
|
+
|
|
761
|
+
EXAMPLES::
|
|
762
|
+
|
|
763
|
+
sage: from sage.geometry.linear_expression import LinearExpressionModule
|
|
764
|
+
sage: M.<y> = LinearExpressionModule(ZZ)
|
|
765
|
+
sage: L = M.change_ring(QQ); L
|
|
766
|
+
Module of linear expressions in variable y over Rational Field
|
|
767
|
+
|
|
768
|
+
TESTS::
|
|
769
|
+
|
|
770
|
+
sage: L.change_ring(QQ) is L
|
|
771
|
+
True
|
|
772
|
+
"""
|
|
773
|
+
return LinearExpressionModule(base_ring, self._names)
|