GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#(C) Graham Ellis, 2005-2006
#RT:=0;
#####################################################################
InstallGlobalFunction(IntegralHomology,
function(X,n)
local
Homology_Obj,
Homology_Arr,
HomologyAsFpGroup, xx;
if not EvaluateProperty(X,"characteristic")=0 then
Print("ERROR: There is an inconsitency with characteristic of Z. \n");
return fail; fi;
#####################################################################
#####################################################################
Homology_Obj:=function(C,n)
local
M1, M2,
dim,
BasisKerd1, BasisImaged2, BasisKerd1cp, BasisImaged2cp,
Rels, Smith, TorsionCoefficients,
Dimension, Boundary,
i;
if n <0 then return false; fi;
Dimension:=C!.dimension;
Boundary:=C!.boundary;
########################
if n=0 then
BasisKerd1:=IdentityMat(Dimension(n));
else
M1:=[];
for i in [1..Dimension(n)] do
M1[i]:=Boundary(n,i);
od;
ConvertToMatrixRep(M1);
BasisKerd1:=LLLReducedBasis(M1,"linearcomb").relations;
M1:=0;
fi;
#######################
M2:=[];
for i in [1..Dimension(n+1)] do
M2[i]:=Boundary(n+1,i);
od;
ConvertToMatrixRep(M2);
BasisImaged2:=BaseIntMat(M2);
dim:=Length(BasisImaged2);
M2:=0;
BasisImaged2:=MutableCopyMat(List([1..dim],i->BasisImaged2[i]));
#!!!!!!!!!!!!!!!CHANGE IT
if Length(BasisImaged2)>0 then
Rels:=SolutionsMatDestructive(BasisKerd1, BasisImaged2);
else
Rels:=[];
fi;
Smith:= SmithNormalFormIntegerMat(Rels);
TorsionCoefficients:=[];
for i in [1..Length(BasisKerd1)] do
if i<=Length(Smith) then
TorsionCoefficients[i]:=Smith[i][i];
else
TorsionCoefficients[i]:=0;
fi;
od;
return rec(
torsionCoefficients:=Filtered(TorsionCoefficients, i-> not (i=1)),
rels:=Rels,
basisKerd1:=BasisKerd1);
end;
#####################################################################
#####################################################################
#####################################################################
#####################################################################
HomologyAsFpGroup:=function(C,n)
local
F, H, HH, HHhomH, nn, expH,
Rels, Fgens, FhomFH, FHhomH, FhomH,
FH, Frels, Hgens, FHgens, IHC, HhomC, ChomH,
Vector2Word, BasisKerd1, rel, i, j, Htmp,HtmphomH,
sem, z1,sol1,lngm ;
if not "fpIntHom" in NamesOfComponents(C) then
C!.fpIntHom:=[1..1000]; #SLOPPPY! Some one might ask for
#the 1000-dimensional homology
fi;
if n=0 then nn:=1000; else nn:=n; fi;
if IsInt(C!.fpIntHom[nn]) then
IHC:=Homology_Obj(C,n);
BasisKerd1:=IHC.basisKerd1;
Rels:=IHC.rels;
expH:=Lcm(IHC.torsionCoefficients);
F:=FreeGroup(Length(BasisKerd1));
Fgens:=GeneratorsOfGroup(F);
Frels:=[];
#####################################################################
Vector2Word:=function(rel)
local w,i;
w:=Identity(F);
for i in [1..Length(Fgens)] do
w:=w*Fgens[i]^rel[i];
od;
return w;
end;
#####################################################################
for rel in Rels do
Append(Frels,[Vector2Word(rel)]);
od;
################################# #Should make "abelian groups"
for i in [1..Length(Fgens)] do #type in GAP
for j in [i..Length(Fgens)] do
Append(Frels,[Fgens[i]*Fgens[j]*Fgens[i]^-1*Fgens[j]^-1]);
od;
od;
FH:=F/Frels;
FHgens:=GeneratorsOfGroup(FH);
FHhomH:=NqEpimorphismNilpotentQuotient(FH,1);
H:=Range(FHhomH);
################################
#####################################################################
HhomC:=function(w);
return BasisKerd1[w];
end;
#####################################################################
if Length(BasisKerd1)=0 then
#####################################################################
ChomH:=function(v) #Am I sure about this fix?
return Identity(H);
end;
#####################################################################
else
z1 := Zero(BasisKerd1[1][1]);
#sol1:=ListWithIdenticalEntries(Length(BasisKerd1),z1);
sol1:=List([1..Length(BasisKerd1)],i->z1);
lngm:=Length(BasisKerd1[1]);
sem := SemiEchelonMatTransformationDestructive(1*BasisKerd1);
#####################################################################
ChomH:=function(v)
local w,i,xx, vno, z,x, row, ncols,sol,vec,solmat;
### w:=SolutionMat(BasisKerd1,v) mod expH;
ncols := Length(BasisKerd1[1]);
vec:=v;
z := StructuralCopy(z1);
sol := StructuralCopy(sol1);
ConvertToVectorRepNC(sol);
for i in [1..ncols] do
vno := sem.heads[i];
if vno <> 0 then
x := vec[i];
if x <> z then
AddRowVector(vec, sem.vectors[vno], -x);
AddRowVector(sol, sem.coeffs[vno], x);
fi;
fi;
od;
sol:=sol mod expH;
xx:=Identity(H);
for i in [1..Length(sol)] do
xx:=xx*Image(FHhomH,FHgens[i]^sol[i]);
od;
return xx;
end;
#####################################################################
fi;
C!.fpIntHom[nn]:=rec(
fpgroup:=H,
h2c:=HhomC,
c2h:=ChomH );
fi;
return C!.fpIntHom[nn];
end;
#####################################################################
#####################################################################
#####################################################################
#####################################################################
Homology_Arr:=function(f,n)
local
C,D,ChomD,
HC, HChomC, ChomHC, IHC,
HD, HDhomD, DhomHD, IHD,
HChomHD, gensHC, imageGensHC,
x;
C:=f!.source;
D:=f!.target;
ChomD:=f!.mapping;
IHC:=HomologyAsFpGroup(C,n);
HC:=IHC.fpgroup;
gensHC:=GeneratorsOfGroup(HC);
HChomC:=IHC.h2c;
ChomHC:=IHC.c2h;
IHD:=HomologyAsFpGroup(D,n);
HD:=IHD.fpgroup;
HDhomD:=IHD.h2c;
DhomHD:=IHD.c2h;
imageGensHC:=[];
for x in [1..Length(gensHC)] do
Append(imageGensHC,[ DhomHD(ChomD(HChomC(x),n)) ] );
od;
HChomHD:=GroupHomomorphismByImagesNC(HC,HD,gensHC,imageGensHC);
return HChomHD;
end;
#####################################################################
#####################################################################
if EvaluateProperty(X,"type")="chainComplex" then
xx:=IntegralHomologyOfChainComplex(X,n);
return xx; fi;
if EvaluateProperty(X,"type")="chainMap" then
xx:=Homology_Arr(X,n);
return xx; fi;
Print("ERROR: Input should be a chain complex or chain map.\n");
end );