GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
##
## HAPPRIME - poincare.gi
## Operations and Methods for Poincare Series
## Paul Smith
##
## Copyright (C) 2007-2008
## Paul Smith
## National University of Ireland Galway
##
## This file is part of HAPprime.
##
## HAPprime is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## HAPprime is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
##
## $Id: poincare.gi 314 2008-09-08 12:05:35Z pas $
##
#############################################################################
#####################################################################
## <#GAPDoc Label="PoincareSeriesLHS_manPoincare">
## <ManSection>
## <Attr Name="PoincareSeriesLHS" Arg="G"/>
##
## <Returns>
## Rational function
## </Returns>
## <Description>
## For a finite p-group <A>G</A>, this function calculates
## and returns a quotient of polynomials <M>f(x) = P(x)/Q(x)</M>
## (i.e. the Poincaré series) whose
## coefficient of <M>x^k</M> equals the rank of the vector space
## <M>H_k(G, \mathbb{F}_p)</M> for all <M>k</M> in the range <M>k=1</M> to
## <M>k=n</M>.
## <P/>
## This function computes a Lyndon-Hoschild-Serre spectral sequence for
## the &p;-group &G;. The last sheet of
## this sequence will have the same additive structure as the mod-<M>p</M>
## group cohomology ring of &G;, and thus the same Poincaré
## series, which is returned by this function.
## <P/>
## See Section <Ref Sect="ExPoincare"/> for an example and more description.
## </Description>
## </ManSection>
## <#/GAPDoc>
#####################################################################
InstallMethod(PoincareSeriesLHS,
"generic method",
[IsGroup],
function(G)
####
#### Added by Graham Ellis (22/12/2008)
if SSortedList(Factors(Order(G)))<>[2] then
Print("This function is currently implemented only for 2-groups.\n");
return fail;
fi;
####
####
return HilbertPoincareSeries(LHSSpectralSequenceLastSheet(G));
end);
#####################################################################
#####################################################################
## <#GAPDoc Label="PoincareSeriesAutoMem_DTmanPoincare">
## <ManSection>
## <Oper Name="PoincareSeriesAutoMem" Arg="G [, n]"/>
##
## <Returns>
## Rational function
## </Returns>
## <Description>
## For a finite p-group <A>G</A>, this function calculates
## and returns a quotient of polynomials <M>f(x) = P(x)/Q(x)</M>
## (i.e. the Poincaré series) whose
## coefficient of <M>x^k</M> equals the rank of the vector space
## <M>H_k(G, \mathbb{F}_p)</M> for all <M>k</M> in the range <M>k=1</M> to
## <M>k=n</M>. If no value is given for <A>n</A> then increasing values of
## <M>n</M> are tried to find the minimum value which gives a consistent
## Poincaré series, defined as a the minimum value <M>n > 10</M> such that
## <C>PoincareSeries(G, n) = PoincareSeries(G, n-1) = PoincareSeries(G, n-2)</C>.
## <P/>
## This function uses the &HAP; function
## <Ref Func="PoincareSeries" BookName="HAP"/> to calculate the Poincaré
## series, but the &HAPprime; function
## <Ref Oper="ExtendResolutionPrimePowerGroupAutoMem" BookName="HAPprime"/> to calculate
## and gradually extend the resolution, so should be both faster and more
## memory-efficient than using <K>PoincareSeries</K> by itself.
## See Section <Ref Sect="PoincareExample"/> for an example.
## <P/>
## The Poincaré series calculated using this function is likely to be correct,
## but we have no proof that this will be the case. If a correct Poincaré
## series is required, use <Ref Oper="PoincareSeriesLHS" BookName="HAPprime"/>
## </Description>
## </ManSection>
## <#/GAPDoc>
#####################################################################
InstallMethod(PoincareSeriesAutoMem,
"generic method",
[IsGroup, IsPosInt],
function(G, n)
return PoincareSeries(ResolutionPrimePowerGroupAutoMem(G, n));
end);
#####################################################################
InstallMethod(PoincareSeriesAutoMem,
"generic method",
[IsGroup],
function(G)
local factors, numToCompare, R,
dims, length, Pseries, found, match, i, t;
Info(InfoHAPprime, 2, "Using HAPprime version ", HAPPRIME_VersionWithSVN());
Info(InfoHAPprime, 2, "Max available memory ", GasmanLimits().max);
t := Runtime();
# If the group factors, then I can just do the Poincare series of the factors
# and then find their product.
factors := DirectFactorsOfGroup(G);
if Length(factors) > 1 then
Info(InfoHAPprime, 1, "Splitting into ", Length(factors), " factors to find Poincaré series");
factors := List(factors, g->PoincareSeriesAutoMem(g));
return Product(factors);
else
# Build a resolution estimate its PoincareSeries
length := 10;
numToCompare := 3;
R := ResolutionPrimePowerGroupAutoMem(G, length);
dims := List([0..length], i->ResolutionModuleRank(R, i));
Pseries := [];
for i in [1..numToCompare] do
Pseries[i] := PoincareSeries(dims, length-numToCompare+i);
od;
Info(InfoHAPprime, 2, "Time taken so far: ", Runtime() - t, "ms");
found := false;
while not found do
match := List([1..(numToCompare-1)], i->Pseries[i] = Pseries[i+1]);
if not false in match then
found := true;
else
# Find the next stage in the resolution
R := ExtendResolutionPrimePowerGroupAutoMem(R);
length := length + 1;
Add(dims, ResolutionModuleRank(R, length));
Remove(Pseries, 1);
Pseries[numToCompare] := PoincareSeries(dims, length);
Info(InfoHAPprime, 2, "Time taken so far: ", Runtime() - t, "ms");
fi;
od;
fi;
return Pseries[1];
end);
#####################################################################
InstallMethod(PoincareSeriesAutoMemStop,
"generic method",
[IsGroup],
function(G)
local orderG, nGgens, factors, numToCompare, R,
dims, length, Pseries, found, match, i, stop,
size, radicalcomputebyes, memfree, t;
Info(InfoHAPprime, 2, "Using HAPprime version ", HAPPRIME_VersionWithSVN());
Info(InfoHAPprime, 2, "Max available memory ", GasmanLimits().max);
t := Runtime();
orderG := Order(G);
nGgens := Length(MinimalGeneratingSet(G));
# If the group factors, then I can just do the Poincare series of the factors
# and then find their product.
factors := DirectFactorsOfGroup(G);
if Length(factors) > 1 then
Info(InfoHAPprime, 1, "Splitting into ", Length(factors), " factors to find Poincaré series");
factors := List(factors, g->PoincareSeriesAutoMem(g));
return Product(factors);
else
# Build a resolution estimate its PoincareSeries
length := 10;
numToCompare := 3;
R := ResolutionPrimePowerGroupAutoMem(G, length);
dims := List([0..length], i->ResolutionModuleRank(R, i));
Pseries := [];
for i in [1..numToCompare] do
Pseries[i] := PoincareSeries(dims, length-numToCompare+i);
od;
Info(InfoHAPprime, 2, "Time taken so far: ", Runtime() - t, "ms");
found := false;
stop := false;
while not found and not stop do
match := List([1..(numToCompare-1)], i->Pseries[i] = Pseries[i+1]);
if not false in match then
found := true;
else
# Find the next stage in the resolution
# How big is the current one?
size := ResolutionModuleRank(R, ResolutionLength(R));
radicalcomputebyes := Int(nGgens * orderG * orderG * size * size / 5); # In bytes
GASMAN("collect");
memfree := GasmanStatistics().full.freekb;
memfree := memfree + GasmanLimits().max - GasmanStatistics().full.totalkb;
memfree := memfree * 1024; # convert to Mb
# Allow a factor of two spare
if memfree > (radicalcomputebyes * 2) then
R := ExtendResolutionPrimePowerGroupRadical(R);
else
stop := true;
fi;
if not stop then
length := length + 1;
Add(dims, ResolutionModuleRank(R, length));
Remove(Pseries, 1);
Pseries[numToCompare] := PoincareSeries(dims, length);
fi;
Info(InfoHAPprime, 2, "Time taken so far: ", Runtime() - t, "ms");
fi;
od;
if stop then
Info(InfoHAPprime, 1, "Stopped: about to run out of memory for Radical");
return fail;
fi;
fi;
return Pseries[1];
end);
#####################################################################