Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

r""" 

Euclidean Groups 

 

AUTHORS: 

 

- Volker Braun: initial version 

""" 

 

############################################################################## 

# Copyright (C) 2013 Volker Braun <vbraun.name@gmail.com> 

# 

# Distributed under the terms of the GNU General Public License (GPL) 

# 

# The full text of the GPL is available at: 

# 

# http://www.gnu.org/licenses/ 

############################################################################## 

 

 

from sage.categories.groups import Groups 

from sage.groups.group import Group 

from sage.matrix.all import MatrixSpace 

from sage.modules.all import FreeModule 

from sage.structure.unique_representation import UniqueRepresentation 

from sage.misc.cachefunc import cached_method 

 

from sage.groups.affine_gps.group_element import AffineGroupElement 

from sage.groups.affine_gps.affine_group import AffineGroup 

 

 

class EuclideanGroup(AffineGroup): 

r""" 

an Euclidean group. 

 

The Euclidean group `E(A)` (or general affine group) of an affine 

space `A` is the group of all invertible affine transformations from 

the space into itself preserving the Euclidean metric. 

 

If we let `A_V` be the affine space of a vector space `V` 

(essentially, forgetting what is the origin) then the Euclidean group 

`E(A_V)` is the group generated by the general linear group `SO(V)` 

together with the translations. Recall that the group of translations 

acting on `A_V` is just `V` itself. The general linear and translation 

subgroups do not quite commute, and in fact generate the semidirect 

product 

 

.. MATH:: 

 

E(A_V) = SO(V) \ltimes V. 

 

As such, the group elements can be represented by pairs `(A,b)` of a 

matrix and a vector. This pair then represents the transformation 

 

.. MATH:: 

 

x \mapsto A x + b. 

 

We can also represent this as a linear transformation in `\dim(V) + 1` 

dimensional space as 

 

.. MATH:: 

 

\begin{pmatrix} 

A & b \\ 

0 & 1 

\end{pmatrix} 

 

and lifting `x = (x_1, \ldots, x_n)` to `(x_1, \ldots, x_n, 1)`. 

 

.. SEEALSO:: 

 

- :class:`AffineGroup` 

 

INPUT: 

 

Something that defines an affine space. For example 

 

- An affine space itself: 

 

* ``A`` -- affine space 

 

- A vector space: 

 

* ``V`` -- a vector space 

 

- Degree and base ring: 

 

* ``degree`` -- An integer. The degree of the affine group, that 

is, the dimension of the affine space the group is acting on. 

 

* ``ring`` -- A ring or an integer. The base ring of the affine 

space. If an integer is given, it must be a prime power and 

the corresponding finite field is constructed. 

 

* ``var`` -- (default: ``'a'``) Keyword argument to specify the finite 

field generator name in the case where ``ring`` is a prime power. 

 

EXAMPLES:: 

 

sage: E3 = EuclideanGroup(3, QQ); E3 

Euclidean Group of degree 3 over Rational Field 

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])) 

[ 6/7 -2/7 3/7] [10] 

x |-> [-2/7 3/7 6/7] x + [11] 

[ 3/7 6/7 -2/7] [12] 

sage: E3([[6/7, -2/7, 3/7], [-2/7, 3/7, 6/7], [3/7, 6/7, -2/7]], [10,11,12]) 

[ 6/7 -2/7 3/7] [10] 

x |-> [-2/7 3/7 6/7] x + [11] 

[ 3/7 6/7 -2/7] [12] 

sage: E3([6/7, -2/7, 3/7, -2/7, 3/7, 6/7, 3/7, 6/7, -2/7], [10,11,12]) 

[ 6/7 -2/7 3/7] [10] 

x |-> [-2/7 3/7 6/7] x + [11] 

[ 3/7 6/7 -2/7] [12] 

 

Instead of specifying the complete matrix/vector information, you can 

also create special group elements:: 

 

sage: E3.linear([6/7, -2/7, 3/7, -2/7, 3/7, 6/7, 3/7, 6/7, -2/7]) 

[ 6/7 -2/7 3/7] [0] 

x |-> [-2/7 3/7 6/7] x + [0] 

[ 3/7 6/7 -2/7] [0] 

sage: E3.reflection([4,5,6]) 

[ 45/77 -40/77 -48/77] [0] 

x |-> [-40/77 27/77 -60/77] x + [0] 

[-48/77 -60/77 5/77] [0] 

sage: E3.translation([1,2,3]) 

[1 0 0] [1] 

x |-> [0 1 0] x + [2] 

[0 0 1] [3] 

 

Some additional ways to create Euclidean groups:: 

 

sage: A = AffineSpace(2, GF(4,'a')); A 

Affine Space of dimension 2 over Finite Field in a of size 2^2 

sage: G = EuclideanGroup(A); G 

Euclidean Group of degree 2 over Finite Field in a of size 2^2 

sage: G is EuclideanGroup(2,4) # shorthand 

True 

 

sage: V = ZZ^3; V 

Ambient free module of rank 3 over the principal ideal domain Integer Ring 

sage: EuclideanGroup(V) 

Euclidean Group of degree 3 over Integer Ring 

 

sage: EuclideanGroup(2, QQ) 

Euclidean Group of degree 2 over Rational Field 

 

TESTS:: 

 

sage: E6 = EuclideanGroup(6, QQ) 

sage: E6 is E6 

True 

sage: V = QQ^6 

sage: E6 is EuclideanGroup(V) 

True 

sage: G = EuclideanGroup(2, GF(5)); G 

Euclidean Group of degree 2 over Finite Field of size 5 

sage: TestSuite(G).run() 

 

REFERENCES: 

 

- :wikipedia:`Euclidean_group` 

""" 

def _element_constructor_check(self, A, b): 

""" 

Verify that ``A``, ``b`` define an affine group element. 

 

This is called from the group element constructor and can be 

overridden for subgroups of the affine group. It is guaranteed 

that ``A``, ``b`` are in the correct matrix/vector space. 

 

INPUT: 

 

- ``A`` -- an element of :meth:`matrix_space`. 

 

- ``b`` -- an element of :meth:`vector_space`. 

 

OUTPUT: 

 

The return value is ignored. You must raise a ``TypeError`` if 

the input does not define a valid group element. 

 

TESTS:: 

 

sage: E3 = EuclideanGroup(3, QQ) 

sage: A = E3.matrix_space()([6/7,-2/7,3/7,-2/7,3/7,6/7,3/7,6/7,-2/7]) 

sage: det(A) 

-1 

sage: b = E3.vector_space().an_element() 

sage: E3._element_constructor_check(A, b) 

 

sage: A = E3.matrix_space()([1,2,3,4,5,6,7,8,0]) 

sage: det(A) 

27 

sage: E3._element_constructor_check(A, b) 

Traceback (most recent call last): 

... 

TypeError: A must be orthogonal (unitary) 

""" 

if not A.is_unitary(): 

raise TypeError('A must be orthogonal (unitary)') 

 

def _latex_(self): 

r""" 

EXAMPLES:: 

 

sage: G = EuclideanGroup(6, GF(5)) 

sage: latex(G) 

\mathrm{E}_{6}(\Bold{F}_{5}) 

""" 

return "\\mathrm{E}_{%s}(%s)"%(self.degree(), self.base_ring()._latex_()) 

 

def _repr_(self): 

""" 

String representation of this group. 

 

EXAMPLES:: 

 

sage: EuclideanGroup(6, GF(5)) 

Euclidean Group of degree 6 over Finite Field of size 5 

""" 

return "Euclidean Group of degree %s over %s"%(self.degree(), self.base_ring()) 

 

def random_element(self): 

""" 

Return a random element of this group. 

 

EXAMPLES:: 

 

sage: G = EuclideanGroup(4, GF(3)) 

sage: G.random_element() # random 

[2 1 2 1] [1] 

[1 2 2 1] [0] 

x |-> [2 2 2 2] x + [1] 

[1 1 2 2] [2] 

sage: G.random_element() in G 

True 

 

TESTS:: 

 

sage: G.random_element().A().is_unitary() 

True 

""" 

while True: 

v = self.vector_space().random_element() 

try: 

g1 = self.reflection(v) 

break 

except ValueError: # v has norm zero 

pass 

g2 = self.translation(self.vector_space().random_element()) 

return g1 * g2