diff --git a/doc/SimplicialSurfaces.xml b/doc/SimplicialSurfaces.xml index 59799d70..fe649c53 100644 --- a/doc/SimplicialSurfaces.xml +++ b/doc/SimplicialSurfaces.xml @@ -28,6 +28,7 @@ <#Include SYSTEM "_Chapter_AccessIncidenceGeometry.xml"> <#Include SYSTEM "_Chapter_Constructors.xml"> <#Include SYSTEM "_Chapter_Properties.xml"> + <#Include SYSTEM "_Chapter_Graphs.xml"> <#Include SYSTEM "_Chapter_Embeddings.xml"> <#Include SYSTEM "ExampleImplementations.xml"> diff --git a/gap/PolygonalComplexes/graphs.gd b/gap/PolygonalComplexes/graphs.gd new file mode 100644 index 00000000..f7185241 --- /dev/null +++ b/gap/PolygonalComplexes/graphs.gd @@ -0,0 +1,310 @@ +############################################################################# +## +## SimplicialSurface package +## +## Copyright 2012-2018 +## Markus Baumeister, RWTH Aachen University +## Alice Niemeyer, RWTH Aachen University +## +## Licensed under the GPL 3 or later. +## +############################################################################# + +#! @BeginChunk Graphs_Packages +#! Digraphs, GRAPE and NautyTracesInterface. +#! @EndChunk + +#! @BeginChunk Graphs_LabelShift +#! +#! The vertex labels stay the same. +#! The edge labels are shifted upwards by the maximal vertex label. +#! +#! The face labels are shifted upwards by the sum of the maximal +#! vertex label and the maximal edge label. +#! +#! @EndChunk + +#! @Chapter Graphs and isomorphisms +#! @ChapterLabel Graphs +#! +#! All polygonal structures from chapter +#! can be completely described by their incidence structure. Therefore the +#! isomorphism problem reduces to the graph isomorphism problem. This chapter +#! explains the associated functionality. +#! +#! Most of the methods in this chapter need access to one of the graph +#! packages in &GAP;. Currently supported are the packages +#! @InsertChunk Graphs_Packages +#! A discussion of their +#! individual merits is postponed to section +#! . +#! +#! In section the concept of incidence +#! graphs is introduced. While this is the backbone of the isomorphism testing +#! and automorphism group computation, it may be skipped at first. +#! +#! Section contains the method +#! IsIsomorphicIncidenceStructure +#! (). +#! +#! Section explains in detail +#! how to use the automorphism group of polygonal complexes. + +#! @Section Incidence graph +#! @SectionLabel Graphs_Incidence +#! +#! The incidence relation (which is central to our concept of polygonal +#! complexes, compare chapter ) can be interpreted +#! as a coloured undirected graph, the incidence graph of the polygonal +#! complex. +#! +#! The vertices of this incidence graph consist of all vertices (colour 0), +#! edges (colour 1) and +#! faces (colour 2) of the polygonal complex. The edges of the incidence graph are given +#! by pairs of vertices-edges and edges-faces that are incident to each other. +#! +#! As an example, consider the polygonal surface from section +#! : +#! +#! \input{Image_IncidenceGraph.tex} +#! +#! +#! Unfortunately the vertex labels of the graph in &GAP; have to be distinct, +#! which is not guaranteed in general. +#! Therefore we shift the labels of the edges by the maximal vertex label and +#! the face labels by the sum of the maximal vertex and edge labels. In the +#! example above the maximal vertex label is 11 and the maximal edge label +#! is 13. It would be modified like this: +#! +#! { +#! \def\shiftLabels{1} +#! \input{Image_IncidenceGraph.tex} +#! } +#! +#! +#! The incidence graph is given as a &GAP;-graph. Currently these packages +#! are supported: +#! @InsertChunk Graphs_Packages +#! + +#! @BeginGroup IncidenceGraph +#! @Description +#! Return the incidence graph (a coloured, undirected graph) of the given +#! polygonal complex. The incidence +#! graph is defined as follows: +#! +#! The vertices are the vertices (colour 0), edges (colour 1) and +#! faces (colour 2) of complex. The labels are shifted in the +#! following way: +#! @InsertChunk Graphs_LabelShift +#! +#! The edges are vertex-edge-pairs or edge-face-pairs such that the +#! elements of the pair are incident in complex. +#! +#! +#! +#! The returned graph can be given in three different formats, corresponding +#! to different graph packages: +#! @InsertChunk Graphs_Packages +#! +#! TODO example +#! +#! @Returns a graph as defined in the package Digraphs +#! @Arguments complex +DeclareAttribute( "IncidenceDigraphsGraph", IsPolygonalComplex ); +#! @Returns a graph as defined in the package GRAPE +#! @Arguments complex +DeclareAttribute( "IncidenceGrapeGraph", IsPolygonalComplex ); +#! @Returns a graph as defined in the package NautyTracesInterface +#! @Arguments complex +DeclareAttribute( "IncidenceNautyGraph", IsPolygonalComplex ); +#! @EndGroup + + +#! @Section Isomorphism testing +#! @SectionLabel Graphs_Isomorphism +#! +#! Since all polygonal structures (from polygonal complexes to simplicial +#! surfaces) from chapter are completely +#! described by their incidence structure, the isomorphism problem for +#! those reduces to the graph isomorphism problem. +#! +#! The graph isomorphism problem is solved by Nauty/Bliss, depending +#! on the available packages. As long as one of the graph packages of &GAP; +#! is loaded, the isomorphism testing can be executed. The supported packages +#! are +#! @InsertChunk Graphs_Packages + +#! @BeginGroup IsIsomorphicIncidenceStructure +#! @Description +#! Return whether the given polygonal complexes are isomorphic. They are +#! isomorphic if their incidence graphs (compare +#! ) are isomorphic. +#! +#! @ExampleSession +#! gap> IsIsomorphicIncidenceStructure( Cube(), Octahedron() ); +#! false +#! @EndExampleSession +#! +#! @Returns true or false +#! @Arguments complex1, complex2 +DeclareOperation( "IsIsomorphicIncidenceStructure", + [IsPolygonalComplex, IsPolygonalComplex] ); +#TODO Combine with fining-method? +#! @EndGroup + + +#! @Section Automorphism group +#! @SectionLabel Graphs_Automorphisms +#! +#! As long as one of the graph packages ( +#! @InsertChunk Graphs_Packages +#! ) is available +#! the automorphism groups of polygonal complexes can be computed with the +#! method AutomorphismGroup () as the +#! automorphism groups of the corresponding incidence graphs (see section +#! for details). +#! +#! Unfortunately it is not completely trivial to work with the automorphism +#! group of a polygonal complex in &GAP;. This can already be seen on the +#! example of a tetrahedron. +#! +#! \input{_TIKZ_Tetrahedron_constructor.tex} +#! +#! @ExampleSession +#! gap> tetra := Tetrahedron();; +#! gap> aut := AutomorphismGroup(tetra); +#! Group([ (3,4)(6,7)(8,9)(11,12), (1,2)(6,8)(7,9)(13,14), (2,3)(5,6)(9,10)(12,14) ]) +#! @EndExampleSession +#! The generators of this group seem very complicated in comparison to +#! the size of the automorphism group - it is just a symmetric group +#! on four elements. +#! @ExampleSession +#! gap> Size(aut); +#! 24 +#! gap> IsSymmetricGroup(aut); +#! true +#! @EndExampleSession +#! Furthermore there are labels (like 14) that don't appear as labels +#! of the tetrahedron. +#! +#! This complication appears because there are surfaces where it is +#! necessary to describe the action on vertices, edges and faces +#! separately. One such example is the janus-head, two triangles +#! combined along all their edges. +#! +#! \input{_TIKZ_Janus_constructor.tex} +#! +#! If the automorphism group would be determined by the action on +#! the vertices (or edges) alone, it would be a subgroup of the +#! symmetric group on 3 elements. Then it would have at most 6 +#! elements. If it were determined by the action on the faces, it +#! would have at most 2 elements. But it actually has 12 elements. +#! @ExampleSession +#! gap> autJan := AutomorphismGroup( JanusHead() ); +#! Group([ (7,8), (2,3)(4,5), (1,2)(5,6) ]) +#! gap> Size(autJan); +#! 12 +#! @EndExampleSession +#! +#! The labels for vertices, edges and faces in polygonal complexes +#! may overlap. Then the automorphisms can't be represented as permutations +#! over the integers - which is important for fast performance in &GAP;. +#! Therefore the edges and faces are relabelled for the purpose of the +#! automorphisms. +#! @InsertChunk Graphs_LabelShift +#! To see the action on the original labels, the method +#! DisplayAsAutomorphism () can +#! be used. +#! @ExampleSession +#! gap> DisplayAsAutomorphism( tetra, (3,4)(6,7)(8,9)(11,12) ); +#! [ (3,4), (2,3)(4,5), (1,2) ] +#! @EndExampleSession +#! The first component describes the action on the vertices, the +#! second component shows the action on the edges and the final +#! component represents the action on the faces. + +#! @BeginGroup AutomorphismGroup +#! @Description +#! Compute the automorphism group of the polygonal complex complex as +#! a permutation group. +#! +#! The automorphisms see the labels of complex in the following way: +#! @InsertChunk Graphs_LabelShift +#! For a more exhaustive explanation (and the reason for this) see section +#! . +#! +#! To see the action on the original labels, use the method +#! DisplayAsAutomorphism(). +#! +#! For example, the automorphism group of an icosahedron +#! () is the direct product of a cyclic group +#! of order 2 and an alternating group of order 60. +#! @ExampleSession +#! gap> autIco := AutomorphismGroup( Icosahedron() );; +#! gap> Size(autIco); +#! 120 +#! gap> StructureDescription(autIco); +#! "C2 x A5" +#! @EndExampleSession +#TODO example with picture? or more of them? Is this really necessary for the kind of people who look at this method.. +#! +#! @Arguments complex +#! @Returns a permutation group +DeclareAttribute( "AutomorphismGroup", IsPolygonalComplex ); +#! @EndGroup + +#! @BeginGroup DisplayAsAutomorphism +#! @Description +#! Display an automorphism of the given complex by its individual +#! action on vertices, edges and faces. If this is not possible (because +#! the given permutation is not an automorphism) fail is returned. +#! +#! An explanation for the necessity of this method is given in section +#! . +#! +#! We illustrate this on the example of a tetrahedron. +#! +#! \input{_TIKZ_Tetrahedron_constructor.tex} +#! +#! @ExampleSession +#! gap> tetra := Tetrahedron();; +#! gap> aut := AutomorphismGroup( tetra ); +#! Group([ (3,4)(6,7)(8,9)(11,12), (1,2)(6,8)(7,9)(13,14), (2,3)(5,6)(9,10)(12,14) ]) +#! gap> DisplayAsAutomorphism( tetra, (3,4)(6,7)(8,9)(11,12) ); +#! [ (3,4), (2,3)(4,5), (1,2) ] +#! gap> DisplayAsAutomorphism( tetra, (1,2)(6,8)(7,9)(13,14) ); +#! [ (1,2), (2,4)(3,5), (3,4) ] +#! gap> DisplayAsAutomorphism( tetra, (2,3)(5,6)(9,10)(12,14) ); +#! [ (2,3), (1,2)(5,6), (2,4) ] +#! gap> DisplayAsAutomorphism( tetra, (1,5) ); +#! fail +#! @EndExampleSession +#! +#! @Arguments complex, perm +#! @Returns A list of three permutations or fail +DeclareOperation( "DisplayAsAutomorphism", [IsPolygonalComplex, IsPerm] ); +#! @EndGroup + + +#! TODO explain restrictions to vertices etc., when are they sufficient (anomalies?)? + + + + + + +#! @Section Which graph package should be used? +#! @SectionLabel Graphs_Discussion +#! TODO + + +#! * Digraphs (method IncidenceDigraphsGraph). +#! This is returned if IncidenceGraph is called. +#! * GRAPE (method IncidenceGrapeGraph). Since GRAPE +#! stores its graphs as records that are changed if some properties are +#! computed, the result of IncidenceGrapeGraph usually can't be +#! used immediately (since it is immutable). Therefore +#! ShallowCopy(IncidenceGrapeGraph(complex)) has +#! to be used. +#! * NautyTracesInterface (method IncidenceNautyGraph). diff --git a/gap/PolygonalComplexes/graphs.gi b/gap/PolygonalComplexes/graphs.gi index b2828cca..037ba5ce 100644 --- a/gap/PolygonalComplexes/graphs.gi +++ b/gap/PolygonalComplexes/graphs.gi @@ -16,53 +16,19 @@ ##### ##### -## -## We define a more general package loading method that works even -## if loading the package normally throws an error (as happens -## quite often when working with Digraphs). -##TODO maybe use CALL_WITH_CATCH(LoadPackage, ["name"]); instead? -#BindGlobal( "__SIMPLICIAL_LoadPackage", -# function(name) -# local breakOnError, res; -# -# breakOnError := BreakOnError; -# BreakOnError := false; -# res := LoadPackage(name); - - # If there was an error in the loading, return false -# if not IsBound(res) then -# res := false; -# fi; - -# BreakOnError := breakOnError; -# return res; -# end -#); - -InstallMethod( IncidenceGraph, "for a polygonal complex", - [IsPolygonalComplex], - function(complex) - return IncidenceDigraphsGraph(complex); - end -); - ####################################### ## ## Digraphs ## if IsPackageMarkedForLoading( "Digraphs", ">=0.10.1" ) then -InstallMethod( IncidenceDigraphsGraph, "for a polygonal complex", - [IsPolygonalComplex], - function( complex ) - if LoadPackage("Digraphs") <> true then - Error("Package Digraphs has to be available to use IncidenceDigraphsGraph."); - fi; - - return Digraph( IncidenceGrapeGraph(complex) ); - #TODO is there a better way? - end -); + InstallMethod( IncidenceDigraphsGraph, "for a polygonal complex", + [IsPolygonalComplex], + function( complex ) + return Digraph( IncidenceGrapeGraph(complex) ); + #TODO is there a better way? + end + ); fi; ## ## End Digraphs @@ -76,48 +42,46 @@ fi; ## ## GRAPE ## -InstallMethod( IncidenceGrapeGraph, "for a polygonal complex", - [IsPolygonalComplex], - function(complex) - local graph, vertices, edges, faces, names, colours, incidence, - trivialAction, maxVert, maxEdge; - - if LoadPackage("GRAPE") <> true then - Error("Package GRAPE has to be available to use IncidenceGrapeGraph."); - fi; - - maxVert := Maximum( Vertices(complex) ); - maxEdge := Maximum( Edges(complex) ); - vertices := ShallowCopy( Vertices(complex) ); - edges := List( Edges(complex), e -> e + maxVert ); - faces := List( Faces(complex), f -> f + maxVert + maxEdge ); - - names := Union( vertices, edges, faces); - colours := [vertices,edges, faces]; - incidence := function(x,y) - if x in vertices and y in edges then - return x in VerticesOfEdges(complex)[y-maxVert]; - elif x in edges and y in vertices then - return y in VerticesOfEdges(complex)[x-maxVert]; - elif x in edges and y in faces then - return x-maxVert in EdgesOfFaces(complex)[y-maxVert-maxEdge]; - elif x in faces and y in edges then - return y-maxVert in EdgesOfFaces(complex)[x-maxVert-maxEdge]; - else - return false; - fi; - end; - - trivialAction := function( pnt, g ) - return pnt; - end; - - graph := Graph( Group( () ), names, trivialAction, incidence ); - graph!.colourClasses := colours; - - return graph; - end -); +if IsPackageMarkedForLoading( "GRAPE", ">=0" ) then + InstallMethod( IncidenceGrapeGraph, "for a polygonal complex", + [IsPolygonalComplex], + function(complex) + local graph, vertices, edges, faces, names, colours, incidence, + trivialAction, maxVert, maxEdge; + + maxVert := Maximum( Vertices(complex) ); + maxEdge := Maximum( Edges(complex) ); + vertices := ShallowCopy( Vertices(complex) ); + edges := List( Edges(complex), e -> e + maxVert ); + faces := List( Faces(complex), f -> f + maxVert + maxEdge ); + + names := Union( vertices, edges, faces); + colours := [vertices,edges, faces]; + incidence := function(x,y) + if x in vertices and y in edges then + return x in VerticesOfEdges(complex)[y-maxVert]; + elif x in edges and y in vertices then + return y in VerticesOfEdges(complex)[x-maxVert]; + elif x in edges and y in faces then + return x-maxVert in EdgesOfFaces(complex)[y-maxVert-maxEdge]; + elif x in faces and y in edges then + return y-maxVert in EdgesOfFaces(complex)[x-maxVert-maxEdge]; + else + return false; + fi; + end; + + trivialAction := function( pnt, g ) + return pnt; + end; + + graph := Graph( Group( () ), names, trivialAction, incidence ); + graph!.colourClasses := colours; + + return graph; + end + ); +fi; ## ## End GRAPE ## @@ -129,40 +93,38 @@ InstallMethod( IncidenceGrapeGraph, "for a polygonal complex", ## ## NautyTracesInterface ## -InstallMethod( IncidenceNautyGraph, "for a polygonal complex", - [IsPolygonalComplex], - function(complex) - local maxVertex, maxEdge, maxFace, edgeList, colourList, v, e, f, - colSet, vertexList; - - if LoadPackage("NautyTracesInterface") <> true then - Error("Package NautyTracesInterface has to be available to use IncidenceNautyGraph."); - fi; +if IsPackageMarkedForLoading("NautyTracesInterface", ">=0") then + InstallMethod( IncidenceNautyGraph, "for a polygonal complex", + [IsPolygonalComplex], + function(complex) + local maxVertex, maxEdge, maxFace, edgeList, colourList, v, e, f, + colSet, vertexList; - maxVertex := Maximum( Vertices(complex) ); - maxEdge := Maximum( Edges(complex) ); + maxVertex := Maximum( Vertices(complex) ); + maxEdge := Maximum( Edges(complex) ); - vertexList := ShallowCopy( Vertices(complex) ); - edgeList := []; - colourList := List( [1..NumberOfVertices(complex)], i -> 0 ); + vertexList := ShallowCopy( Vertices(complex) ); + edgeList := []; + colourList := List( [1..NumberOfVertices(complex)], i -> 0 ); - for e in Edges(complex) do - Add(colourList, 1); - Append(edgeList, List( VerticesOfEdges(complex)[e], + for e in Edges(complex) do + Add(colourList, 1); + Append(edgeList, List( VerticesOfEdges(complex)[e], v -> [v, maxVertex + e] ) ); - Add(vertexList, maxVertex + e); - od; + Add(vertexList, maxVertex + e); + od; - for f in Faces(complex) do - Add(colourList, 2); - Add(vertexList, maxVertex + maxEdge + f); - Append(edgeList, List( EdgesOfFaces(complex)[f], + for f in Faces(complex) do + Add(colourList, 2); + Add(vertexList, maxVertex + maxEdge + f); + Append(edgeList, List( EdgesOfFaces(complex)[f], e -> [maxVertex + e, maxVertex + maxEdge + f] ) ); - od; + od; - return NautyColoredGraphWithNodeLabels( edgeList, colourList, vertexList ); - end -); + return NautyColoredGraphWithNodeLabels( edgeList, colourList, vertexList ); + end + ); +fi; ## ## End NautyTracesInterface ## @@ -173,39 +135,79 @@ InstallMethod( IncidenceNautyGraph, "for a polygonal complex", ####################################### ## -## Isomorphism test +## Isomorphism test and automorphism group ## + +## The order of installation describes which of these functions is +## preferred - the last one has highest priority. InstallMethod( IsIsomorphicIncidenceStructure, "for two polygonal complexes", [IsPolygonalComplex, IsPolygonalComplex], function(complex1, complex2) - if LoadPackage("NautyTracesInterface") = true then - return IsomorphismGraphs( - UnderlyingNautyGraph( IncidenceNautyGraph(complex1) ), - UnderlyingNautyGraph( IncidenceNautyGraph(complex2) )) <> fail; - elif LoadPackage("GRAPE") = true then + Error("IsIsomorphicIncidenceStructure: One of the packages NautyTracesInterface or GRAPE has to be available."); + end +); +InstallMethod( AutomorphismGroup, "for a polygonal complex", + [IsPolygonalComplex], + function(complex) + Error("AutomorphismGroup: One of the packages NautyTracesInterface, Digraphs or GRAPE has to be available."); + end +); + +if IsPackageMarkedForLoading("GRAPE", ">=0") then + InstallMethod( IsIsomorphicIncidenceStructure, + "for two polygonal complexes", + [IsPolygonalComplex, IsPolygonalComplex], + function(complex1, complex2) return IsIsomorphicGraph( ShallowCopy( IncidenceGrapeGraph(complex1) ), ShallowCopy( IncidenceGrapeGraph(complex2) ) ); - elif not ARCH_IS_WINDOWS() and LoadPackage("Digraphs") = true then # We disable Digraphs on Windows as it may not load - #TODO is this possible? Then maybe put in in second place - Error("Isomorphism test in Digraphs not implemented. GRAPE and NautyTracesInterface are not loaded."); - else - Error("Isomorphism test needs at least one of the packages NautyTracesInterface, Digraphs or GRAPE."); - fi; - end -); + end + ); + + InstallMethod( AutomorphismGroup, "for a polygonal complex", + [IsPolygonalComplex], + function(complex) + return AutGroupGraph( ShallowCopy( IncidenceGrapeGraph(complex) ) ); + end + ); +fi; + +if IsPackageMarkedForLoading("Digraphs", ">=0") and not ARCH_IS_WINDOWS() then + +#TODO install the digraphs function as soon as it is available + + InstallMethod( AutomorphismGroup, "for a polygonal complex", + [IsPolygonalComplex], + function(complex) + return AutomorphismGroup( IncidenceDigraphsGraph(complex) ); + end + ); +fi; + +if IsPackageMarkedForLoading("NautyTracesInterface", ">=0") then + InstallMethod( IsIsomorphicIncidenceStructure, + "for two polygonal complexes", + [IsPolygonalComplex, IsPolygonalComplex], + function(complex1, complex2) + return IsomorphismGraphs( + UnderlyingNautyGraph( IncidenceNautyGraph(complex1) ), + UnderlyingNautyGraph( IncidenceNautyGraph(complex2) )) <> fail; + end + ); + + InstallMethod( AutomorphismGroup, "for a polygonal complex", + [IsPolygonalComplex], + function(complex) + return AutomorphismGroup( IncidenceNautyGraph(complex) ); + end + ); +fi; ####################################### ## ## Automorphism group ## -InstallMethod( AutomorphismGroup, "for a polygonal complex", - [IsPolygonalComplex], - function(complex) - return AutomorphismGroup( IncidenceNautyGraph(complex) ); - end -); InstallMethod( DisplayAsAutomorphism, "for a polygonal complex and a permutation", diff --git a/gap/PolygonalComplexes/incidence_geometry.gd b/gap/PolygonalComplexes/incidence_geometry.gd index 9ab9f87c..95e612a8 100644 --- a/gap/PolygonalComplexes/incidence_geometry.gd +++ b/gap/PolygonalComplexes/incidence_geometry.gd @@ -1212,124 +1212,3 @@ DeclareOperation( "EdgeFacePathPartitionOfVertexNC", [ IsPolygonalComplex, IsPosInt ]); #! @EndGroup -#! @Section Isomorphism testing -#! @SectionLabel Access_IsomorphismTest -#! -#! All structures from chapter , from -#! polygonal complexes to simplicial surfaces, are completely described -#! by their incidence structure. Since the -#! incidence structure can be equivalently described as a graph (compare -#! section ), the isomorphism problem -#! for polygonal complexes reduces to the graph isomorphism problem. -#! -#! The graph isomorphism problem is solved by Nauty/Bliss, depending -#! on the available packages. The NautyTracesInterface is preferred -#! since it provides a fast interface to Nauty and also computes the -#! automorphism group of the polygonal complex. If this is not available, the -#! packages Digraphs and GRAPE will also be sufficient for an -#! isomorphism test. -#! - -#! @Description -#! Return whether the given polygonal complexes are isomorphic. They are -#! isomorphic if their incidence graphs (compare -#! ) are isomorphic. -#! -#! @ExampleSession -#! gap> IsIsomorphicIncidenceStructure( Cube(), Octahedron() ); -#! false -#! @EndExampleSession -#! -#! @Returns true or false -#! @Arguments complex1, complex2 -DeclareOperation( "IsIsomorphicIncidenceStructure", - [IsPolygonalComplex, IsPolygonalComplex] ); -#TODO Combine with fining-method? - -#! @Section Incidence graphs -#! @SectionLabel Access_IncidenceGraph -#! -#! The incidence relation (which is central to our concept of polygonal -#! complexes, compare chapter ) can be interpreted -#! as a coloured undirected graph, the incidence graph of the polygonal -#! complex. -#! -#! The vertices of this incidence graph consist of all vertices (colour 0), -#! edges (colour 1) and -#! faces (colour 2) of the polygonal complex. The edges of the incidence graph are given -#! by pairs of vertices-edges and edges-faces that are incident to each other. -#! -#! As an example, consider the polygonal surface from section -#! : -#! -#! \input{Image_IncidenceGraph.tex} -#! -#! -#! Unfortunately the vertex labels of the graph in &GAP; have to be distinct, -#! which is not guaranteed in general. -#! Therefore we shift the labels of the edges by the maximal vertex label and -#! the face labels by the sum of the maximal vertex and edge labels. In the -#! example above the maximal vertex label is 11 and the maximal edge label -#! is 13. It would be modified like this: -#! -#! { -#! \def\shiftLabels{1} -#! \input{Image_IncidenceGraph.tex} -#! } -#! -#! -#! The incidence graph is given as a &GAP;-graph. Currently three different -#! packages are supported: -#! * Digraphs (method IncidenceDigraphsGraph). -#! This is returned if IncidenceGraph is called. -#! * GRAPE (method IncidenceGrapeGraph). Since GRAPE -#! stores its graphs as records that are changed if some properties are -#! computed, the result of IncidenceGrapeGraph usually can't be -#! used immediately (since it is immutable). Therefore -#! ShallowCopy(IncidenceGrapeGraph(complex)) has -#! to be used. -#! * NautyTracesInterface (method IncidenceNautyGraph). -#! -#TODO html links -#! TODO compare packages - -#! @BeginGroup IncidenceGraph -#! @Description -#! Return the incidence graph (a coloured, undirected graph) of the given -#! polygonal complex. The incidence -#! graph is defined as follows: -#! * The vertices are the vertices (colour 0), edges (colour 1) and -#! faces (colour 2) of complex. The labels are shifted in the -#! following way: -#! * The vertex labels stay the same. -#! * The edge labels are shifted by the maximal vertex label (to be -#! distinct from them). -#! * The face labels are shifted by the sum of maximal vertex label and -#! maximal edge label. -#! * The edges are vertex-edge-pairs or edge-face-pairs such that the -#! elements of the pair are incident in complex. -#! -#! The returned graph can be given in three different formats, corresponding -#! to different graph packages: Digraphs, GRAPE and -#! NautyTracesInterface. -#! -#! TODO example -#! -#! @Returns a graph as defined in the package Digraphs -#! @Arguments complex -DeclareOperation( "IncidenceGraph", [IsPolygonalComplex] ); -#! @Arguments complex -DeclareAttribute( "IncidenceDigraphsGraph", IsPolygonalComplex ); -#! @Returns a graph as defined in the package GRAPE -#! @Arguments complex -DeclareAttribute( "IncidenceGrapeGraph", IsPolygonalComplex ); -#! @Returns a graph as defined in the package NautyTracesInterface -#! @Arguments complex -DeclareAttribute( "IncidenceNautyGraph", IsPolygonalComplex ); -#! @EndGroup - -#TODO better to split the methods to explain each graph individually? -# Now they are synchronised.. - - - diff --git a/gap/PolygonalComplexes/properties.gd b/gap/PolygonalComplexes/properties.gd index 1c74aa26..51be7cb1 100644 --- a/gap/PolygonalComplexes/properties.gd +++ b/gap/PolygonalComplexes/properties.gd @@ -631,147 +631,6 @@ DeclareAttribute( "OrientationByEdgesAsList", IsRamifiedPolygonalSurface ); -#! @Section Automorphism group -#! @SectionLabel Automorphisms -#! -#! As long as the package NautyTracesInterface is available -#! the automorphism groups of polygonal complexes can be computed with the -#! method AutomorphismGroup () as the -#! automorphism groups of the corresponding incidence graphs (see section -#! for details). -#! -#! Unfortunately it is not completely trivial to work with the automorphis -#! group of a polygonal complex in &GAP;. This can already be seen on the -#! example of a tetrahedron. -#! -#! \input{_TIKZ_Tetrahedron_constructor.tex} -#! -#! @ExampleSession -#! gap> tetra := Tetrahedron();; -#! gap> aut := AutomorphismGroup(tetra); -#! Group([ (3,4)(6,7)(8,9)(11,12), (1,2)(6,8)(7,9)(13,14), (2,3)(5,6)(9,10)(12,14) ]) -#! @EndExampleSession -#! The generators of this group seem very complicated in comparison to -#! the size of the automorphism group - it is just a symmetric group -#! on four elements. -#! @ExampleSession -#! gap> Size(aut); -#! 24 -#! gap> IsSymmetricGroup(aut); -#! true -#! @EndExampleSession -#! Furthermore there are labels (like 14) that don't appear as labels -#! of the tetrahedron. -#! -#! This complication appears because there are surfaces where it is -#! necessary to describe the action on vertices, edges and faces -#! separately. One such example is the janus-head, two triangles -#! combined along all their edges. -#! -#! \input{_TIKZ_Janus_constructor.tex} -#! -#! If the automorphism group would be determined by the action on -#! the vertices (or edges) alone, it would be a subgroup of the -#! symmetric group on 3 elements. Then it would have at most 6 -#! elements. If it were determined by the action on the faces, it -#! would have at most 2 elements. But it actually has 12 elements. -#! @ExampleSession -#! gap> autJan := AutomorphismGroup( JanusHead() ); -#! Group([ (7,8), (2,3)(4,5), (1,2)(5,6) ]) -#! gap> Size(autJan); -#! 12 -#! @EndExampleSession -#! -#! The labels for vertices, edges and faces in polygonal complexes -#! may overlap. Then the automorphisms can't be represented as permutations -#! over the integers - which is important for fast performance in &GAP;. -#! Therefore the edges and faces are relabelled for the purpose of the -#! automorphisms. -#! * The vertex labels stay the same -#! * The edge labels are shifted upwards by the maximal vertex label. -#! * The face labels are shifted upwards by the sum of maximal vertex -#! label and maximal edge label. -#! To see the action on the original labels, the method -#! DisplayAsAutomorphism () can -#! be used. -#! @ExampleSession -#! gap> DisplayAsAutomorphism( tetra, (3,4)(6,7)(8,9)(11,12) ); -#! [ (3,4), (2,3)(4,5), (1,2) ] -#! @EndExampleSession -#! The first component describes the action on the vertices, the -#! second component shows the action on the edges and the final -#! component represents the action on the faces. - -#! @BeginGroup AutomorphismGroup -#! @Description -#! Compute the automorphism group of the polygonal complex complex as -#! a permutation group. -#! -#! The automorphisms see the labels of complex in the following way: -#! * The vertex labels stay the same. -#! * The edge labels are shifted upwards by the maximal vertex label. -#! * The face labels are shifted upwards by the sum of the maximal vertex -#! label and the maximal edge label. -#! For a more exhaustive explanation (and the reason for this) see section -#! . -#! -#! To see the action on the original labels, use the method -#! DisplayAsAutomorphism(). -#! -#! For example, the automorphism group of an icosahedron -#! () is the direct product of a cyclic group -#! of order 2 and an alternating group of order 60. -#! @ExampleSession -#! gap> autIco := AutomorphismGroup( Icosahedron() );; -#! gap> Size(autIco); -#! 120 -#! gap> StructureDescription(autIco); -#! "C2 x A5" -#! @EndExampleSession -#TODO example with picture? or more of them? Is this really necessary for the kind of people who look at this method.. -#! -#! @Arguments complex -#! @Returns a permutation group -DeclareAttribute( "AutomorphismGroup", IsPolygonalComplex ); -#! @EndGroup - -#! @BeginGroup DisplayAsAutomorphism -#! @Description -#! Display an automorphism of the given complex by its individual -#! action on vertices, edges and faces. If this is not possible (because -#! the given permutation is not an automorphism) fail is returned. -#! -#! An explanation for the necessity of this method is given in section -#! . -#! -#! We illustrate this on the example of a tetrahedron. -#! -#! \input{_TIKZ_Tetrahedron_constructor.tex} -#! -#! @ExampleSession -#! gap> tetra := Tetrahedron();; -#! gap> aut := AutomorphismGroup( tetra ); -#! Group([ (3,4)(6,7)(8,9)(11,12), (1,2)(6,8)(7,9)(13,14), (2,3)(5,6)(9,10)(12,14) ]) -#! gap> DisplayAsAutomorphism( tetra, (3,4)(6,7)(8,9)(11,12) ); -#! [ (3,4), (2,3)(4,5), (1,2) ] -#! gap> DisplayAsAutomorphism( tetra, (1,2)(6,8)(7,9)(13,14) ); -#! [ (1,2), (2,4)(3,5), (3,4) ] -#! gap> DisplayAsAutomorphism( tetra, (2,3)(5,6)(9,10)(12,14) ); -#! [ (2,3), (1,2)(5,6), (2,4) ] -#! gap> DisplayAsAutomorphism( tetra, (1,5) ); -#! fail -#! @EndExampleSession -#! -#! @Arguments complex, perm -#! @Returns A list of three permutations or fail -DeclareOperation( "DisplayAsAutomorphism", [IsPolygonalComplex, IsPerm] ); -#! @EndGroup - - -#! TODO explain restrictions to vertices etc., when are they sufficient (anomalies?)? - - - #! @Section Types of edges #! @SectionLabel Properties_EdgeTypes #! diff --git a/init.g b/init.g index 899ace6d..652cd380 100644 --- a/init.g +++ b/init.g @@ -16,6 +16,7 @@ ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/polygonal_hierarchy.g ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/incidence_geometry.gd" ); ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/constructors.gd" ); ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/properties.gd" ); +ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/graphs.gd" ); ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/modification.gd" ); ReadPackage( "SimplicialSurfaces", "gap/PolygonalComplexes/embedding.gd" );