SharedCubicBraidGroup / cubic_braid.pyOpen in CoCalc
Authors: Samuel Lelièvre, Ivan Marin, Andrew Mathas, Sebastian Oehms, Travis Scrimshaw
Description: code directory
1
# This file was *autogenerated* from the file cubic_braid.sage
2
from sage.all_cmdline import * # import sage library
3
_sage_const_3 = Integer(3); _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_7 = Integer(7); _sage_const_6 = Integer(6); _sage_const_5 = Integer(5); _sage_const_4 = Integer(4); _sage_const_100 = Integer(100); _sage_const_1024 = Integer(1024); _sage_const_32 = Integer(32); _sage_const_12 = Integer(12); _sage_const_11 = Integer(11); _sage_const_648 = Integer(648); _sage_const_155520 = Integer(155520); _sage_const_25 = Integer(25); _sage_const_24 = Integer(24); _sage_const_48 = Integer(48)
4
r"""
5
#####################################################################################################################
6
# Cubic factor groups of braid groups
7
#####################################################################################################################
8
9
10
11
12
##############################################################################
13
# Copyright (C) 2016 Sebastian Oehms <[email protected]>
14
#
15
# Distributed under the terms of the GNU General Public License (GPL)
16
#
17
# The full text of the GPL is available at:
18
#
19
# http://www.gnu.org/licenses/
20
##############################################################################
21
22
23
24
This module is devoted for factor groups of the Artin braid groups, such that the images $s_i$ of the braid generators have order three:
25
26
$s_i^3=1$
27
28
In general these groups have firstly been investigated by Coxeter, H.S.M in: "Factor groups of the braid groups, Proceedings of the Fourth Candian Mathematical Congress (Vancover 1957), pp. 95-122".
29
30
Coxeter showed, that these groups are finite as long as the number of strands is less than 6 and infinite elsewise. More explicitely the factor group on three strand braids is isomorphic to $SL(2,3)$, on four strand braids to $GU(3,2)$ and on five strand braids to $Sp(4,3) x C_3$. Today, these groups are known as irreducible complex reflection groups enumerated in the Shephard-Todd classification as $G_{4}$, $G_{25}$ and $G_{32}$.
31
32
Coxeter realized these groups as subgroups of unitary groups with respect to a certain hermitian form over the complex numbers (in fact over $\QQ$ adjoined with a primitive 12-th root of unity).
33
34
In "Einige endliche Faktorgruppen der Zopfgruppen" (Math. Z., 163 (1978), 291-302) J. Assion considered two series $S(m)$ and $U(m)$ of finite dimensional factors of these groups. The additional relations on the braid group generators $\{ s_1, \cdot , s_{m-1}\}$ are
35
36
37
S) $s_3 s_1 t_2 s_1 t_2^{-1} t_3 t_2 s_1 t_2^{-1} t_3^{-1) = 1$ for $m >= 5$ in case $S(m)$
38
U) $t_1 t_3 = 1$ for $m >= 5$ in case $U(m)$
39
40
where $t_i = (s_i s_{i+1})^3$. He showed that each series of finite cubic braid group factors must be an epimorphic image of one of his two series, as long as the groups with less than 5 strands are the full cubic braid groups, whereas the group on 5 strands is not. He realized the groups $S(m)$ as symplectic groups over $GF(3)$ (resp. subgroups therein) and $U(m)$ as general unitary groups over $GF(4)$ (resp. subgroups therein).
41
42
This class implements all the groups conidered by Coxeter and Assion as finitely presented groups (via the gap interface) together with the classical realizations given by the authors. It also contains the coercion maps between the two ways of
43
realization. In addition the user can construct other realizations and maps to matrix groups with help of the burau representation. In case gap3 and CHEVIE are installed under sage version 7.2 (or later) the reflection groups via the gap3
44
interface are availlable, too. The methods for all this functionality are:
45
46
- as_classical_group
47
- as_matrix_group
48
- as_reflection_group (needs sage version 7.2 up and gap3 + CHEVIE)
49
- as_permutation_group
50
51
Further methods are:
52
53
- order
54
- pre_image_braid_group
55
- cubic_braid_subgroup
56
- character_table
57
58
For more information and EXAMPLES type
59
60
sage: print CubicBraidGroup_class.__doc__
61
62
AUTHOR:
63
64
Sebastian Oehms, Sept. 2016
65
"""
66
67
from sage.groups.finitely_presented import FinitelyPresentedGroup, FinitelyPresentedGroupElement
68
from sage.misc.decorators import options, rename_keyword
69
from sage.groups.braid import *
70
from lib.utils_sys import *
71
from lib.utils_gap_interface import *
72
from lib.local_permgroup import *
73
from lib.local_braid import *
74
from lib.local_matrix_group import *
75
76
77
78
##############################################################################
79
#
80
# Class CubicBraidElement (for elements)
81
#
82
##############################################################################
83
class CubicBraidElement(FinitelyPresentedGroupElement):
84
"""
85
This class models elements of cubic factor groups of the braid group. It is the element class of
86
the CubicBraidGroup_class
87
88
If you don't see this well formatted type
89
90
sage: print CubicBraidElement.__doc__
91
92
It is realized as a particular case of elements of a finitely presented group (inherited from
93
FinitelyPresentedGroupElement)
94
95
EXAMPLES:
96
97
sage: C4.<c1,c2,c3> = CubicBraidGroup(4)
98
sage: C4
99
Cubic Braid group on 4 strands
100
sage: ele1 = c1*c2*c3^-1*c2^-1; type(ele1)
101
<class 'lib.cubic_braid.CubicBraidGroup_class_with_category.element_class'>
102
sage: ele2 = C4((1, 2, -3, -2))
103
sage: ele1 == ele2
104
True
105
106
For more information see the parent class typing
107
108
sage: print CubicBraidGroup_class.__doc__
109
110
AUTHOR
111
112
- Sebastian Oehms, Sept. 2016
113
114
"""
115
116
117
118
def braid(self):
119
"""
120
Return the canonical braid preimage of self as Object of the class Braid,
121
122
If you don't see this well formatted type
123
124
sage: print CubicBraidElement.braid.__doc__
125
126
OUTPUT:
127
128
the preimage of self as instance of the Braid class which is the element class of the BraidGroup_class
129
130
EXAMPLES::
131
132
sage: C3.<c1, c2> = CubicBraidGroup(3)
133
sage: c1.parent()
134
Cubic Braid group on 3 strands
135
sage: c1.braid().parent()
136
Braid group on 3 strands
137
138
For information type
139
140
sage: print CubicBraidGroup_class.__doc__
141
142
143
"""
144
145
pre_image_braid_grp = self.parent().pre_image_braid_group()
146
pre_image_braid = pre_image_braid_grp( self )
147
return pre_image_braid
148
149
150
151
def cubic_writhe( self ):
152
"""
153
Return the exponent_sum of the preimage braid modulo 3
154
155
If you don't see this well formatted type
156
157
sage: print CubicBraidElement.cubic_writhe.__doc__
158
159
OUTPUT:
160
161
Integer 0, 1, 2 giving the exponent_sum modulo 3 in a word in the braid generators representig self
162
163
EXAMPLES::
164
165
sage: S4.<s1,s2,s3>=AssionGroupS(4)
166
sage: s=s1*s2*s3*s2
167
sage: s.cubic_writhe()
168
1
169
sage:
170
171
AUTHOR:
172
173
- Sebastian Oehms, Sept. 2016
174
175
"""
176
exp_sum = self.braid().exponent_sum()
177
return exp_sum % _sage_const_3
178
179
180
181
182
183
def _burau_matrix_(self, rootBur = None, Domain = None, characteristic = None, reduced=False, version='default'):
184
"""
185
Return the Burau matrix of the cubic braid coset.
186
187
If you don't see this well formatted type
188
189
sage: print CubicBraidElement._burau_matrix_.__doc_
190
191
This is the internal version of the "burau_matrix" method which returns more information than the main method
192
193
for more information on the main method "burau_matrix" type
194
195
sage: print CubicBraidElement.burau_matrix.__doc_
196
197
The only difference to that method is this:
198
199
OUTPUT:
200
201
a pair consisting of
202
203
- The Burau matrix of the cubic braid coset with entries in the domain given by the options
204
205
- the value of rootBur which is used. If the keyword rootBur has been set, this value is identical to this.
206
Otherwise, the value which has been calculated from the other parameters is returned
207
208
EXAMPLES:
209
210
sage: S3.<s1,s2>=AssionGroupS(3)
211
sage: s2.burau_matrix( characteristic=2, version='unitary' )
212
[ 1 0]
213
[rI + 1 rI]
214
sage: s2._burau_matrix_( characteristic=2, version='unitary' )
215
(
216
[ 1 0]
217
[rI + 1 rI], rI + 1
218
)
219
sage:
220
221
AUTHOR:
222
223
- Sebastian Oehms, Sept. 2016
224
225
"""
226
227
pre_image_braid = self.braid( )
228
229
BurauOri = pre_image_braid.burau_matrix( var='tt', reduced = reduced, version=version )
230
d = BurauOri.dimensions()
231
232
if Domain != None:
233
if isinstance( Domain, UniversalCyclotomicField):
234
if rootBur == None:
235
if version == 'unitary':
236
rootBur = Domain.gen(_sage_const_12 )
237
else:
238
rootBur = Domain.gen(_sage_const_6 )
239
240
if rootBur == None:
241
tT = var('tT')
242
if version == 'unitary':
243
minPolRootBur = tT**_sage_const_4 -tT**_sage_const_2 +_sage_const_1
244
else:
245
minPolRootBur = tT**_sage_const_2 -tT +_sage_const_1
246
247
if Domain == None:
248
if (characteristic == None):
249
characteristic = _sage_const_0
250
251
try:
252
characteristic = Integer( characteristic )
253
except:
254
raise ValueError('characteristic must be in integer')
255
256
if characteristic <> _sage_const_0 and not characteristic.is_prime():
257
raise ValueError('characteristic must be a prime')
258
if characteristic == _sage_const_0 :
259
if version == 'unitary':
260
PDomain = CyclotomicField(_sage_const_12 )
261
else:
262
PDomain = CyclotomicField(_sage_const_3 )
263
else:
264
PDomain = GF( characteristic )
265
minPolRootBur = PDomain[tT]( minPolRootBur )
266
rootList = minPolRootBur.roots()
267
if len(rootList) == _sage_const_0 :
268
Domain = minPolRootBur.splitting_field(names=('rI',)); (rI,) = Domain._first_ngens(1)
269
minPolRootBur = Domain[tT]( minPolRootBur )
270
else:
271
Domain = PDomain
272
rootList = minPolRootBur.roots()
273
for root in rootList:
274
if root[_sage_const_0 ] == _sage_const_0 :
275
continue
276
rootBur = root[_sage_const_0 ]
277
if root[_sage_const_1 ] == _sage_const_1 :
278
break
279
280
else: # Domain <> None
281
if characteristic == None:
282
characteristic = Domain.characteristic()
283
elif characteristic <> Domain.characteristic():
284
raise ValueError('characteristic of Domain does not match given characteristic')
285
minPolRootBur = Domain[tT]( minPolRootBur )
286
rootList = minPolRootBur.roots()
287
if len(rootList) == _sage_const_0 :
288
print "Warning: Domain extended to splitting field of", minPolRootBur
289
Domain = minPolRootBur.splitting_field(names=('rI',)); (rI,) = Domain._first_ngens(1)
290
minPolRootBur = Domain[tT]( minPolRootBur )
291
rootList = minPolRootBur.roots()
292
for root in rootList:
293
if root[_sage_const_0 ] == _sage_const_0 :
294
continue
295
rootBur = root[_sage_const_0 ]
296
if root[_sage_const_1 ] == _sage_const_1 :
297
break
298
else: # rootBur <> None
299
if Domain == None:
300
Domain = rootBur.parent()
301
if characteristic == None:
302
characteristic = Domain.characteristic()
303
elif characteristic <> Domain.characteristic():
304
raise ValueError('characteristic of Domain does not match given characteristic')
305
306
if _sage_const_1 not in Domain:
307
raise ValueError('rootBur must belong to a domain containing 1')
308
if version == 'unitary':
309
testRootBur = Domain(rootBur**_sage_const_4 -rootBur**_sage_const_2 +_sage_const_1 )
310
if testRootBur <> _sage_const_0 :
311
raise ValueError('rootBur must vanish on x**4-x**2+1')
312
else:
313
testRootBur = Domain(rootBur**_sage_const_2 -rootBur +_sage_const_1 )
314
if testRootBur <> _sage_const_0 :
315
raise ValueError('rootBur must vanish on x**2-x+1')
316
317
def conv2Domain ( LaurPol ):
318
PolConst = LaurPol.polynomial_construction()
319
R = Domain['tt']; (tt,) = R._first_ngens(1)
320
p1 = R( PolConst[_sage_const_0 ] )
321
p2 = rootBur**(PolConst[_sage_const_1 ])
322
erg = p1.substitute( tt = rootBur ) * p2
323
return erg
324
325
BurauMat = matrix(d[_sage_const_0 ],d[_sage_const_1 ], lambda i,j: conv2Domain(BurauOri[i,j] ) )
326
327
return BurauMat, rootBur
328
329
330
331
332
333
334
335
def burau_matrix(self, rootBur = None, Domain = None, characteristic = None, reduced=False, version='default'):
336
r"""
337
Return the Burau matrix of the cubic braid coset.
338
339
If you don't see this well formatted type
340
341
sage: print CubicBraidElement.burau_matrix.__doc_
342
343
This method uses the same method belonging to the Braid class, but reduces the parameter to a primitive six
344
root of unity, respectivly an element vanishing on the polynomial $x^2-x+1$
345
346
INPUT: (all parameters are optional by keyword )
347
348
- "rootBur": six root of unity in some field (default six root of unity over $\QQ$)
349
- "Domain": base_ring for the burau matrix (default is Cyclotomic Field of order 3 and degree 2, resp. the
350
domain of rootBur if given)
351
- "reduced": boolean (default: False); whether to return the reduced or unreduced Burau representation
352
(see Braid class )
353
- "characteristic": integer giving the characteristic of the domain (default is 0 or the characteristic of
354
the doamain if given)
355
- "version": values:
356
'unitary': gives the unitary form according to Squier (see Braid._unitary_burau_matrix_() )
357
'default': the method behaves like the original one of the Braid -class
358
any value else: gives the reduced form given on wikipedia
359
360
361
OUTPUT:
362
363
The Burau matrix of the cubic braid coset with entries in the domain given by the options
364
365
If you need the values of the reconstructed keywords "rootBur", "Domain" or "characteristic" use the internal
366
version _burau_matrix_ of this method
367
368
RAISE:
369
370
- ValueError: 'characteristic must be in integer'
371
372
- ValueError: 'characteristic must be a prime'
373
374
- ValueError: 'characteristic of Domain does not match given characteristic'
375
376
- ValueError: 'rootBur must belong to a domain containing 1'
377
378
- ValueError: 'rootBur must vanish on $x^2-x+1$ default case
379
380
- ValueError: 'rootBur must vanish on $x^4-x^2+1$ in case of call with version = 'unitary'
381
382
383
384
EXAMPLES::
385
386
sage: C3.<c1, c2> = CubicBraidGroup(3)
387
sage: ele1 = c1*c2*c1
388
sage: BurauTest = ele1.burau_matrix(); print BurauTest
389
[ -zeta3 1 zeta3]
390
[ -zeta3 zeta3 + 1 0]
391
[ 1 0 0]
392
sage: BurauTest.base_ring()
393
Cyclotomic Field of order 3 and degree 2
394
sage:
395
sage: BurauTest = ele1.burau_matrix( characteristic = 0 ); print BurauTest
396
[ -zeta3 1 zeta3]
397
[ -zeta3 zeta3 + 1 0]
398
[ 1 0 0]
399
sage: BurauTest.base_ring()
400
Cyclotomic Field of order 3 and degree 2
401
sage:
402
sage: BurauTest = ele1.burau_matrix( Domain = QQ ); print BurauTest
403
Warning: Domain extended to splitting field of tT^2 - tT + 1
404
[-rI + 1 1 rI - 1]
405
[-rI + 1 rI 0]
406
[ 1 0 0]
407
sage: BurauTest.base_ring()
408
Number Field in rI with defining polynomial tT^2 - tT + 1
409
sage:
410
sage: BurauTest = ele1.burau_matrix( Domain = QQ[I, sqrt(3)] ); print BurauTest
411
[ 1/2*sqrt3*I + 1/2 1 -1/2*sqrt3*I - 1/2]
412
[ 1/2*sqrt3*I + 1/2 -1/2*sqrt3*I + 1/2 0]
413
[ 1 0 0]
414
sage: BurauTest.base_ring()
415
Number Field in I with defining polynomial x^2 + 1 over its base field
416
sage:
417
sage: BurauTest = ele1.burau_matrix( characteristic = 7 ); print BurauTest
418
[3 1 4]
419
[3 5 0]
420
[1 0 0]
421
sage: BurauTest.base_ring()
422
Finite Field of size 7
423
sage:
424
sage: BurauTest = ele1.burau_matrix( characteristic = 2 ); print BurauTest
425
[rI + 1 1 rI + 1]
426
[rI + 1 rI 0]
427
[ 1 0 0]
428
sage: BurauTest.base_ring()
429
Finite Field in rI of size 2^2
430
sage:
431
sage:
432
sage: F4.<r64> = GF(4)
433
sage: BurauTest = ele1.burau_matrix( rootBur=r64 ); print BurauTest
434
[r64 + 1 1 r64 + 1]
435
[r64 + 1 r64 0]
436
[ 1 0 0]
437
sage: BurauTest.base_ring()
438
Finite Field in r64 of size 2^2
439
sage:
440
sage: BurauTest = ele1.burau_matrix( Domain = GF(5) ); print BurauTest
441
Warning: Domain extended to splitting field of tT^2 + 4*tT + 1
442
[2*rI + 2 1 3*rI + 3]
443
[2*rI + 2 3*rI + 4 0]
444
[ 1 0 0]
445
sage: BurauTest.base_ring()
446
Finite Field in rI of size 5^2
447
sage:
448
sage: BurauTest = ele1.burau_matrix( version = 'unitary' ); print BurauTest
449
[ 0 -zeta12^3]
450
[-zeta12^3 0]
451
sage: BurauTest.base_ring()
452
Cyclotomic Field of order 12 and degree 4
453
sage:
454
sage: BurauTest = ele1.burau_matrix( Domain = QQ[I, sqrt(3)], version = 'unitary' ); print BurauTest
455
[ 0 -I]
456
[-I 0]
457
sage: BurauTest.base_ring()
458
Number Field in I with defining polynomial x^2 + 1 over its base field
459
460
AUTHOR:
461
462
- Sebastian Oehms, Sept. 2016
463
464
465
REFERENCES:
466
467
- :wikipedia: "Burau_representation"
468
469
470
for more inormation type
471
sage: print Braid.burau_matrix.__doc__
472
sage: print local_Braid.burau_matrix.__doc__
473
sage: print local_Braid.__burau_matrix_wikipedia__.__doc__
474
sage: print local_Braid.__burau_matrix_unitary__.__doc__
475
476
"""
477
478
res = self._burau_matrix_( rootBur = rootBur, Domain = Domain, characteristic = characteristic, reduced = reduced,
479
version = version)[_sage_const_0 ]
480
return res
481
482
483
484
485
486
##############################################################################
487
#
488
# Class CubicBraidGroup_class (for the group itself)
489
#
490
##############################################################################
491
class CubicBraidGroup_class(FinitelyPresentedGroup):
492
r"""
493
Class to handel cubic factors of braid group on n strands
494
495
If you don't see this well formatted type
496
497
sage: print CubicBraidGroup_class.__doc__
498
499
This class implements quotient groups of the braid group mapping their generators to elements of order 3
500
(see the module header for more informations on these groups)
501
502
These groups are implemented as a particular case of finitely presented groups similar to the BraidGroup class
503
504
A cubic braid group can be created by giving the number of strands, and the name of the generators in a similar
505
way as it works for the BraidGroup class.
506
507
INPUT (to the constructor):
508
509
- "names": (see the BraidGroup_class docomentation)
510
511
- "AdditionalRelation": (keyword, explantaion see below)
512
513
- "verbose": (keyword, explantaion see below)
514
515
516
RAISE (on init):
517
518
- ValueError: "the number of strands must be an integer larger than one"
519
520
521
Setting the keyword 'AdditionalRelation' to one on the values 'S' or 'U' the additional relations due to
522
Assion are added:
523
524
'S': $s_3 s_1 t_2 s_1 t_2^{-1} t_3 t_2 s_1 t_2^{-1} t_3^{-1) = 1$ for $m >= 5$
525
'U': $t_1 t_3 = 1$ for $m >= 5$
526
527
528
where $t_i = (s_i s_{i+1})^3$. If AdditionalRelation='C' (default) only the cubic relation on the generators is
529
active (Coxeters case of investigation). Note that for n=2,3,4 the groups do not differ between the three possible
530
values of AdditionalRelation (as finitely presented groups). But anyway, the classes for 'C', 'S' and 'U' are
531
different, since they have different classical realizations implemented .
532
533
Setting the keyword verbose it is possible to print time stamp messages in order to do a performance or
534
call stack debugging. This keyword uses the timeStampControl class. For more information on this type
535
536
print setupTimeStamp.__doc__
537
print timeStampControl.__doc__
538
print timeStampControl.print_timestamp.__doc__
539
print print_time_tb.__doc__
540
541
542
The creation of instances of this class can also be done more easy by help of the functions CubicBraidGroup,
543
AssionGroupS and AssionGroupU (similar to the function BraidGroup with respect to the BraidGroup_class)
544
545
546
EXAMPLES:
547
548
sage: from cubic_braid import *
549
sage: U3 = CubicBraidGroup(3, AdditionalRelation = 'U'); U3
550
Assion group on 3 strands of type U
551
sage: U3.gens()
552
(c0, c1)
553
554
alternate possibilities defining U3:
555
556
sage: U3 = AssionGroupU(3); U3
557
Assion group on 3 strands of type U
558
sage: U3.gens()
559
(u0, u1)
560
561
sage: U3.<u1,u2> = AssionGroupU(3); U3
562
Assion group on 3 strands of type U
563
sage: U3.gens()
564
(u1, u2)
565
566
alternates naming the generators:
567
568
sage: U3 = AssionGroupU(3, 'a, b'); U3
569
Assion group on 3 strands of type U
570
sage: U3.gens()
571
(a, b)
572
573
sage: C3 = CubicBraidGroup(3, 't'); C3
574
Cubic Braid group on 3 strands
575
sage: C3.gens()
576
(t0, t1)
577
578
sage: U3.is_isomorphic( C3 )
579
True
580
sage: U3.as_classical_group()
581
Subgroup of (The projective general unitary group of degree 3 over Finite Field of size 2) generated by
582
[(1,7,6) (3,19,14)(4,15,10)(5,11,18)(12,16,20), (1,12,13)(2,15,19)(4,9,14)(5,18,8)(6,21,16)]
583
sage: C3.as_classical_group()
584
Subgroup of General Unitary Group of degree 2 over Universal Cyclotomic Field with respect to hermitian form
585
[-E(12)^7 + E(12)^11 -1]
586
[ -1 -E(12)^7 + E(12)^11]
587
generated by (
588
[ E(3) E(12)^11]
589
[ 0 1],
590
[ 1 0]
591
[E(12)^11 E(3)])
592
593
594
using verbose mode:
595
596
sage: C3.<c1,c2> = CubicBraidGroup(3, verbose=True); C3
597
L: StackInfo Elapse: 0, Total: 0 Ident: C3 In: __init__ Line: 403
598
L: StackInfo Elapse: 197, Total: 0 Begin In: __create_classical_realization__ Line: 910
599
L: StackInfo Elapse: 8, Total: 0 Begin In: as_matrix_group Line: 1031
600
L: Body Elapse: 92, Total: 0 genList prepared In: as_matrix_group Line: 1038
601
L: Body Elapse: 52, Total: 0 MatGroup defined In: as_matrix_group Line: 1054
602
L: StackInfo Elapse: 356, Total: 0 Begin In: gap_hom Line: 143
603
L: Debug Elapse: 8, Total: 0 GroupHomomorphis In: gap_hom Line: 188
604
L: Debug Elapse: 17, Total: 0 checked if groupMap works In: gap_hom Line: 199
605
L: StackInfo Elapse: 8, Total: 0 End In: gap_hom Line: 226
606
L: StackInfo Elapse: 44, Total: 0 Begin In: __check_homomorphism__ Line: 60
607
L: StackInfo Elapse: 52, Total: 0 End In: __check_homomorphism__ Line: 625
608
L: Body Elapse: 3, Total: 0 Hom from self defined In: as_matrix_group Line: 1064
609
L: StackInfo Elapse: 62, Total: 0 Begin In: gap_hom Line: 143
610
L: Debug Elapse: 4, Total: 0 GroupHomomorphis In: gap_hom Line: 188
611
L: Debug Elapse: 20, Total: 0 checked if groupMap works In: gap_hom Line: 199
612
L: StackInfo Elapse: 4, Total: 0 End In: gap_hom Line: 226
613
L: Body Elapse: 35, Total: 0 Section to self defined In: as_matrix_group Line: 1077
614
L: StackInfo Elapse: 3, Total: 0 Ende In: as_matrix_group Line: 1102
615
L: StackInfo Elapse: 3, Total: 0 End In: __create_classical_realization__ Line: 975
616
L: StackInfo Elapse: 12, Total: 0 Ident: C3 In: __init__ Line: 472
617
Cubic Braid group on 3 strands
618
sage:
619
sage:
620
sage: C3.<c1,c2> = CubicBraidGroup(3, verbose=30); C3
621
L: StackInfo Elapse: 62, Total: 0 (truncated 1) Begin In: __create_classical_realization__ Line: 910
622
---> __init__ In: lib/cubic_braid.py Line: 471
623
---> __classcall__ In: /opt/sage/sage-6.9-i686-Linux/local/lib/python2.7/site-packages/sage/structure
624
/unique_representation.py Line: 1021
625
---> CubicBraidGroup In: lib/cubic_braid.py Line: 1231
626
L: StackInfo Elapse: 405, Total: 0 Begin In: as_matrix_group Line: 1031
627
---> __create_classical_realization__ In: lib/cubic_braid.py Line: 968
628
---> __init__ In: lib/cubic_braid.py Line: 471
629
---> __classcall__ In: /opt/sage/sage-6.9-i686-Linux/local/lib/python2.7/site-packages/sage/structure
630
/unique_representation.py Line: 1021
631
L: Body Elapse: 145, Total: 0 genList prepared In: as_matrix_group Line: 1038
632
---> __create_classical_realization__ In: lib/cubic_braid.py Line: 968
633
---> __init__ In: lib/cubic_braid.py Line: 471
634
---> __classcall__ In: /opt/sage/sage-6.9-i686-Linux/local/lib/python2.7/site-packages/sage/structure
635
/unique_representation.py Line: 1021
636
Cubic Braid group on 3 strands
637
sage:
638
639
640
TESTS:
641
642
sage: C4 = CubicBraidGroup(4)
643
sage: TestSuite(C4).run()
644
sage: C5 = CubicBraidGroup(5)
645
sage: TestSuite(C5).run()
646
sage: C6 = CubicBraidGroup(6)
647
sage: TestSuite(C6).run()
648
sage: S3 = AssionGroupS(3)
649
sage: TestSuite(S3).run()
650
sage: S4 = AssionGroupS(4)
651
sage: TestSuite(S5).run()
652
sage: U3 = AssionGroupU(3)
653
sage: TestSuite(U3).run()
654
sage: U4 = AssionGroupU(4)
655
sage: TestSuite(U4).run()
656
sage: U5 = AssionGroupU(5)
657
sage: TestSuite(U5).run()
658
659
METHODS (implemented / overwriten here):
660
661
- as_classical_group(): type
662
sage: print CubicBraidGroup_class.as_classical_group.__doc__
663
- as_matrix_group(): type
664
sage: print CubicBraidGroup_class.as_matrix_group.__doc__
665
- as_refection_group(): type
666
sage: print CubicBraidGroup_class.as_refection_group.__doc__
667
- as_permutation_group(): type
668
sage: print CubicBraidGroup_class.as_permutation_group.__doc__
669
- pre_image_braid_group: type
670
sage: print CubicBraidGroup_class.pre_image_braid_group.__doc__
671
- cubic_braid_subgroup(): type
672
sage: print CubicBraidGroup_class.cubic_braid_subgroup.__doc__
673
- centralizing_element(): type
674
sage: print CubicBraidGroup_class.centralizing_element.__doc__
675
- order(): type
676
sage: print CubicBraidGroup_class.order.__doc__
677
- character_table(): type
678
sage: print CubicBraidGroup_class.character_table.__doc__
679
680
AUTHOR
681
682
- Sebastian Oehms, Sept. 2016
683
684
REFERENCES:
685
686
- Coxeter, H.S.M: "Factor groups of the braid groups, Proceedings of the Fourth Candian Mathematical Congress
687
(Vancover 1957), pp. 95-122".
688
689
- J. Assion: "Einige endliche Faktorgruppen der Zopfgruppen" (Math. Z., 163 (1978), 291-302)
690
"""
691
692
693
694
Element = CubicBraidElement
695
696
###########################################################################################
697
# private methods
698
###########################################################################################
699
def __init__(self, names, AdditionalRelation = 'C', verbose = False ):
700
"""
701
Python constructor.
702
703
for more information type
704
705
sage: print CubicBraidGroup_class.__doc__
706
707
708
AUTHOR
709
710
- Sebastian Oehms, Sept. [email protected][email protected]
711
712
"""
713
714
self._AdditionalRelation_ = AdditionalRelation
715
self._verbose_ = verbose
716
717
n = Integer(len(names))
718
self._nstrands_ = n+_sage_const_1
719
self._ident_ = self._AdditionalRelation_ + self._nstrands_.str()
720
721
self._TimeStamp_ = setupTimeStamp( verbose = verbose, Offset = _sage_const_2 , ShowDateTime = False )
722
self._TimeStampSub_ = setupTimeStamp( verbose = verbose, Offset = _sage_const_1 , ShowDateTime = False )
723
self.__print_timestamp__( "Ident: %s" %(self._ident_), TsLevel.StackInfo )
724
725
726
b = []
727
bi = []
728
t = []
729
ti = []
730
731
sage.groups.braid.BraidGroup_class = local_BraidGroup_class
732
self._pre_image_braid_group_ = BraidGroup( names )
733
734
735
if n<_sage_const_1 : #n is the number of generators, not the number of strands (see ticket 14081)
736
raise ValueError("the number of strands must be an integer larger than one")
737
free_group = FreeGroup(names)
738
739
oneHundertMB = _sage_const_100 *_sage_const_1024 **_sage_const_2
740
work_space_needed = {'C5':_sage_const_5 , 'C6':_sage_const_48 , 'U6':_sage_const_24 , 'S6':_sage_const_24 }
741
if self._ident_ in work_space_needed.keys(): # need to extend GAP-workspace
742
gap_extend_workspace( work_space_needed[self._ident_]*oneHundertMB )
743
744
745
# internal naming of elements for convinience
746
for i in range(_sage_const_1 , n+_sage_const_1 ):
747
b.append(free_group([i]))
748
bi.append(free_group([-i]))
749
if i < n:
750
tt = free_group([i, i+_sage_const_1 ])**_sage_const_3
751
t.append(tt)
752
tt = free_group([-i, -i-_sage_const_1 ])**_sage_const_3
753
ti.append(tt)
754
755
# first the braid relation
756
rels = list(self._pre_image_braid_group_.relations())
757
758
# then the cubic relation
759
for i in range(_sage_const_0 , n):
760
rels.append(b[i]**_sage_const_3 )
761
762
# then Assions relation Satz 2.2 type='S' Satz 2.4 type='U'
763
if n>_sage_const_3 :
764
for i in range(_sage_const_0 , n-_sage_const_3 ):
765
if AdditionalRelation == 'U':
766
rels.append((t[i]*t[i+_sage_const_2 ])**_sage_const_3 )
767
elif AdditionalRelation == 'S':
768
rels.append(b[i+_sage_const_2 ]*b[i]*t[i+_sage_const_1 ]*b[i]*ti[i+_sage_const_1 ]*t[i+_sage_const_2 ]*t[i+_sage_const_1 ]*b[i]*ti[i+_sage_const_1 ]*ti[i+_sage_const_2 ])
769
770
771
FinitelyPresentedGroup.__init__(self, free_group, tuple(rels))
772
self._nstrands_ = n+_sage_const_1
773
self._ident_ = self._AdditionalRelation_ + self._nstrands_.str()
774
self._b_ = b
775
self._bi_ = bi
776
self._t_ = t
777
self._ti_ = ti
778
self._free_group_ = free_group
779
self._checked_homomorphism_=[]
780
781
782
# ------------------------------------------------------------------------------------------------
783
# the following global pointers to classical group realizations will be set in the private method
784
# __create_classical_realization__
785
# ------------------------------------------------------------------------------------------------
786
self._classical_group_ = None # This is the classical Group returned by as_classical_group
787
self._classical_group_gens_ = None # generators of the former group
788
self._classical_base_group_ = None # this only differs special cases for AssionGroup from the former
789
self._classical_base_group_gens_ = None # generators of the former group
790
self._centralizing_matrix_ = None # for AssionGroup: element in classical base group commuting self
791
self._centralizing_element_ = None # image under nat. map of the former one in the proj. classical group
792
self._classical_embedding_ = None # as subgroup of classical base group (if different from class. group)
793
794
self.__create_classical_realization__()
795
self.__print_timestamp__( "Ident: %s" %(self._ident_), TsLevel.StackInfo )
796
797
return
798
799
800
801
def __reduce__(self):
802
"""
803
Checks or unity
804
805
If you don't see this well formatted type
806
807
sage: print CubicBraidGroup_class.__recuce__.__doc__
808
809
TESTS:
810
811
sage: C3=CubicBraidGroup(3)
812
sage: C3.__reduce__()
813
(<class 'lib.cubic_braid.CubicBraidGroup_class'>, (('c0', 'c1'), 'C', False))
814
sage: U3.<u1,u2>=AssionGroupU(3, verbose=100)
815
sage: U3.__reduce__()
816
(<class 'lib.cubic_braid.CubicBraidGroup_class'>, (('u1', 'u2'), 'U', 100))
817
818
"""
819
return (CubicBraidGroup_class, (self.variable_names(), self._AdditionalRelation_, self._verbose_,))
820
821
822
823
def _repr_(self):
824
"""
825
Return a string representation
826
827
If you don't see this well formatted type
828
829
sage: print CubicBraidGroup_class._repr_.__doc__
830
831
OUTPUT:
832
833
String decribing self
834
835
TESTS:
836
837
sage: C5 = CubicBraidGroup(5)
838
sage: C5 # indirect doctest
839
CubicBraid group on 5 strands
840
"""
841
if self._AdditionalRelation_ == 'C':
842
return "Cubic Braid group on %s strands"%(self._nstrands_)
843
else:
844
return "Assion group on %s strands of type %s"%(self._nstrands_ ,self._AdditionalRelation_)
845
846
847
848
# -------------------------------------------------------------------------------
849
# Methods for test_suite
850
# -------------------------------------------------------------------------------
851
def _test_constructions(self, **options):
852
"""
853
Method called by TestSuite
854
855
If you don't see this well formatted type
856
857
sage: print CubicBraidGroup_class._test_constructions.__doc__
858
859
the following is checked:
860
- construction of classical group was faithfull
861
- construction of permutation groups attached to self is faithful
862
- coercion maps to and from classical group exist and are inverse to each other
863
- coercion maps to and from permutatiobn group exist and are inverse to each other
864
- existence of some examples of matrix representations and commutativity between coercion maps
865
866
AUTHOR
867
868
- Sebastian Oehms, Sept. 2016
869
870
"""
871
# ------------------------------------------------------------------------
872
# testing existence of classical group and coercion maps to and from self
873
# ------------------------------------------------------------------------
874
875
self.__print_timestamp__( "Begin", TsLevel.StackInfo )
876
877
Cl=self.as_classical_group()
878
homToClass = Cl.coerce_map_from( self )
879
homToClassNotNone = self._tester(**options)
880
homToClassNotNone.assert_( homToClass != None )
881
homToClassCheck = self._tester(**options)
882
883
self.__print_timestamp__ ("Check hom to classical", TsLevel.Body )
884
homToClassCheck.assert_( self.__check_homomorphism__( homToClass ) == True )
885
886
self.__print_timestamp__ ("Section from classical", TsLevel.Body )
887
sectFromClass = self.coerce_map_from( Cl )
888
sectFromClassNotNone = self._tester(**options)
889
sectFromClassNotNone.assert_( sectFromClass != None )
890
891
892
# ------------------------------------------------------------------------
893
# testing if coercion maps are inverse to each other
894
# ------------------------------------------------------------------------
895
self.__print_timestamp__ ("Testing inverse", TsLevel.Body )
896
Clgen1 = Cl.gens()[_sage_const_0 ]
897
Clgen1Braid = self(Clgen1)
898
Clgen1Back = Cl(Clgen1Braid)
899
testClgen1Back = self._tester(**options)
900
testClgen1Back.assert_( Clgen1Back == Clgen1 )
901
902
# ------------------------------------------------------------------------
903
# testing the order calculation of the group
904
# ------------------------------------------------------------------------
905
self.__print_timestamp__ ("Testing order", TsLevel.Body )
906
907
orderForm = self.order()
908
orderCalc = self.order( by_formula = False )
909
testOrder = self._tester(**options)
910
testOrder.assert_( orderForm == orderCalc )
911
912
# ------------------------------------------------------------------------
913
# preparing tests of matrix and permutation groups
914
# ------------------------------------------------------------------------
915
F3 = GF(_sage_const_3 ); r63=F3(_sage_const_2 ); F4 = GF(_sage_const_4 , names=('r64',)); (r64,) = F4._first_ngens(1)
916
917
self.__print_timestamp__ ("Testing permutation and matrix group", TsLevel.Body )
918
919
def test_attached_group( AttGroup, EleClass, EleSelf ):
920
"""
921
local function in CubicBraidGroup_class._test_constructions.__doc__
922
923
it tests conversion maps from self and the classical group to the given attached Group which must have
924
been defined using the as_matrix_group or as_ermutation_group methods
925
926
INPUT:
927
928
- "AttGroup": attached group (matrix group or permutation group) to be tested
929
- "EleSelf": element of self used to perform the test
930
- "EleClass": element of the classical group of self used to perform the test
931
932
"""
933
self.__print_timestamp__("Begin", TsLevel.StackInfo)
934
AttEleSelf = AttGroup(EleSelf)
935
self.__print_timestamp__ ("rightHandSide", TsLevel.BodySub1)
936
AttEleClass = AttGroup(EleClass)
937
self.__print_timestamp__ ("leftHandSide", TsLevel.BodySub1)
938
AttComute = self._tester(**options)
939
AttComute.assert_(AttEleSelf == AttEleClass)
940
self.__print_timestamp__("End", TsLevel.StackInfo)
941
942
943
944
# ---------------------------------------------------------------------------------------------
945
# existence of attached reflection group and commutativity between coercion maps
946
# ---------------------------------------------------------------------------------------------
947
self.__print_timestamp__ ("reflection group", TsLevel.BodySub1)
948
try:
949
# ---------------------------------------------------------------------------------------------
950
# the reflection group may not be constructable in the following plausible cases:
951
# - sage version is less than 7.2 -> class IrreducibleComplexReflectionGroup is not availlable
952
# - gap3 or CHEVIE is not installed
953
# - self is not of type 'C' or not finite
954
# ---------------------------------------------------------------------------------------------
955
Refl = self.as_reflection_group()
956
except:
957
Refl = None
958
959
if Refl != None:
960
test_attached_group(Refl, Clgen1, Clgen1Braid)
961
962
963
# ---------------------------------------------------------------------------------------------
964
# existence of attached permutation groups and commutativity between coercion maps
965
# ---------------------------------------------------------------------------------------------
966
self.__print_timestamp__ ("permutation group", TsLevel.BodySub1)
967
Perm = self.as_permutation_group()
968
test_attached_group(Perm, Clgen1, Clgen1Braid)
969
970
self.__print_timestamp__ ("native permutation group", TsLevel.BodySub1)
971
if self._nstrands_ < _sage_const_4 :
972
PermN = self.as_permutation_group(native=True)
973
test_attached_group(PermN, Clgen1, Clgen1Braid)
974
975
# ---------------------------------------------------------------------------------------------
976
# existence of some examples of matrix representations and commutativity between coercion maps
977
# ---------------------------------------------------------------------------------------------
978
self.__print_timestamp__ ("Default MatrixGroup", TsLevel.BodySub1)
979
MatDEF = self.as_matrix_group()
980
test_attached_group(MatDEF, Clgen1, Clgen1Braid)
981
982
self.__print_timestamp__ ("MatrixGroup over GF(3)", TsLevel.BodySub1)
983
if self._AdditionalRelation_ != 'U' or self._nstrands_ < _sage_const_5 : # not well defined elsewise
984
MatF3 = self.as_matrix_group(rootBur=r63)
985
test_attached_group(MatF3, Clgen1, Clgen1Braid)
986
987
self.__print_timestamp__ ("MatrixGroup over GF(4)", TsLevel.BodySub1)
988
if self._AdditionalRelation_ != 'S' or self._nstrands_ < _sage_const_5 : # not well defined elsewise
989
MatF4 = self.as_matrix_group(rootBur=r64)
990
test_attached_group(MatF4, Clgen1, Clgen1Braid)
991
992
self.__print_timestamp__ ("MatrixGroup over GF(5)", TsLevel.BodySub1)
993
if self._nstrands_ < _sage_const_5 or self._AdditionalRelation_ == 'C':
994
MatF5 = self.as_matrix_group(characteristic = _sage_const_5 )
995
test_attached_group(MatF5, Clgen1, Clgen1Braid)
996
997
self.__print_timestamp__ ("MatrixGroup over GF(7)", TsLevel.BodySub1)
998
MatF7 = self.as_matrix_group(Domain=GF(_sage_const_7 ))
999
test_attached_group(MatF7, Clgen1, Clgen1Braid)
1000
1001
self.__print_timestamp__("End", TsLevel.StackInfo)
1002
1003
return
1004
1005
# -------------------------------------------------------------------------------
1006
# -------------------------------------------------------------------------------
1007
# local utility-methods
1008
# -------------------------------------------------------------------------------
1009
1010
def __print_timestamp__( self, Text, Level ):
1011
"""
1012
Method to print time stamped logging messages
1013
1014
If you don't see this well formatted type
1015
1016
sage: print CubicBraidGroup_class.__print_timestamp__.__doc__
1017
1018
This method uses the timeStampControl class. For more information on this type
1019
1020
print timeStampControl.__doc__
1021
print timeStampControl.print_timestamp.__doc__
1022
print print_time_tb.__doc__
1023
1024
INPUT:
1025
1026
- "Text": Text to be printed in the log message
1027
- "Level": indicates the level (importance) of the message. The following values are posible
1028
0 TsLevel.Silent to be pinted independent on any verbose mode
1029
1 TsLevel.StackInfo classifies messages on entry and exit of subroutines
1030
2 TsLevel.Body to be used in the body of a function
1031
3 TsLevel.BodySub1 subordinary message to TsLevel.Body
1032
4 TsLevel.BodySub2 subordinary message to TsLevel.Body1
1033
5 TsLevel.Debug to print debug information
1034
1035
Note, that the higher levels include the for comming lower ones.
1036
1037
AUTHOR
1038
1039
- Sebastian Oehms, Sept. 2016
1040
1041
"""
1042
self._TimeStamp_.print_timestamp( Text = Text, Level = Level )
1043
1044
1045
1046
# -------------------------------------------------------------------------------
1047
# Method to check if a map from self to another group vanisches on the relations
1048
# of self
1049
# -------------------------------------------------------------------------------
1050
def __check_homomorphism__(self, test_map ):
1051
"""
1052
Method to check if the given map is well defined with respect to the relations of self
1053
1054
If you don't see this well formatted type
1055
1056
sage: print CubicBraidGroup_class.__check_homomorphism__.__doc__
1057
1058
INPUT:
1059
1060
- "test_map": the map from self to another group to be tested
1061
1062
OUTPUT:
1063
1064
boolean True if test_map vanishes on all relations of self, else false
1065
1066
WARNINGS:
1067
1068
"Warning: homomorphism not well defined for relation %s giving: %s" n case the result is False
1069
1070
EXAMPLES:
1071
1072
sage: S4.<s1,s2,s3>=AssionGroupS(4); S4
1073
Assion group on 4 strands of type S
1074
sage: S4Cl = S4.as_classical_group()
1075
sage: f = S4Cl.convert_map_from( S4 )
1076
sage: S4.__check_homomorphism__(f)
1077
True
1078
1079
Note, the following may be an irritation: The generators of S4 and S4Cl are the same as set but in different order
1080
1081
sage: ClassGens=S4Cl.gens(); ClassGens
1082
[(5,8,11)(6,9,12)(7,10,13)(23,26,29)(24,27,30)(25,28,31)(32,38,35)(33,39,36)(34,40,37),
1083
(2,11,8)(3,13,9)(4,12,10)(17,35,26)(18,36,27)(19,37,28)(20,29,38)(21,30,39)(22,31,40),
1084
(1,25,24)(2,29,26)(3,27,31)(6,16,33)(7,34,15)(8,20,35)(9,36,22)(11,38,17)(13,18,40)]
1085
1086
sage: S4Cl(s1)
1087
(2,11,8)(3,13,9)(4,12,10)(17,35,26)(18,36,27)(19,37,28)(20,29,38)(21,30,39)(22,31,40)
1088
sage: S4Cl(s2)
1089
(5,8,11)(6,9,12)(7,10,13)(23,26,29)(24,27,30)(25,28,31)(32,38,35)(33,39,36)(34,40,37)
1090
1091
AUTHOR
1092
1093
- Sebastian Oehms, Sept. 2016
1094
1095
"""
1096
1097
self.__print_timestamp__( "Begin", TsLevel.StackInfo )
1098
check_needed = True
1099
checked_homomorphism = list(self._checked_homomorphism_)
1100
if checked_homomorphism != None:
1101
if test_map in checked_homomorphism:
1102
check_needed = False
1103
1104
1105
if (check_needed == False ):
1106
return True
1107
1108
self.__print_timestamp__( "check_needed", TsLevel.Body )
1109
1110
for relation in list(self.relations()):
1111
self.__print_timestamp__( "relation %s"%(relation), TsLevel.Debug )
1112
relVal = test_map(relation)
1113
self.__print_timestamp__( "relation tested", TsLevel.Debug )
1114
if relVal.is_one() == False:
1115
print "Warning: homomorphism not well defined for relation %s giving: %s"%(relation, relVal )
1116
return False
1117
1118
self.__print_timestamp__( "check_ok", TsLevel.Body )
1119
1120
checked_homomorphism.append( test_map )
1121
1122
self.__print_timestamp__( "check_registerd", TsLevel.Body )
1123
1124
self._checked_homomorphism_ = checked_homomorphism
1125
self.__print_timestamp__( "End", TsLevel.StackInfo )
1126
return True
1127
1128
1129
def __create_classical_realization__(self):
1130
"""
1131
internal method to create the classical groups attached to self
1132
1133
If you don't see this well formatted type
1134
1135
sage: print CubicBraidGroup_class.__create_classical_realization__.__doc__
1136
1137
INPUT:
1138
1139
no
1140
1141
OUTPUT:
1142
1143
no
1144
1145
this methods sets the following global parameters of self:
1146
1147
- self._classical_group_ This is the classical group returned by as_classical_group method
1148
- self._classical_group_gens_ generators of the former group
1149
- self._classical_base_group_ this only differs in special cases for AssionGroup from the former
1150
- self._classical_base_group_gens_ generators of the former group
1151
- self._centralizing_matrix_ for AssionGroup: element in classical base group commuting with self
1152
- self._centralizing_element_ image under natural map of the former one in the projective classical group
1153
- self._classical_embedding_ as subgroup of classical base group (if different from class. group)
1154
1155
AUTHOR
1156
1157
- Sebastian Oehms, Sept. 2016
1158
1159
"""
1160
1161
# -------------------------------------------------------------------------------
1162
# local methods to create maps to and from the classical group
1163
# -------------------------------------------------------------------------------
1164
1165
1166
1167
# -------------------------------------------------------------------------------
1168
# create a map from self to the classical realization
1169
# via transvections using the work of Assion
1170
# -------------------------------------------------------------------------------
1171
def create_hom_to_classical( self, Group, ImList ):
1172
"""
1173
internal method to create the homomorphism from self to classical group
1174
1175
this is a local function in CubicBraidGroup_class.__create_classical_realization__ using
1176
gap_hom
1177
1178
see also:
1179
sage: print gap_hom.__doc__
1180
1181
INPUT:
1182
1183
- "Group": target of the map
1184
- "ImList": list of the images of the braid generators
1185
1186
OUTPUT:
1187
1188
the created homomorphism.
1189
1190
The created homomorphism is registered as coercion and conversion map for Group
1191
1192
AUTHOR
1193
1194
- Sebastian Oehms, Sept. 2016
1195
1196
"""
1197
self.__print_timestamp__( "Begin", TsLevel.StackInfo )
1198
if ImList[_sage_const_0 ] in Group:
1199
homToGroup = gap_hom( self, Group, GensTo = ImList, verbose = self._TimeStampSub_ )
1200
else:
1201
GroupImage = ImList[_sage_const_0 ].parent()
1202
homToImage = gap_hom( self, GroupImage, GensTo = ImList, verbose = self._TimeStampSub_ )
1203
homToGroup = homToImage
1204
if Group.has_coerce_map_from( GroupImage ):
1205
incl = Group.coerce_map_from( GroupImage )
1206
homToGroup = incl * homToImage
1207
Group.register_coercion( homToGroup )
1208
self.__print_timestamp__( "End", TsLevel.StackInfo )
1209
return homToGroup
1210
1211
1212
1213
1214
1215
# -------------------------------------------------------------------------------
1216
# Set up all incrediences of the classical group (generic part)
1217
# -------------------------------------------------------------------------------
1218
def SetUpClassicalGroup( self, m, n, BaseGroup, ProjGroup, centralizing_vector, transvec2mat, transvecList ):
1219
"""
1220
internal method to create classical group for Assion groups
1221
1222
this is a local function in CubicBraidGroup_class.__create_classical_realization__
1223
1224
It handels the common part of symplectic and unitary version and creates all conversion map using gap_hom
1225
1226
see also:
1227
sage: print gap_hom.__doc__
1228
1229
INPUT:
1230
1231
- "BaseGroup": The symplectic or unitary groups Sp(m,3) resp. GU(m,2)
1232
- "ProjGroup": The projeective imaged of these group
1233
- "centralizing_vector": The centralizing vector described by Assion
1234
- "transvec2mat": Function to create the transection map from transvection vector
1235
- "transvecList": List of transvection vectors
1236
1237
OUTPUT:
1238
1239
the function sets the global parameters of self decribed under
1240
1241
sage: print CubicBraidGroup_class.__create_classical_realization__.__doc__
1242
1243
AUTHOR
1244
1245
- Sebastian Oehms, Sept. 2016
1246
1247
"""
1248
1249
1250
self.__print_timestamp__( "Begin", TsLevel.StackInfo )
1251
1252
centralizing_matrix = BaseGroup(transvec2mat(centralizing_vector, fact=_sage_const_1 ))
1253
centralizing_element = None
1254
1255
# ------------------------------------------------------------------------------
1256
# preparing the projective group realizaton
1257
# ------------------------------------------------------------------------------
1258
natHom = gap_hom( BaseGroup, ProjGroup, verbose = self._TimeStampSub_ )
1259
1260
1261
# ------------------------------------------------------------------------------
1262
# Setting the List of Braid Images or try to fetch them from library
1263
# ------------------------------------------------------------------------------
1264
ClGenList=[]
1265
centralizing_element = natHom( centralizing_matrix )
1266
1267
anz_tv=_sage_const_0
1268
BaseClGenList=[]
1269
for v in transvecList:
1270
anz_tv=anz_tv+_sage_const_1
1271
if anz_tv >= n:
1272
break
1273
transvecMat = transvec2mat( v )
1274
BaseClGenList.append( BaseGroup(transvecMat) )
1275
if m == n: # case of centralizer in projective group
1276
projTransvecMat = natHom( transvecMat )
1277
ClGenList.append( projTransvecMat )
1278
else:
1279
ClGenList.append( BaseGroup(transvecMat) )
1280
1281
1282
ClassicalGroup = BaseGroup
1283
if m == n: # case of centralizer in projective group
1284
# ClassicalGroup = ProjGroup.centralizer( centralizing_element ) # to large set of generators
1285
ClassicalGroup = ProjGroup.subgroup( ClGenList )
1286
for gen in ClGenList: # checking centralizer property
1287
if gen * centralizing_element != centralizing_element *gen:
1288
print "Internal Error! centralzier property failed for:", gen, centralizing_element
1289
1290
Embedding = None
1291
if ClassicalGroup == BaseGroup:
1292
create_hom_to_classical( self, ClassicalGroup, ClGenList )
1293
gap_hom( ClassicalGroup, self, GensFrom = ClGenList, verbose = self._TimeStampSub_ )
1294
else:
1295
Embedding = BaseGroup.subgroup( BaseClGenList )
1296
create_hom_to_classical( self, ClassicalGroup, ClGenList )
1297
create_hom_to_classical( self, Embedding, BaseClGenList )
1298
try:
1299
# --------------------------------------------------------------------------------------
1300
# Note: this may fail for large permutation groups such as AssionGroupU( 6 )
1301
# gap-Error: Gap terminated unexpectedly while reading in a large line
1302
# --------------------------------------------------------------------------------------
1303
gap_hom( ClassicalGroup, self, GensFrom = ClGenList, verbose = self._TimeStampSub_ )
1304
except:
1305
print "Warning: no map back from classical group (gap overflow)"
1306
1307
gap_hom( Embedding, self, GensFrom = BaseClGenList, verbose = self._TimeStampSub_ )
1308
1309
1310
1311
self._classical_group_ = ClassicalGroup
1312
self._classical_group_gens_ = ClGenList
1313
self._classical_base_group_ = BaseGroup
1314
self._classical_base_group_gens = BaseClGenList
1315
self._centralizing_matrix_ = centralizing_matrix
1316
self._centralizing_element_ = centralizing_element
1317
self._classical_embedding_ = Embedding
1318
1319
self.__print_timestamp__( "End", TsLevel.StackInfo )
1320
return
1321
1322
1323
1324
# -------------------------------------------------------------------------------
1325
# local methods to set up the classical group (spezific part)
1326
# -------------------------------------------------------------------------------
1327
# Case for symlectic groups
1328
# -------------------------------------------------------------------------------
1329
def create_transvecListSympl( self, m ):
1330
"""
1331
internal method to create classical group for symplectic Assion groups (type 'S' )
1332
1333
this is a local function in CubicBraidGroup_class.__create_classical_realization__
1334
1335
INPUT
1336
1337
- m the dimension of the classical groups vectorspace of operation
1338
1339
The routine calculates the central vector and the transvections as vector as given by Assion and then uses
1340
SetUpClassicalGroup to complete the construction
1341
1342
AUTHOR
1343
1344
- Sebastian Oehms, Sept. 2016
1345
1346
"""
1347
self.__print_timestamp__( "Begin", TsLevel.StackInfo )
1348
1349
# -----------------------------------------------------------
1350
# getting the invariant bilinearform of the group
1351
# in symplectic case possible by corresponding method
1352
# and setting constants
1353
# -----------------------------------------------------------
1354
BaseGroup = Sp( m, _sage_const_3 )
1355
ProjGroup = PSp( m, _sage_const_3 )
1356
1357
bform = BaseGroup.invariant_form()
1358
n = self._nstrands_
1359
bas =bform.column_space().basis()
1360
if m % _sage_const_2 == _sage_const_0 :
1361
mhalf = m/_sage_const_2
1362
else:
1363
mhalf = (m-_sage_const_1 )/_sage_const_2
1364
1365
# -----------------------------------------------------------
1366
# computing a hyperbolic decomposition basis with respect
1367
# to the invariant bilinear form
1368
# -----------------------------------------------------------
1369
xbas =[]
1370
ybas =[]
1371
for i in range(mhalf):
1372
xbas.append( bas[mhalf -i -_sage_const_1 ] )
1373
ybas.append( bas[mhalf +i ] )
1374
1375
# -----------------------------------------------------------
1376
# computing the List of transvection vectors according to
1377
# Assion paper, page 292
1378
# -----------------------------------------------------------
1379
transvecList =[xbas[_sage_const_0 ]] # t_1 = x_1
1380
for i in range(mhalf-_sage_const_1 ):
1381
transvecList.append(ybas[i]) # t_{2i} = y_i
1382
transvecList.append(xbas[i] + xbas[i+_sage_const_1 ] ) # t_{2i+1} = x_j + x_(j+1)
1383
transvecList.append(ybas[mhalf-_sage_const_1 ] ) # t_n = y_m
1384
1385
# -----------------------------------------------------------
1386
# Convertion-Map from transvection vector to transvection
1387
# matrix
1388
# -----------------------------------------------------------
1389
def transvec2mat( v, bas=bas, bform=bform, fact=_sage_const_1 ):
1390
t = []
1391
for x in bas:
1392
t.append( x + fact*(x * bform * v) * v )
1393
Mt = matrix( bform.base_ring(), t )
1394
return Mt
1395
1396
# ------------------------------------------------------------------------------
1397
# setting the centralizing matrix for the case of projective group realizaton
1398
# ------------------------------------------------------------------------------
1399
central_vector = xbas[mhalf-_sage_const_1 ]
1400
1401
SetUpClassicalGroup( self, m, n, BaseGroup, ProjGroup, central_vector, transvec2mat, transvecList )
1402
1403
self.__print_timestamp__( "End", TsLevel.StackInfo )
1404
1405
return
1406
1407
1408
1409
# -------------------------------------------------------------------------------
1410
# Case for unitary groups
1411
# -------------------------------------------------------------------------------
1412
def create_transvecListUnitar( self, m ):
1413
"""
1414
internal method to create classical group for unitary Assion groups (type 'U' )
1415
1416
this is a local function in CubicBraidGroup_class.__create_classical_realization__
1417
1418
INPUT
1419
1420
- m the dimension of the classical groups vectorspace of operation
1421
1422
The routine calculates the central vector and the transvections as vector as given by Assion and then uses
1423
SetUpClassicalGroup to complete the construction
1424
1425
AUTHOR
1426
1427
- Sebastian Oehms, Sept. 2016
1428
1429
"""
1430
1431
self.__print_timestamp__( "Begin", TsLevel.StackInfo )
1432
1433
# ---------------------------------------------------------------------
1434
# getting the invariant bilinearform of the group and setting constants
1435
# in unitary case this is not implemented in sage but can
1436
# be looked up by the GAP-function InvariantSesquilinearForm
1437
# for instance:
1438
# gap> GU3:=GeneralUnitaryGroup( 3, 2 );
1439
# gap> InvariantSesquilinearForm(GU3);
1440
# rec( matrix := [ [ 0*Z(2), 0*Z(2), Z(2)^0 ], [ 0*Z(2), Z(2)^0, 0*Z(2) ], [ Z(2)^0, 0*Z(2), 0*Z(2) ] ] )
1441
# ---------------------------------------------------------------------
1442
1443
BaseGroup = GU( m, _sage_const_2 )
1444
ProjGroup = PGU( m, _sage_const_2 )
1445
oneMat = BaseGroup.one().matrix()
1446
n = self._nstrands_
1447
bform = matrix( m,m, lambda i,j: oneMat[i, m-_sage_const_1 -j] )
1448
bas = bform.column_space().basis()
1449
BasR = bform.base_ring()
1450
vA = BasR.gen()
1451
1452
if m % _sage_const_3 == _sage_const_1 :
1453
mthird = (m-_sage_const_1 )/_sage_const_3
1454
elif m % _sage_const_3 == _sage_const_2 :
1455
mthird = (m-_sage_const_2 )/_sage_const_3
1456
else:
1457
mthird = m/_sage_const_3
1458
1459
# -----------------------------------------------------------
1460
# computing a orthonormal basis with respect
1461
# to the invariant bilinear form
1462
# -----------------------------------------------------------
1463
xbas =[]
1464
for i in range(m):
1465
if _sage_const_2 *i == m-_sage_const_1 :
1466
xbas.append(bas[i])
1467
else:
1468
xbas.append( vA*bas[i] + vA.frobenius()*bas[m-_sage_const_1 -i])
1469
1470
# -----------------------------------------------------------
1471
# computing the List of transvection vectors according to
1472
# Assion paper, page 293
1473
# -----------------------------------------------------------
1474
transvecList =[xbas[_sage_const_0 ]] # t_1 = x_1
1475
if m > _sage_const_1 :
1476
transvecList.append(xbas[_sage_const_0 ]+xbas[_sage_const_1 ]+xbas[_sage_const_2 ] ) # t_2 = x_1 + x_2 + x_3
1477
for j in range(mthird):
1478
pos = _sage_const_3 *(j+_sage_const_1 ) -_sage_const_1 # 3i-1, j = i-1: j=0, i=1, pos=2 x_{pos} =xbas[pos-1]
1479
transvecList.append(xbas[pos-_sage_const_1 ]) # t_{3i} = x_{3i-1}
1480
if pos +_sage_const_1 < m:
1481
transvecList.append(xbas[pos-_sage_const_1 ]+xbas[pos]+xbas[pos+_sage_const_1 ] ) # t_{3i+1} = x_{3i-1} + x_{3i} + x_{3i+1}
1482
if pos +_sage_const_3 < m:
1483
transvecList.append(xbas[pos+_sage_const_1 ]+xbas[pos+_sage_const_2 ]+xbas[pos+_sage_const_3 ] ) # t_{3i+2} = x_{3i+1} + x_{3i+2} + x_{3i+3}
1484
1485
# -----------------------------------------------------------
1486
# Convertion-Map from transvection vector to transvection
1487
# matrix
1488
# -----------------------------------------------------------
1489
def transvec2mat( v, bas=bas, bform=bform, fact=vA ):
1490
1491
def conjVec( vec ):
1492
erg = list(vec)
1493
for i in range(len(vec)):
1494
erg[i] = erg[i].frobenius()
1495
return vector(erg)
1496
1497
t = []
1498
for x in bas:
1499
# note x does not change under conjugation, since it belongs to standard basis
1500
t.append( x + fact *(x * bform * conjVec(v)) * v )
1501
Mt = matrix( bform.base_ring(), t )
1502
return Mt
1503
1504
1505
# ------------------------------------------------------------------------------
1506
# setting the centralizing matrix for the case of projective group realizaton
1507
# ------------------------------------------------------------------------------
1508
central_vector = xbas[m-_sage_const_2 ]+xbas[m-_sage_const_1 ]
1509
1510
SetUpClassicalGroup( self, m, n, BaseGroup, ProjGroup, central_vector, transvec2mat, transvecList )
1511
1512
self.__print_timestamp__( "End", TsLevel.StackInfo )
1513
1514
return
1515
1516
1517
#----------------------------------------------------------------------------------------------------------
1518
#----------------------------------------------------------------------------------------------------------
1519
# local functions definition section finishes here
1520
#----------------------------------------------------------------------------------------------------------
1521
#----------------------------------------------------------------------------------------------------------
1522
1523
self.__print_timestamp__( "Begin", TsLevel.StackInfo )
1524
1525
# -------------------------------------------------------------------------------
1526
# initializatn of constants
1527
# -------------------------------------------------------------------------------
1528
n = self._nstrands_
1529
anz_gen = n-_sage_const_1
1530
1531
# -------------------------------------------------------------------------------
1532
# Setting the Classical group
1533
# -------------------------------------------------------------------------------
1534
if n == _sage_const_1 :
1535
ClassicalGroup = AbelianGroup([_sage_const_1 ])
1536
self._classical_group_ = ClassicalGroup
1537
self._classical_group_gens_ = ClassicalGroup.gens()
1538
self._classical_base_group_ = ClassicalGroup
1539
self._classical_base_group_gens_ = ClassicalGroup.gens()
1540
elif n == _sage_const_2 and self._AdditionalRelation_ =='C':
1541
ClassicalGroup = AbelianGroup([_sage_const_3 ])
1542
self._classical_group_ = ClassicalGroup
1543
self._classical_group_gens_ = ClassicalGroup.gens()
1544
self._classical_base_group_ = ClassicalGroup
1545
self._classical_base_group_gens_ = ClassicalGroup.gens()
1546
else:
1547
dim_sympl_group = n-_sage_const_1 # for S(n-1) = Sp(n-1, 3)
1548
dim_unitary_group = n-_sage_const_1 # for U(n-1) = GU(n-1, 2)
1549
if n % _sage_const_2 == _sage_const_0 :
1550
dim_sympl_group = n # for S(n-1) = Z(PSp(n, 3))
1551
if n % _sage_const_3 == _sage_const_0 :
1552
dim_unitary_group = n # for U(n-1) = Z(PGU( n, 3))
1553
1554
1555
if self._AdditionalRelation_ =='S':
1556
create_transvecListSympl( self, dim_sympl_group )
1557
elif self._AdditionalRelation_ =='U':
1558
create_transvecListUnitar( self, dim_unitary_group )
1559
else:
1560
# -----------------------------------------------------------------------------------------------
1561
# connection between Coxeter realization and unitary Burau representation according to Squier
1562
# -----------------------------------------------------------------------------------------------
1563
# Coxeter p = 3, \theta =\pi/3 = primitive 6th root of unity
1564
# i\theta = \pi/3+\pi/2 = 5\pi/6 = 5th power of primitive 12th root of unity (z12 = gap E(12))
1565
# i\theta = z12^5
1566
# unitary Form of Coxeter: f
1567
# unitary Form of Squier: J(s)
1568
# Then we have J(z12) = 2 f
1569
# unitary Burau Matrix Coxeter for b_1: buc_i
1570
# unitary Burau Matrix Squier for b_1: bus_i
1571
# Then we have buc_i[i,i-1] = buc_[i,i+1]= - z12^5, buc_[i,i] = 1 + 2*cos(\pi/6)*z12^5
1572
# Then we have bus_i[i,i-1] = bus_[i,i+1]= s, bus_[i,i] = -s^2
1573
# now - z12^5 = z12^(-1)
1574
# and 1 + 2*cos(\pi/6)*z12^5 = 1 + sqrt(3)*(-sqrt(3)/2 + I/2) = 1- 3/2 + sqrt(3)I/2 = z12^4 = - z12^(-2)
1575
# finally: Coxeters Realization is the unitary Burau representation of Squier for s = z12^(-1)
1576
# -----------------------------------------------------------------------------------------------
1577
UCF = UniversalCyclotomicField()
1578
z12inverse = UCF.gen(_sage_const_12 ,_sage_const_11 )
1579
ClassicalGroup = self.as_matrix_group( rootBur=z12inverse, Domain=UCF, version='unitary', check=False )
1580
self._classical_group_ = ClassicalGroup
1581
self._classical_group_gens_ = ClassicalGroup.gens()
1582
self._classical_base_group_ = ClassicalGroup
1583
self._classical_base_group_gens_ = ClassicalGroup.gens()
1584
self._classical_embedding_ = ClassicalGroup
1585
1586
self.__print_timestamp__( "End", TsLevel.StackInfo )
1587
1588
return
1589
1590
1591
1592
1593
1594
# ----------------------------------------------------------------------------------
1595
# ----------------------------------------------------------------------------------
1596
# public methods
1597
# ----------------------------------------------------------------------------------
1598
# change_debug_options
1599
# ----------------------------------------------------------------------------------
1600
def change_debug_options(self, verbose = None, for_subroutine = False, ShowDateTime = False ):
1601
"""
1602
Changes the options for timestamp debug log messages
1603
1604
If you don't see this well formatted type
1605
1606
sage: print CubicBraidGroup_class.change_debug_options.__doc__
1607
1608
The verbose -mode which has been set in the constructor can be modified here. It is possible set the mode
1609
separately for main routines (this module) and routines from external modules.
1610
1611
Furthermore the printing of the datetime-string in the messages can be turned on
1612
1613
INPUT (all optional keywords):
1614
1615
- "verbose" (default = unchanged) the new verbose mode to be set. For more informati9on on the possible
1616
values type sage: print CubicBraidGroup_class.__doc__
1617
- "for_subroutine" boolean (default = False): decides wether to apply the setting to log messages of this module
1618
(False) or to subroutines from external modules (True) such as lib.utils_gap_interface
1619
- "ShowDateTime" boolean (default = False): decides wether to print a datetime-string in the msages
1620
1621
EXAMPLES:
1622
1623
sage: from cubic_braid import *
1624
sage: C3 = CubicBraidGroup(3)
1625
sage: C3.change_debug_options(verbose=True)
1626
sage: C5c5= C3.as_matrix_group( characteristic=5)
1627
L: StackInfo : Elapse: 4711, Total: 4 Begin In: as_matrix_group Line: 1789
1628
L: Body : Elapse: 685, Total: 5 genList prepared In: as_matrix_group Line: 1805
1629
L: Body : Elapse: 147, Total: 5 MatGroup defined In: as_matrix_group Line: 1830
1630
L: StackInfo : Elapse: 38, Total: 5 Begin In: __check_homomorphism__ Line: 1058
1631
L: Body : Elapse: 2, Total: 5 check_needed In: __check_homomorphism__ Line: 1069
1632
L: Debug : Elapse: 2, Total: 5 relation c0*c1*c0*c1^-1*c0^-1*c1^-1 In: __check_homomorphism__ Line:
1633
1072
1634
L: Debug : Elapse: 6, Total: 5 relation tested In: __check_homomorphism__ Line: 1074
1635
L: Debug : Elapse: 6, Total: 5 relation c0^3 In: __check_homomorphism__ Line: 1072
1636
L: Debug : Elapse: 5, Total: 5 relation tested In: __check_homomorphism__ Line: 1074
1637
L: Debug : Elapse: 6, Total: 5 relation c1^3 In: __check_homomorphism__ Line: 1072
1638
L: Debug : Elapse: 6, Total: 5 relation tested In: __check_homomorphism__ Line: 1074
1639
L: Body : Elapse: 8, Total: 5 check_ok In: __check_homomorphism__ Line: 1079
1640
L: Body : Elapse: 3, Total: 5 check_registerd In: __check_homomorphism__ Line: 1083
1641
L: StackInfo : Elapse: 5, Total: 5 End In: __check_homomorphism__ Line: 1086
1642
L: Body : Elapse: 2, Total: 5 Hom from self defined In: as_matrix_group Line: 1840
1643
L: Body : Elapse: 904, Total: 6 Section to self defined In: as_matrix_group Line: 1853
1644
L: Body : Elapse: 4, Total: 6 section to classical group defined In: as_matrix_group Line: 1873
1645
L: StackInfo : Elapse: 367, Total: 6 Ende In: as_matrix_group Line: 1893
1646
sage:
1647
sage: C3.change_debug_options(ShowDateTime = True)
1648
sage: C5c5= C3.as_matrix_group( characteristic=5)
1649
L: StackInfo : 2017-01-26 18:01:50.782780 Elapse: 2986, Total: 2 Begin In: as_matrix_group Line: 1789
1650
L: Body : 2017-01-26 18:01:50.859565 Elapse: 77, Total: 3 genList prepared In: as_matrix_group Line:
1651
1805
1652
L: Body : 2017-01-26 18:01:50.889521 Elapse: 29, Total: 3 MatGroup defined In: as_matrix_group Line:
1653
1830
1654
L: StackInfo : 2017-01-26 18:01:50.908706 Elapse: 19, Total: 3 Begin In: __check_homomorphism__ Line: 1058
1655
..........................................
1656
L: Body : 2017-01-26 18:01:51.370860 Elapse: 3, Total: 3 section to classical group defined In:
1657
as_matrix_group Line: 1873
1658
L: StackInfo : 2017-01-26 18:01:51.373498 Elapse: 2, Total: 3 Ende In: as_matrix_group Line: 1893
1659
sage:
1660
1661
AUTHOR
1662
1663
- Sebastian Oehms, Jan. 2017
1664
1665
"""
1666
1667
if verbose == None:
1668
verbose = self._verbose_
1669
1670
if for_subroutine == False:
1671
self._verbose_ = verbose
1672
self._TimeStamp_ = setupTimeStamp( verbose = verbose, Offset = _sage_const_2 , ShowDateTime = ShowDateTime )
1673
else:
1674
self._TimeStampSub_ = setupTimeStamp( verbose = verbose, Offset = _sage_const_1 , ShowDateTime = ShowDateTime )
1675
1676
1677
1678
1679
1680
1681
# ----------------------------------------------------------------------------------
1682
# pre_image_braid_group
1683
# ----------------------------------------------------------------------------------
1684
def pre_image_braid_group(self):
1685
"""
1686
Return an Objekt of the class BraidGroup with identical generators, such that there exists an epimorhism to self
1687
1688
If you don't see this well formatted type
1689
1690
sage: print CubicBraidGroup_class.pre_image_braid_group.__doc__
1691
1692
OUTPUT:
1693
1694
Instance of the class BraidGroup having conversion maps to and from self (which is just a section in the
1695
latter case)
1696
1697
EXAMPLES:
1698
1699
sage: from cubic_braid import *
1700
sage: U5=AssionGroupU(5); U5
1701
Assion group on 5 strands of type U
1702
sage: B5=U5.pre_image_braid_group(); B5
1703
Braid group on 5 strands
1704
sage: b=B5([4,3,2,-4,1])
1705
sage: u=U5([4,3,2,-4,1])
1706
sage: u == b
1707
False
1708
sage: b.burau_matrix()
1709
[ 1 - t t 0 0 0]
1710
[ 1 - t 0 t 0 0]
1711
[ 1 - t 0 0 0 t]
1712
[ 1 - t 0 0 1 -1 + t]
1713
[ 1 0 0 0 0]
1714
sage: u.burau_matrix()
1715
[ -zeta3 zeta3 + 1 0 0 0]
1716
[ -zeta3 0 zeta3 + 1 0 0]
1717
[ -zeta3 0 0 0 zeta3 + 1]
1718
[ -zeta3 0 0 1 zeta3]
1719
[ 1 0 0 0 0]
1720
sage: bU = U5(b)
1721
sage: uB = B5(u)
1722
sage:
1723
sage: bU == u
1724
True
1725
sage: uB == b
1726
True
1727
1728
AUTHOR
1729
1730
- Sebastian Oehms, Sept. 2016
1731
1732
"""
1733
return self._pre_image_braid_group_
1734
1735
1736
1737
1738
# ----------------------------------------------------------------------------------
1739
# as_matrix_group
1740
# ----------------------------------------------------------------------------------
1741
def as_matrix_group(self, rootBur=None, Domain=None, characteristic=None, reduced=False,
1742
version='default', section=True, check=True):
1743
"""
1744
creates an epimorphic image of self as a matrix group by use of the burau representation
1745
1746
If you don't see this well formatted type
1747
1748
sage: print CubicBraidGroup_class.as_matrix_group.__doc__
1749
1750
INPUT: (all parameters are optional by keyword )
1751
1752
- "rootBur": six root of unity in some field (default six root of unity over QQ)
1753
- "Domain": base_ring for the burau matrix (default is Cyclotomic Field of order 3 and degree 2, resp. the
1754
domain of rootBur if given)
1755
- "characteristic": integer giving the characteristic of the domain (default is 0 or the characteristic of
1756
the doamain if given). If none of the keywords "rootBur", "Domain" and "characteristic" is given
1757
the default characteristic is 3 (resp. 2) if self is of Assion type 'S' (resp. 'U')
1758
- "reduced": boolean (default: False); whether to return the reduced or unreduced Burau representation (see
1759
Braid class )
1760
- "version": values:
1761
'unitary': gives the unitary form according to Squier (see Braid._unitary_burau_matrix_() )
1762
'default': the method behaves like the original one of the Braid -class
1763
- any value else gives the reduced form given on wikipedia
1764
- "section"; boolean (default: True) Setting this to False creates a map back to self only in the case of
1765
isomorphism. By default the map is created as a section in any case.
1766
1767
compare the INPUT of
1768
1769
sage: print CubicBraidElement.burau_matrix.__doc_
1770
1771
OUTPUT:
1772
1773
an instance of the class FinitelyGeneratedMatrixGroup_gap according to the Input parameters together with a map
1774
from an to self and the classical group the map backwards (in both cases) is given if the the matrix group is
1775
isomorphic to self or if the keyword section = True (default)
1776
1777
RAISE:
1778
1779
- ValueError: "matrix group fails to be an epimorphic image of %s" if the burau map does not vanish on the
1780
relation of self see example with U5 below
1781
1782
EXAMPLES:
1783
1784
sage: from cubic_braid import *
1785
sage: C5=CubicBraidGroup(5)
1786
sage:
1787
sage: M5ch5 = C5.as_matrix_group(characteristic=5); M5ch5
1788
Matrix group over Finite Field in rI of size 5^2 with 4 generators (
1789
[2*rI + 2 3*rI + 4 0 0 0]
1790
[ 1 0 0 0 0]
1791
[ 0 0 1 0 0]
1792
[ 0 0 0 1 0]
1793
[ 0 0 0 0 1],
1794
1795
[ 1 0 0 0 0]
1796
[ 0 2*rI + 2 3*rI + 4 0 0]
1797
[ 0 1 0 0 0]
1798
[ 0 0 0 1 0]
1799
[ 0 0 0 0 1],
1800
1801
[ 1 0 0 0 0]
1802
[ 0 1 0 0 0]
1803
[ 0 0 2*rI + 2 3*rI + 4 0]
1804
[ 0 0 1 0 0]
1805
[ 0 0 0 0 1],
1806
1807
[ 1 0 0 0 0]
1808
[ 0 1 0 0 0]
1809
[ 0 0 1 0 0]
1810
[ 0 0 0 2*rI + 2 3*rI + 4]
1811
[ 0 0 0 1 0]
1812
)
1813
sage:
1814
sage: c=C5([3,4,-2,-3,1]); c
1815
c2*c1^-1*c0*c3*c2^-1
1816
sage:
1817
sage: cM=M5ch5(c); cM
1818
[2*rI + 2 3*rI + 4 0 0 0]
1819
[ 0 0 0 1 0]
1820
[2*rI + 1 0 2*rI + 2 3*rI 3*rI + 3]
1821
[2*rI + 2 0 0 3*rI + 4 0]
1822
[ 0 0 2*rI + 2 3*rI + 4 0]
1823
sage:
1824
sage: mC=C5(cM)
1825
sage: mC == c
1826
True
1827
1828
sage: C5Cl=C5.as_classical_group()
1829
sage:
1830
sage: mCl=C5Cl(cM); mCL
1831
[ E(3) E(12)^11 0 0]
1832
[ -E(12)^11 1 -E(4) -E(3)^2]
1833
[ E(3) E(12)^11 E(3)^2 -2*E(12)^7 - E(12)^11]
1834
[ 0 1 E(12)^7 -E(3)^2]
1835
sage:
1836
sage: cCl=C5Cl(c)
1837
sage: mCl == cCl
1838
True
1839
sage:
1840
sage: cClM=M5ch5(cCl)
1841
sage: cClM == cM
1842
True
1843
1844
sage: U5=AssionGroupU(5); U5
1845
Assion group on 5 strands of type U
1846
sage: M5ch3 = U5.as_matrix_group(characteristic=3)
1847
Warning: homomorphism not well defined for relation ((u0*u1)^3*(u2*u3)^3)^3 giving: [1 1 2 1 2]
1848
[2 0 2 1 2]
1849
[2 1 1 1 2]
1850
[2 1 2 0 2]
1851
[2 1 2 1 1]
1852
---------------------------------------------------------------------------
1853
ValueError Traceback (most recent call last)
1854
......................
1855
ValueError: matrix group fails to be an epimorphic image of Assion group on 5 strands of type U
1856
sage:
1857
1858
1859
AUTHOR
1860
1861
- Sebastian Oehms, Sept. 2016
1862
1863
"""
1864
1865
# -------------------------------------------------------------------------------
1866
# define matrix group by generotors using the Burau represntation
1867
# -------------------------------------------------------------------------------
1868
self.__print_timestamp__("Begin", TsLevel.StackInfo)
1869
1870
1871
# -------------------------------------------------------------------------------
1872
# adaption of default options for Assion groups on more then 4 stands
1873
# (in order to achive the maps beeing well defined)
1874
# -------------------------------------------------------------------------------
1875
if rootBur == None and Domain == None and characteristic == None:
1876
if self._AdditionalRelation_ == 'S':
1877
characteristic = _sage_const_3
1878
elif self._AdditionalRelation_ == 'U':
1879
characteristic = _sage_const_2
1880
else:
1881
characteristic = _sage_const_0
1882
self.__print_timestamp__("default characteristic set to %d" %(characteristic), TsLevel.Debug)
1883
1884
1885
genList =[]
1886
for braidGen in list(self.gens()):
1887
burMat = braidGen._burau_matrix_(rootBur=rootBur, Domain=Domain, characteristic=characteristic, reduced=reduced,
1888
version=version)
1889
if rootBur == None:
1890
rootBur = burMat[_sage_const_1 ]
1891
if Domain == None:
1892
Domain = rootBur.parent()
1893
if characteristic == None:
1894
characteristic = Domain.characteristic()
1895
1896
genList.append(burMat[_sage_const_0 ])
1897
1898
self.__print_timestamp__("genList prepared", TsLevel.Body)
1899
1900
avoid_gap_worspace_error = False
1901
if self.order() == infinity:
1902
avoid_gap_worspace_error = True
1903
1904
if version == 'unitary':
1905
hermFormBraid = self.pre_image_braid_group().__unitary_form__()
1906
d = hermFormBraid.dimensions()[_sage_const_0 ]
1907
s = hermFormBraid.base_ring().gen()
1908
hermForm = matrix(d,d, lambda i, j: Domain(hermFormBraid[i,j].subs({s:rootBur})))
1909
if is_FiniteField(Domain):
1910
if hermForm.determinant() == _sage_const_0 :
1911
print "Warning: hermitian form %s is degenerated" %(hermForm)
1912
BaseGroup = GU(d, Domain, var=Domain.gen(), hermitian_form=hermForm)
1913
else:
1914
BaseGroup = GU(d, Domain, hermitian_form=hermForm)
1915
1916
self.__print_timestamp__("Base Group %s defined" %(BaseGroup), TsLevel.Debug)
1917
1918
MatGroup = BaseGroup.subgroup(genList)
1919
1920
else:
1921
MatGroup = MatrixGroup(genList)
1922
1923
self.__print_timestamp__("MatGroup defined", TsLevel.Body)
1924
1925
# -------------------------------------------------------------------------------
1926
# check if there is a well defined map to MatGroup
1927
# Register map from self to MatGroup
1928
# -------------------------------------------------------------------------------
1929
homToMat = gap_hom(self, MatGroup, verbose=self._TimeStampSub_)
1930
1931
if check == True:
1932
if self.__check_homomorphism__(homToMat) == False:
1933
raise ValueError( "matrix group fails to be an epimorphic image of %s"%(self._repr_()) )
1934
1935
self.__print_timestamp__("Hom from self defined", TsLevel.Body)
1936
1937
# -------------------------------------------------------------------------------
1938
# define a section from MatGroup to self
1939
# and register
1940
# -------------------------------------------------------------------------------
1941
homFromMat = None
1942
if avoid_gap_worspace_error == True:
1943
# workspace of more than 2 GB is not enought to calculate a section
1944
print "Warning: no section back from matrix group over (gap overflow)", MatGroup.base_ring()
1945
elif section == True:
1946
try:
1947
homFromMat = gap_hom( MatGroup, self, verbose = self._TimeStampSub_)
1948
self.__print_timestamp__("Section to self defined", TsLevel.Body)
1949
except:
1950
print "Warning: no section back from matrix group over", MatGroup.base_ring()
1951
else:
1952
try:
1953
homFromMat = gap_hom(MatGroup, self, check=True, verbose=self._TimeStampSub_)
1954
self.__print_timestamp__("Homomorphism to self defined", TsLevel.Body)
1955
except:
1956
print "Warning: no homomorphism back from matrix group over", MatGroup.base_ring()
1957
1958
# -------------------------------------------------------------------------------
1959
# Register section from MatGroup to ClassicalGroup
1960
# -------------------------------------------------------------------------------
1961
ClassicalGroup = self._classical_group_
1962
1963
if ClassicalGroup != None:
1964
if homFromMat != None:
1965
homToClass = ClassicalGroup.coerce_map_from(self)
1966
if homToClass != None:
1967
ClassicalGroup.register_coercion(homToClass * homFromMat)
1968
self.__print_timestamp__("section to classical group defined", TsLevel.Body)
1969
else:
1970
print "Warning: no map from matrix group over"
1971
print MatGroup.base_ring(), "to classical group", ClassicalGroup
1972
1973
# -------------------------------------------------------------------------------
1974
# Register section from MatGroup to ClassicalEmbedding (if exists)
1975
# -------------------------------------------------------------------------------
1976
ClassicalEmbedding = self._classical_embedding_
1977
1978
if ClassicalEmbedding != None and ClassicalEmbedding != ClassicalGroup:
1979
if homFromMat != None:
1980
homToEmb = ClassicalEmbedding.coerce_map_from(self)
1981
if homToEmb != None:
1982
ClassicalEmbedding.register_coercion(homToEmb * homFromMat)
1983
self.__print_timestamp__("section to classical embedding defined", TsLevel.Body)
1984
else:
1985
print "Warning: no map from matrix group over"
1986
print MatGroup.base_ring(), "to classical embedded roup", ClassicalEmbeding
1987
1988
self.__print_timestamp__("Ende", TsLevel.StackInfo)
1989
return MatGroup
1990
1991
1992
1993
1994
1995
1996
# ----------------------------------------------------------------------------------
1997
# Although this method is availlable for finitely presented group
1998
# we use the classical group implementation (by performace reason) to get
1999
# the permutation_group
2000
# ----------------------------------------------------------------------------------
2001
def as_permutation_group(self, native=False ):
2002
"""
2003
This method returns the permutation group corresponding to self together with conversion maps to and from
2004
self and the classical realization of self
2005
2006
INPUT:
2007
2008
- "native" boolean as optional keyword, default = False. If you set this True the permutation group is
2009
calculated with repsect to self as finitely presented group. By default the permutation group is
2010
taken from the classical group realization.
2011
2012
CAUTION: setting native = True may cause a segmentation fault if you use the sage coercion functionality
2013
afterwards (in other context, even though the coercions for the permutation group work fine).
2014
The reason for this is not clear!
2015
2016
OUTPUT:
2017
2018
instance of a subgroup of the symmetric group (PermutationGroup_subgroup) together with conversion maps to
2019
and from self and the classical groups.
2020
2021
RAISE:
2022
2023
- ValueError: "permutation group fails to be an epimorphic image of %s"
2024
2025
EXAMPLE:
2026
2027
sage: C3=CubicBraidGroup(3)
2028
sage:
2029
sage: PC3=C3.as_permutation_group(); PC3
2030
Subgroup of (Symmetric group of order 8! as a permutation group) generated by [(2,3,5)(4,6,8), (1,2,4)(5,7,6)]
2031
sage:
2032
sage: PC3n=C3.as_permutation_group(native=True); PC3n
2033
Subgroup of (Symmetric group of order 24! as a permutation group) generated by [(1,2,3)(4,10,11)(5,12,13)
2034
(6,14,15)(7,16,17)(8,18,19)(9,20,21)(22,23,24),
2035
(1,4,5)(2,6,7)(3,8,9)(10,14,18)(11,22,20)(12,15,23)(13,17,21)(16,19,24)]
2036
sage: C3Cl = C3.as_classical_group()
2037
sage: c=C3([2,1-2]); c
2038
c1*c0^-1
2039
sage: lc=C3Cl(c); lc
2040
[ E(3)^2 -E(12)^7]
2041
[ E(12)^7 -E(3)^2]
2042
sage: pc=PC3(c); pc
2043
(1,5,7,4)(2,8,6,3)
2044
sage: pcn=PC3n(c); pcn
2045
(1,11,24,7)(2,15,22,9)(3,19,23,5)(4,13,16,18)(6,17,20,10)(8,21,12,14)
2046
sage:
2047
sage: clc = C3(lc); clc == c
2048
True
2049
sage: cpc = C3(pc); cpc == c
2050
True
2051
sage: cpcn = C3(pcn); cpcn == c
2052
True
2053
sage: lpc = C3Cl(pc); lpc == lc
2054
True
2055
sage: lpcn = C3Cl(pcn); lpcn == lc
2056
True
2057
sage: plc = PC3(lc); plc == pc
2058
True
2059
sage: plcn = PC3n(lc); plcn == pcn
2060
True
2061
2062
2063
AUTHOR
2064
2065
- Sebastian Oehms, Sept. 2016
2066
2067
"""
2068
2069
# -------------------------------------------------------------------------------
2070
# define permutation group assiossiated to self
2071
# -------------------------------------------------------------------------------
2072
self.__print_timestamp__( "Begin", TsLevel.StackInfo )
2073
2074
ClassicalGroup = self.as_classical_group()
2075
Domain = None
2076
2077
# -------------------------------------------------------------------------------
2078
# naming and initializing the maps
2079
# -------------------------------------------------------------------------------
2080
c2s = self.convert_map_from( ClassicalGroup )
2081
s2c = ClassicalGroup.convert_map_from( self )
2082
s2po = None; po2s = None; c2po = None; po2c = None;
2083
s2p = None; p2s = None; c2p = None; p2c = None;
2084
2085
# -------------------------------------------------------------------------------
2086
# setting the original permutation group
2087
# -------------------------------------------------------------------------------
2088
if native == True or self._nstrands_ < _sage_const_3 :
2089
PermGroupOri = gap_as_permutation_group(self, verbose = self._TimeStampSub_ )
2090
2091
s2po = PermGroupOri.convert_map_from( self )
2092
po2s = self.convert_map_from( PermGroupOri )
2093
2094
SortGenList = [ s2po(gen) for gen in self.gens() ]
2095
else:
2096
if isinstance( ClassicalGroup, PermutationGroup_generic):
2097
PermGroupOri = ClassicalGroup
2098
2099
c2po = Hom( ClassicalGroup, PermGroupOri).identity()
2100
po2c = Hom( PermGroupOri, ClassicalGroup).identity()
2101
2102
else:
2103
PermGroupOri = gap_as_permutation_group( ClassicalGroup, verbose = self._TimeStampSub_ )
2104
2105
c2po = PermGroupOri.convert_map_from( ClassicalGroup )
2106
po2c = ClassicalGroup.convert_map_from( PermGroupOri )
2107
2108
SortGenList = [ c2po(ClassicalGroup(gen)) for gen in self.gens() ]
2109
2110
Domain = SymmetricGroup( len( PermGroupOri.domain() ) )
2111
PermGroup = Domain.subgroup( SortGenList )
2112
2113
po2p = PermGroup.convert_map_from( PermGroupOri )
2114
p2po = PermGroupOri.convert_map_from( PermGroup )
2115
2116
2117
self.__print_timestamp__( "subgroup of %s"%(Domain), TsLevel.Body )
2118
2119
2120
# ---------------------------------------------------------------------------------------------------------
2121
# setting the maps to the permutation group
2122
# ---------------------------------------------------------------------------------------------------------
2123
s2p_hom = None
2124
c2p_hom = None
2125
2126
if c2p == None and c2po != None and po2p != None:
2127
c2p = po2p * c2po
2128
2129
if c2p != None:
2130
c2p_hom = register_hom( ClassicalGroup, PermGroup, c2p, verbose = self._TimeStampSub_ )
2131
self.__print_timestamp__( "c2p_hom defined pos 1", TsLevel.Debug )
2132
2133
if s2p == None and s2po != None and po2p != None:
2134
s2p = po2p * s2po
2135
2136
if s2p != None:
2137
s2p_hom = register_hom( self, PermGroup, s2p, verbose = self._TimeStampSub_ )
2138
self.__print_timestamp__( "s2p_hom defined pos 1", TsLevel.Debug )
2139
2140
if c2p == None and s2p_hom != None:
2141
c2p = s2p_hom * c2s
2142
if native == True:
2143
# Note: in this case registering the map is not neccessary, but may cause a segmentation fault later on
2144
c2p_hom = c2p
2145
else:
2146
c2p_hom = register_hom( ClassicalGroup, PermGroup, c2p, verbose = self._TimeStampSub_ )
2147
self.__print_timestamp__( "c2p_hom defined pos 2", TsLevel.Debug )
2148
2149
if s2p == None and c2p_hom != None:
2150
s2p = c2p_hom * s2c
2151
s2p_hom = register_hom( self, PermGroup, s2p, verbose = self._TimeStampSub_ )
2152
self.__print_timestamp__( "s2p_hom defined pos 2", TsLevel.Debug )
2153
2154
2155
if s2p_hom == None:
2156
print "Warning: no map from self to permutation group defined"
2157
2158
if c2p_hom == None:
2159
print "Warning: no map from classical group to permutation group defined"
2160
2161
self.__print_timestamp__( "homToPerm defined", TsLevel.Debug )
2162
2163
# ---------------------------------------------------------------------------------------------------------
2164
# setting the maps from the permutation group
2165
# ---------------------------------------------------------------------------------------------------------
2166
p2s_hom = None
2167
p2c_hom = None
2168
2169
if p2c == None and po2c != None and p2po != None:
2170
p2c = po2c * p2po
2171
2172
if p2c != None:
2173
p2c_hom = register_hom( PermGroup, ClassicalGroup, p2c, verbose = self._TimeStampSub_ )
2174
self.__print_timestamp__( "p2c_hom defined pos 1", TsLevel.Debug )
2175
2176
if p2s == None and po2s != None and p2po != None:
2177
p2s = po2s * p2po
2178
2179
if p2s != None:
2180
p2s_hom = register_hom( PermGroup, self, p2s, verbose = self._TimeStampSub_ )
2181
self.__print_timestamp__( "p2s_hom defined pos 1", TsLevel.Debug )
2182
2183
if p2c == None and p2s_hom != None:
2184
p2c = s2c * p2s_hom
2185
p2c_hom = register_hom( PermGroup, ClassicalGroup, p2c, verbose = self._TimeStampSub_ )
2186
self.__print_timestamp__( "p2c_hom defined pos 2", TsLevel.Debug )
2187
2188
if p2s == None and p2c_hom != None:
2189
p2s = c2s * p2c_hom
2190
p2s_hom = register_hom( PermGroup, self, p2s, verbose = self._TimeStampSub_ )
2191
self.__print_timestamp__( "p2s_hom defined pos 2", TsLevel.Debug )
2192
2193
2194
if p2s_hom == None:
2195
print "Warning: no map from permutation group to self defined"
2196
2197
if c2p_hom == None:
2198
print "Warning: no map from permutation group to classical group defined"
2199
2200
self.__print_timestamp__( "homFromPerm defined", TsLevel.Debug )
2201
2202
2203
2204
2205
2206
2207
2208
if s2p_hom != None:
2209
self.__print_timestamp__( "checking homToPerm", TsLevel.Body )
2210
2211
if self.__check_homomorphism__( s2p_hom ) == False:
2212
raise ValueError( "permutation group fails to be an epimorphic image of %s"%(self._repr_()) )
2213
self.__print_timestamp__( "check homToPerm finished", TsLevel.Body )
2214
2215
2216
self.__print_timestamp__( "End", TsLevel.StackInfo )
2217
2218
return PermGroup
2219
2220
2221
2222
2223
2224
2225
# ----------------------------------------------------------------------------------
2226
# as_classical_group
2227
# ----------------------------------------------------------------------------------
2228
def as_classical_group(self, embedded=False):
2229
"""
2230
creates an isomorphic image of self as a classical group according to the construction given by Coxeter resp. Assion
2231
2232
If you don't see this well formatted type
2233
2234
sage: print CubicBraidGroup_class.as_classical_group.__doc__
2235
2236
INPUT: (optional as keyword)
2237
2238
- "embedded": boolean (default = False). This boolean does effect the cases of AssionGroups where they are
2239
realized as projective groups, only. More precisely: if self is of type 'S' (for example) and the
2240
number of strands n is even, than its classical group is a subgroup of PSp(n,3) (being
2241
centralized by the element self.centralizing_element( projective = True)). By default this group
2242
will be given. Setting embedded = True the classical realization is given as subgroup of its
2243
classical enlargement with one more stand (in this case as subgroup of Sp(n-1,3))
2244
2245
OUTPUT:
2246
2247
depending on the type of self and the number of strands an instance of Sp(n-1,3), GU(n-1,2), Subgroup of
2248
PSp(n,3), PGU(n,2) or a subgroup of GU(n-1, UCF) (type 'C' ) with respect to a certain hermitian form
2249
attached to the burau representation (used by Coxeter and Squier). Here UCF stands for the universal
2250
cyclotomic field.
2251
2252
RAISE:
2253
2254
- ValueError: "no classical group defined" if the construction was not possible
2255
2256
- ValueError: "no classical embedding defined" if the construction was not possible
2257
2258
EXAMPLES:
2259
2260
sage: from cubic_braid import *
2261
sage: U3 = AssionGroupU(3)
2262
sage: U3Cl = U3.as_classical_group(); U3Cl
2263
Subgroup of (The projective general unitary group of degree 3 over Finite Field of size 2) generated by
2264
[(1,7,6)(3,19,14)(4,15,10)(5,11,18)(12,16,20),
2265
(1,12,13)(2,15,19)(4,9,14)(5,18,8)(6,21,16)]
2266
2267
sage: U3Clemb = U3.as_classical_group(embedded=True); U3Clemb
2268
Matrix group over Finite Field in a of size 2^2 with 2 generators (
2269
[0 0 a] [a + 1 a a]
2270
[0 1 0] [ a a + 1 a]
2271
[a 0 a], [ a a a + 1]
2272
)
2273
sage: u = U3([-2,1,-2,1]); u
2274
(u1^-1*u0)^2
2275
sage: uCl = U3Cl(u); uCl
2276
(1,16)(2,9)(3,10)(4,19)(6,12)(7,20)(13,21)(14,15)
2277
sage:
2278
sage: uCle = U3Clemb(u); uCle
2279
[a + 1 a + 1 1]
2280
[a + 1 0 a]
2281
[ 1 a a]
2282
sage:
2283
sage: U3(uCl) == u
2284
True
2285
sage: U3(uCle) == u
2286
True
2287
sage: U4 = AssionGroupU(4)
2288
sage: U4Cl = U4.as_classical_group(); U4Cl
2289
General Unitary Group of degree 3 over Finite Field in a of size 2^2 with respect to hermitian form [0 0 1]
2290
[0 1 0]
2291
[1 0 0]
2292
sage: uCle in U4Cl
2293
True
2294
sage: C4 = CubicBraidGroup(4)
2295
sage: C4Cl = C4.as_classical_group(); C4Cl
2296
Subgroup of General Unitary Group of degree 3 over Universal Cyclotomic Field with respect to hermitian form
2297
[-E(12)^7 + E(12)^11 -1 0]
2298
[ -1 -E(12)^7 + E(12)^11 -1]
2299
[ 0 -1 -E(12)^7 + E(12)^11]
2300
generated by (
2301
[ E(3) E(12)^11 0]
2302
[ 0 1 0]
2303
[ 0 0 1],
2304
[ 1 0 0]
2305
[E(12)^11 E(3) E(12)^11]
2306
[ 0 0 1],
2307
[ 1 0 0]
2308
[ 0 1 0]
2309
[ 0 E(12)^11 E(3)])
2310
sage: type(C4Cl)
2311
<class 'lib.local_matrix_group.MatrixGroup_subgroup_with_category'>
2312
2313
2314
2315
AUTHOR
2316
2317
- Sebastian Oehms, Sept. 2016
2318
2319
2320
"""
2321
2322
# -------------------------------------------------------------------------------
2323
# the classical group have already been created in __init__
2324
# -------------------------------------------------------------------------------
2325
2326
if embedded == False or self._classical_embedding_ == None or self._classical_group_ == self._classical_embedding_:
2327
if self._classical_group_ == None:
2328
raise ValueError( "no classical group defined")
2329
else:
2330
return self._classical_group_
2331
else:
2332
# ----------------------------------------------------------------------------------------
2333
# there is a difference between self._classical_group_ and self._classical_embedding_
2334
# only in the cases where self._nstrands_ divides by 2 (AssionGroupS) resp. 3
2335
# (AssionGroupU). In this case the embedding is the subgroup of the classical group
2336
# of one strand more (self._nstrands_ +1) generated by the first self._nstrands_ -1
2337
# generators
2338
# ----------------------------------------------------------------------------------------
2339
if self._classical_embedding_ == None:
2340
raise ValueError( "no classical embedding defined")
2341
else:
2342
return self._classical_embedding_
2343
2344
2345
2346
2347
2348
2349
# ----------------------------------------------------------------------------------
2350
# as_refection_group
2351
# ----------------------------------------------------------------------------------
2352
def as_reflection_group(self, check=False ):
2353
"""
2354
creates an isomorphic image of self as irreducible complex reflection group. This is possible only for the finite
2355
cubic braid groups of type 'C'
2356
2357
If you don't see this well formatted type
2358
2359
sage: print CubicBraidGroup_class.as_classical_group.__doc__
2360
2361
This method uses the sage implementation of reflection group via the gap3 CHEVIE package. To use this methode
2362
you must have sage from version 7.2 up and gap3 with CHEVIE installed
2363
2364
INPUT (optional):
2365
2366
-check : boolean (default false): can be set to force a check of well definiteness of the morphism from self
2367
2368
OUTPUT:
2369
2370
an object of the class IrreducibleComplexReflectionGroup (from sage.combinat.root_system.reflection_group_complex)
2371
together with isomorphism to and from self and self.as_classical_group()
2372
2373
RAISE:
2374
2375
- ValueError: "no refection group defined" if the construction was not possible
2376
- ImportError: "cannot import name IrreducibleComplexReflectionGroup" means:Sage Version 7.2 up is needed for
2377
this functionality"
2378
2379
2380
EXAMPLES:
2381
2382
sage: from lib.cubic_braid import *
2383
sage: C3.<c1,c2> = CubicBraidGroup(3)
2384
sage: R3 = C3.as_reflection_group(); R3
2385
Irreducible complex reflection group of rank 2 and type ST4
2386
sage: type(R3)
2387
<class 'lib.local_permgroup.IrreducibleComplexReflectionGroup_with_category'>
2388
sage:
2389
sage: R3.cartan_matrix()
2390
[-2*E(3) - E(3)^2 E(3)^2]
2391
[ -E(3)^2 -2*E(3) - E(3)^2]
2392
sage: R3.simple_roots()
2393
Finite family {1: (0, -2*E(3) - E(3)^2), 2: (2*E(3)^2, E(3)^2)}
2394
sage: R3.simple_coroots()
2395
Finite family {1: (0, 1), 2: (1/3*E(3) - 1/3*E(3)^2, 1/3*E(3) - 1/3*E(3)^2)}
2396
sage:
2397
2398
Conversion maps:
2399
2400
sage:
2401
sage: C3Cl = C3.as_classical_group()
2402
sage: ele = c1*c2**2; ele
2403
c1*c2^2
2404
sage: rele = R3(ele); rele
2405
(1,14,12,18)(2,15,24,16)(3,22,19,4)(5,6,17,20)(7,10,23,21)(8,11,9,13)
2406
sage: rele.matrix()
2407
[-1/3*E(3) + 1/3*E(3)^2 1/3*E(3) + 2/3*E(3)^2]
2408
[-4/3*E(3) - 2/3*E(3)^2 1/3*E(3) - 1/3*E(3)^2]
2409
sage: clele = C3Cl(ele); clele
2410
[ -E(3)^2 E(12)^7]
2411
[-E(12)^7 E(3)^2]
2412
sage: clrele = C3Cl(rele); clrele
2413
[ -E(3)^2 E(12)^7]
2414
[-E(12)^7 E(3)^2]
2415
sage: C3(rele)
2416
c1*c2^-1
2417
2418
The refelection groups can also be viewed as subgroups of unitary groups over the universal cyclotomic field. This
2419
functionality is availlable just in the context of cubic braid groups in addition to the basic functionality of the
2420
IrreducibleComplexReflectionGroup_class. Note that the unitary group corresponding to the reflection group is
2421
isomorphic but diferent from the classical group due to different hermitian forms for the unitary groups they live in.
2422
2423
sage: C4=CubicBraidGroup(4)
2424
sage: R4=C4.as_reflection_group()
2425
sage: R4Cl=R4.as_unitary_group(); R4Cl
2426
Subgroup of General Unitary Group of degree 3 over Universal Cyclotomic Field generated by:
2427
([ 1 0 0]
2428
[ 0 1 0]
2429
[ 0 0 E(3)],
2430
[-1/3*E(3) - 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2]
2431
[ 2/3*E(3) + 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2]
2432
[ 2/3*E(3) + 1/3*E(3)^2 2/3*E(3) + 1/3*E(3)^2 -1/3*E(3) - 2/3*E(3)^2],
2433
[ 1 0 0]
2434
[ 0 E(3) 0]
2435
[ 0 0 1])
2436
sage: C4Cl=C4.as_classical_group(); C4Cl
2437
Subgroup of Unitary Group of degree 3 over Universal Cyclotomic Field with respect to hermitian form
2438
[-E(12)^7 + E(12)^11 -1 0]
2439
[ -1 -E(12)^7 + E(12)^11 -1]
2440
[ 0 -1 -E(12)^7 + E(12)^11] generated by:
2441
([ E(3) E(12)^11 0]
2442
[ 0 1 0]
2443
[ 0 0 1],
2444
[ 1 0 0]
2445
[E(12)^11 E(3) E(12)^11]
2446
[ 0 0 1],
2447
[ 1 0 0]
2448
[ 0 1 0]
2449
[ 0 E(12)^11 E(3)])
2450
sage: C4ClAmbient = C4Cl.ambient(); C4ClAmbient
2451
Unitary Group of degree 3 over Universal Cyclotomic Field with respect to hermitian form
2452
[-E(12)^7 + E(12)^11 -1 0]
2453
[ -1 -E(12)^7 + E(12)^11 -1]
2454
[ 0 -1 -E(12)^7 + E(12)^11]
2455
sage: R4ClAmbient = R4Cl.ambient(); R4ClAmbient
2456
General Unitary Group of degree 3 over Universal Cyclotomic Field
2457
sage: C4ClAmbient == R4ClAmbient
2458
False
2459
2460
2461
AUTHOR:
2462
2463
- Sebastian Oehms, Mar. 2017
2464
2465
2466
"""
2467
2468
# -------------------------------------------------------------------------------
2469
# the reflection groups are taken via gap3 -CHEVIE - Interface
2470
# sage Version 7.2 or later is needed
2471
# They are called according to the Shephard-Todd classification:
2472
# 2 strands -> G(2,1,1)
2473
# 3 strands -> G4
2474
# 4 strands -> G25
2475
# 5 strands -> G32
2476
# -------------------------------------------------------------------------------
2477
2478
if self._AdditionalRelation_ != 'C' or self._nstrands_ > _sage_const_5 or self._nstrands_ < _sage_const_2 :
2479
raise ValueError( "no reflection group defined")
2480
2481
# -------------------------------------------------------------------------------
2482
# define reflection group assiossiated to self
2483
# -------------------------------------------------------------------------------
2484
self.__print_timestamp__( "Begin", TsLevel.StackInfo )
2485
2486
ReflectGroup = None
2487
2488
from lib.local_permgroup import IrreducibleComplexReflectionGroup
2489
2490
def ReflectionGroup( *args,**kwds):
2491
"""
2492
This local Function overloads the corresponding function of sage.combinat.root_system.reflection_group_real
2493
in order to make "call by name conversion" availlable via the local_permgroup module
2494
"""
2495
RefGroup = IrreducibleComplexReflectionGroup(tuple(args),
2496
index_set=kwds.get('index_set', None),
2497
hyperplane_index_set=kwds.get('hyperplane_index_set', None),
2498
reflection_index_set=kwds.get('reflection_index_set', None))
2499
return RefGroup
2500
2501
2502
if self._nstrands_ == _sage_const_2 :
2503
ReflectGroup = ReflectionGroup( [_sage_const_2 ,_sage_const_1 ,_sage_const_1 ] )
2504
elif self._nstrands_ == _sage_const_3 :
2505
ReflectGroup = ReflectionGroup( _sage_const_4 )
2506
elif self._nstrands_ == _sage_const_4 :
2507
ReflectGroup = ReflectionGroup( _sage_const_25 )
2508
elif self._nstrands_ == _sage_const_5 :
2509
ReflectGroup = ReflectionGroup( _sage_const_32 )
2510
2511
self.__print_timestamp__( "ReflectGroup %s defined" %(ReflectGroup), TsLevel.Body )
2512
2513
# -------------------------------------------------------------------------------
2514
# check if there is a well defined map to MatGroup
2515
# Register map from self to MatGroup
2516
# -------------------------------------------------------------------------------
2517
homToRefl = gap_hom( self, ReflectGroup, verbose = self._TimeStampSub_ )
2518
2519
if check == True:
2520
if self.__check_homomorphism__( homToRefl ) == False:
2521
raise ValueError( "refection group fails to be an epimorphic image of %s"%(self._repr_()) )
2522
2523
self.__print_timestamp__( "Hom from self defined", TsLevel.Body )
2524
2525
try:
2526
homFromRefl = gap_hom( ReflectGroup, self, verbose = self._TimeStampSub_ )
2527
self.__print_timestamp__( "Hom to self defined", TsLevel.Body )
2528
except:
2529
print "Warning: no section back from reflection group"
2530
2531
2532
# -------------------------------------------------------------------------------
2533
# maps to and from the classical group
2534
# -------------------------------------------------------------------------------
2535
ClassicalGroup = self.as_classical_group()
2536
c2s = self.convert_map_from( ClassicalGroup )
2537
s2c = ClassicalGroup.convert_map_from( self )
2538
2539
r2c = s2c * homFromRefl
2540
r2c_hom = register_hom( ReflectGroup, ClassicalGroup, r2c, verbose = self._TimeStampSub_ )
2541
self.__print_timestamp__( "r2c_hom defined", TsLevel.Debug )
2542
2543
c2r = homToRefl * c2s
2544
c2r_hom = register_hom( ClassicalGroup, ReflectGroup, c2r, verbose = self._TimeStampSub_ )
2545
self.__print_timestamp__( "c2r_hom defined", TsLevel.Debug )
2546
2547
self.__print_timestamp__( "End", TsLevel.StackInfo )
2548
2549
return ReflectGroup
2550
2551
2552
2553
# ----------------------------------------------------------------------------------
2554
# centralizing element in the classical symplectic resp. unitary group
2555
# ----------------------------------------------------------------------------------
2556
def centralizing_element(self, projective=False ):
2557
"""
2558
returns the centralizing element defined in the work of Assion (Hilfssatz 1.1.3 and 1.2.3)
2559
2560
If you don't see this well formatted type
2561
2562
sage: print CubicBraidGroup_class.centralizing_element.__doc__
2563
2564
INPUT: (optional as keyword)
2565
2566
- "projective": boolean (default = False). This boolean does effect the cases of AssionGroups where they are
2567
realized as projective groups, only. More precisely: if self is of type 'S' (for example) and
2568
the number of strands n is even, than its classical group is a subgroup of
2569
PSp(n,3) (being centralized by this element). By default this group will be given.
2570
Setting embedded = True the classical realization is given as subgroup of its classical
2571
enlargement with one more stand (in this case as subgroup of Sp(n,3))
2572
2573
OUTPUT:
2574
2575
depending on the optional keyword a permutation as an element of PSp(n,3) (type S) or PGU(n,2) (type U) if
2576
projective = True and n == 0 mod 2 (type S) reps. n == 0 mod 3 (type U) is returned. Elsewise the
2577
centralizing element is a matrix belonging to Sp(n,3) reps. GU(n,2).
2578
2579
RAISE:
2580
2581
- ValueError: "no centralizing element defined"
2582
2583
2584
EXAMPLES:
2585
2586
sage: U3=AssionGroupU(3); U3
2587
Assion group on 3 strands of type U
2588
sage:
2589
sage: U3Cl = U3.as_classical_group(); U3Cl
2590
Subgroup of (The projective general unitary group of degree 3 over Finite Field of size 2) generated by
2591
[(1,7,6) (3,19,14)(4,15,10)(5,11,18)(12,16,20), (1,12,13)(2,15,19)(4,9,14)(5,18,8)(6,21,16)]
2592
sage:
2593
sage: U3Clem = U3.as_classical_group(embedded=True); U3Clem
2594
Matrix group over Finite Field in a of size 2^2 with 2 generators (
2595
[0 0 a] [a + 1 a a]
2596
[0 1 0] [ a a + 1 a]
2597
[a 0 a], [ a a a + 1]
2598
)
2599
sage:
2600
sage: u3cent = U3.centralizing_element(); u3cent
2601
[a + 1 a + 1 1]
2602
[a + 1 0 a]
2603
[ 1 a a]
2604
sage: u3cent in U3Cl
2605
False
2606
sage: u3centP in U3Cl
2607
True
2608
sage: u3cent in U3Clem
2609
True
2610
sage: u3centP in U3Clem
2611
False
2612
2613
considering u3cent as element in AssionGroupU(4)
2614
2615
sage: U4=AssionGroupU(4); U4
2616
Assion group on 4 strands of type U
2617
sage:
2618
sage: U4Cl = U4.as_classical_group(); U4Cl
2619
General Unitary Group of degree 3 over Finite Field in a of size 2^2 with respect to hermitian form [0 0 1]
2620
[0 1 0]
2621
[1 0 0]
2622
sage: u3cent in U4Cl
2623
True
2624
sage: U4(u3cent)
2625
(u0*u1^-1)^2
2626
sage:
2627
sage: # calculating the centralizer of u3cent in U4Cl via GAP functions in order to
2628
sage: # check if U3Clem is a subgroup of the centralizer of u3cent in U4Cl
2629
sage:
2630
sage: CentU4u3cent = gap_centralizer( U4Cl, u3cent ); CentU4u3cent
2631
Matrix group over Finite Field in a of size 2^2 with 4 generators (
2632
[a + 1 a + 1 1] [a + 1 0 0] [ 1 1 a + 1] [1 0 1]
2633
[a + 1 0 a] [ 0 a + 1 0] [ 0 a a] [0 a 0]
2634
[ 1 a a], [ 0 0 a + 1], [ 0 0 1], [1 0 0]
2635
)
2636
sage:
2637
sage: CentU4u3cent.gens()[0] in U3Clem
2638
True
2639
sage: CentU4u3cent.gens()[1] in U3Clem
2640
False
2641
sage: CentU4u3cent.gens()[2] in U3Clem
2642
True
2643
sage: CentU4u3cent.gens()[3] in U3Clem
2644
False
2645
sage:
2646
sage: CentU4u3cent.order()
2647
72
2648
sage: U3Clem.order()
2649
24
2650
2651
check that U3Clem is a subgroup of index 3 in CentU4u3cent
2652
2653
sage: U3Clem.gens()[0] in CentU4u3cent
2654
True
2655
sage: U3Clem.gens()[1] in CentU4u3cent
2656
True
2657
2658
2659
AUTHOR
2660
2661
- Sebastian Oehms, Sept. 2016
2662
2663
"""
2664
2665
# -------------------------------------------------------------------------------
2666
# the centralizing elements have already been created in __init__
2667
# -------------------------------------------------------------------------------
2668
if self._centralizing_matrix_ == None:
2669
raise ValueError( "no centralizing element defined")
2670
else:
2671
if projective == True:
2672
return self._centralizing_element_
2673
else:
2674
return self._centralizing_matrix_
2675
2676
2677
# ----------------------------------------------------------------------------------
2678
# calculating the order by formula
2679
# ----------------------------------------------------------------------------------
2680
def order(self, by_formula = True ):
2681
"""
2682
to avoid long waittime on calculations the order will be obtained by formular resp. direct value
2683
2684
If you don't see this well formatted type
2685
2686
sage: print CubicBraidGroup_class.order.__doc__
2687
2688
INPUT:
2689
2690
- "by_formula": (optional keyword) boolean (default = True). In the default case the order is calculated from
2691
formulas for simple group of Lie typ. If set to false the order is calculated by native function with
2692
respect to the classical group (in the cases where this is finite).
2693
2694
OUTPUT:
2695
2696
size of the group as Integer ore infinity
2697
2698
EXAMPLES:
2699
2700
sage: S6=AssionGroupS(6)
2701
sage: S6.order()
2702
12597120
2703
sage: S6.order(by_formula=False)
2704
12597120
2705
sage:
2706
sage: C6=CubicBraidGroup(6)
2707
sage: C6.order()
2708
+Infinity
2709
2710
2711
AUTHOR
2712
2713
- Sebastian Oehms, Sept. 2016
2714
2715
REFERENCES:
2716
2717
- Carter, R.W.: "Simple groups of Lie type", John Wiley & Sons (London 1989)
2718
2719
"""
2720
2721
n = self._nstrands_
2722
2723
if by_formula == False:
2724
if self._AdditionalRelation_ == 'C' and n > _sage_const_5 :
2725
order = infinity
2726
else:
2727
order = self.as_classical_group().order()
2728
return order
2729
2730
m = n -_sage_const_1 # dim of classical group
2731
2732
order = _sage_const_0
2733
if n == _sage_const_1 :
2734
order = _sage_const_1
2735
elif n == _sage_const_2 :
2736
order = _sage_const_3
2737
elif n == _sage_const_3 :
2738
order = _sage_const_24
2739
elif n == _sage_const_4 :
2740
order = _sage_const_648
2741
2742
2743
if self._AdditionalRelation_ == 'S':
2744
q = _sage_const_3 # size of base_ring
2745
if n % _sage_const_2 != _sage_const_0 :
2746
l = m/_sage_const_2
2747
# -------------------------------------------------------------------------------------------------------
2748
# using the formula (for example from Carter, R.W., page 4) for self.as_classical_group() isomorphic to
2749
# PSp(2l,q)
2750
# PSp(2l,q).order() = 1/(2,q-1) * q^l^2*(q^2-1)*...*(q^(2*l)-1)
2751
# thus Sp(2l,q).order() = q^l^2*(q^2-1)*...*(q^(2*l)-1)
2752
# since Sp(2l,q).order() = (q-1)*PSp(2l,q).order()
2753
# -------------------------------------------------------------------------------------------------------
2754
order = _sage_const_1
2755
for i in range(l):
2756
order = order * (q**(_sage_const_2 *(i+_sage_const_1 ))-_sage_const_1 )
2757
order = order * q**l**_sage_const_2
2758
2759
elif self._AdditionalRelation_ == 'U':
2760
q = _sage_const_2 # characteristic of base_ring
2761
if n % _sage_const_3 != _sage_const_0 :
2762
# -----------------------------------------------------------------------------------------------------
2763
# using the formula (for example from Carter, R.W.,page 4) for self.as_classical_group() isomorphic to
2764
# PSU(m,q)
2765
# PSU(m,q).order() = 1/(m,q+1)*q^(m*(m-1)/2)*(q^2-1)*(q^3+1)...*(q^m - (-1)^m)
2766
# thus GU(m,q).order() = (q+1)*q^(m*(m-1)/2)*(q^2-1)*(q^3+1)...*(q^m - (-1)^m)
2767
# since GU(m,q).order() = (q+1)**2*PSU(m,q).order() for m % 3 == 0
2768
# and GU(m,q).order() = (q+1)*PSU(m,q).order() for m % 3 != 0
2769
# -----------------------------------------------------------------------------------------------------
2770
order = _sage_const_1
2771
for i in range(m-_sage_const_1 ):
2772
order = order * (q**(i+_sage_const_2 ) - (-_sage_const_1 )**(i+_sage_const_2 ))
2773
order = order * (q+_sage_const_1 )*q**(m*(m-_sage_const_1 )/_sage_const_2 )
2774
2775
elif self._AdditionalRelation_ == 'C':
2776
if order > _sage_const_0 :
2777
pass
2778
elif n == _sage_const_5 :
2779
order = _sage_const_155520
2780
else:
2781
order = infinity
2782
2783
if order == _sage_const_0 :
2784
order = self.as_classical_group().order()
2785
2786
return order
2787
2788
2789
# ----------------------------------------------------------------------------------
2790
# creating a CubicBraidGroup as subgroup of self on less strands
2791
# ----------------------------------------------------------------------------------
2792
def cubic_braid_subgroup( self, nstrands = None ):
2793
"""
2794
creates a CubicBraidGroup as subgroup of self on the first "n_strands" strands
2795
2796
If you don't see this well formatted type
2797
2798
sage: print CubicBraidGroup_class.order.__doc__
2799
2800
INPUT:
2801
2802
- "nstrands": Integer > 0 and < self._nstrands_ giving the number of strand for the subgroup.
2803
the default is one strand less than self
2804
2805
OUTPUT:
2806
2807
an instance of the this class realizing the subgroup
2808
2809
EXAMPLES:
2810
2811
2812
2813
AUTHOR
2814
2815
- Sebastian Oehms, Sept. 2016
2816
2817
"""
2818
2819
if nstrands == None:
2820
nstrands = self._nstrands_ -_sage_const_1
2821
2822
n = self._nstrands_
2823
2824
try:
2825
nstrands = Integer( nstrands )
2826
except:
2827
raise TypeError( "nstrands must be an integer" )
2828
2829
if nstrands >= n or nstrands <= _sage_const_0 :
2830
raise ValueError( "nstrands must be positive and less than %s" %(self._nstrands_) )
2831
2832
Gens = self.gens()
2833
GensRed = tuple( [ Gens[i] for i in range(nstrands -_sage_const_1 ) ])
2834
2835
SGrp = CubicBraidGroup( names = GensRed, AdditionalRelation = self._AdditionalRelation_, verbose = self._verbose_ )
2836
2837
def embed( ele ):
2838
return self( ele.Tietze() )
2839
2840
register_hom( SGrp, self, embed, verbose = self._TimeStampSub_ )
2841
2842
return SGrp
2843
2844
2845
2846
2847
2848
2849
2850
# ----------------------------------------------------------------------------------
2851
# Although GAP can calculate character tables for finitely presentet groups
2852
# this method is not offered by the sage gap interface
2853
# we therefore use the permutation group implementation to get it
2854
# ----------------------------------------------------------------------------------
2855
def character_table( self ):
2856
"""
2857
calculates the character_table of the cubic braid group via the gap interface
2858
2859
OUTPUT:
2860
2861
Character table as matrix (instance of sage.matrix.matrix_cyclo_dense.Matrix_cyclo_dense)
2862
2863
EXAMPLE:
2864
2865
sage: U3=AssionGroupU(3); U3
2866
Assion group on 3 strands of type U
2867
sage: U3ct=U3.character_table(); U3ct
2868
[ 1 1 1 1 1 1 1]
2869
[ 1 -zeta3 - 1 zeta3 1 zeta3 -zeta3 - 1 1]
2870
[ 1 zeta3 -zeta3 - 1 1 -zeta3 - 1 zeta3 1]
2871
[ 2 -1 -1 0 1 1 -2]
2872
[ 2 -zeta3 zeta3 + 1 0 -zeta3 - 1 zeta3 -2]
2873
[ 2 zeta3 + 1 -zeta3 0 zeta3 -zeta3 - 1 -2]
2874
[ 3 0 0 -1 0 0 3]
2875
2876
2877
2878
2879
AUTHOR
2880
2881
- Sebastian Oehms, Sept. 2016
2882
2883
"""
2884
PermGroup = self.as_permutation_group()
2885
CharTab = PermGroup.character_table()
2886
2887
return CharTab
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
##############################################################################
2904
#
2905
# Functions to create Objects
2906
#
2907
##############################################################################
2908
def CubicBraidGroup(n=None, names='c', AdditionalRelation = 'C', verbose = False ):
2909
"""
2910
Constructs cubic quotients of braid groups as instance of the CubicBraidGroup_class
2911
2912
If you don't see this well formatted type
2913
2914
sage: print CubicBraidGroup.__doc__
2915
2916
for more information about the CubicBraidGroup_class type
2917
2918
sage: print CubicBraidGroup_class.__doc__
2919
2920
INPUT:
2921
2922
- "n": integer or None (default). The number of strands. If not specified the "names" are counted and the group is
2923
assumed to have one more strand than generators.
2924
2925
- "names": string or list/tuple/iterable of strings (default:'c'). The generator names or name prefix.
2926
2927
The entry can be either a string with the names of the generators, or the number of generators and the prefix
2928
of the names to be given. The default prefix is 'c'
2929
2930
- "AdditionalRelation": (optional keyword, default = 'C') is passed to the corresponding keyword parameter of
2931
the constructor of the CubicBraidGroup_class. For more information type
2932
sage: print CubicBraidGroup_class.__doc__
2933
2934
- "verbose": (optional keyword, default = False) is passed to the corresponding keyword parameter of
2935
the constructor of the CubicBraidGroup_class. For more information type
2936
sage: print CubicBraidGroup_class.__doc__
2937
2938
2939
2940
This function is adapted from the BraidGroup function!
2941
2942
EXAMPLES:
2943
2944
sage: C3=CubicBraidGroup(3); C3.generators()
2945
(c0, c1)
2946
sage: CubicBraidGroup(3, 'g').generators()
2947
(g0, g1)
2948
sage: U3.<u1,u2>=CubicBraidGroup(3, AdditionalRelation = 'U'); U3.generators()
2949
(u1, u2)
2950
2951
2952
AUTHOR
2953
2954
- Sebastian Oehms, Sept. 2016
2955
2956
"""
2957
# Support Freegroup('a,b') syntax
2958
if n is not None:
2959
try:
2960
n = Integer(n)-_sage_const_1
2961
except TypeError:
2962
names = n
2963
2964
n = None
2965
# derive n from counting names
2966
if n is None:
2967
if isinstance(names, six.string_types):
2968
n = len(names.split(','))
2969
else:
2970
names = list(names)
2971
n = len(names)
2972
try:
2973
from sage.structure.category_object import normalize_names
2974
except:
2975
from sage.structure.parent import normalize_names
2976
names = tuple(normalize_names(n, names))
2977
return CubicBraidGroup_class(names, AdditionalRelation, verbose )
2978
2979
2980
# ----------------------------------------------------------------------------------
2981
# Short-Hand-Calls
2982
# ----------------------------------------------------------------------------------
2983
2984
2985
def AssionGroupS(n=None, names='s', verbose = False ):
2986
"""
2987
Constructs cubic quotients of braid groups as instance of the CubicBraidGroup_class which have been investigated
2988
by J.Assion under the notation S(m)
2989
2990
If you don't see this well formatted type
2991
2992
sage: print AssionGroupS.__doc__
2993
2994
for more information about the CubicBraidGroup_class type
2995
2996
sage: print CubicBraidGroup_class.__doc__
2997
2998
This function is a short hand cut for the CubicBraidGroup function setting AdditionalRelation ='S' and
2999
default names='s'
3000
3001
INPUT:
3002
3003
- "n": integer or None (default). The number of strands. This parameter is passed to the corresponding parameter
3004
of the CubicBraidGroup function For more information type
3005
sage: print CubicBraidGroup.__doc__
3006
3007
- "names": string or list/tuple/iterable of strings (default:'s'). This parameter is passed to the corresponding
3008
parameter of the CubicBraidGroup function For more information type
3009
sage: print CubicBraidGroup.__doc__
3010
3011
- "verbose": (optional keyword, default = False) is passed to the corresponding keyword parameter of
3012
the constructor of the CubicBraidGroup_class. For more information type
3013
sage: print CubicBraidGroup_class.__doc__
3014
3015
EXAMPLES:
3016
3017
sage: S3=AssionGroupS(3); S3
3018
Assion group on 3 strands of type S
3019
sage: S3x=CubicBraidGroup(3, names='s', AdditionalRelation = 'S'); S3x
3020
Assion group on 3 strands of type S
3021
sage: S3 == S3x
3022
True
3023
3024
AUTHOR
3025
3026
- Sebastian Oehms, Sept. 2016
3027
3028
"""
3029
3030
return CubicBraidGroup(n = n, names = names, AdditionalRelation = 'S', verbose = verbose )
3031
3032
def AssionGroupU(n=None, names='u', verbose = False ):
3033
"""
3034
Constructs cubic quotients of braid groups as instance of the CubicBraidGroup_class which have been investigated
3035
by J.Assion under the notation U(m)
3036
3037
If you don't see this well formatted type
3038
3039
sage: print AssionGroupU.__doc__
3040
3041
for more information about the CubicBraidGroup_class type
3042
3043
sage: print CubicBraidGroup_class.__doc__
3044
3045
This function is a short hand cut for the CubicBraidGroup function setting AdditionalRelation ='U' and
3046
default names='u'
3047
3048
INPUT:
3049
3050
- "n": integer or None (default). The number of strands. This parameter is passed to the corresponding parameter
3051
of the CubicBraidGroup function For more information type
3052
sage: print CubicBraidGroup.__doc__
3053
3054
- "names": string or list/tuple/iterable of strings (default:'u'). This parameter is passed to the corresponding
3055
parameter of the CubicBraidGroup function For more information type
3056
sage: print CubicBraidGroup.__doc__
3057
3058
- "verbose": (optional keyword, default = False) is passed to the corresponding keyword parameter of
3059
the constructor of the CubicBraidGroup_class. For more information type
3060
sage: print CubicBraidGroup_class.__doc__
3061
3062
EXAMPLES:
3063
3064
sage: U3=AssionGroupU(3); U3
3065
Assion group on 3 strands of type U
3066
sage: U3x=CubicBraidGroup(3, names='u', AdditionalRelation = 'U'); U3x
3067
Assion group on 3 strands of type U
3068
sage: U3 == U3x
3069
True
3070
3071
AUTHOR
3072
3073
- Sebastian Oehms, Sept. 2016
3074
3075
"""
3076
3077
return CubicBraidGroup(n = n, names = names, AdditionalRelation = 'U', verbose = verbose )
3078
3079
3080
3081
3082
3083
3084
3085
3086