@@ -317,7 +317,7 @@ def fundamental_group(self, simplify=True):
317
317
sage: Sigma3 = groups.permutation.Symmetric(3)
318
318
sage: BSigma3 = Sigma3.nerve()
319
319
sage: pi = BSigma3.fundamental_group(); pi
320
- Finitely presented group < e0, e1 | e0 ^2, e1^3, (e0 *e1^-1 )^2 >
320
+ Finitely presented group < e1, e2 | e2 ^2, e1^3, (e2 *e1)^2 >
321
321
sage: pi.order()
322
322
6
323
323
sage: pi.is_abelian()
@@ -331,19 +331,27 @@ def fundamental_group(self, simplify=True):
331
331
"""
332
332
# Import this here to prevent importing libgap upon startup.
333
333
from sage .groups .free_group import FreeGroup
334
- skel = self .n_skeleton (2 )
334
+ if not self .n_cells (1 ):
335
+ return FreeGroup ([]).quotient ([])
336
+ FG = self ._universal_cover_dict ()[0 ]
337
+ if simplify :
338
+ return FG .simplified ()
339
+ else :
340
+ return FG
335
341
342
+ def _universal_cover_dict (self ):
343
+ r"""
344
+ Return the fundamental group and dictionary sending each edge to
345
+ the corresponding group element
346
+ """
347
+ from sage .groups .free_group import FreeGroup
348
+ skel = self .n_skeleton (2 )
336
349
graph = skel .graph ()
337
350
if not skel .is_connected ():
338
351
graph = graph .subgraph (skel .base_point ())
339
-
340
- edges = [e [2 ] for e in graph .edges (sort = True )]
352
+ edges = [e [2 ] for e in graph .edges (sort = False )]
341
353
spanning_tree = [e [2 ] for e in graph .min_spanning_tree ()]
342
354
gens = [e for e in edges if e not in spanning_tree ]
343
-
344
- if not gens :
345
- return FreeGroup ([]).quotient ([])
346
-
347
355
gens_dict = dict (zip (gens , range (len (gens ))))
348
356
FG = FreeGroup (len (gens ), 'e' )
349
357
rels = []
@@ -361,10 +369,13 @@ def fundamental_group(self, simplify=True):
361
369
# sigma is not in the correct connected component.
362
370
z [i ] = FG .one ()
363
371
rels .append (z [0 ]* z [1 ].inverse ()* z [2 ])
364
- if simplify :
365
- return FG .quotient (rels ).simplified ()
366
- else :
367
- return FG .quotient (rels )
372
+ G = FG .quotient (rels )
373
+ char = {g : G .gen (i ) for i ,g in enumerate (gens )}
374
+ for e in edges :
375
+ if not e in gens :
376
+ char [e ] = G .one ()
377
+ return (G , char )
378
+
368
379
369
380
def universal_cover_map (self ):
370
381
r"""
@@ -382,48 +393,18 @@ def universal_cover_map(self):
382
393
To: RP^2
383
394
Defn: [(1, 1), (1, e), (f, 1), (f, e), (f * f, 1), (f * f, e)] --> [1, 1, f, f, f * f, f * f]
384
395
sage: phi.domain().face_data()
385
- {(f, 1): ((1, e), (1, 1)) ,
386
- (f, e): ((1, 1), (1, e)) ,
387
- (f * f, 1): ((f , e), s_0 (1, 1), (f , 1)),
388
- (f * f, e): ((f, 1), s_0 (1, e ), (f , e)),
389
- (1 , e): None ,
390
- (1, 1): None }
396
+ { (1, 1): None ,
397
+ (1, e): None ,
398
+ ( f, 1): ((1 , e), (1 , 1)),
399
+ ( f, e): ((1, 1 ), (1 , e)),
400
+ (f * f, 1): ((f , e), s_0 (1, 1), (f, 1)) ,
401
+ (f * f, e): ((f, 1), s_0 (1, e), (f, e)) }
391
402
392
403
"""
393
- from sage .groups .free_group import FreeGroup
394
- skel = self .n_skeleton (2 )
395
- graph = skel .graph ()
396
- if not skel .is_connected ():
397
- graph = graph .subgraph (skel .base_point ())
398
- edges = [e [2 ] for e in graph .edges (sort = False )]
399
- spanning_tree = [e [2 ] for e in graph .min_spanning_tree ()]
400
- gens = [e for e in edges if e not in spanning_tree ]
401
-
402
- if not gens :
403
- return self
404
-
405
- gens_dict = dict (zip (gens , range (len (gens ))))
406
- FG = FreeGroup (len (gens ), 'e' )
407
- rels = []
408
-
409
- for f in skel .n_cells (2 ):
410
- z = dict ()
411
- for i , sigma in enumerate (skel .faces (f )):
412
- if sigma in spanning_tree :
413
- z [i ] = FG .one ()
414
- elif sigma .is_degenerate ():
415
- z [i ] = FG .one ()
416
- elif sigma in edges :
417
- z [i ] = FG .gen (gens_dict [sigma ])
418
- else :
419
- # sigma is not in the correct connected component.
420
- z [i ] = FG .one ()
421
- rels .append (z [0 ]* z [1 ].inverse ()* z [2 ])
422
- G = FG .quotient (rels )
423
- char = {g : G .gen (i ) for i ,g in enumerate (gens )}
424
- for e in edges :
425
- if not e in gens :
426
- char [e ] = G .one ()
404
+ edges = self .n_cells (1 )
405
+ if not edges :
406
+ return self .identity ()
407
+ G , char = self ._universal_cover_dict ()
427
408
return self .covering_map (char )
428
409
429
410
def covering_map (self , character ):
@@ -445,6 +426,7 @@ def covering_map(self, character):
445
426
sage: S1 = simplicial_sets.Sphere(1)
446
427
sage: W = S1.wedge(S1)
447
428
sage: G = CyclicPermutationGroup(3)
429
+ sage: a, b = W.n_cells(1)
448
430
sage: C = W.covering_map({a : G.gen(0), b : G.one()})
449
431
sage: C
450
432
Simplicial set morphism:
@@ -454,15 +436,15 @@ def covering_map(self, character):
454
436
sage: C.domain()
455
437
Simplicial set with 9 non-degenerate simplices
456
438
sage: C.domain().face_data()
457
- {(sigma_1, ()): ((*, ()), (*, ())),
458
- (sigma_1, (1,2,3)): ((*, (1,2,3)), (*, (1,2,3))),
459
- (sigma_1, (1,3,2)): ((*, (1,3,2)), (*, (1,3,2))),
439
+ {(*, ()): None,
440
+ (*, (1,2,3)): None,
441
+ (*, (1,3,2)): None,
442
+ (sigma_1, ()): ((*, (1,2,3)), (*, ())),
460
443
(sigma_1, ()): ((*, ()), (*, ())),
444
+ (sigma_1, (1,2,3)): ((*, (1,3,2)), (*, (1,2,3))),
461
445
(sigma_1, (1,2,3)): ((*, (1,2,3)), (*, (1,2,3))),
462
- (sigma_1, (1,3,2)): ((*, (1,3,2)), (*, (1,3,2))),
463
- (*, ()): None,
464
- (*, (1,3,2)): None,
465
- (*, (1,2,3)): None}
446
+ (sigma_1, (1,3,2)): ((*, ()), (*, (1,3,2))),
447
+ (sigma_1, (1,3,2)): ((*, (1,3,2)), (*, (1,3,2)))}
466
448
467
449
"""
468
450
from sage .topology .simplicial_set import AbstractSimplex , SimplicialSet
@@ -531,17 +513,17 @@ def cover(self, character):
531
513
sage: W = S1.wedge(S1)
532
514
sage: G = CyclicPermutationGroup(3)
533
515
sage: (a, b) = W.n_cells(1)
534
- sage: C = W.cover({a : G.gen(0), b : G.gen(0)^2}).domain()
516
+ sage: C = W.cover({a : G.gen(0), b : G.gen(0)^2})
535
517
sage: C.face_data()
536
- {(sigma_1, ()): ((*, (1,2,3)), (*, ())),
537
- (sigma_1, (1,2,3)): ((*, (1,3,2)), (*, (1,2,3))),
538
- (sigma_1, (1,3,2)): ((*, ()), (*, (1,3,2))),
518
+ {(*, ()): None,
519
+ (*, (1,2,3)): None,
520
+ (*, (1,3,2)): None,
521
+ (sigma_1, ()): ((*, (1,2,3)), (*, ())),
539
522
(sigma_1, ()): ((*, (1,3,2)), (*, ())),
523
+ (sigma_1, (1,2,3)): ((*, (1,3,2)), (*, (1,2,3))),
540
524
(sigma_1, (1,2,3)): ((*, ()), (*, (1,2,3))),
541
- (sigma_1, (1,3,2)): ((*, (1,2,3)), (*, (1,3,2))),
542
- (*, (1,2,3)): None,
543
- (*, ()): None,
544
- (*, (1,3,2)): None}
525
+ (sigma_1, (1,3,2)): ((*, ()), (*, (1,3,2))),
526
+ (sigma_1, (1,3,2)): ((*, (1,2,3)), (*, (1,3,2)))}
545
527
sage: C.homology(1)
546
528
Z x Z x Z x Z
547
529
sage: C.fundamental_group()
@@ -563,14 +545,14 @@ def universal_cover(self):
563
545
sage: C
564
546
Simplicial set with 8 non-degenerate simplices
565
547
sage: C.face_data()
566
- {(f, 1): ((1, e), (1, 1)),
548
+ {(1, 1): None,
549
+ (1, e): None,
550
+ (f, 1): ((1, e), (1, 1)),
567
551
(f, e): ((1, 1), (1, e)),
568
552
(f * f, 1): ((f, e), s_0 (1, 1), (f, 1)),
569
553
(f * f, e): ((f, 1), s_0 (1, e), (f, e)),
570
554
(f * f * f, 1): ((f * f, e), s_0 (f, 1), s_1 (f, 1), (f * f, 1)),
571
- (f * f * f, e): ((f * f, 1), s_0 (f, e), s_1 (f, e), (f * f, e)),
572
- (1, e): None,
573
- (1, 1): None}
555
+ (f * f * f, e): ((f * f, 1), s_0 (f, e), s_1 (f, e), (f * f, e))}
574
556
sage: C.fundamental_group()
575
557
Finitely presented group < | >
576
558
0 commit comments