|
################################################################################
##
## simpcomp / generate.gi
##
## Generate simplicial complexes or construct them using existing
## complexes.
##
## $Id$
##
################################################################################
#checks if labels of a facet list are valid
SCIntFunc.HasValidLabels:=
function(facets)
local i,j;
for j in [1..Size(facets)] do
for i in facets[j] do
if IsRat(i) or IsCyclotomic(i) or IsFFE(i) or IsPerm(i) or IsBool(i) or IsChar(i) or IsList(i) then
continue;
else
Info(InfoSimpcomp,1,"SCIntFunc.HasValidLabels: vertex labels have to be rationals, cyclotomics, finite field elements, permutations, characters, lists or strings");
return false;
fi;
od;
od;
return true;
end;
#checks if facet list is valid
SCIntFunc.IsValidFacetList:=
function(facets)
if(not IsList(facets) or not IsDuplicateFreeList(facets) or not ForAll(facets,x->IsList(x) and IsDuplicateFree(x)) or not SCIntFunc.HasValidLabels(facets)) then
return false;
else
return true;
fi;
end;
#extract dimension of facet list
SCIntFunc.GetFacetListDimension:=
function(facets)
if facets<>[] then
return MaximumList(List(facets,x->Length(x)))-1;
else
return -1;
fi;
end;
#recursive function to make deep (i.e. full) copies of objects
SCIntFunc.DeepCopy:=
function(obj)
local tmprec,key,scnew,i,cobj;
if(SCIsSimplicialComplex(obj)) then
scnew:=SCIntFunc.SCNew();
scnew!.Properties:=SCIntFunc.DeepCopy(obj!.Properties);
scnew!.PropertiesTmp:=SCIntFunc.DeepCopy(obj!.PropertiesTmp);
return scnew;
elif(IsRecord(obj)) then
tmprec:=rec();
for key in RecNames(obj) do
tmprec.(key):=SCIntFunc.DeepCopy(obj.(key));
od;
return tmprec;
elif(not IsList(obj)) then
return ShallowCopy(obj);
elif(ForAll(obj,x->not IsList(x))) then
return ShallowCopy(obj);
else
cobj:=[];
for i in [1..Length(obj)] do
if not IsBound(obj[i]) then
continue;
fi;
cobj[i]:=SCIntFunc.DeepCopy(obj[i]);
od;
return cobj;
fi;
end;
#apply a function "deeply" on a list
SCIntFunc.DeepList:=function(list,func)
if not IsList(list) or (IsList(list) and not ForAny(list,IsList)) then
return func(list);
else
return List(list,x->SCIntFunc.DeepList(x,func));
fi;
end;
#deep sort a list
SCIntFunc.DeepSortList:=function(list)
if not IsList(list) then
return;
elif ForAll(list,x->not IsList(x) or IsStringRep(x)) then
Sort(list);
else
Perform(list,SCIntFunc.DeepSortList);
Sort(list);
fi;
end;
################################################################################
##<#GAPDoc Label="SCFromGenerators">
## <ManSection>
## <Meth Name="SCFromGenerators" Arg="group, generators"/>
## <Returns>simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Constructs a simplicial complex object from the set of <Arg>generators</Arg> on which the group <Arg>group</Arg> acts, i.e. a complex which has <Arg>group</Arg> as a subgroup of the automorphism group and a facet list that consists of the <Arg>group</Arg>-orbits specified by the list of representatives passed in <Arg>generators</Arg>. Note that <Arg>group</Arg> is not stored as an attribute of the resulting complex as it might just be a subgroup of the actual automorphism group. Internally calls <C>Orbits</C> and <Ref Func="SCFromFacets" />.
## <Example><![CDATA[
## gap> #group: AGL(1,7) of order 42
## gap> G:=Group([(2,6,5,7,3,4),(1,3,5,7,2,4,6)]);;
## gap> c:=SCFromGenerators(G,[[ 1, 2, 4 ]]);
## gap> SCLib.DetermineTopologicalType(c);
## [ [ true, 5 ] ] # the 7-vertex torus
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCFromGenerators,
"for Group and List",
[IsPermGroup,IsList],
function(group,generators)
local complex,facets,os,g,vertices,newGens,ggens,newGGens,len;
if not IsDuplicateFreeList(generators) or IsEmpty(generators) then
Info(InfoSimpcomp,1,"SCFromGenerators: first argument must be a group in permutation representation, second a nonempty list of generators.");
return fail;
fi;
os:=Orbits(group,generators,OnSets);
facets:=Union(os);
len:=List(os,x->Size(x));
if(not SCIntFunc.IsValidFacetList(facets)) then
Info(InfoSimpcomp,1,"SCFromGenerators: group operation yields invalid facet list!");
return fail;
fi;
complex:=SCFromFacets(facets);
if(complex=fail) then
return fail;
fi;
#vertices:=SCVertices(complex);
#if vertices = fail then
# return fail;
#fi;
#if Size(group) = 1 then
# g:=Group(());
#else
# ggens:=GeneratorsOfGroup(group);
# newGGens:=List(ggens,x->SCIntFunc.RelabelPermutation(x,vertices));
# g:=Group(newGGens);
#fi;
#newGens:=SCIntFunc.RelabelSimplexListInv(generators,vertices);
#SetSCAutomorphismGroup(complex,g);
#SetSCAutomorphismGroupSize(complex,Size(g));
#SetSCAutomorphismGroupStructure(complex,StructureDescription(g));
#SetSCAutomorphismGroupTransitivity(complex,Transitivity(g));
#SetSCGeneratorsEx(complex,List(newGens,x->[x,len[Position(newGens,x)]]));
if HasStructureDescription(group) then
SCRename(complex, Concatenation("complex from generators under group ",StructureDescription(group)));
elif HasName(group) then
SCRename(complex, Concatenation("complex from generators under group ",Name(group)));
else
SCRename(complex,"complex from generators under unknown group");
fi;
return complex;
end);
################################################################################
##<#GAPDoc Label="SCFromFacets">
## <ManSection>
## <Meth Name="SCFromFacets" Arg="facets"/>
## <Returns>simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Constructs a simplicial complex object from the given facet list. The facet list <Arg>facets</Arg> has to be a duplicate free list (or set) which consists of duplicate free entries, which are in turn lists or sets. For the vertex labels (i. e. the entries of the list items of <Arg>facets</Arg>) an ordering via the less-operator has to be defined. Following Section 4.11 of the &GAP; manual this is the case for objects of the following families: rationals <C>IsRat</C>, cyclotomics <C>IsCyclotomic</C>, finite field elements <C>IsFFE</C>, permutations <C>IsPerm</C>, booleans <C>IsBool</C>, characters <C>IsChar</C> and lists (strings) <C>IsList</C>.<P/>
## Internally the vertices are mapped to the standard labeling <M>1..n</M>, where <M>n</M> is the number of vertices of the complex and the vertex labels of the original complex are stored in the property ''VertexLabels'', see <Ref Func="SCLabels" /> and the <C>SCRelabel..</C> functions like <Ref Func="SCRelabel" /> or <Ref Func="SCRelabelStandard" />.
## <Example><![CDATA[
## gap> c:=SCFromFacets([[1,2,5], [1,4,5], [1,4,6], [2,3,5], [3,4,6], [3,5,6]]);
## gap> c:=SCFromFacets([["a","b","c"], ["a","b",1], ["a","c",1], ["b","c",1]]);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCFromFacets,
"for List",
[IsList],
function(facets)
local lfacets,obj,dim,known,vertices,i,j,idx;
if(not SCIntFunc.IsValidFacetList(facets)) then
Info(InfoSimpcomp,1,"SCFromFacets: invalid facet list!");
return fail;
fi;
dim:=SCIntFunc.GetFacetListDimension(facets);
if(dim=-1) then
obj:=SCEmpty();
else
lfacets:=Set(SCIntFunc.DeepCopy(facets));
Perform(lfacets,Sort);
Sort(lfacets);
vertices:=Union(lfacets);
for i in [1..Size(lfacets)] do
for j in [1..Size(lfacets[i])] do
idx:=Position(vertices,lfacets[i][j]);
if idx<>fail then
lfacets[i][j]:=idx;
else
Info(InfoSimpcomp,1,"SCFromFacets: error in vertex index.");
return fail;
fi;
od;
od;
obj:=SCIntFunc.SCNew();
SetSCVertices(obj,vertices);
SetSCDim(obj,dim);
SetSCFacetsEx(obj,lfacets);
SetSCName(obj,Concatenation("unnamed complex ",String(SCSettings.ComplexCounter)));
SCSettings.ComplexCounter:=SCSettings.ComplexCounter+1;
fi;
return obj;
end);
################################################################################
##<#GAPDoc Label="SC">
## <ManSection>
## <Meth Name="SC" Arg="facets"/>
## <Returns>simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## A shorter function to create a simplicial complex from a facet list, just calls <Ref Func="SCFromFacets" Style="Text"/>(<Arg>facets</Arg>).
## <Example><![CDATA[
## gap> c:=SC(Combinations([1..6],5));
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SC,
"for List",
[IsList],
function(facets)
return SCFromFacets(facets);
end);
################################################################################
##<#GAPDoc Label="SCEmpty">
## <ManSection>
## <Func Name="SCEmpty" Arg=""/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Generates an empty complex (of dimension <M>-1</M>), i. e. a <C>SCSimplicialComplex</C> object with empty facet list.
## <Example><![CDATA[
## gap> SCEmpty();
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCEmpty,
function()
local obj;
obj:=SCIntFunc.SCNew();
SetSCVertices(obj,[]);
SetSCDim(obj,-1);
SetSCFacetsEx(obj,[]);
SetSCName(obj,"empty complex");
SetFilterObj(obj,IsEmpty);
return obj;
end);
##########################
## <#GAPDoc Label="SCFVectorBdCrossPolytope">
## <ManSection>
## <Func Name="SCFVectorBdCrossPolytope" Arg="d"/>
## <Returns> a list of integers of size <C>d + 1</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the <M>f</M>-vector of the <M>d</M>-dimensional cross polytope without generating the underlying complex.
## <Example><![CDATA[
## gap> SCFVectorBdCrossPolytope(50);
## [100, 4900, 156800, 3684800, 67800320, 1017004800, 12785203200,
## 137440934400, 1282782054400, 10518812846080, 76500457062400,
## 497252970905600, 2907017368371200, 15365663232819200, 73755183517532160,
## 322678927889203200, 1290715711556812800, 4732624275708313600,
## 15941471244491161600, 49418560857922600960, 141195888165493145600,
## 372243705163572838400, 906332499528699084800, 2039248123939572940800,
## 4241636097794311716864, 8156992495758291763200, 14501319992459185356800,
## 23823597130468661657600, 36146147370366245273600, 50604606318512743383040,
## 65296266217435797913600, 77539316133205010022400, 84588344872587283660800,
## 84588344872587283660800, 77337915312079802204160, 64448262760066501836800,
## 48771658304915190579200, 33370081998099867238400, 20535435075753764454400,
## 11294489291664570449920, 5509506971543692902400, 2361217273518725529600,
## 878592473867432755200, 279552150776001331200, 74547240206933688320,
## 16205921784116019200, 2758454771764428800, 344806846470553600,
## 28147497671065600, 1125899906842624]
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##########################
InstallGlobalFunction(SCFVectorBdCrossPolytope,
function(d)
local F,i;
if(d<=0) then
Info(InfoSimpcomp,1,"SCFVectorBdCrossPolytope: dimension must be positive.");
return fail;
fi;
F:=ListWithIdenticalEntries(d,0);
for i in [1..d] do
F[i]:=(2^i)*Binomial(d,i);
od;
return F;
end);
##########################
## <#GAPDoc Label="SCFVectorBdCyclicPolytope">
## <ManSection>
## <Func Name="SCFVectorBdCyclicPolytope" Arg="d, n"/>
## <Returns> a list of integers of size <C>d+1</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the <M>f</M>-vector of the <Arg>d</Arg>-dimensional cyclic polytope on <Arg>n</Arg> vertices, <M>n\geq d+2</M>, without generating the underlying complex.
## <Example><![CDATA[
## gap> SCFVectorBdCyclicPolytope(25,198);
## [ 198, 19503, 1274196, 62117055, 2410141734, 77526225777, 2126433621312,
## 50768602708824, 1071781612741840, 20256672480820776, 346204947854027808,
## 5395027104058600008, 48354596155522298656, 262068846498922699590,
## 940938105142239825104, 2379003007642628680027, 4396097923113038784642,
## 6062663500381642763609, 6294919173643129209180, 4911378208855785427761,
## 2840750019404460890298, 1183225500922302444568, 335951678686835900832,
## 58265626173398052500, 4661250093871844200 ]
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##########################
InstallGlobalFunction(SCFVectorBdCyclicPolytope,
function(d,n)
local F,i,j,x;
if(d<=0 or n<d+2) then
Info(InfoSimpcomp,1,"SCFVectorBdCyclicPolytope: dimension must be positive, n>d+1.");
return fail;
fi;
F:=ListWithIdenticalEntries(d,0);
for i in [1..Int(d/2)] do
F[i]:=Binomial(n,i);
od;
for i in [Int(d/2)+1..d] do
F[i]:=0;
for j in [0..Int(d/2)] do
x:=(Binomial(d-j,i-j)+Binomial(j,i-d+j))*Binomial(n-d-1+j,j);
if(d mod 2 = 0 and j=d/2) then
F[i]:=F[i]+x/2;
else
F[i]:=F[i]+x;
fi;
od;
od;
return F;
end);
################################################################################
##<#GAPDoc Label="SCFVectorBdSimplex">
## <ManSection>
## <Func Name="SCFVectorBdSimplex" Arg="d"/>
## <Returns> a list of integers of size <C>d + 1</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the <M>f</M>-vector of the <M>d</M>-simplex without generating the underlying complex.
## <Example><![CDATA[
## gap> SCFVectorBdSimplex(100);
## [101, 5050, 166650, 4082925, 79208745, 1267339920, 17199613200,
## 202095455100, 2088319702700, 19212541264840, 158940114100040,
## 1192050855750300, 8160963550905900, 51297485177122800, 297525414027312240,
## 1599199100396803290, 7995995501984016450, 37314645675925410100,
## 163006083742200475700, 668324943343021950370, 2577824781465941808570,
## 9373908296239788394800, 32197337191432316660400, 104641345872155029146300,
## 322295345286237489770604, 942094086221309585483304,
## 2616928017281415515231400, 6916166902815169575968700,
## 17409661513983013070541900, 41783187633559231369300560,
## 95696978128474368620010960, 209337139656037681356273975,
## 437704928371715151926754675, 875409856743430303853509350,
## 1675784582908852295948146470, 3072271735332895875904935195,
## 5397234129638871133346507775, 9090078534128625066688855200,
## 14683973016669317415420458400, 22760158175837441993901710520,
## 33862674359172779551902544920, 48375249084532542217003635600,
## 66375341767149302111702662800, 87494768693060443692698964600,
## 110826707011209895344085355160, 134919469404951176940625649760,
## 157884485473879036845412994400, 177620046158113916451089618700,
## 192119641762857909630770403900, 199804427433372226016001220056,
## 199804427433372226016001220056, 192119641762857909630770403900,
## 177620046158113916451089618700, 157884485473879036845412994400,
## 134919469404951176940625649760, 110826707011209895344085355160,
## 87494768693060443692698964600, 66375341767149302111702662800,
## 48375249084532542217003635600, 33862674359172779551902544920,
## 22760158175837441993901710520, 14683973016669317415420458400,
## 9090078534128625066688855200, 5397234129638871133346507775,
## 3072271735332895875904935195, 1675784582908852295948146470,
## 875409856743430303853509350, 437704928371715151926754675,
## 209337139656037681356273975, 95696978128474368620010960,
## 41783187633559231369300560, 17409661513983013070541900,
## 6916166902815169575968700, 2616928017281415515231400,
## 942094086221309585483304, 322295345286237489770604,
## 104641345872155029146300, 32197337191432316660400, 9373908296239788394800,
## 2577824781465941808570, 668324943343021950370, 163006083742200475700,
## 37314645675925410100, 7995995501984016450, 1599199100396803290,
## 297525414027312240, 51297485177122800, 8160963550905900, 1192050855750300,
## 158940114100040, 19212541264840, 2088319702700, 202095455100, 17199613200,
## 1267339920, 79208745, 4082925, 166650, 5050, 101]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCFVectorBdSimplex,
function(d)
local F;
if(d<0) then
Info(InfoSimpcomp,1,"SCFVectorBdSimplex: dimension must be positive.");
return fail;
fi;
if d=0 then
return [0];
fi;
F:=[1..d];
Apply(F,x->Binomial(d+1,x));
return F;
end);
################################################################################
##<#GAPDoc Label="SCBdCrossPolytope">
## <ManSection>
## <Func Name="SCBdCrossPolytope" Arg="d"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Generates the boundary of the <M>d</M>-dimensional cross polytope <M>\beta^{d}</M>, a centrally symmetric combinatorial <M>d-1</M>-sphere.
## <Example><![CDATA[
## gap> SCBdCrossPolytope(3); # the octahedron
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCBdCrossPolytope,
function(d)
local i,j,complex,newComplex,tmp,sc,FVectorCrossPoly,fvec;
if(d<0) then
Info(InfoSimpcomp,1,"SCBdCrossPolytope: dimension must be non-negative.");
return fail;
fi;
complex:=[[1],[2]];
for i in [1..d-1] do
newComplex:=[];
for j in [1..Size(complex)] do
tmp:=[Union(complex[j],[2*i+1]),Union(complex[j],[2*i+2])];
Append(newComplex,tmp);
od;
complex:=newComplex;
od;
sc:=SCFromFacets(complex);
if(sc<>fail) then
SCRename(sc,Concatenation(["Bd(\\beta^",String(d),")"]));
SetSCTopologicalType(sc,Concatenation("S^",String(d-1)));
fvec:=SCFVectorBdCrossPolytope(d);
tmp:=[];
for i in [1..d] do
tmp[2*i-1]:=i-1;
tmp[2*i]:=fvec[i];
od;
SetComputedSCNumFacess(sc,tmp);
SetSCEulerCharacteristic(sc,1+(-1)^(d-1));
SetSCIsConnected(sc,true);
SetSCIsStronglyConnected(sc,true);
SetSCHasBoundary(sc,false);
SetSCHomology(sc,Concatenation(ListWithIdenticalEntries(d-1,[0,[]]),[[1,[]]]));
fi;
return sc;
end);
################################################################################
##<#GAPDoc Label="SCBdCyclicPolytope">
## <ManSection>
## <Func Name="SCBdCyclicPolytope" Arg="d, n"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Generates the boundary complex of the <Arg>d</Arg>-dimensional cyclic polytope (a combinatorial <M>d-1</M>-sphere) on <Arg>n</Arg> vertices, where <M>n\geq d+2</M>.
## <Example><![CDATA[
## gap> SCBdCyclicPolytope(3,8);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCBdCyclicPolytope,
function(d,n)
local s,i,a,b,facets,sc,fvec,tmp;
if(d<0 or n<d+2) then
Info(InfoSimpcomp,1,"SCBdCyclicPolytope: dimension must be non-negative, n>=d+2.");
return fail;
fi;
#construct facets using gale's evenness condition
facets:=[];
if IsInt(d/2) = true then
for s in Combinations([1..(n-d/2)],d/2) do
a:=[];
for i in s do
Add(a,i+Position(s,i)-1);
Add(a,i+Position(s,i));
od;
Add(facets,a);
od;
for s in Combinations([1..(n-2-(d-2)/2)],(d-2)/2) do
a:=[];
for i in s do
Add(a,i+Position(s,i));
Add(a,i+Position(s,i)+1);
od;
Add(a,1);
Add(a,n);
Add(facets,a);
od;
else
for s in Combinations([1..(n-1-(d-1)/2)],(d-1)/2) do
a:=[];
b:=[];
for i in s do
Add(a,i+Position(s,i));
Add(a,i+Position(s,i)+1);
Add(b,i+Position(s,i)-1);
Add(b,i+Position(s,i));
od;
Add(a,1);
Add(b,n);
Add(facets,a);
Add(facets,b);
od;
fi;
sc:=SCFromFacets(facets);
if(sc<>fail) then
SCRename(sc,Concatenation(["Bd(C_",String(d),"(",String(n),"))"]));
SetSCTopologicalType(sc,Concatenation("S^",String(d-1)));
fvec:=SCFVectorBdCyclicPolytope(d,n);
tmp:=[];
for i in [1..d] do
tmp[2*i-1]:=i-1;
tmp[2*i]:=fvec[i];
od;
SetComputedSCNumFacess(sc,tmp);
SetSCEulerCharacteristic(sc,1+(-1)^(d-1));
SetSCIsConnected(sc,true);
SetSCIsStronglyConnected(sc,true);
SetSCHasBoundary(sc,false);
SetSCHomology(sc,Concatenation(ListWithIdenticalEntries(d-1,[0,[]]),[[1,[]]]));
fi;
return sc;
end);
################################################################################
##<#GAPDoc Label="SCBdSimplex">
## <ManSection>
## <Func Name="SCBdSimplex" Arg="d"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Generates the boundary of the <M>d</M>-simplex <M>\Delta^d</M>, a combinatorial <M>d-1</M>-sphere.
## <Example><![CDATA[
## gap> SCBdSimplex(5);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCBdSimplex,
function(d)
local complex,sc,fvec,tmp,G,i;
if(d<0) then
Info(InfoSimpcomp,1,"SCBdSimplex: dimension must be non-negative.");
return fail;
fi;
complex:=Combinations([1..d+1],d);
sc:=SCFromFacets(complex);
if(sc<>fail) then
SCRename(sc,Concatenation(["S^",String(d-1),"_",String(d+1)]));
SetSCTopologicalType(sc,Concatenation("S^",String(d-1)));
fvec:=SCFVectorBdSimplex(d);
tmp:=[];
for i in [1..d] do
tmp[2*i-1]:=i-1;
tmp[2*i]:=fvec[i];
od;
SetComputedSCNumFacess(sc,tmp);
SetSCEulerCharacteristic(sc,1+(-1)^(d-1));
G:=SymmetricGroup(IsPermGroup,d+1);
SetSCAutomorphismGroup(sc,G);
SetSCAutomorphismGroupTransitivity(sc,d+1);
SetSCAutomorphismGroupSize(sc,Factorial(d+1));
SetSCAutomorphismGroupStructure(sc,Concatenation("S",String(d+1)));
SetSCGeneratorsEx(sc,[[[1..d],[d+1]]]);
if d>1 then
SetSCIsConnected(sc,true);
SetSCIsStronglyConnected(sc,true);
elif d=1 then
SetSCIsConnected(sc,false);
SetSCIsStronglyConnected(sc,false);
fi;
SetSCHasBoundary(sc,false);
SetSCHomology(sc,Concatenation(ListWithIdenticalEntries(d-1,[0,[]]),[[1,[]]]));
fi;
return sc;
end);
################################################################################
##<#GAPDoc Label="SCSimplex">
## <ManSection>
## <Func Name="SCSimplex" Arg="d"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Generates the <Arg>d</Arg>-simplex.
## <Example><![CDATA[
## gap> SCSimplex(3);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCSimplex,
function(d)
local facets,i,sc,tmp,fvec;
facets:=[[1..d+1]];
sc:=SCFromFacets(facets);
if(sc<>fail) then
fvec:=SCFVectorBdSimplex(d);
tmp:=[];
for i in [1..d] do
tmp[2*i-1]:=i-1;
tmp[2*i]:=fvec[i];
od;
tmp[2*d+1]:=d;
tmp[2*(d+1)]:=1;
SetComputedSCNumFacess(sc,tmp);
SCRename(sc,Concatenation(["B^",String(d),"_",String(d+1)]));
SetSCTopologicalType(sc,Concatenation("B^",String(d)));
SetSCEulerCharacteristic(sc,1);
fi;
return sc;
end);
################################################################################
##<#GAPDoc Label="SCCartesianProduct">
## <ManSection>
## <Meth Name="SCCartesianProduct" Arg="complex1,complex2"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes the simplicial cartesian product of <Arg>complex1</Arg> and <Arg>complex2</Arg> where <Arg>complex1</Arg> and <Arg>complex2</Arg> are pure, simplicial complexes. The original vertex labeling of <Arg>complex1</Arg> and <Arg>complex2</Arg> is changed into the standard one. The new complex has vertex labels of type <M>[v_i, v_j]</M> where <M>v_i</M> is a vertex of <Arg>complex1</Arg> and <M>v_j</M> is a vertex of <Arg>complex2</Arg>.<P/>
## If <M>n_i</M>, <M>i=1,2</M>, are the number facets and <M>d_i</M>, <M>i=1,2</M>, are the dimensions of <Arg>complexi</Arg>, then the new complex has <M>n_1 \cdot n_2 \cdot { d_1+d_2 \choose d_1}</M> facets. The number of vertices of the new complex equals the product of the numbers of vertices of the arguments.
## <Example><![CDATA[
## gap> c1:=SCBdSimplex(2);;
## gap> c2:=SCBdSimplex(3);;
## gap> c3:=SCCartesianProduct(c1,c2);
## gap> c3.Homology;
## [ [ 0, [ ] ], [ 1, [ ] ], [ 1, [ ] ], [ 1, [ ] ] ]
## gap> c3.F;
## [ 12, 48, 72, 36 ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCCartesianProduct,
"for SCSimplicialComplex and SCSimplicialComplex",
[SCIsSimplicialComplex,SCIsSimplicialComplex],
function(complex1, complex2)
local dim1, dim2,facets1,facets2,facets,nFacets,
i, j, flag, tmp, idx, element, facet, ctr,
combinations, paths,names,scprod,toptypes,vertices;
if SCIsEmpty(complex1) or SCIsEmpty(complex2) then
return SCEmpty();
fi;
#save names
if HasSCName(complex1) and HasSCName(complex2) then
names:=[SCName(complex1),SCName(complex2)];
fi;
if HasSCTopologicalType(complex1) and HasSCTopologicalType(complex2) then
toptypes:=[SCTopologicalType(complex1),SCTopologicalType(complex2)];
fi;
vertices:=[];
# extract facets
facets1:=SCFacetsEx(complex1);
facets2:=SCFacetsEx(complex2);
if facets1=fail or facets2=fail then
return fail;
fi;
# compute complex dimensions
tmp :=SCIsPure(complex1);
dim1:= SCDim(complex1);
if dim1=fail or tmp=fail or tmp=false then
if(tmp=false) then
Info(InfoSimpcomp,1,"SCCartesianProduct: complex1 not pure");
return fail;
else
return fail;
fi;
fi;
tmp :=SCIsPure(complex2);
dim2:= SCDim(complex2);
if dim1=fail or tmp=fail or tmp=false then
if(tmp=false) then
Info(InfoSimpcomp,1,"SCCartesianProduct: complex2 not pure");
return fail;
else
return fail;
fi;
fi;
# compute possible combinations
combinations:=Cartesian(facets1,facets2);
# compute paths
tmp:=Concatenation(ListWithIdenticalEntries(dim1,1),ListWithIdenticalEntries(dim2,2));
paths:=Arrangements(tmp,Size(tmp));
# compute facets of Cartesian product
facets:=[];
nFacets:= Size(facets1)*Size(facets2)*Binomial(dim1+dim2,dim1);
ctr:=0;
for element in combinations do
for i in paths do
idx:=[1,1];
facet:=[];
facet[1]:=[element[1][1],element[2][1]];
for j in [1..dim1+dim2] do
idx[i[j]]:=idx[i[j]]+1;
facet[j+1]:=[element[1][idx[1]],element[2][idx[2]]];
od;
if Size(facet)=dim1 + dim2 + 1 then
Add(facets,facet);
else
Info(InfoSimpcomp,1,"SCCartesianProduct: facet ",facet," has wrong dimension.");
fi;
ctr:=ctr+1;
od;
od;
vertices:=Union(facets);
for i in [1..Size(facets)] do
for j in [1..Size(facets[i])] do
facets[i][j] := Position(vertices,facets[i][j]);
od;
od;
scprod:=SCFromFacets(facets);
if(IsBound(toptypes)) then
SetSCTopologicalType(scprod,Concatenation([toptypes[1],"x",toptypes[2]]));
fi;
if(IsBound(names)) then
SCRename(scprod,Concatenation([names[1],"x",names[2]]));
fi;
return scprod;
end);
################################################################################
##<#GAPDoc Label="SCCartesianPower">
## <ManSection>
## <Meth Name="SCCartesianPower" Arg="complex,n"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## The new complex is <M>PL</M>-homeomorphic to <M>n</M> times the cartesian product of <Arg>complex</Arg>, of dimensions <M>n \cdot d</M> and has <M>f_{d}^n \cdot n \cdot \frac{2n-1}{2^{n-1}}!</M> facets where <M>d</M> denotes the dimension and <M>f_d</M> denotes the number of facets of <Arg>complex</Arg>. Note that the complex returned by the function is not the <M>n</M>-fold cartesian product <Arg>complex</Arg><M>^n</M> of <Arg>complex</Arg> (which, in general, is not simplicial) but a simplicial subdivision of <Arg>complex</Arg><M>^n</M>.
## <Example><![CDATA[
## gap> c:=SCBdSimplex(2);;
## gap> 4torus:=SCCartesianPower(c,4);
## gap> 4torus.Homology;
## [ [ 0, [ ] ], [ 4, [ ] ], [ 6, [ ] ], [ 4, [ ] ], [ 1, [ ] ] ]
## gap> 4torus.Chi;
## 0
## gap> 4torus.F;
## [ 81, 1215, 4050, 4860, 1944 ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCCartesianPower,
"for SCSimplicialComplex and Int",
[SCIsSimplicialComplex,IsInt],
function(complex, n)
local dim1, facets1,facets,nFacets,
i, j, k, flag, tmp, idx, element, facet, ctr,
combinations, paths, vertices, sc, name, toptype;
if SCIsEmpty(complex) then
return SCEmpty();
fi;
if HasSCName(complex) then
name:=SCName(complex);
fi;
if HasSCTopologicalType(complex) then
toptype:=SCTopologicalType(complex);
fi;
# extract facets
facets1:=SCFacetsEx(complex);
if facets1=fail then
return fail;
fi;
# compute possible combinations
tmp:=ListWithIdenticalEntries(n,facets1);
combinations:=Cartesian(tmp);
# compute complex dimensions
tmp :=SCIsPure(complex);
dim1:= SCDim(complex);
if dim1=fail or tmp=fail or tmp=false then
if(tmp=false) then
Info(InfoSimpcomp,1,"SCCartesianPower: complex not pure");
fi;
return fail;
fi;
# compute paths
tmp:=[];
for i in [1..n] do
for j in [1..dim1] do
Add(tmp,i);
od;
od;
paths:=Arrangements(tmp,Size(tmp));
# compute facets of Cartesian product
facets:=[];
nFacets:= (Size(facets1)^n)*n*(Factorial(2*n-1)/2^(n-1));
ctr:=0;
for element in combinations do
for i in paths do
idx:=ListWithIdenticalEntries(n,1);
facet:=[];
facet[1]:=[];
for j in [1..n] do
facet[1][j]:=element[j][1];
od;
for j in [1..n*dim1] do
facet[j+1]:=[];
idx[i[j]]:=idx[i[j]]+1;
for k in [1..n] do
facet[j+1][k]:=element[k][idx[k]];
od;
od;
if Size(facet)=n*dim1 + 1 then
Add(facets,facet);
else
Info(InfoSimpcomp,1,"SCCartesianPower: facet ",facet," has wrong dimension.");
fi;
ctr:=ctr+1;
od;
od;
vertices:=Union(facets);
for i in [1..Size(facets)] do
for j in [1..Size(facets[i])] do
facets[i][j] := Position(vertices,facets[i][j]);
od;
od;
sc:=SCFromFacets(facets);
if(IsBound(toptype)) then
SetSCTopologicalType(sc,Concatenation(["(",toptype,")^",String(n)]));
fi;
if(IsBound(name)) then
SCRename(sc,Concatenation(["(",name,")^",String(n)]));
fi;
return sc;
end);
################################################################################
##<#GAPDoc Label="SCConnectedSumMinus">
## <ManSection>
## <Meth Name="SCConnectedSumMinus" Arg="complex1,complex2"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## In a lexicographic ordering the smallest facet of both <Arg>complex1</Arg> and <Arg>complex2</Arg> is removed and the complexes are glued together along the resulting boundaries. The bijection used to identify the vertices of the boundaries differs from the one chosen in <Ref Func="SCConnectedSum"/> by a transposition. Thus, the topological type of <C>SCConnectedSumMinus</C> is different from the one of <Ref Func="SCConnectedSum"/> whenever <Arg>complex1</Arg> and <Arg>complex2</Arg> do not allow an orientation reversing homeomorphism.
## <Example><![CDATA[
## gap> SCLib.SearchByName("T^2"){[1..6]};
## [ [ 4, "T^2 (VT)" ], [ 5, "T^2 (VT)" ], [ 9, "T^2 (VT)" ],
## [ 10, "T^2 (VT)" ], [ 17, "T^2 (VT)" ], [ 20, "(T^2)#2" ] ]
## gap> torus:=SCLib.Load(last[1][1]);;
## gap> genus2:=SCConnectedSumMinus(torus,torus);
## gap> genus2.Homology;
## [ [ 0, [ ] ], [ 4, [ ] ], [ 1, [ ] ] ]
## gap> genus2.Chi;
## -2
## ]]></Example>
## <Example><![CDATA[
## gap> SCLib.SearchByName("CP^2");
## [ [ 16, "CP^2 (VT)" ], [ 96, "CP^2#-CP^2" ],
## [ 97, "CP^2#CP^2" ], [ 185, "CP^2#(S^2xS^2)" ],
## [ 397, "Gaifullin CP^2" ],
## [ 457, "(S^3~S^1)#(CP^2)^{#5} (VT)" ] ]
## gap> cp2:=SCLib.Load(last[1][1]);;
## # CP^2 # CP^2 (signature of intersection form is 2)
## gap> c1:=SCConnectedSum(cp2,cp2);;
## # CP^2 # - CP^2 (signature of intersection form is 0)
## gap> c2:=SCConnectedSumMinus(cp2,cp2);;
## gap> c1.F=c2.F;
## true
## gap> c1.ASDet=c2.ASDet;
## true
## gap> SCIsIsomorphic(c1,c2);
## false
## gap> PrintArray(SCIntersectionForm(c1));
## [ [ 1, 0 ],
## [ 0, 1 ] ]
## gap> PrintArray(SCIntersectionForm(c2));
## [ [ 1, 0 ],
## [ 0, -1 ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCConnectedSumMinus,
"for SCSimplicialComplex and SCSimplicialComplex",
[SCIsSimplicialComplex,SCIsSimplicialComplex],
function(complex1, complex2)
local maxvertex1, maxvertex2, facets1, facets2, simplex1, simplex2,
maptable, i, j, sc, name1, name2, vertices, idx, dim1, dim2, pure1, pure2;
pure1:=SCIsPure(complex1);
pure2:=SCIsPure(complex2);
if pure1 <> true or pure2 <> true then
Info(InfoSimpcomp,1,"SCConnectedSumMinus: complexes must be pure simplicial copmplexes.");
return fail;
fi;
dim1:=SCDim(complex1);
dim2:=SCDim(complex2);
if dim1 = fail or dim2 = fail then
Info(InfoSimpcomp,1,"SCConnectedSumMinus: complexes must have the same dimension");
return fail;
fi;
if dim1 < 1 or dim2 < 1 then
Info(InfoSimpcomp,1,"SCConnectedSumMinus: complexes must have at least dimension 1.");
return fail;
fi;
if dim1 <> dim2 then
Info(InfoSimpcomp,1,"SCConnectedSumMinus: complexes are not of the same dimension.");
return fail;
fi;
if HasSCName(complex1) and HasSCName(complex2) then
name1:=SCName(complex1);
name2:=SCName(complex2);
fi;
# compute maximal labels
maxvertex1:=Maximum(SCVerticesEx(complex1));
maxvertex2:=Maximum(SCVerticesEx(complex2));
if maxvertex1=fail or maxvertex2=fail then
Info(InfoSimpcomp,1,"SCConnectedSumMinus: complex lacks vertex labels.");
return fail;
fi;
# facets in standard labeling
facets1:=SCIntFunc.DeepCopy(SCFacetsEx(complex1));
facets2:=SCIntFunc.DeepCopy(SCFacetsEx(complex2)+maxvertex1);
if facets1=fail or facets2=fail then
Info(InfoSimpcomp,1,"SCConnectedSumMinus: complex lacks facets.");
return fail;
fi;
# relabel facets2
simplex1:=SCIntFunc.DeepCopy(facets1[1]);
simplex2:=SCIntFunc.DeepCopy(facets2[1]);
RemoveSet(facets1,simplex1);
RemoveSet(facets2,simplex2);
for i in [1..Size(facets2)] do
for j in [1..Size(facets2[i])] do
if facets2[i][j] in simplex2 then
idx := Position(simplex2,facets2[i][j]);
facets2[i][j]:=simplex1[idx];
fi;
od;
od;
for i in [1..Size(facets2)] do
Sort(facets2[i]);
od;
Sort(facets2);
if not IsSet(facets1) then
facets1:=Set(facets1);
fi;
if not IsSet(facets2) then
facets2:=Set(facets2);
fi;
sc:=SCFromFacets(Union(facets1,facets2));
vertices:=SCVerticesEx(sc);
if(vertices=fail) then
return fail;
fi;
SCRelabelStandard(sc);
if(IsBound(name1) and IsBound(name2)) then
SCRename(sc,Concatenation(name1,"#+-",name2));
fi;
return sc;
end);
SCIntFunc.ConnectedSumEx:=function(facets1,facets2)
local simplex1,simplex2,i,j, idx;
# relabel facets2
simplex1:=SCIntFunc.DeepCopy(facets1[1]);
simplex2:=SCIntFunc.DeepCopy(facets2[1]);
Remove(facets1,Position(facets1,simplex1));
Remove(facets2,Position(facets2,simplex2));
for i in [1..Size(facets2)] do
for j in [1..Size(facets2[i])] do
if facets2[i][j] in simplex2 then
idx := Position(simplex2,facets2[i][j]);
if idx = 1 then
facets2[i][j]:=simplex1[2];
elif idx = 2 then
facets2[i][j]:=simplex1[1];
else
facets2[i][j]:=simplex1[idx];
fi;
fi;
od;
od;
return [facets1,facets2];
end;
################################################################################
##<#GAPDoc Label="SCConnectedSum">
## <ManSection>
## <Meth Name="SCConnectedSum" Arg="complex1,complex2"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## In a lexicographic ordering the smallest facet of both <Arg>complex1</Arg> and <Arg>complex2</Arg> is removed and the complexes are glued together along the resulting boundaries. The bijection used to identify the vertices of the boundaries differs from the one chosen in <Ref Func="SCConnectedSumMinus"/> by a transposition. Thus, the topological type of <C>SCConnectedSum</C> is different from the one of <Ref Func="SCConnectedSumMinus"/> whenever <Arg>complex1</Arg> and <Arg>complex2</Arg> do not allow an orientation reversing homeomorphism.
## <Example><![CDATA[
## gap> SCLib.SearchByName("T^2"){[1..6]};
## [ [ 4, "T^2 (VT)" ], [ 5, "T^2 (VT)" ], [ 9, "T^2 (VT)" ],
## [ 10, "T^2 (VT)" ], [ 17, "T^2 (VT)" ], [ 20, "(T^2)#2" ] ]
## gap> torus:=SCLib.Load(last[1][1]);;
## gap> genus2:=SCConnectedSum(torus,torus);
## gap> genus2.Homology;
## [ [ 0, [ ] ], [ 4, [ ] ], [ 1, [ ] ] ]
## gap> genus2.Chi;
## -2
## ]]></Example>
## <Example><![CDATA[
## gap> SCLib.SearchByName("CP^2");
## [ [ 16, "CP^2 (VT)" ], [ 96, "CP^2#-CP^2" ],
## [ 97, "CP^2#CP^2" ], [ 185, "CP^2#(S^2xS^2)" ],
## [ 397, "Gaifullin CP^2" ],
## [ 457, "(S^3~S^1)#(CP^2)^{#5} (VT)" ] ]
## gap> cp2:=SCLib.Load(last[1][1]);;
## # CP^2 # CP^2 (signature of intersection form is 2)
## gap> c1:=SCConnectedSum(cp2,cp2);;
## # CP^2 # - CP^2 (signature of intersection form is 0)
## gap> c2:=SCConnectedSumMinus(cp2,cp2);;
## gap> c1.F=c2.F;
## true
## gap> c1.ASDet=c2.ASDet;
## true
## gap> SCIsIsomorphic(c1,c2);
## false
## gap> PrintArray(SCIntersectionForm(c1));
## [ [ 1, 0 ],
## [ 0, 1 ] ]
## gap> PrintArray(SCIntersectionForm(c2));
## [ [ 1, 0 ],
## [ 0, -1 ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCConnectedSum,
"for SCSimplicialComplex and SCSimplicialComplex",
[SCIsSimplicialComplex,SCIsSimplicialComplex],
function(complex1, complex2)
local maxvertex1, maxvertex2, facets,facets1, facets2, simplex1, simplex2,
maptable, i, j, sc, name1, name2, vertices, idx, dim1, dim2, pure1, pure2;
if(not SCIsSimplicialComplex(complex1) or not SCIsSimplicialComplex(complex2)) then
Info(InfoSimpcomp,1,"SCConnectedSum: arguments must be of type SCSimplicialComplex.");
return fail;
fi;
pure1:=SCIsPure(complex1);
pure2:=SCIsPure(complex2);
if pure1 <> true or pure2 <> true then
Info(InfoSimpcomp,1,"SCConnectedSum: complexes must be pure simplicial copmplexes.");
return fail;
fi;
dim1:=SCDim(complex1);
dim2:=SCDim(complex2);
if dim1 = fail or dim2 = fail then
Info(InfoSimpcomp,1,"SCConnectedSum: complexes must have the same dimension");
return fail;
fi;
if dim1 < 1 or dim2 < 1 then
Info(InfoSimpcomp,1,"SCConnectedSum: complexes must have at least dimension 1.");
return fail;
fi;
if dim1 <> dim2 then
Info(InfoSimpcomp,1,"SCConnectedSum: complexes are not of the same dimension.");
return fail;
fi;
if HasSCName(complex1) and HasSCName(complex2) then
name1:=SCName(complex1);
name2:=SCName(complex2);
fi;
# compute maximal labels
maxvertex1:=Maximum(SCVerticesEx(complex1));
maxvertex2:=Maximum(SCVerticesEx(complex2));
if maxvertex1=fail or maxvertex2=fail then
Info(InfoSimpcomp,1,"SCConnectedSum: complex lacks vertex labels.");
return fail;
fi;
# facets in standard labeling
facets1:=SCIntFunc.DeepCopy(SCFacetsEx(complex1));
facets2:=SCIntFunc.DeepCopy(SCFacetsEx(complex2)+maxvertex1);
if facets1=fail or facets2=fail or name1 = fail or name2 = fail then
Info(InfoSimpcomp,1,"SCConnectedSum: complex lacks name or facets.");
return fail;
fi;
facets:=SCIntFunc.ConnectedSumEx(facets1,facets2);
facets1:=facets[1];
facets2:=facets[2];
for i in [1..Size(facets2)] do
Sort(facets2[i]);
od;
Sort(facets2);
if not IsSet(facets1) then
facets1:=Set(facets1);
fi;
if not IsSet(facets2) then
facets2:=Set(facets2);
fi;
sc:=SCFromFacets(Union(facets1,facets2));
if(IsBound(name1) and IsBound(name2)) then
SCRename(sc,Concatenation(name1,"#+-",name2));
fi;
return sc;
end);
################################################################################
##<#GAPDoc Label="SCConnectedProduct">
## <ManSection>
## <Meth Name="SCConnectedProduct" Arg="complex,n"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## If <M>n \geq 2</M>, the function internally calls <M>1 \times</M> <Ref Func="SCConnectedSum"/> and <M>(n-2) \times</M> <Ref Func="SCConnectedSumMinus"/>.
## <Example><![CDATA[
## gap> SCLib.SearchByName("T^2"){[1..6]};
## [ [ 4, "T^2 (VT)" ], [ 5, "T^2 (VT)" ], [ 9, "T^2 (VT)" ],
## [ 10, "T^2 (VT)" ], [ 17, "T^2 (VT)" ], [ 20, "(T^2)#2" ] ]
## gap> torus:=SCLib.Load(last[1][1]);;
## gap> genus10:=SCConnectedProduct(torus,10);
## gap> genus10.Chi;
## -18
## gap> genus10.F;
## [ 43, 183, 122 ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCConnectedProduct,
"for SCSimplicialComplex and Int",
[SCIsSimplicialComplex,IsInt],
function(complex, n)
local maxvertex, newComplex, maptable, i, idx, tmp, sc, dim, facets, facets1, facets2, name, pure;
if(not SCIsSimplicialComplex(complex)) then
Info(InfoSimpcomp,1,"SCConnectedProduct: argument must be of type SCSimplicialComplex.");
return fail;
fi;
pure:=SCIsPure(complex);
if pure <> true then
Info(InfoSimpcomp,1,"SCConnectedProduct: complex must be a pure simplicial complex.");
return fail;
fi;
dim := SCDim(complex);
if dim = fail then
return fail;
fi;
if dim < 1 then
Info(InfoSimpcomp,1,"SCConnectedProduct: complex must be at least of dimensions 1.");
return fail;
fi;
if SCIsEmpty(complex) then
Info(InfoSimpcomp,1,"SCConnectedProduct: complexes is empty.");
return SCEmpty();
fi;
if n<1 then
return SCEmpty();
elif n=1 then
return complex;
else
name:=SCName(complex);
maxvertex:=Maximum(SCVerticesEx(complex));
if maxvertex=fail then
Info(InfoSimpcomp,1,"SCConnectedProduct: complex lacks vertex labels.");
return fail;
fi;
# facets in standard labeling
facets1:=SCIntFunc.DeepCopy(SCFacetsEx(complex));
if facets1=fail then
return fail;
fi;
for i in [1..(n-1)] do
facets2:=SCIntFunc.DeepCopy(SCFacetsEx(complex)+i*maxvertex);
facets1:=Concatenation(SCIntFunc.ConnectedSumEx(facets1,facets2));
od;
for i in [1..Size(facets1)] do
Sort(facets1[i]);
od;
Sort(facets1);
if not IsSet(facets1) then
facets1:=Set(facets1);
fi;
sc:=SCFromFacets(facets1);
if(name<>fail) then
SCRename(sc,Concatenation(Concatenation(ListWithIdenticalEntries(n-1,Concatenation(name,"#+-"))),name));
fi;
return sc;
fi;
end);
################################################################################
##<#GAPDoc Label="SCDifferenceCycleExpand">
## <ManSection>
## <Func Name="SCDifferenceCycleExpand" Arg="diffcycle"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## <Arg>diffcycle</Arg> induces a simplex <M>\Delta = ( v_1 , \ldots , v_{n+1} )</M> by <M>v_1 = </M><Arg>diffcycle[1]</Arg>, <M>v_i = v_{i-1} + </M> <Arg>diffcycle[i]</Arg> and a cyclic group action by <M>\mathbb{Z}_{\sigma}</M> where <M>\sigma = \sum </M> <Arg>diffcycle[i]</Arg> is the modulus of <C>diffcycle</C>. The function returns the <M>\mathbb{Z}_{\sigma}</M>-orbit of <M>\Delta</M>.<P/>
## Note that modulo operations in &GAP; are often a little bit cumbersome, since all integer ranges usually start from <M>1</M>.
## <Example><![CDATA[
## gap> c:=SCDifferenceCycleExpand([1,1,2]);;
## gap> c.Facets;
## [ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 3, 4 ], [ 2, 3, 4 ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCDifferenceCycleExpand,
function(diffcycle)
local rs,i,modulus,orbit;
if(Length(diffcycle)<1 or not ForAll(diffcycle,IsPosInt)) then
Info(InfoSimpcomp,1,"SCDifferenceCycleExpand: invalid difference cycle.");
return fail;
fi;
modulus:=Sum(diffcycle);
rs:=[0];
for i in [1..Length(diffcycle)-1] do
rs[i+1]:=(rs[i]+diffcycle[i]) mod modulus;
od;
orbit:=[Set(rs)];
for i in [1..modulus-1] do
AddSet(orbit,Set((rs+i) mod modulus));
od;
return SCFromFacets(orbit+1);
end);
################################################################################
##<#GAPDoc Label="SCFromDifferenceCycles">
## <ManSection>
## <Meth Name="SCFromDifferenceCycles" Arg="diffcycles"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Creates a simplicial complex object from the list of difference cycles provided. If <Arg>diffcycles</Arg> is of length <M>1</M> the computation is equivalent to the one in <Ref Func="SCDifferenceCycleExpand"/>. Otherwise the induced modulus (the sum of all entries of a difference cycle) of all cycles has to be equal and the union of all expanded difference cycles is returned.<P/>
## A <M>n</M>-dimensional difference cycle <M>D = (d_1 : \ldots : d_{n+1})</M> induces a simplex <M>\Delta = ( v_1 , \ldots , v_{n+1} )</M> by <M>v_1 = d_1</M>, <M>v_i = v_{i-1} + d_i</M> and a cyclic group action by <M>\mathbb{Z}_{\sigma}</M> where <M>\sigma = \sum d_i</M> is the modulus of <M>D</M>. The function returns the <M>\mathbb{Z}_{\sigma}</M>-orbit of <M>\Delta</M>.<P/>
## Note that modulo operations in &GAP; are often a little bit cumbersome, since all integer ranges usually start from <M>1</M>.
## <Example><![CDATA[
## gap> c:=SCFromDifferenceCycles([[1,1,6],[2,3,3]]);;
## gap> c.F;
## [ 8, 24, 16 ]
## gap> c.Homology;
## [ [ 0, [ ] ], [ 2, [ ] ], [ 1, [ ] ] ]
## gap> c.Chi;
## 0
## gap> c.HasBoundary;
## false
## gap> SCIsPseudoManifold(c);
## true
## gap> SCIsManifold(c);
## #I SCIsManifold: link is sphere.
## #I SCIsManifold: transitive automorphism group, checking only one link.
## true
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCFromDifferenceCycles,
"for List of difference cycles",
[IsList],
function(diffcycles)
local modulus,expanded,complex,facets;
if(Length(diffcycles)<1 or not ForAll(diffcycles,IsList)) then
Info(InfoSimpcomp,1,"SCFromDifferenceCycles: invalid difference cycle list.");
return fail;
fi;
modulus:=Sum(diffcycles[1]);
expanded:=List(diffcycles,SCDifferenceCycleExpand);
if(ForAny(diffcycles,x->Sum(x)<>modulus) or fail in expanded) then
Info(InfoSimpcomp,1,"SCFromDifferenceCycles: invalid difference cycle in arguments.");
return fail;
fi;
facets:=List(expanded,SCFacets);
complex:=SC(Union(facets));
if complex=fail then
return fail;
fi;
SetSCDifferenceCycles(complex,diffcycles);
SCRename(complex,Concatenation("complex from diffcycles ",String(diffcycles)));
return complex;
end);
################################################################################
##<#GAPDoc Label="SCDifferenceCycleCompress">
## <ManSection>
## <Func Name="SCDifferenceCycleCompress" Arg="simplex,modulus"/>
## <Returns> list with possibly duplicate entries upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## A difference cycle is returned, i. e. a list of integer values of length <M>(d+1)</M>, if <M>d</M> is the dimension of <Arg>simplex</Arg>, and a sum equal to <Arg>modulus</Arg>. In some sense this is the inverse operation of <Ref Func="SCDifferenceCycleExpand"/>.
## <Example><![CDATA[
## gap> sphere:=SCBdSimplex(4);;
## gap> gens:=SCGenerators(sphere);
## [ [ [ 1, 2, 3, 4 ], [ [ 5 ] ] ] ]
## gap> diffcycle:=SCDifferenceCycleCompress(gens[1][1],5);
## [ 1, 1, 1, 2 ]
## gap> c:=SCDifferenceCycleExpand([1,1,1,2]);;
## gap> c.Facets;
## [ [ 1, 2, 3, 4 ], [ 1, 2, 3, 5 ], [ 1, 2, 4, 5 ], [ 1, 3, 4, 5 ],
## [ 2, 3, 4, 5 ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCDifferenceCycleCompress,
function(simplex,modulus)
local dc,i,j,sum;
if(Length(simplex)<2 or modulus<2 or not ForAll(simplex,x->x>=0)) then
Info(InfoSimpcomp,1,"SCDifferenceCycleCompress: invalid simplex or simplex labeling.");
return fail;
fi;
dc:=[];
sum:=0;
for i in [1..Length(simplex)-1] do
dc[i]:=AbsoluteValue(simplex[i+1]-simplex[i]);
sum:=sum+dc[i];
od;
dc[Length(simplex)]:=-sum mod modulus;
return Set(Orbit(CyclicGroup(IsPermGroup,Length(simplex)),dc,Permuted))[1];
end);
################################################################################
##<#GAPDoc Label="SCStronglyConnectedComponents">
## <ManSection>
## <Meth Name="SCStronglyConnectedComponents" Arg="complex"/>
## <Returns> a list of simplicial complexes of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes all strongly connected components of a pure simplicial complex.
## <Example><![CDATA[
## gap> c:=SC([[1,2,3],[2,3,4],[4,5,6],[5,6,7]]);;
## gap> comps:=SCStronglyConnectedComponents(c);
## gap> comps[1].Facets;
## [ [ 1, 2, 3 ], [ 2, 3, 4 ] ]
## gap> comps[2].Facets;
## [ [ 4, 5, 6 ], [ 5, 6, 7 ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCStronglyConnectedComponents,
"for SCSimplicialComplex and IsEmpty",
[SCIsSimplicialComplex and IsEmpty],
function(complex)
SetSCIsStronglyConnected(complex,true);
return [SCEmpty()];
end);
InstallMethod(SCStronglyConnectedComponents,
"for SCSimplicialComplex",
[SCIsSimplicialComplex],
function(complex)
local ispure, i, j, flag, untreated, allComponents, curComponent, boundary, faces, labels, dim, facets, name;
labels:=SCVertices(complex);
if(labels=fail) then
Info(InfoSimpcomp,1,"SCStronglyConnectedComponents: argument lacks vertex labels.");
return fail;
fi;
dim := SCDim(complex);
if dim = fail then
return fail;
fi;
ispure := SCIsPure(complex);
if ispure = fail then
return fail;
fi;
if not ispure then
Info(InfoSimpcomp,1,"SCStronglyConnectedComponents: argument must be a pure simplicial complex.");
return fail;
fi;
if dim = 0 then
facets:=SCFacets(complex);
if facets = fail then
return fail;
fi;
allComponents := List(facets,x->SC([x]));
if fail in allComponents then
return fail;
fi;
SetSCIsStronglyConnected(complex,Length(allComponents)=1);
return allComponents;
fi;
untreated:=SCIntFunc.DeepCopy(SCFacetsEx(complex));
if untreated=fail then
return fail;
fi;
allComponents :=[];
while untreated<>[] do
curComponent:=[untreated[1]];
Remove(untreated,1);
flag:=0;
while flag=0 do
flag:=1;
boundary:=SCBoundary(SC(curComponent));
faces:=SCFacets(boundary);
if faces=fail then
return fail;
fi;
for i in faces do
for j in Reversed([1..Size(untreated)]) do
if IsSubset(untreated[j],i) then
flag:=0;
Add(curComponent,untreated[j]);
Remove(untreated,j);
fi;
od;
od;
od;
AddSet(allComponents,curComponent);
od;
name:=SCName(complex);
if(name<>fail and Size(allComponents)>0) then
for i in [1..Length(allComponents)] do
allComponents[i]:=SCFromFacets(SCIntFunc.RelabelSimplexList(allComponents[i],labels));
SCRename(allComponents[i],Concatenation(["Strongly connected component #",String(i)," of ",name]));
od;
fi;
SetSCIsStronglyConnected(complex,Length(allComponents)=1);
return allComponents;
end);
################################################################################
##<#GAPDoc Label="SCConnectedComponents">
## <ManSection>
## <Meth Name="SCConnectedComponents" Arg="complex"/>
## <Returns> a list of simplicial complexes of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Computes all connected components of an arbitrary simplicial complex.
## <Example><![CDATA[
## gap> c:=SC([[1,2,3],[3,4,5],[4,5,6,7,8]]);;
## gap> SCRename(c,"connected complex");;
## gap> SCConnectedComponents(c);
## gap> c:=SC([[1,2,3],[4,5],[6,7,8]]);;
## gap> SCRename(c,"non-connected complex");;
## gap> SCConnectedComponents(c);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallMethod(SCConnectedComponents,
"for SCPolyhedralComplex and IsEmpty",
[SCIsPolyhedralComplex and IsEmpty],
function(complex)
SetSCIsConnected(complex,true);
return [SCEmpty()];
end);
InstallMethod(SCConnectedComponents,
"for SCSimplicialComplex",
[SCIsSimplicialComplex],
function(complex)
local vertices, star, conncomps, verticesComponent, innerVertices, treatedVertices, name, i, labels, span, facets, sc;
labels:=SCVertices(complex);
if(labels=fail) then
Info(InfoSimpcomp,1,"SCConnectedComponents: complex lacks vertex labels.");
return fail;
fi;
facets:=SCFacetsEx(complex);
vertices:=SCVerticesEx(complex);
if facets=fail or vertices=fail then
return fail;
fi;
conncomps:=[];
conncomps:=[];
while vertices<>[] do
innerVertices:=[vertices[1]];
treatedVertices:=[];
verticesComponent:=[];
while verticesComponent<>vertices and innerVertices<>[] do
star:=Filtered(facets,x->innerVertices[1] in x);
AddSet(treatedVertices,innerVertices[1]);
RemoveSet(innerVertices,innerVertices[1]);
innerVertices:=Union(innerVertices,Difference(Union(star),treatedVertices));
verticesComponent:=Union(verticesComponent,Union(star));
od;
span:=Filtered(facets,x->IsSubset(verticesComponent,x));
Add(conncomps,span);
vertices:=Difference(vertices,verticesComponent);
od;
name:=SCName(complex);
if name = fail then
return fail;
fi;
if(Size(conncomps)>0) then
for i in [1..Length(conncomps)] do
conncomps[i]:=SCFromFacets(SCIntFunc.RelabelSimplexList(conncomps[i],labels));
SCRename(conncomps[i],Concatenation(["Connected component #",String(i)," of ",name]));
od;
fi;
SetSCIsConnected(complex,Size(conncomps)=1);
return conncomps;
end);
SCIntFunc.AGL1p:=function(p)
local b,factor,start,i,j,perm,t,l,G;
if(not IsPrime(p) or p < 5) then
Info(InfoSimpcomp,1,"SCAGL1: argument must be a prime > 3.");
return fail;
fi;
factor:=0;
for j in [2..p-2] do
if Gcd(j,p-1) = 1 then
b:=[];
b[1]:=1;
b[2]:=j;
start:=j;
i:=3;
while start <> 1 and i < p do
start:=start*j mod p;
b[i]:=start;
i:=i+1;
od;
if i > p then
Info(InfoSimpcomp,1,"SCAGL1: no generator found.");
return fail;
fi;
if Size(b) = p-1 then
factor:=j;
break;
fi;
fi;
od;
if factor = 0 then
Info(InfoSimpcomp,1,"SCAGL1: no generator found.");
return fail;
fi;
perm:=List([1..p-1],x->factor*x mod p)+1;
perm:=Concatenation([1],perm);
l:=PermList(perm);
t:=PermList(Concatenation([2..p],[1]));
G:=Group(t,l);
SetName(G,Concatenation("AGL(1,",String(p),")"));
return G;
end;
################################################################################
##<#GAPDoc Label="SCSeriesAGL">
## <ManSection>
## <Func Name="SCSeriesAGL" Arg="p"/>
## <Returns> a permutation group and a list of <M>5</M>-tuples of integers upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## For a given prime <Arg>p</Arg> the automorphism group (AGL<M>(1,p)</M>) and the generators of all members of the series of <M>2</M>-transitive combinatorial <M>4</M>-pseudomanifolds with <Arg>p</Arg> vertices from <Cite Key="Spreer10Diss"/>, Section 5.2, is computed. The affine linear group AGL<M>(1,p)</M> is returned as the first argument. If no member of the series with <Arg>p</Arg> vertices exists only the group is returned.
## <Example><![CDATA[
## gap> gens:=SCSeriesAGL(17);
## [ AGL(1,17), [ [ 1, 2, 4, 8, 16 ] ] ]
## gap> c:=SCFromGenerators(gens[1],gens[2]);;
## gap> SCIsManifold(SCLink(c,1));
## true
## ]]></Example>
## <Example><![CDATA[
## gap> List([19..23],x->SCSeriesAGL(x));
## #I SCSeriesAGL: argument must be a prime > 13.
## #I SCSeriesAGL: argument must be a prime > 13.
## #I SCSeriesAGL: argument must be a prime > 13.
## [ [ AGL(1,19), [ [ 1, 2, 10, 12, 17 ] ] ], fail, fail, fail,
## [ AGL(1,23), [ [ 1, 2, 7, 9, 19 ], [ 1, 2, 4, 8, 22 ] ] ] ]
## gap> for i in [80000..80100] do if IsPrime(i) then Print(i,"\n"); fi; od;
## 80021
## 80039
## 80051
## 80071
## 80077
## gap> SCSeriesAGL(80021);
## [ AGL(1,80021), [ ] ]
## gap> SCSeriesAGL(80039);
## [ AGL(1,80039), [ [ 1, 2, 6496, 73546, 78018 ] ] ]
## gap> SCSeriesAGL(80051);
## [ AGL(1,80051), [ [ 1, 2, 31498, 37522, 48556 ] ] ]
## gap> SCSeriesAGL(80071);
## [ AGL(1,80071), [ ] ]
## gap> SCSeriesAGL(80077);
## [ AGL(1,80077), [ [ 1, 2, 4126, 39302, 40778 ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCSeriesAGL,
function(p)
local b,factor,start,i,j,perm,t,l,candidates,c,G;
if(not IsPrime(p) or p <= 14) then
Info(InfoSimpcomp,1,"SCSeriesAGL: argument must be a prime > 13.");
return fail;
fi;
factor:=0;
for j in [2..p-2] do
if Gcd(j,p-1) = 1 then
b:=[];
b[1]:=1;
b[2]:=j;
start:=j;
i:=3;
while start <> 1 and i < p do
start:=start*j mod p;
b[i]:=start;
i:=i+1;
od;
if i > p then
Info(InfoSimpcomp,1,"SCSeriesAGL: no generator found.");
return fail;
fi;
if Size(b) = p-1 then
factor:=j;
break;
fi;
fi;
od;
if factor = 0 then
Info(InfoSimpcomp,1,"SCSeriesAGL: no generator found.");
return fail;
fi;
perm:=List([1..p-1],x->factor*x mod p)+1;
perm:=Concatenation([1],perm);
l:=PermList(perm);
t:=PermList(Concatenation([2..p],[1]));
G:=Group(t,l);
SetName(G,Concatenation("AGL(1,",String(p),")"));
candidates:=[];
for i in [2..(p-1)] do
if ((1-b[((2*(i-1)-0) mod (p-1)) + 1]) mod p = b[((3*(i-1)-0) mod (p-1)) +1]) then
c:=[0,1,b[i],b[((2*(i-1)-0) mod (p-1)) + 1],b[((3*(i-1)-0) mod (p-1)) +1]];
Sort(c);
c:=c+1;
Add(candidates,c);
fi;
od;
if candidates=[] then
return G;
else
return [G,candidates];
fi;
end);
################################################################################
##<#GAPDoc Label="SCSeriesBid">
## <ManSection>
## <Func Name="SCSeriesBid" Arg="i,d"/>
## <Returns> a simplicial complex upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Constructs the complex <M>B(i,d)</M> as described in <Cite Key="Klee11CentSymmMnfFewVert" />, cf. <Cite Key="Effenberger10Diss" />, <Cite Key="Sparla99LBTComb2kMnf" />. The complex <M>B(i,d)</M> is a <M>i</M>-Hamiltonian subcomplex of the <M>d</M>-cross polytope and its boundary topologically is a sphere product <M>S^i\times S^{d-i-2}</M> with vertex transitive automorphism group.
## <Example><![CDATA[
## gap> b26:=SCSeriesBid(2,6);
## gap> s2s2:=SCBoundary(b26);
## gap> SCFVector(s2s2);
## gap> SCAutomorphismGroup(s2s2);
## gap> SCIsManifold(s2s2);
## gap> SCHomology(s2s2);
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCSeriesBid,
function(i,d)
local facets,b,changes,f,j,c;
if(not IsInt(i) or not IsPosInt(d) or i<0) then
Info(InfoSimpcomp,1,"SCSeriesBid: argument i must be a non-negative integer between 0 and d-2, argument d a positive integer.");
return fail;
fi;
#returns list of facets with exactly b "changes"
changes:=function(b)
local i,o,c;
o:=b[1];
c:=0;
for i in b{[2..Length(b)]} do
if(i<>o) then
c:=c+1;
o:=i;
fi;
od;
return c;
end;
#generate facet list
facets:=[];
for b in Cartesian(ListWithIdenticalEntries(d,[0,1])) do
if(changes(b)<=i) then
#build facet
f:=[];
for j in [1..Length(b)] do
if(b[j]=1) then
f[j]:=d+j;
else
f[j]:=j;
fi;
od;
Add(facets,f);
fi;
od;
c:=SCFromFacets(facets);
SCRename(c,Concatenation("B(",String(i),",",String(d),")"));
SCSetReference(c,"S. Klee and I. Novik, Centrally symmetric manifolds with few vertices, arXiv:1102.0542v1 [math.CO], Preprint, 15 pages, 2011.");
return c;
end);
################################################################################
##<#GAPDoc Label="SCSeriesC2n">
## <ManSection>
## <Func Name="SCSeriesC2n" Arg="n"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Generates the combinatorial <M>3</M>-manifold <M>C_{2n}</M>, <M>n \geq 8</M>, with <M>2n</M> vertices from <Cite Key="Spreer10Diss"/>, Section 4.5.3 and Section 5.2. The complex is homeomorphic to <M>S^2 \times S^1</M> for <M>n</M> odd and homeomorphic to <M>S^2 \dtimes S^1</M> in case <M>n</M> is an even number. In the latter case <M>C_{2n}</M> is isomorphic to <M>D_{2n}</M> from <Ref Func="SCSeriesD2n"/>. The complexes are believed to appear as the vertex links of some of the members of the series of <M>2</M>-transitive <M>4</M>-pseudomanifolds from <Ref Func="SCSeriesAGL"/>. Internally calls <Ref Func="SCFromDifferenceCycles"/>.
## <Example><![CDATA[
## gap> c:=SCSeriesC2n(8);
## gap> SCGenerators(c);
## [ [ [ 1, 2, 3, 6 ], 32 ], [ [ 1, 2, 5, 6 ], 16 ], [ [ 1, 3, 6, 8 ], 16 ],
## [ [ 1, 3, 8, 10 ], 16 ] ]
## ]]></Example>
## <Example><![CDATA[
## gap> c:=SCSeriesC2n(8);;
## gap> d:=SCSeriesD2n(8);
## gap> SCIsIsomorphic(c,d);
## true
## gap> c:=SCSeriesC2n(11);;
## gap> d:=SCSeriesD2n(11);;
## gap> c.Homology;
## [ [ 0, [ ] ], [ 1, [ ] ], [ 1, [ ] ], [ 1, [ ] ] ]
## gap> d.Homology;
## [ [ 0, [ ] ], [ 1, [ ] ], [ 0, [ 2 ] ], [ 0, [ ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCSeriesC2n,
function(n)
local c;
if(not IsInt(n) or n < 8) then
Info(InfoSimpcomp,1,"SCSeriesC2n: argument must be an integer > 7.");
return fail;
fi;
c:=SCFromDifferenceCycles([[1,1,n-5,n+3],[1,1,n+3,n-5],[1,n-5,1,n+3],[2,n-5,2,n+1],[2,n-3,2,n-1]]);
SCRename(c,Concatenation(["C_",String(2*n)," = { (1:1:",String(n-5),":",String(n+3),"),(1:1:",String(n+3),":",String(n-5),"),(1:",String(n-5),":1:",String(n+3),"),(2:",String(n-5),":2:",String(n+1),"),(2:",String(n-3),":2:",String(n-1),") }"]));
if not IsInt(n/2) then
SetSCTopologicalType(c,"S^2 x S^1");
else
SetSCTopologicalType(c,"S^2 ~ S^1");
fi;
return c;
end);
################################################################################
##<#GAPDoc Label="SCSeriesD2n">
## <ManSection>
## <Func Name="SCSeriesD2n" Arg="n"/>
## <Returns> simplicial complex of type <C>SCSimplicialComplex</C> upon success, <K>fail</K> otherwise.</Returns>
## <Description>
## Generates the combinatorial <M>3</M>-manifold <M>D_{2n}</M>, <M>n \geq 8</M>, <M>n \neq 9</M>, with <M>2n</M> vertices from <Cite Key="Spreer10Diss"/>, Section 4.5.3 and Section 5.2. The complex is homeomorphic to <M>S^2 \dtimes S^1</M>. In the case that <M>n</M> is even <M>D_{2n}</M> is isomorphic to <M>C_{2n}</M> from <Ref Func="SCSeriesC2n"/>. The complexes are believed to appear as the vertex links of some of the members of the series of <M>2</M>-transitive <M>4</M>-pseudomanifolds from <Ref Func="SCSeriesAGL"/>. Internally calls <Ref Func="SCFromDifferenceCycles"/>.
## <Example><![CDATA[
## gap> d:=SCSeriesD2n(15);
## gap> SCAutomorphismGroup(d);
## TransitiveGroup(30,14) = t30n14
## gap> StructureDescription(last);
## "D60"
## ]]></Example>
## <Example><![CDATA[
## gap> c:=SCSeriesC2n(8);;
## gap> d:=SCSeriesD2n(8);
## gap> SCIsIsomorphic(c,d);
## true
## gap> c:=SCSeriesC2n(11);;
## gap> d:=SCSeriesD2n(11);;
## gap> c.Homology;
## [ [ 0, [ ] ], [ 1, [ ] ], [ 1, [ ] ], [ 1, [ ] ] ]
## gap> d.Homology;
## [ [ 0, [ ] ], [ 1, [ ] ], [ 0, [ 2 ] ], [ 0, [ ] ] ]
## ]]></Example>
## </Description>
## </ManSection>
##<#/GAPDoc>
################################################################################
InstallGlobalFunction(SCSeriesD2n,
function(n)
local c;
if(not IsInt(n) or n < 8 or n=9) then
Info(InfoSimpcomp,1,"SCSeriesD2n: argument must be an integer > 7 not equal to 9.");
return fail;
fi;
c:=SCFromDifferenceCycles([[1,1,1,2*n-3],[1,2,2*n-5,2],[3,n-4,5,n-4],[2,3,n-4,n-1],[2,n-1,n-4,3]]);
SCRename(c,Concatenation(["D_",String(2*n)," = { (1:1:1:",String(2*n-3),"),(1:2:",String(2*n-5),":2),(3:",String(n-4),":5:",String(n-4),"),(2:3:",String(n-4),":",String(n-1),"),(2:",String(n-1),":",String(n-4),":3) }"]));
SetSCTopologicalType(c,"S^2 ~ S^1");
return c;
end);
--> --------------------
--> maximum size reached
--> --------------------
[ Dauer der Verarbeitung: 0.43 Sekunden
(vorverarbeitet)
]
|