Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/groups/affine_gps/euclidean_group.py
8815 views
1
r"""
2
Euclidean Groups
3
4
AUTHORS:
5
6
- Volker Braun: initial version
7
"""
8
9
##############################################################################
10
# Copyright (C) 2013 Volker Braun <[email protected]>
11
#
12
# Distributed under the terms of the GNU General Public License (GPL)
13
#
14
# The full text of the GPL is available at:
15
#
16
# http://www.gnu.org/licenses/
17
##############################################################################
18
19
20
from sage.categories.groups import Groups
21
from sage.groups.group import Group
22
from sage.matrix.all import MatrixSpace
23
from sage.modules.all import FreeModule
24
from sage.structure.unique_representation import UniqueRepresentation
25
from sage.misc.cachefunc import cached_method
26
27
from sage.groups.affine_gps.group_element import AffineGroupElement
28
from sage.groups.affine_gps.affine_group import AffineGroup
29
30
31
class EuclideanGroup(AffineGroup):
32
r"""
33
A Euclidean group.
34
35
The Euclidean group `E(A)` (or general affine group) of an affine
36
space `A` is the group of all invertible affine transformations from
37
the space into itself preserving the Euclidean metric.
38
39
If we let `A_V` be the affine space of a vector space `V`
40
(essentially, forgetting what is the origin) then the Euclidean group
41
`E(A_V)` is the group generated by the general linear group `SO(V)`
42
together with the translations. Recall that the group of translations
43
acting on `A_V` is just `V` itself. The general linear and translation
44
subgroups do not quite commute, and in fact generate the semidirect
45
product
46
47
.. MATH::
48
49
E(A_V) = SO(V) \ltimes V.
50
51
As such, the group elements can be represented by pairs `(A,b)` of a
52
matrix and a vector. This pair then represents the transformation
53
54
.. MATH::
55
56
x \mapsto A x + b.
57
58
We can also represent this as a linear transformation in `\dim(V) + 1`
59
dimensional space as
60
61
.. MATH::
62
63
\begin{pmatrix}
64
A & b \\
65
0 & 1
66
\end{pmatrix}
67
68
and lifting `x = (x_1, \ldots, x_n)` to `(x_1, \ldots, x_n, 1)`.
69
70
.. SEEALSO::
71
72
- :class:`AffineGroup`
73
74
INPUT:
75
76
Something that defines an affine space. For example
77
78
- An affine space itself:
79
80
* ``A`` -- affine space
81
82
- A vector space:
83
84
* ``V`` -- a vector space
85
86
- Degree and base ring:
87
88
* ``degree`` -- An integer. The degree of the affine group, that
89
is, the dimension of the affine space the group is acting on.
90
91
* ``ring`` -- A ring or an integer. The base ring of the affine
92
space. If an integer is given, it must be a prime power and
93
the corresponding finite field is constructed.
94
95
* ``var`` -- (Defalut: ``'a'``) Keyword argument to specify the finite
96
field generator name in the case where ``ring`` is a prime power.
97
98
EXAMPLES::
99
100
sage: E3 = EuclideanGroup(3, QQ); E3
101
Euclidean Group of degree 3 over Rational Field
102
sage: E3(matrix(QQ,[(6/7, -2/7, 3/7), (-2/7, 3/7, 6/7), (3/7, 6/7, -2/7)]), vector(QQ,[10,11,12]))
103
[ 6/7 -2/7 3/7] [10]
104
x |-> [-2/7 3/7 6/7] x + [11]
105
[ 3/7 6/7 -2/7] [12]
106
sage: E3([[6/7, -2/7, 3/7], [-2/7, 3/7, 6/7], [3/7, 6/7, -2/7]], [10,11,12])
107
[ 6/7 -2/7 3/7] [10]
108
x |-> [-2/7 3/7 6/7] x + [11]
109
[ 3/7 6/7 -2/7] [12]
110
sage: E3([6/7, -2/7, 3/7, -2/7, 3/7, 6/7, 3/7, 6/7, -2/7], [10,11,12])
111
[ 6/7 -2/7 3/7] [10]
112
x |-> [-2/7 3/7 6/7] x + [11]
113
[ 3/7 6/7 -2/7] [12]
114
115
Instead of specifying the complete matrix/vector information, you can
116
also create special group elements::
117
118
sage: E3.linear([6/7, -2/7, 3/7, -2/7, 3/7, 6/7, 3/7, 6/7, -2/7])
119
[ 6/7 -2/7 3/7] [0]
120
x |-> [-2/7 3/7 6/7] x + [0]
121
[ 3/7 6/7 -2/7] [0]
122
sage: E3.reflection([4,5,6])
123
[ 45/77 -40/77 -48/77] [0]
124
x |-> [-40/77 27/77 -60/77] x + [0]
125
[-48/77 -60/77 5/77] [0]
126
sage: E3.translation([1,2,3])
127
[1 0 0] [1]
128
x |-> [0 1 0] x + [2]
129
[0 0 1] [3]
130
131
Some additional ways to create Euclidean groups::
132
133
sage: A = AffineSpace(2, GF(4,'a')); A
134
Affine Space of dimension 2 over Finite Field in a of size 2^2
135
sage: G = EuclideanGroup(A); G
136
Euclidean Group of degree 2 over Finite Field in a of size 2^2
137
sage: G is EuclideanGroup(2,4) # shorthand
138
True
139
140
sage: V = ZZ^3; V
141
Ambient free module of rank 3 over the principal ideal domain Integer Ring
142
sage: EuclideanGroup(V)
143
Euclidean Group of degree 3 over Integer Ring
144
145
sage: EuclideanGroup(2, QQ)
146
Euclidean Group of degree 2 over Rational Field
147
148
TESTS::
149
150
sage: E6 = EuclideanGroup(6, QQ)
151
sage: E6 is E6
152
True
153
sage: V = QQ^6
154
sage: E6 is EuclideanGroup(V)
155
True
156
sage: G = EuclideanGroup(2, GF(5)); G
157
Euclidean Group of degree 2 over Finite Field of size 5
158
sage: TestSuite(G).run()
159
160
REFERENCES:
161
162
- :wikipedia:`Euclidean_group`
163
"""
164
def _element_constructor_check(self, A, b):
165
"""
166
Verify that ``A``, ``b`` define an affine group element.
167
168
This is called from the group element constructor and can be
169
overridden for subgroups of the affine group. It is guaranteed
170
that ``A``, ``b`` are in the correct matrix/vetor space.
171
172
INPUT:
173
174
- ``A`` -- an element of :meth:`matrix_space`.
175
176
- ``b`` -- an element of :meth:`vector_space`.
177
178
OUTPUT:
179
180
The return value is ignored. You must raise a ``TypeError`` if
181
the input does not define a valid group element.
182
183
TESTS::
184
185
sage: E3 = EuclideanGroup(3, QQ)
186
sage: A = E3.matrix_space()([6/7,-2/7,3/7,-2/7,3/7,6/7,3/7,6/7,-2/7])
187
sage: det(A)
188
-1
189
sage: b = E3.vector_space().an_element()
190
sage: E3._element_constructor_check(A, b)
191
192
sage: A = E3.matrix_space()([1,2,3,4,5,6,7,8,0])
193
sage: det(A)
194
27
195
sage: E3._element_constructor_check(A, b)
196
Traceback (most recent call last):
197
...
198
TypeError: A must be orthogonal (unitary)
199
"""
200
if not A.is_unitary():
201
raise TypeError('A must be orthogonal (unitary)')
202
203
def _latex_(self):
204
r"""
205
EXAMPLES::
206
207
sage: G = EuclideanGroup(6, GF(5))
208
sage: latex(G)
209
\mathrm{E}_{6}(\Bold{F}_{5})
210
"""
211
return "\\mathrm{E}_{%s}(%s)"%(self.degree(), self.base_ring()._latex_())
212
213
def _repr_(self):
214
"""
215
String representation of this group.
216
217
EXAMPLES::
218
219
sage: EuclideanGroup(6, GF(5))
220
Euclidean Group of degree 6 over Finite Field of size 5
221
"""
222
return "Euclidean Group of degree %s over %s"%(self.degree(), self.base_ring())
223
224
def random_element(self):
225
"""
226
Return a random element of this group.
227
228
EXAMPLES::
229
230
sage: G = EuclideanGroup(4, GF(3))
231
sage: G.random_element() # random
232
[2 1 2 1] [1]
233
[1 2 2 1] [0]
234
x |-> [2 2 2 2] x + [1]
235
[1 1 2 2] [2]
236
sage: G.random_element() in G
237
True
238
239
TESTS::
240
241
sage: G.random_element().A().is_unitary()
242
True
243
"""
244
while True:
245
v = self.vector_space().random_element()
246
try:
247
g1 = self.reflection(v)
248
break
249
except ValueError: # v has norm zero
250
pass
251
g2 = self.translation(self.vector_space().random_element())
252
return g1 * g2
253
254
255