Quelle diagram.gi
Sprache: unbekannt
|
|
#############################################################################
##
## diagram.gi FinInG package
## John Bamberg
## Anton Betten
## Jan De Beule
## Philippe Cara
## Michel Lavrauw
## Max Neunhoeffer
##
## Copyright 2018 Colorado State University
## Sabancı Üniversitesi
## Università degli Studi di Padova
## Universiteit Gent
## University of St. Andrews
## University of Western Australia
## Vrije Universiteit Brussel
##
##
## Implementation stuff for diagram geometries
##
#############################################################################
#################################################################
# Technicalities: Availability test for GRAPE and GraphViz/dotty
#################################################################
Whereisdot := function() # Undocumented since technical
local str, outputtext;
if not ARCH_IS_UNIX() then
Info(InfoFinInG, 1, "Package `FinInG': non-Unix architecture! Don't know how to make diagram drawings in that case.");
return false;
else # See whether 'dot' is installed
str:=""; outputtext:=OutputTextString(str, true);
Process(DirectoryCurrent(), Filename(DirectoriesSystemPrograms(), "which"), InputTextNone(), outputtext, ["dot"]);
if str = ""
then
Info(InfoFinInG, 1, "Package `FinInG': dot not installed on your system. Please install GraphViz on your system.");
Info(InfoFinInG, 1, "Package `FinInG': or find a friend who can compile your dot-files.");
return false;
fi;
fi;
return true;
end;
#############################################################################
##
## Coset geometries
##
#############################################################################
#
#############################################################################
#O CosetGeometry
#
# Constructs a Coset geometry from a group and a list of subgroups
##
InstallMethod( CosetGeometry, "for groups and list of subgroups",[ IsGroup , IsHomogeneousList ],
function( g, l )
## We assume the types of the geometry index the set l, the ordering
## of l is important.
local geo, ty;
geo := rec( group := g, parabolics := l );
ty := NewType( GeometriesFamily, IsCosetGeometry and IsCosetGeometryRep );
ObjectifyWithAttributes( geo, ty,
AmbientGeometry, geo,
TypesOfElementsOfIncidenceStructure, [1..Size(l)],
RankAttr, Size(l),
RepresentativesOfElements, l );
## To speed up IncidenceGraph (and hence also DiagramOfGeometry)
if HasIsHandledByNiceMonomorphism(g) and IsHandledByNiceMonomorphism(g) and FINING.Fast then
SetIsHandledByNiceMonomorphism(geo, true);
fi;
return geo;
end );
# CHECKED 140913
#########################################################################
#O Rank2Residues
#
# Adds all rank 2 residues to an incidence geometry
# Technical and undocumented
##
InstallMethod( Rank2Residues, [ IsIncidenceGeometry ],
function( geo )
local types, residues, res, x, ty;
types := TypesOfElementsOfIncidenceStructure( geo );
residues := [];
for x in Combinations( types, 2 ) do
res := rec( edge := x, geo := geo );
ty := NewType( Rank2ResidueFamily, IsRank2Residue and IsRank2ResidueRep );
Objectify( ty, res );
Add(residues, res);
od;
Setter( Rank2ResiduesAttr )( geo, residues );
return residues;
end );
# CHECKED 25/3/2014
##########################################################################
#O MakeRank2Residue
#
# Actually computes the given rank 2 residue of given type <edge>
# Technical and undocumented
##
InstallMethod( MakeRank2Residue, [ IsRank2Residue ],
function( res )
local geo, flag;
geo:=res!.geo;
if IsCosetGeometry(geo) then
flag:=FlagOfIncidenceStructure(geo, StandardFlagOfCosetGeometry(geo)!.els{Difference(TypesOfElementsOfIncidenceStructure(geo),res!.edge)});
#I know this is ugly but I have no time to define subflags
res!.residuegeometry:=CanonicalResidueOfFlag(geo,flag);
else
Error("Don't know how to compute residue!\n");
# We could use the generic residue here, with a warning.
fi;
end );
####################################################
## Natural action on coset geometry element
##
####################################################
InstallGlobalFunction( OnCosetGeometryElement,
function( c, t )
return Wrap(c!.geo, c!.type, OnRight(c!.obj, t));
end );
#
#############################################################################
#O \^( <x>, <gm> )
##
InstallOtherMethod( \^,
"for an element of a coset geometry and an element of its group",
[IsElementOfCosetGeometry, IsMultiplicativeElementWithInverse],
function(x, gm)
return OnCosetGeometryElement(x,gm);
end );
#
#############################################################################
#O \^( <x>, <gm> )
##
InstallOtherMethod( \^,
"for a flag of a coset geometry and an element of its group",
[IsFlagOfCosetGeometry, IsMultiplicativeElementWithInverse],
function(x, gm)
return FlagOfIncidenceStructure(x!.geo, OnTuples(x!.els,gm));
end );
# Obsolete since there is generic version in geometry.g*
#############################################################################
#O Type ( <flag> )
##
#InstallMethod( Type,
# "for a flag of a coset geometry",
# [IsFlagOfCosetGeometry],
# function(flag)
# return Set(List(flag!.els,Type));
# end );
# CHECKED 24/3/2014 PhC
# added check 17/12/14 jdb
#############################################################################
#O FlagOfIncidenceStructure( <cg>, <els> )
# returns the flag of the coset geometry <cg> with elements in <els>.
# the method does check whether the input really determines a flag.
##
InstallMethod( FlagOfIncidenceStructure,
"for a coset geometry and a list of pairwise incident elements",
[ IsCosetGeometry, IsElementOfIncidenceStructureCollection ],
function(cg,els)
local list,i,test,type,flag;
list := Set(ShallowCopy(els));
if Length(list) > Rank(cg) then
Error("A flag must contain at most Rank(<cg>) elements.\n");
fi;
test := List(list,x->AmbientGeometry(x));
if not ForAll(test,x->x=cg) then
Error("not all elements have <incgeo> as ambient geometry");
fi;
test := Set(List([1..Length(list)-1],i -> IsIncident(list[i],list[i+1])));
if (test <> [ true ] and test <> []) then
Error("<els> does not determine a flag.\n");
fi;
flag := rec(geo := cg, types := List(list,x->x!.type), els := list);
ObjectifyWithAttributes(flag, IsFlagOfCGType, IsEmptyFlag, false, RankAttr, Size(list));
return flag;
end);
#############################################################################
#O FlagOfIncidenceStructure( <ps>, <els> )
# returns the empty flag of the projective space <ps>.
##
InstallMethod( FlagOfIncidenceStructure,
"for a coset geometry and an empty list",
[ IsCosetGeometry, IsList and IsEmpty ],
function(cg,els)
local flag;
flag := rec(geo := cg, types := [], els := [] );
ObjectifyWithAttributes(flag, IsFlagOfCGType, IsEmptyFlag, true, RankAttr, 0 );
return flag;
end);
# Obsolete since there is a generic version 140913
#############################################################################
#O \= ( < flag1 >, <flag2 > )
# Returns true if <flag1> and <flag2> represent the same flag in a
# coset geometry
#
##
#InstallOtherMethod( \=, [ IsFlagOfCosetGeometry, IsFlagOfCosetGeometry ],
# function( flag1, flag2 )
# local result, cg1, cg2;
# cg1:=flag1!.geo;
# cg2:=flag2!.geo;
# if cg1 <> cg2 then
# Print("#I the two flags are not in the same incidence structure!\n");
# return false;
# fi;
# result:= (Set(flag1!.types)=Set(flag2!.types)) and (Set(flag1!.els)=Set(flag2!.els));
# return result;
# end );
#
# 140913 PhC
#############################################################################
#O \= ( < cg1 >, <cg2 > )
# Returns true if <cg1> and <cg2> are the same coset geometry
#
##
InstallOtherMethod( \=, [ IsCosetGeometry, IsCosetGeometry
],
function( cg1, cg2 )
local result, g1, g2, pabs1, pabs2;
result:=(cg1!.group = cg2!.group);
result:=result and (cg1!.parabolics = cg2!.parabolics);
return result;
end );
#
# CHECKED 140913 PhC
##########################################################################
#O ElementsOfIncidenceStructure
#
# Gives elements of type <j> in coset geometry <cg>
##
InstallMethod( ElementsOfIncidenceStructure, [IsCosetGeometry, IsPosInt],
function( cg, j )
local vars;
if j > Rank(cg) then
Error("<cg> has no elements of type <j>.\n");
fi;
vars := rec( geometry := cg, type := j );
Objectify(
NewType( ElementsCollFamily, IsElementsOfIncidenceStructure and
IsElementsOfCosetGeometry and
IsElementsOfCosetGeometryRep),
vars );
return vars;
end );
# CHECKED 140913 PhC
#############################################################################
#O ElementsOfIncidenceStructure( <cg> )
# returns all the elements of the coset geometry <cg>
##
InstallMethod( ElementsOfIncidenceStructure,
"for a coset geometry",
[IsCosetGeometry],
function( cg )
return Objectify(
NewType( ElementsCollFamily, IsAllElementsOfCosetGeometry and IsAllElementsOfCosetGeometryRep ),
rec( geometry := cg,
type := "all") #added this field in analogy with the collection that contains all subspaces of a vector space.
);
end);
# CHECKED 140913 PhC
#############################################################################
#O RandomElement( <cg> )
# returns a random element of random type in the given coset geometry
# <cg>
##
InstallMethod( RandomElement,
"for a coset geometry",
[IsCosetGeometry],
function(cg)
local i;
i:=Random(TypesOfElementsOfIncidenceStructure(cg));
return Random(ElementsOfIncidenceStructure(cg,i));
end );
# CHECKED 140913 PhC
#############################################################################
#O RandomChamber( <cg> )
# returns a random chamber in the given coset geometry
# <cg>
##
InstallOtherMethod( RandomChamber,
"for a coset geometry",
[IsCosetGeometry],
function(cg)
local ele, els;
ele:=Random(cg!.group);
els:=OnTuples(StandardFlagOfCosetGeometry(cg)!.els,ele);
return FlagOfIncidenceStructure(cg,els);
end );
# CHECKED 140913 PhC
#############################################################################
#O RandomFlag( <cg> )
# returns a random flag in the given coset geometry
# <cg>
##
InstallOtherMethod( RandomFlag,
"for a coset geometry",
[IsCosetGeometry],
function(cg)
local type, flag;
type:=Random(Combinations(TypesOfElementsOfIncidenceStructure(cg)));
flag:=RandomChamber(cg)!.els{type};
return FlagOfIncidenceStructure(cg,flag);
end );
# 140806 Not needed! Already defined generically
#############################################################################
#O ElementsOfFlag( <flag> )
# returns elements of a flag
#
##
#InstallMethod( ElementsOfFlag,
# "for a coset geometry flag",
# [IsFlagOfCosetGeometry],
# function(flag)
# return flag!.els;
# end );
#
#############################################################################
#O Random( <alleleofcg> )
# returns a random element a coset geometry
#
##
InstallMethod( Random,
"for element category of coset geometry",
[IsAllElementsOfCosetGeometry],
function(allele)
return RandomElement(allele!.geometry);
end );
#
###########################################################################
#O Size
#
# Returns the number of elements in the object <vs> of type ElementsOfCosetGeometry
##
InstallMethod(Size, [IsElementsOfCosetGeometry],
function( vs )
local cg;
cg := vs!.geometry;
return IndexNC(cg!.group, cg!.parabolics[vs!.type]);
end );
#
###########################################################################
#O Wrap
#
# Make an object from an element of a coset geometry
##
InstallMethod( Wrap, "for a coset geometry and an object (coset)",
[IsCosetGeometry, IsPosInt, IsObject],
function( geo, type, o )
local w;
w := rec( geo := geo, type := type, obj := o );
Objectify( NewType( ElementsOfIncidenceStructureFamily,
IsElementOfCosetGeometryRep and IsElementOfCosetGeometry ), w );
return w;
end );
#
##########################################################################
#O Iterator
#
# Iterator
##
InstallMethod(Iterator, "for elements of a coset geometry",
[IsElementsOfCosetGeometry],
function( vs )
local cg, j, g, h, iter, newiter;
cg := vs!.geometry;
j := vs!.type;
g := cg!.group;
h := cg!.parabolics[j];
iter := Iterator(RightCosets(g,h));
## Wrap 'em up
newiter := IteratorByFunctions( rec(
NextIterator := function( i )
local x;
x := NextIterator(i!.S);
return Wrap(cg, j, x);
end,
IsDoneIterator := function(i)
return IsDoneIterator(i!.S);
end,
ShallowCopy := function(i)
return rec( S := ShallowCopy(i!.S) );
end,
S := iter ));
return newiter;
end );
# CHECKED 06/09/11 PhC
#############################################################################
#O IsIncident( <ele1>, <ele2> )
#
# for elements ele1 and ele2 from the same coset geometry. Checks nonempty
# intersection unless types are the same, then only EQUAL elements can be
# incident.
##
InstallMethod( IsIncident,
"for elements of a coset geometry",
[IsElementOfCosetGeometry, IsElementOfCosetGeometry],
function( x, y )
local vx, vy, tx, ty, g, h, k;
if x!.geo <> y!.geo then Error("The two elements do not belong to the same incidence structure.\n"); fi;
vx := x!.obj; vy := y!.obj;
tx := x!.type; ty := y!.type;
if (tx = ty) then
if vx=vy then
return true;
else # There was a problem here when making the incidence graph, because of loops.
return false;
fi;
fi;
## Let Ha and Kb be two right cosets, and let g=ab^-1.
## Then Ha and Kb intersect if and only if g is an element of the double
## coset HK.
g := Representative(vx) * Representative(vy)^-1;
h := ActingDomain(vx);
k := ActingDomain(vy);
return g in DoubleCoset(h, One(h), k);
end );
###################################################
## Extract components from Coset geometry object
##
##
###################################################
# CHECKED 28/11/11 PhC
#############################################################################
#O ParabolicSubgroups ( <cg> )
# for a coset geometry <cg> returns the defining parabolic subgroups.
##
InstallMethod( ParabolicSubgroups, "for coset geometries",
[ IsCosetGeometry ], cg -> cg!.parabolics );
# CHECKED 28/11/11 PhC
#############################################################################
#O AmbientGroup ( <cg> )
# for a coset geometry <cg> returns the defining group.
##
InstallMethod( AmbientGroup, "for coset geometries",
[ IsCosetGeometry ], cg -> cg!.group );
# CHECKED 28/11/11 PhC
#############################################################################
#O BorelSubgroup ( <cg> )
# for a coset geometry <cg> returns the Borel subgroup. This is the
# intersection of the parabolic subgroups.
##
InstallMethod( BorelSubgroup, "for coset geometries",
[ IsCosetGeometry ], cg -> Intersection(cg!.parabolics) );
##############################################################
## Investigate some properties for Coset geometries
##
##
##############################################################
# CHECKED 18/3/2014 PhC
#############################################################################
#O IsFlagTransitiveGeometry
#
# Checks whether a Coset incidence structure is flag transitive
##
InstallMethod( IsFlagTransitiveGeometry, "for coset geometries",
[ IsCosetGeometry ],
function( cg )
## From Buekenhout's chapter in the "Handbook of Incidence Geometry"
## a coset geometry with parabolics {Gi} is flag-transitive if
## (G1 G2) \cap (G1 G3) \cap ... \cap (G1 Gn) = G1( G2 \cap...\cap Gn),
## (G2 G3) \cap ...\cap (G2 Gn) = G2( G3 \cap ... \cap Gn),
## ..., (G(n-2) G(n-1)) \cap (G(n-2) G(n)) = G(n-2)( G(n-1)\cap Gn )
## For each case, we have that the right-hand side is contained in
## the left-hand side, so it suffices to compute sizes of the entities
## in each equation.
local g, parabolics, gi, gj, orb, trans, rank,
left, int, newint, act, right, i, j;
g := cg!.group;
parabolics := cg!.parabolics;
rank := Size(parabolics);
## Note that |G1( G2 \cap...\cap Gn)| = |( G2 \cap...\cap Gn) : (G1\cap G2 \cap...\cap Gn)|.
## So to efficiently compute the right hand side, we do the "shortest one" first
## and iterate. To compute the left hand sides is much more difficult.
## For the first case, we need to compute the intersections of the orbits
## of G2, G3, ..., Gn on the trivial coset G1 in the action of G on
## the right cosets of G1.
## Start from the end, where the number of intersections are shortest
## and go upwards.
int := Intersection( parabolics[rank - 1], parabolics[rank] );
for i in [2..rank-1] do
# compute right-hand side
newint := Intersection( int, parabolics[rank - i] );
right := Size(int) / Size(newint);
# compute left-hand side
gi := parabolics[rank-i];
act := FactorCosetAction(g, gi);
orb := [1..Index(g,gi)];
for j in [rank-i+1..rank] do
gj := Image(act, parabolics[j]);
orb := Intersection(orb, Orbit(gj, 1));
od;
left := Size(orb);
if left > right then
return false;
fi;
int := newint;
od;
return true;
end );
# CHECKED 24/3/2014 PhC
#############################################################################
#O IsFirmGeometry
#
# Checks whether a coset geometry is firm
##
InstallMethod( IsFirmGeometry, "for coset geometries",
[ IsCosetGeometry ],
function( cg )
local parabolics, pis, without_i, int, borel, i;
parabolics := ParabolicSubgroups( cg );
pis := [];
for i in [1..Size(parabolics)] do
without_i := Difference( [1..Size(parabolics)], [ i ] );
int := Intersection( parabolics{without_i} );
Add(pis, int);
od;
if HasIsFlagTransitiveGeometry( cg ) and IsFlagTransitiveGeometry( cg ) then
## In this case, the coset geometry is firm
## if and only if the borel subgroup is not
## contained in any Pi = \cap{Hj: j<>i}.
borel := BorelSubgroup( cg );
return not ForAny(pis, t -> IsSubset(borel, t));
else
## In this case, the coset geometry is firm
## if and only if for every i, Pi is not contained in Hi
## (where the Hi's are the parabolics).
return not ForAny([1..Size(parabolics)], i ->
IsSubset(parabolics[i], pis[i]) );
fi;
end );
# CHECKED 24/3/2014 PhC
#############################################################################
#O IsThinGeometry
#
# Checks whether a coset geometry is thin
##
InstallMethod( IsThinGeometry, "for coset geometries",
[ IsCosetGeometry ],
function( cg )
local parabolics, pis, without_i, int, borel, i, result;
parabolics := ParabolicSubgroups( cg );
pis := [];
for i in [1..Size(parabolics)] do
without_i := Difference( [1..Size(parabolics)], [ i ] );
int := Intersection( parabolics{without_i} );
Add(pis, int);
od;
result:= ForAll(pis, psg -> Index(psg, BorelSubgroup(cg))=2 );
if result then
Setter(IsThickGeometry)(cg,false);
Setter(IsFirmGeometry)(cg, true);
fi;
return result;
end );
# CHECKED 27/3/2014 PhC
#############################################################################
#O IsThickGeometry
#
# Checks whether a coset geometry is thick
##
InstallMethod( IsThickGeometry, "for coset geometries",
[ IsCosetGeometry ],
function( cg )
local parabolics, pis, without_i, int, borel, i, result;
parabolics := ParabolicSubgroups( cg );
pis := [];
for i in [1..Size(parabolics)] do
without_i := Difference( [1..Size(parabolics)], [ i ] );
int := Intersection( parabolics{without_i} );
Add(pis, int);
od;
result:= ForAll([1..Size(parabolics)], i ->
Index(pis[i], BorelSubgroup(cg))>2 );
if result then
Setter(IsThinGeometry)(cg,false);
Setter(IsFirmGeometry)(cg,true);
fi;
return result;
end );
# CHECKED 06/09/11 PhC
#############################################################################
#O IsConnected( <cg> )
# Returns true iff the coset geometry cg is connected
##
InstallMethod( IsConnected,
"for coset geometries",
[ IsCosetGeometry ],
function( cg )
## A coset geometry is connected if and only if the
## parabolics generate the group.
local parabolics, g, gens;
g := cg!.group;
parabolics := ParabolicSubgroups( cg );
gens := Union( List(parabolics, GeneratorsOfGroup) );
return Group( gens ) = g;
end );
# CHECKED 07/02/12 PhC
#############################################################################
#O IsResiduallyConnected
#
# Returns true iff the coset geometry is residually connected
##
InstallMethod( IsResiduallyConnected, "for coset geometries",
[ IsCosetGeometry ],
function( cg )
## A coset geometry is residually connected if and only
## if for every subset J of the types I with |I-J|>1, we have
## \cap{Hj: j in J} = < \cap{Hi: i in J\cup {j}} : j in I-J >
local rank, typeset, typesubsets, k, lhs, rhs, subset, test, int, iter;
rank:=Rank(cg);
typesubsets:=[];
typeset:=TypesOfElementsOfIncidenceStructure(cg);
for k in [1..rank-2] do
Append(typesubsets, Combinations(typeset, k));
od;
iter := Iterator(typesubsets);
test:=true;
while not IsDoneIterator(iter) and test do
subset:=NextIterator(iter);
lhs := Size(Intersection(ParabolicSubgroups(cg){subset}));
rhs := [];
int:=Intersection(ParabolicSubgroups(cg){subset});
for k in Difference(typeset,subset) do
Add(rhs, Intersection(int,ParabolicSubgroups(cg)[k]));
od;
rhs:=Size(SubgroupNC(cg!.group,Union(rhs)));
if lhs<>rhs then test:=false; fi;
od;
return test;
end );
# CHECKED 24/3/2014 PhC
#############################################################################
#O StandardFlagOfCosetGeometry(<cg>)
#
# Returns standard chamber of a coset geometry <cg>.
##
InstallMethod( StandardFlagOfCosetGeometry, "for coset geometries",
[ IsCosetGeometry ],
function(cg)
local parabolics, flag;
parabolics:=cg!.parabolics;
flag:=List([1..Size(parabolics)], i -> Wrap(cg,i,RightCoset(parabolics[i],Identity(cg!.group))));
return FlagOfIncidenceStructure(cg,flag);
end );
# CHECKED 27/3/2014
#############################################################################
# FlagToStandardFlag
#
#
##
InstallMethod( FlagToStandardFlag, "for coset geometries",
[ IsCosetGeometry, IsFlagOfCosetGeometry ],
function( cg, flag )
## This operation returns an element g which maps
## "flag" to the standard flag consisting of trivial
## cosets of parabolic subgroups.
## Suppose [G(1) a(1), ..., G(n) a(n)] is a flag.
## Let x(1) = a(1)^-1 and then define x(i) inductively
## by the condition
## x(i)^-1 in G(1) \cap G(2)\cap ... \cap G(i-1)\cap G(i)a(i)x(1)x(2)...x(i-1)
## Then g = x(1)x(2)...x(n) maps our flag to [G(1),...,G(n)].
local g, x, reps, pabs, i, int, ginv;
# initialise
flag:=flag!.els;
reps := List(flag, t -> Representative(t!.obj) );
pabs := ParabolicSubgroups( cg ){ List(flag, t->t!.type) };
g := reps[1]^-1;
int := pabs[1];
for i in [2..Size(flag)] do
if i > 2 then
int := Intersection(int, pabs[i-1]);
fi;
ginv := g^-1;
repeat
x := PseudoRandom(int);
until x * ginv in flag[i]!.obj;
g := g * x^-1;
od;
return g;
end );
# CHECKED 27/3/2014 PhC
#############################################################################
# CanonicalResidueOfFlag
#
#
##
InstallMethod( CanonicalResidueOfFlag, "for coset geometries",
[ IsCosetGeometry, IsFlagOfCosetGeometry ],
function( cg, flag )
## return coset geometry which is isomorphic to residue of the given flag
## have non-empty intersection with all of the elements
## of flag
local typesflag, types, parabolics, i, resg, respabs;
typesflag := Set(flag!.types);
# if IsFlagTransitiveGeometry( cg ) then
# typesflag := Set(flag, t->t!.type);
if IsEmpty( typesflag ) then
return cg;
fi;
types := Difference( TypesOfElementsOfIncidenceStructure(cg), typesflag);
if IsEmpty( types ) then
return CosetGeometry( Group(()), [] );
fi;
parabolics := ParabolicSubgroups( cg ){types};;
resg := Intersection( ParabolicSubgroups( cg ){typesflag} );
respabs := [];
for i in parabolics do
Add( respabs, Intersection( resg, i ) );
od;
# else
# Error("not implemented for not flag-transitive geometries.\n");
# fi;
return CosetGeometry( resg, respabs );
end );
# CHECKED 140913 PhC
#############################################################################
#O ResidueOfFlag
#
# Computes the residue of the given flag in AmbientGeometry(flag)
##
InstallOtherMethod( ResidueOfFlag, "for coset geometries",
[ IsFlagOfCosetGeometry ],
function( flag )
## return all right cosets of parabolics which
## have non-empty intersection with all of the elements
## of flag
local cg, typesflag, types, r, parabolics, i, resg, respabs;
cg:=flag!.geo;
if IsFlagTransitiveGeometry( cg ) then
typesflag := Set(flag!.types);
if IsEmpty( typesflag ) then
return cg;
fi;
types := Difference( TypesOfElementsOfIncidenceStructure(cg), typesflag);
if IsEmpty( types ) then
return CosetGeometry( Group(()), [] );
fi;
parabolics := ParabolicSubgroups( cg ){types};;
resg := Intersection( ParabolicSubgroups( cg ){typesflag} );
respabs := [];
for i in parabolics do
Add( respabs, Intersection( resg, i ) );
od;
## up to this point, we have the residue of the standard flag,
## and so we need to map back to our original flag
## The mathematics here needs checking/testing!
r := FlagToStandardFlag( cg, flag );
r:=Inverse(r);
respabs := List(respabs, t -> t^r);
resg := resg^r;
else
Error("not implemented for not flag-transitive geometries.\n");
fi;
return CosetGeometry( resg, respabs );
end );
#
#############################################################################
# IncidenceGraph
#
#
##
InstallMethod( IncidenceGraph, [ IsCosetGeometry and IsHandledByNiceMonomorphism ],
function( geo )
## This operation returns the multiparitite incidence graph
## associated to "geo", and it also sets a mutable attribute
## IncidenceGraphAttr which can be called hence.
## Here we have a speedup from the NiceMonomorphism
local fastgeo, gamma, hom;
#the following is obsolete: grape is a NeededOtherPackage (PackageInfo.g)
#if not "grape" in RecNames(GAPInfo.PackagesLoaded) then
# Error("You must load the Grape package in order to use IncidenceGraph.\n");
#fi;
if FINING.Fast then
Print("#I Using NiceMonomorphism...\n");
hom := NiceMonomorphism(geo!.group);
fastgeo:=CosetGeometry(NiceObject(geo!.group), List(geo!.parabolics, h -> Image(hom, h)));
gamma := IncidenceGraph( fastgeo );
else
gamma := IncidenceGraph( geo );
fi;
Setter( IncidenceGraphAttr )( geo, gamma );
return gamma;
end );
#
#############################################################################
# IncidenceGraph
#
#
##
InstallMethod( IncidenceGraph, [ IsCosetGeometry ],
function( geo )
## This operation returns the multiparitite incidence graph
## associated to "geo", and it also sets a mutable attribute
## IncidenceGraphAttr which can be called hence.
## Slower version
local g, vars, gamma, allvars, reps, hom1, hom2, im1, im2, d, em1, em2, gens, newgens, diagonal;
#if not "grape" in RecNames(GAPInfo.PackagesLoaded) then
# Error("You must load the Grape package.\n");
#fi;
g := geo!.group;
if Size(ParabolicSubgroups(geo)) = 2 then
hom1 := FactorCosetAction(g, ParabolicSubgroups(geo)[1]);
hom2 := FactorCosetAction(g, ParabolicSubgroups(geo)[2]);
im1 := Image(hom1);
im2 := Image(hom2);
d := DirectProduct(im1,im2);
em1 := Embedding(d,1);
em2 := Embedding(d,2);
gens := GeneratorsOfGroup(g);
newgens := List(gens, x -> Image(em1,Image(hom1,x)) * Image(em2,Image(hom2,x)));
diagonal:=Group(newgens);
gamma := NullGraph(diagonal);
## [A,B]
AddEdgeOrbit(gamma, [1, DegreeAction(im1)+1]);
AddEdgeOrbit(gamma, [DegreeAction(im1)+1, 1]);
else
allvars := List( [1..Size(TypesOfElementsOfIncidenceStructure(geo))],
i -> ElementsOfIncidenceStructure(geo, i) );
vars := Concatenation( List(allvars, AsList) );
gamma := Graph( g, vars, OnCosetGeometryElement,
function(x,y) return IsIncident(x,y); end, true);
fi;
Setter( IncidenceGraphAttr )( geo, gamma );
return gamma;
end );
#
################################################################
# O AutGroupIncidenceStructureWithNauty( <inc> )
#
# Computes automorphism group of incidence structure via Nauty
# Should first check whether <inc> has an incidence graph
# At the moment this works for coset geometries
#
# The resulting group is a permutation group and its action on
# the original incidence structure is not explicitly given
#
InstallMethod( AutGroupIncidenceStructureWithNauty,
[ IsCosetGeometry ],
function( inc )
local colorclasses, sum, i, incgrph;
# automorphisms should fix the type set. This is done by using
# colorClasses in Nauty. We use the fact that when defining the
# incidence graph, the vertices are an enumeration of all elements
# of type 1, followed by alle elements of type 2, ...
# So the color classes are easy to give.
#
colorclasses:=[];
sum:=0;
for i in TypesOfElementsOfIncidenceStructure(inc) do
Add(colorclasses,
[sum+1..sum+NrElementsOfIncidenceStructure(inc,i)]);
sum:=sum+NrElementsOfIncidenceStructure(inc,i);
od;
incgrph:=IncidenceGraph(inc);
return(AutGroupGraph(incgrph, colorclasses));
end);
#
################################################################
# O CorGroupIncidenceStructureWithNauty( <inc> )
#
# Computes correlation group of incidence structure via Nauty
# Should first check whether <inc> has an incidence graph
# At the moment this works for coset geometries
#
InstallMethod( CorGroupIncidenceStructureWithNauty,
[ IsCosetGeometry ],
function( inc )
return(AutGroupGraph(IncidenceGraph(inc)));
end );
#
################################################################
# O IsIsomorphicIncidenceStructureWithNauty( <inc1>, <inc2> )
#
# Computes whether <inc1> and <inc2> are isomorphic incidence
# structures, using nauty on coloured graphs.
#
InstallMethod( IsIsomorphicIncidenceStructureWithNauty,
[ IsCosetGeometry, IsCosetGeometry ],
function( inc1, inc2 )
local colorclasses1, colorclasses2, sum, i, incgrph1, incgrph2;
colorclasses1:=[];
sum:=0;
for i in TypesOfElementsOfIncidenceStructure(inc1) do
Add(colorclasses1,
[sum+1..sum+NrElementsOfIncidenceStructure(inc1,i)]);
sum:=sum+NrElementsOfIncidenceStructure(inc1,i);
od;
colorclasses2:=[];
sum:=0;
for i in TypesOfElementsOfIncidenceStructure(inc2) do
Add(colorclasses2,
[sum+1..sum+NrElementsOfIncidenceStructure(inc2,i)]);
sum:=sum+NrElementsOfIncidenceStructure(inc2,i);
od;
if colorclasses2 <> colorclasses1 then
return false;
fi;
incgrph1:=IncidenceGraph(inc1);
incgrph2:=IncidenceGraph(inc2);
return(IsIsomorphicGraph(rec(graph:=incgrph1, colourClasses:=colorclasses1), rec(graph:=incgrph2, colourClasses:=colorclasses1)));
end);
#############################################################################
# View/Print methods
#############################################################################
InstallMethod( ViewObj, "for diagrams",
[ IsDiagram and IsDiagramRep ],
function( diag )
Print("< Diagram >");
end );
InstallMethod( ViewObj, "for diagram with geometry",
[ IsDiagram and IsDiagramRep and HasGeometryOfDiagram],
function( diag )
local geo;
geo := GeometryOfDiagram( diag );
Print("< Diagram of ");
ViewObj(geo);
Print(" >");
end );
InstallMethod( ViewObj, "for coset geometry",
[ IsCosetGeometry and IsCosetGeometryRep ],
function( geo )
Print("CosetGeometry( ", geo!.group, " )");
end );
InstallMethod( ViewObj, "for flag of coset geometry",
[ IsFlagOfCosetGeometry ],
function( flag )
Print("<Flag of coset geometry < ", flag!.geo, " >>");
end );
InstallMethod( PrintObj, "for flag of coset geometry",
[ IsFlagOfCosetGeometry ],
function( flag )
Print("Flag of coset geometry ", flag!.geo, " with elements ", flag!.els );
end );
InstallMethod( PrintObj, "for coset geometry",
[ IsCosetGeometry and IsCosetGeometryRep ],
function( geo )
Print("CosetGeometry( ", geo!.group, " , ", geo!.parabolics , " )");
end );
InstallMethod( ViewObj, "for all elements of coset geometry",
[ IsElementsOfCosetGeometry and IsElementsOfCosetGeometryRep ],
function( vs )
Print("<elements of type ", vs!.type," of ");
ViewObj(vs!.geometry);
Print(">");
end );
InstallMethod( PrintObj, "for coset geometry", [ IsElementsOfCosetGeometry and
IsElementsOfCosetGeometryRep ],
function( vs )
Print("ElementsOfIncidenceStructure( ",vs!.geometry," , ",vs!.type,")");
end );
InstallMethod( ViewObj, "for coset geometry", [ IsElementOfCosetGeometry ],
function( v )
Print("<element of type ", v!.type," of ");
ViewObj(v!.geo);
Print(">");
end );
InstallMethod( PrintObj, "for element of coset geometry", [ IsElementOfCosetGeometry ],
function( v )
Print(v!.obj);
end );
InstallMethod( ViewObj, "for vertex of diagram", [ IsVertexOfDiagram and IsVertexOfDiagramRep ],
function( v )
Print("Diagram vertex(",v!.type,")");
end );
InstallMethod( PrintObj, "for vertex of diagram", [ IsVertexOfDiagram and IsVertexOfDiagramRep ],
function( v )
Print("Vertex(",v!.type,")");
end );
InstallMethod( ViewObj, "for edge of diagram", [ IsEdgeOfDiagram and IsEdgeOfDiagramRep ],
function( e )
Print("Diagram edge(",e!.edge,")");
end );
InstallMethod( PrintObj, "for edge of diagram", [ IsEdgeOfDiagram and IsEdgeOfDiagramRep ],
function( e )
Print("Edge(",e!.edge,")");
end );
InstallMethod( ViewObj, "for rank 2 residue", [ IsRank2Residue and IsRank2ResidueRep ],
function( e )
Print("Rank 2 residue of type ",e!.edge," of ", e!.geo);
end );
InstallMethod( PrintObj, "for rank 2 residue", [ IsRank2Residue and IsRank2ResidueRep ],
function( e )
Print("Rank2Residue(",e!.edge,") of ", e!.geo);
end );
#############################################################################
# Methods for diagrams of geometries.
#############################################################################
#
#############################################################################
#O \= ( < vertex1 >, <vertex2 > )
# Returns true if <vertex1> and <vertex2> represent the same type in a
# diagram.
#
##
InstallMethod( \=, [ IsVertexOfDiagram and IsVertexOfDiagramRep,
IsVertexOfDiagram and IsVertexOfDiagramRep ],
function( u, v )
return u!.type = v!.type;
end );
#
#############################################################################
#O \= ( < edge1 >, < edge 2 > )
# Equality of edges in a diagram.
#
##
InstallMethod( \=, [ IsEdgeOfDiagram and IsEdgeOfDiagramRep,
IsEdgeOfDiagram and IsEdgeOfDiagramRep ],
function( u, v )
return u!.edge = v!.edge;
end );
# CHECKED 140913 PhC
#############################################################################
#F DiagramOfGeometry
#
#
##
InstallMethod( DiagramOfGeometry, "for flag-transitive coset geometry", [IsCosetGeometry],
function( cg )
local rank2residues, vertices, types, x, v, edges, parameters, e, diagram, parabolics;
##########Removed on 20/03/2012 by PhC because FT test is time-consuming.
# The documentation mentions this
#
# if not IsFlagTransitiveGeometry(cg) then
# Error("usage DiagramOfGeometry: only works for flag-transitive geometries.\n");
# fi;
rank2residues := Rank2Residues( cg );
Perform(rank2residues, MakeRank2Residue);
parabolics := cg!.parabolics;
vertices := [];
types := TypesOfElementsOfIncidenceStructure( cg );
## Wrapping up...
for x in types do
v := rec( type := x );
Objectify( NewType( VertexOfDiagramFamily, IsVertexOfDiagram and
IsVertexOfDiagramRep ), v);
Add( vertices, v );
od;
edges := [];
## Wrapping up...
for x in rank2residues do
parameters := Rank2Parameters( x!.residuegeometry );
if not parameters[1] = [2,2,2] then
e := rec( edge := x!.edge );
Objectify( NewType( EdgeOfDiagramFamily,
IsEdgeOfDiagram and IsEdgeOfDiagramRep ), e);
SetParametersEdge(e, parameters[1]);
if not HasOrderVertex( vertices[x!.edge[1]] ) then
SetOrderVertex( vertices[x!.edge[1]], parameters[2][1] );
SetNrElementsVertex( vertices[x!.edge[1]], IndexNC(cg!.group, parabolics[x!.edge[1]]) );
SetStabiliserVertex( vertices[x!.edge[1]], parabolics[x!.edge[1]] );
fi;
if not HasOrderVertex( vertices[x!.edge[2]] ) then
SetOrderVertex( vertices[x!.edge[2]], parameters[3][1] );
SetNrElementsVertex( vertices[x!.edge[2]], IndexNC(cg!.group, parabolics[x!.edge[2]]) );
SetStabiliserVertex( vertices[x!.edge[2]], parabolics[x!.edge[2]] );
fi;
Add( edges, e );
fi;
od;
diagram := rec( vertices := vertices, edges := edges );;
Objectify( NewType( DiagramFamily, IsDiagram and IsDiagramRep ), diagram);
SetGeometryOfDiagram( diagram, cg );
return diagram;
end );
# CHECKED 24/3/2014 PhC
#############################################################################
#O DrawDiagram
#
#
##
InstallGlobalFunction( DrawDiagram,
function( arg )
local diagram, filename, vertices, edges, longstring, v, e, vertexverbosity, edgeverbosity, arglen;
vertexverbosity:=0; #default orders and nr of elements
edgeverbosity:=1; #default shorthand for generalized n-gons
arglen:=Length(arg);
############################# Checking arguments and initializing
if not(arglen in [2,3,4]) then
Error("usage DrawDiagram: must have at least 2 and at most 4 arguments.\n");
elif not(IsDiagram(arg[1]) and IsString(arg[2])) then
Error("usage DrawDiagram: first argument must be a diagram, second argument must be a filename string.\n");
fi;
diagram:=arg[1];
filename:=arg[2];
vertices := diagram!.vertices;
edges := diagram!.edges;
if arglen > 2 then
if IsPosInt(arg[3]) or IsZero(arg[3]) then
vertexverbosity:=arg[3];
else
Error("usage DrawDiagram: third argument must be a vertex verbosity natural number.\n");
fi;
if (arglen = 4) then
if (IsPosInt(arg[4]) or IsZero(arg[4])) then
edgeverbosity:=arg[4];
else
Error("Usage DrawDiagram: fourth argument must be an edge verbosity natural number.\n");
fi;
fi;
fi;
##################Done checking!
longstring := "digraph DIAGRAM{\n rankdir = LR;\n";
for v in vertices do
longstring:=Concatenation(longstring, "subgraph cluster", String(v!.type), " {\n");
longstring:=Concatenation(longstring, "color=transparent\n");
longstring:=Concatenation(longstring, "node [shape=circle, width=0.1]; ", String(v!.type), " [label=\"\"];\n");
longstring:=Concatenation(longstring, "labelloc=b\n");
if vertexverbosity =2 then
longstring:=Concatenation(longstring, "label=\"", "\";\n}\n");
elif vertexverbosity =1 then
longstring:=Concatenation(longstring, "label=\"", String(OrderVertex(v)),
"\";\n}\n");
else
longstring:=Concatenation(longstring, "label=\"", String(OrderVertex(v)), "\\n", String(NrElementsVertex(v)),
"\";\n}\n");
fi;
od;
for e in edges do
longstring:=Concatenation(longstring, String(e!.edge[1]), " -> ", String(e!.edge[2]));
if edgeverbosity = 2 then #no label, i.e. basic diagram
longstring:=Concatenation(longstring, " [label = \"", "\", arrowhead = none ];\n");
elif edgeverbosity = 1 and Size(Set(ParametersEdge(e)))= 1 then #shorthand generalized n-gons
longstring:=Concatenation(longstring, " [label = \"", String(ParametersEdge(e)[1]), "\", arrowhead = none ];\n");
else
longstring:=Concatenation(longstring, " [label = \"", String(ParametersEdge(e)[2]), " ",
String(ParametersEdge(e)[1]), " ",
String(ParametersEdge(e)[3]), "\", arrowhead = none ];\n");
fi;
od;
longstring:=Concatenation(longstring, "}\n");
PrintTo( Concatenation(filename, ".dot") , longstring );
######## Checking the availability of GraphViz dot in path...
if Whereisdot() then
Exec( Concatenation("dot -Tps ", filename, ".dot -o ", filename, ".ps") );
else
Info(InfoWarning, 1, "Package `FinInG': Only .dot file written for diagram.");
fi;
return;
end );
# CHECKED 25/3/2014 PhC
#############################################################################
#O DrawDiagramWithNeato
#
#
##
InstallGlobalFunction( DrawDiagramWithNeato,
function( arg )
local diagram, filename, vertices, edges, longstring, v, e, vertexverbosity, edgeverbosity, arglen;
vertexverbosity:=0; #default orders and nr of elements
edgeverbosity:=1; #default shorthand for generalized n-gons
arglen:=Length(arg);
############################# Checking arguments and initializing
if not(arglen in [2,3,4]) then
Error("usage DrawDiagram: must have at least 2 and at most 4 arguments.\n");
elif not(IsDiagram(arg[1]) and IsString(arg[2])) then
Error("usage DrawDiagram: first argument must be a diagram, second argument must be a filename string.\n");
fi;
diagram:=arg[1];
filename:=arg[2];
vertices := diagram!.vertices;
edges := diagram!.edges;
if arglen > 2 then
if IsPosInt(arg[3]) or IsZero(arg[3]) then
vertexverbosity:=arg[3];
else
Error("usage DrawDiagram: third argument must be a vertex verbosity natural number.\n");
fi;
if (arglen = 4) then
if (IsPosInt(arg[4]) or IsZero(arg[4])) then
edgeverbosity:=arg[4];
else
Error("Usage DrawDiagram: fourth argument must be an edge verbosity natural number.\n");
fi;
fi;
fi;
##################Done checking!
longstring := "digraph DIAGRAM{\n rankdir = LR;\n";
for v in vertices do
longstring:=Concatenation(longstring, "subgraph cluster", String(v!.type), " {\n");
longstring:=Concatenation(longstring, "color=transparent\n");
longstring:=Concatenation(longstring, "node [shape=circle, width=0.1]; ", String(v!.type), " [label=\"\"];\n");
longstring:=Concatenation(longstring, "labelloc=b\n");
if vertexverbosity =2 then
longstring:=Concatenation(longstring, "label=\"", "\";\n}\n");
elif vertexverbosity =1 then
longstring:=Concatenation(longstring, "label=\"", String(OrderVertex(v)),
"\";\n}\n");
else
longstring:=Concatenation(longstring, "label=\"", String(OrderVertex(v)), "\\n", String(NrElementsVertex(v)),
"\";\n}\n");
fi;
od;
for e in edges do
longstring:=Concatenation(longstring, String(e!.edge[1]), " -> ", String(e!.edge[2]));
if edgeverbosity = 2 then #no label, i.e. basic diagram
longstring:=Concatenation(longstring, " [label = \"", "\", arrowhead = none ];\n");
elif edgeverbosity = 1 and Size(Set(ParametersEdge(e)))= 1 then #shorthand generalized n-gons
longstring:=Concatenation(longstring, " [label = \"", String(ParametersEdge(e)[1]), "\", arrowhead = none ];\n");
else
longstring:=Concatenation(longstring, " [label = \"", String(ParametersEdge(e)[2]), " ",
String(ParametersEdge(e)[1]), " ",
String(ParametersEdge(e)[3]), "\", arrowhead = none ];\n");
fi;
od;
longstring:=Concatenation(longstring, "}\n");
PrintTo( Concatenation(filename, ".dot") , longstring );
######## Checking the availability of GraphViz dot in path...
if Whereisdot() then
Exec( Concatenation("neato -Tps ", filename, ".dot -o ", filename, ".ps") );
else
Info(InfoWarning, 1, "Package `FinInG': Only .dot file written for diagram.");
fi;
return;
end );
####################################
## Draw diagram using ASCII characters, mainly for Display
## Obsolete !
##
###################################
#
#############################################################################
#F Drawing_Diagram
# Left over from Bamberg times
#
##
InstallGlobalFunction( Drawing_Diagram,
function( verts, edges, way )
local mat, v, e, v1, v2, c1, c2, posvertices,
breadth, height, edges2, label, unit;
## The unit we use for the character size of an edge
unit := 3;
## First find dimensions of diagram
breadth := Maximum( List(way, t->t[2]) );
height := Maximum( List(way, t->t[1]) );
edges2 := List(edges, t -> [Position(verts, t!.edge[1]), Position(verts, t!.edge[2]), t] );;
# We now work out where to put the lines,
# and what type of lines they are
# 1: ---
# 2: |
# 3: /
# 4: \
mat := NullMat( (unit + 1)*(height - 1) + 1, (unit + 1) * (breadth - 1) + 1, Integers);
## put vertices in (-1)
posvertices := List( way, v ->
[ (unit + 1) * (v[1] - 1) + 1, (unit + 1) *(v[2] - 1) + 1] );
for v in posvertices do
mat[v[1]][v[2]] := -1;
od;
## put lines in
for e in edges2 do
v1 := posvertices[ e[1] ];
v2 := posvertices[ e[2] ];
## start at middle of edge
c1 := (v1[1]+v2[1])/2;
c2 := (v1[2]+v2[2])/2;
if HasResidueLabelForEdge( e[3] ) then
label := ResidueLabelForEdge( e[3] );
if label = "4" then
if v1[1] = v2[1] then
mat[c1]{[c2-1,c2,c2+1]} := [ "=", "=", "="];
elif v1[2] = v2[2] then
mat{[c1-1,c1,c1+1]}[c2] := ["||", "||", "||"];
elif (v1[1] - v2[1]) * (v1[2]-v2[2]) < 0 then
mat[c1+1][c2-1] := "//";
mat[c1][c2] := "//";
mat[c1-1][c2+1] := "//";
else
mat[c1-1][c2+1] := "\\\\";
mat[c1][c2] := "\\\\";
mat[c1+1][c2-1] := "\\\\";
fi;
elif label = "3" or label = "-" then
if v1[1] = v2[1] then
mat[c1]{[c2-1,c2,c2+1]} := [ "-", "-", "-"];
elif v1[2] = v2[2] then
mat{[c1-1,c1,c1+1]}[c2] := ["|", "|", "|"];
elif (v1[1] - v2[1]) * (v1[2]-v2[2]) < 0 then
mat[c1+1][c2-1] := "/";
mat[c1][c2] := "/";
mat[c1-1][c2+1] := "/";
else
mat[c1-1][c2-1] := "\\";
mat[c1][c2] := "\\";
mat[c1+1][c2+1] := "\\";
fi;
else
if v1[1] = v2[1] then
mat[c1]{[c2-1,c2,c2+1]} := ["-", label, "-"];
elif v1[2] = v2[2] then
mat{[c1-1,c1,c1+1]}[c2] := ["|", label, "|"];
elif (v1[1] - v2[1]) * (v1[2]-v2[2]) < 0 then
mat[c1+1][c2-1] := "/";
mat[c1][c2] := label;
mat[c1-1][c2+1] := "/";
else
mat[c1-1][c2+1] := "\\";
mat[c1][c2] := label;
mat[c1+1][c2-1] := "\\";
fi;
fi;
else
if v1[1] = v2[1] then
mat[c1]{[c2-1,c2,c2+1]} := [1,1,1];
elif v1[2] = v2[2] then
mat[c1][c2] := 2;
elif (v1[1] - v2[1]) * (v1[2]-v2[2]) < 0 then
mat[c1][c2] := 3;
else
mat[c1][c2] := 4;
fi;
fi;
od;
return mat;
end );
#############################################
## Display diagram using ASCII
##
##
#############################################
InstallMethod( Display, [ IsDiagram and IsDiagramRep ],
function( diag )
local way, verts, edges, breadth, height, i, j, mat;
way := diag!.drawing;
verts := diag!.vertices;
edges := diag!.edges;
mat := Drawing_Diagram( verts, edges, way );
for i in [1..NrRows(mat)] do
for j in [1..NrCols(mat)] do
if mat[i,j] = 0 then Print(" ");
# if IsOddInt(j) then Print( " " );
# else Print( " " );
# fi;
elif mat[i,j] = -1 then
Print( "o" );
elif mat[i,j] = 1 then
Print( "-" );
elif mat[i,j] = 2 then
Print( "|" );
elif mat[i,j] = 3 then
Print( " /" );
elif mat[i,j] = 4 then
Print( " \\" );
else
Print( mat[i,j] );
fi;
od;
Print("\n");
od;
return;
end );
####################################################
## Special diagrams
##
##
####################################################
#
#############################################################################
#F DiagramOfGeometry ( < projsp > )
#
#
##
InstallMethod( DiagramOfGeometry, "for a projective space", [ IsProjectiveSpace ],
function( geo )
local vertices, types, x, v, edges, newedges, e, way, diagram, q;
vertices := [];
types := TypesOfElementsOfIncidenceStructure( geo );
q := Size( geo!.basefield );
## Wrapping up...
for x in types do
v := rec( type := x );
Objectify( NewType( VertexOfDiagramFamily, IsVertexOfDiagram and
IsVertexOfDiagramRep ), v);
SetOrderVertex(v, q);
Add( vertices, v );
od;
edges := List([1..Size(types)-1], i -> vertices{[i,i+1]} );
newedges := [];
## Wrapping up...
for x in edges do
e := rec( edge := x );
Objectify( NewType( EdgeOfDiagramFamily,
IsEdgeOfDiagram and IsEdgeOfDiagramRep ), e);
SetResidueLabelForEdge( e, "3");
Add( newedges, e );
od;
## simple path diagram
way := List([1..Size(types)], i -> [1,i] );
diagram := rec( vertices := vertices, edges := newedges, drawing := way );;
Objectify( NewType( DiagramFamily, IsDiagram and IsDiagramRep ), diagram);
SetGeometryOfDiagram( diagram, geo );
return diagram;
end );
# CHECKED 140913
#############################################################################
#F Rk2GeoDiameter ( < cg > , < type >)
# Computes the point (type 1) or line (type 2) diamater of a rank 2 coset
# geometry.
##
InstallMethod( Rk2GeoDiameter, "for a coset geometry", [IsCosetGeometry,
IsPosInt],
function( cg, type ) # type in {1,2}
local parabs, d, g, gpchain;
if Rank(cg) > 2 then Error("usage Rk2GeoDiameter: this is only for rank 2 geometries.\n"); fi;
if IsZero(type) or type > 2 then
Error("usage Rk2GeoDiameter: the only possible types for a rank 2 coset geometry are 1 (points) and 2 (lines).\n");
fi;
Print("#I If this takes long, you might want to try Rank2Parameters ...\n");
parabs:=ParabolicSubgroups(cg);
g:=AmbientGroup(cg);
d:=0;
gpchain:=parabs[type];
while gpchain <> g do
d:=d+1;
gpchain:=Set(List(Cartesian(gpchain,parabs[((type + d) mod 2) + 1]), Product));
od;
return d;
end );
# CHECKED 140913
#############################################################################
#F Rk2GeoGonality ( < cg > )
# Return half the girth of the incidence graph of <cg>
##
InstallMethod( Rk2GeoGonality, "for a coset geometry", [IsCosetGeometry],
function( cg )
local params;
if Rank(cg) > 2 then Error("usage Rk2GeoGonaloty: this is only for rank 2 geometries.\n"); fi;
params:= Rank2Parameters(cg);
return params[1][1];
end );
#
#############################################################################
#O GeometryOfRank2Residue ( < rk2res > )
# Returns the geometry component of a rank 2 residue.
#
##
InstallMethod( GeometryOfRank2Residue, "for a rank 2 residue", [IsRank2Residue],
function( residue )
return residue!.residuegeometry;
end );
# CHECKED 17/03/2014 PhC
#############################################################################
#F Rank2Parameters ( <geo> )
#
# Computes all parameters of the rank 2 geometry <geo>
# Returns a list of length 3 with
# - [g, dp, dl] as first entry. That is a list with (half) the girth,
# the point- and the line diameter of the geometry.
# - [sp, np] as second entry. That is the point order and the number of points
# - [sl, nl] as third entry. That is the line order and number of lines.
#
# For the moment this only works for a coset geometry geo because
# IncidenceGraph is only inplemented for that kind of geometries and we also
# compute the number of elements as indices of parabolic subgroups.
#
##
InstallMethod( Rank2Parameters, "for a coset geometry of rank 2", [IsCosetGeometry],
function(geo)
local incgr, reps, g, dp, dl, sp, sl, np, nl, locinfo;
# ***** Check that the input is kosher ******
if Size(geo!.parabolics)<>2 then
Error("Usage Rank2Parameters: is ONLY for geometries of rank two!\n");
fi;
incgr:=IncidenceGraph(geo);
reps:=incgr!.representatives; #we assume the GRAPE graph has an element of each type in its 'representative' field. This is indeed the case when the geometry is flag-transitive.
locinfo:=LocalInfo(incgr,reps[1]); #from GRAPE
g:=locinfo!.localGirth / 2;
dp:=locinfo!.localDiameter;
sl:=locinfo!.localParameters[1][3]-1;
locinfo:=LocalInfo(incgr,reps[2]);
dl:=locinfo!.localDiameter;
sp:=locinfo!.localParameters[1][3]-1;
np:=IndexNC(geo!.group, geo!.parabolics[1]);
nl:=IndexNC(geo!.group, geo!.parabolics[2]);
return[[g,dp,dl], [sp,np], [sl,nl]];
end );
#############################################################################
# Methods for LT for elements of coset geometries.
# Are needed when you make incidence graph since GRAPE wants to
# order the elements.
#
# CHECKED PhC 110414
#############################################################################
InstallOtherMethod( \<,
[ IsElementOfCosetGeometry and IsElementOfCosetGeometryRep,
IsElementOfCosetGeometry and IsElementOfCosetGeometryRep ],
function( x, y )
if x!.type = y!.type then
return x!.obj < y!.obj;
else
return x!.type < y!.type;
fi;
end );
#
#############################################################################
#F DiagramOfGeometry ( < classpolsp > )
# produces the diagram of a classical polar space.
#
##
#method to compute the diagram of a cps. Maybe move to another file to make this
#file shorter?
InstallMethod( DiagramOfGeometry, [ IsClassicalPolarSpace ],
function( geo )
local types, v, e, way, diagram, s, t, vertices,
orders, x, edges, newedges, flavour;
vertices := [];
types := TypesOfElementsOfIncidenceStructure( geo );
s := Size( geo!.basefield );
for x in [1..Size(types)] do
v := rec( type := types[x] );
Objectify( NewType( VertexOfDiagramFamily, IsVertexOfDiagram and
IsVertexOfDiagramRep ), v);
if x < Size(types) then
SetOrderVertex(v, s);
fi;
Add( vertices, v );
od;
if HasPolarSpaceType( geo ) then
flavour := PolarSpaceType( geo );
if flavour = "symplectic" or flavour = "parabolic" then
t := s;
elif flavour = "elliptic" then
t := s^2;
elif flavour = "hyperbolic" then
t := 1;
elif flavour = "hermitian" then
if IsEvenInt( geo!.dimension ) then
t := Sqrt(s)^3;
else
t := Sqrt(s);
fi;
fi;
SetOrderVertex(vertices[Size(types)], t);
fi;
edges := List([1..Size(types)-1], i -> vertices{[i,i+1]} );
newedges := [];
for x in [1..Size(edges)] do
e := rec( edge := edges[x] );
Objectify( NewType( EdgeOfDiagramFamily,
IsEdgeOfDiagram and IsEdgeOfDiagramRep ), e);
if x < Size(edges) then
SetResidueLabelForEdge( e, "3");
else
SetResidueLabelForEdge( e, "4");
fi;
Add( newedges, e );
od;
way := List([1..Size(types)], i -> [1,i] );
diagram := rec( vertices := vertices, edges := newedges, drawing := way );;
Objectify( NewType( DiagramFamily, IsDiagram and IsDiagramRep ), diagram);
SetGeometryOfDiagram( diagram, geo );
return diagram;
end );
[ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet)
]
|
2026-04-02
|