\\ --------------- GP code ------------------------------------------------------------ \\ Library for the program Bianchi.gp \\ \\ Description: Compute the quotient of Hyperbolic Space by PSL_2 of imaginary \\ quadratic number fields \\ \\ \\ Author: Alexander D. Rahm \\ \\ Copyright (C) 2010 by Alexander D. Rahm. \\ Bianchi.gp is a free software covered by the GNU General Public License. \\ Version 2.0.1 of October 29th, 2010. \\--------------------------------------------------------------------------------------- ComputeGroupHomology() = { local( zeroethRank, firstRank, secondRank, rankOfd1_02, rankOfd1_01); checkIdealClass_cusp_correspondence(); cleanse2cellList(); print( "Equivariant Euler Characteristic of this PSL_2(Z[w])-cell complex is ", computeEquivariantEulerCharacteristic() ); getTwoCellBoundaryMatrix(); rankOfd1_02 = matrank( CellBoundaryMatrix); getEdgeBoundaryMatrices( ); rankOfd1_01 = matrank( boundaryMatrix); zeroethRank = numberOfVertexOrbits -rankOfd1_01; firstRank = numberOfEdgeOrbits -rankOfd1_01 -rankOfd1_02; secondRank = numberOfTwoCells -rankOfd1_02; if( classNumber > 1, print("Zeroeth row of the E^1-page is: "); print("Z^",numberOfVertexOrbits," <--^",rankOfd1_01," ", "Z^",numberOfEdgeOrbits," <--^",matsnf(CellBoundaryMatrix)," ", "Z^",numberOfTwoCells ); print("Rational homology of this row is: "); print("Q^",zeroethRank," ","Q^",firstRank," ","Q^",secondRank); print("Under the hypothesis that rank(d^2_{2,0}) = ", "number of nontrivial ideal classes, "); print("the homology of PSL_2(R), R = Z[",w, "], with trivial action on the coefficients ", "Q (the field of the rational numbers) is determined by: "); print("rank(H_0(PSL_2(R),Q)) = ",zeroethRank," ", "rank(H_1(PSL_2(R),Q)) = ", firstRank +(classNumber -1)," ","rank(H_2(PSL_2(R),Q)) = ",secondRank); ); if( classNumber == 1, print("q = 0 | Z^",zeroethRank," Z^", firstRank," Z^",secondRank); ); if( boundaryMatrix*CellBoundaryMatrix != 0, print("***Error: Composition of differentials is nonzero. ", "Please type: findErrorInDifferential()"); ); checkPointwiseFixing(); }; /* end of procedure ComputeGroupHomology */ cleanse2cellList()= { local( auxiliaryList:list, auxiliaryCorners, auxiliaryEdges, k); auxiliaryList = listcreate( numberOfSpheres +m); auxiliaryCorners = vector( numberOfSpheres +m); auxiliaryEdges = vector( numberOfSpheres +m); k = 0; for( j = 1, numberOf2cells, if( deleteCellFlag[j] == 0, listput( auxiliaryList, twoCellSupport:list[j]); k++; auxiliaryEdges[k] = edgesOf2cell[j]; auxiliaryCorners[k] = cornersOf2cell[j]; ); ); twoCellSupport = auxiliaryList; listkill( auxiliaryList); edgesOf2cell = auxiliaryEdges; cornersOf2cell = auxiliaryCorners; deleteCellFlag = vector(numberOfSpheres +m); numberOf2cells = length( twoCellSupport:list); /* == k */ }; /* end of procedure cleanse2cellList */ recordEdgeOrientations(j) = { /* Record a vector of Signs: For each edge in edgesOf2cell[j], */ /* record the sign of determinant( origin - barycenter, end - barycenter) */ local( barycenter, Sign, numberOfBoundingEdges, origin, end, xTilde,yTilde,xPrime,yPrime); numberOfBoundingEdges = length( edgesOf2cell[j]); Sign = vector( numberOfBoundingEdges ); /* Construct the barycenter of the projections of the vertices on the 2-cell onto the complex plane. */ barycenter = getBarycenter(j); /* For each edge, */ for ( r = 1, numberOfBoundingEdges, /* Record origin and end of the edge */ origin = component( eval(totalPointSet[ EdgeOrigin[ edgesOf2cell[j][r] ]]),1); end = component( eval(totalPointSet[ EdgeEnd[ edgesOf2cell[j][r] ]]),1); /* record the sign of determinant( origin - barycenter, end - barycenter) */ xTilde = component( origin -barycenter,1); yTilde = component( origin -barycenter,2); xPrime = component( end -barycenter,1); yPrime = component( end -barycenter,2); Sign[r] = sign( xTilde*yPrime -xPrime*yTilde); ); /* Return the vector Sign */ Sign }; /* end of function recordEdgeOrientations */ computeEquivariantEulerCharacteristic() = { /* compute the Equivariant Euler Characteristic of this PSL_2(Z[w])-cell complex */ local( stabilizerCardinal, vertexStabilizerCardinalities); local( edgeStabilizerCardinalities, massFormula); vertexStabilizerCardinalities = vector(23); edgeStabilizerCardinalities = vector(3); /* Count the occurencies of the stabilizer types of the vertex orbits. */ for ( j = 1, numberOfVertexOrbits, stabilizerCardinal = length( stabilizer[vertexOrbitRepresentative[j]]); if ( stabilizerCardinal != 23, /* 23 is artificially associated to Z^2 */ stabilizerCardinal = stabilizerCardinal /2; /* PSL_2 */ ); vertexStabilizerCardinalities[stabilizerCardinal]++; ); /* Count the occurencies of the stabilizer types of the edge orbits. */ for ( j = 1, numberOfEdgeOrbits, stabilizerCardinal = length( edgeStabilizer[ edgeOrbitRepresentative[j]]); if ( stabilizerCardinal == 23, /* 23 is artificially associated to Z^2 */ error("Singular edge occured in function computeEquivariantEulerCharacteristic"); ); stabilizerCardinal = stabilizerCardinal /2; /* PSL_2 */ edgeStabilizerCardinalities[stabilizerCardinal]++; ); numberOfTwoCells = 0; /* each 2-cell contributes the value 1 for the trivial stabilizer: */ for ( j = 1, numberOf2cells, if ( deleteCellFlag[j] == 0, /* only kept 2-cells may contribute */ numberOfTwoCells++; ); ); massFormula = ""; if( vertexStabilizerCardinalities[1] > 0, massFormula = Str( massFormula, vertexStabilizerCardinalities[1]); ); if( vertexStabilizerCardinalities[2] > 0, massFormula = Str( massFormula," +", vertexStabilizerCardinalities[2],"/2"); ); if( vertexStabilizerCardinalities[3] > 0, massFormula = Str( massFormula," +", vertexStabilizerCardinalities[3],"/3"); ); if( vertexStabilizerCardinalities[4] > 0, massFormula = Str( massFormula," +", vertexStabilizerCardinalities[4],"/4"); ); if( vertexStabilizerCardinalities[6] > 0, massFormula = Str( massFormula," +", vertexStabilizerCardinalities[6],"/6"); ); if( vertexStabilizerCardinalities[12] > 0, massFormula = Str( massFormula," +", vertexStabilizerCardinalities[12],"/12"); ); if( edgeStabilizerCardinalities[1] > 0, massFormula = Str( massFormula," -", edgeStabilizerCardinalities[1]); ); if( edgeStabilizerCardinalities[2] > 0, massFormula = Str( massFormula," -", edgeStabilizerCardinalities[2],"/2"); ); if( edgeStabilizerCardinalities[3] > 0, massFormula = Str( massFormula," -", edgeStabilizerCardinalities[3],"/3"); ); massFormula = Str( massFormula," +", numberOfTwoCells); print("The mass formula gives ",massFormula,", so"); /* Return the Equivariant Euler Characteristic for PSL_2(Z[w]): */ eval(massFormula) }; /* end of function computeEquivariantEulerCharacteristic */ Group(A,B) = { /* Compute some elements of the group generated by A and B. */ /* If this is a finite subgroup of a Bianchi group, we get all of its elements. */ /* We take the elements A, B, AB, BA, ABA, BAB, and all their */ /* powers up to the 25th power. */ /* The Bianchi groups do not contain elements of order greater than 24 and finite. */ local( toCompute, Stop, actualPower, computedElements: list); computedElements = listcreate(150); /* Convert entries to "POLMOD" format if necessary. */ if( type(A[1,1]) != "t_POLMOD", A = algMatrix(A); B = algMatrix(B); ); toCompute = [ A, B, A*B, B*A, A*B*A, B*A*B, A^2*B*A^2, B^2*A*B^2, A^2*B, B*A^2, A*B^2, B^2*A, A^2*B^2, B^2*A^2, A*B*A^2, B*A*B^2, B^2*A*B, A^2*B*A ]; for( j = 1, length( toCompute), Stop = 0; for( k = 1, 25, if( Stop == 0, actualPower = (toCompute[j])^k; listput( computedElements, actualPower); if( actualPower == 1, Stop = 1; ); if( k == 25, print("This group seems to be infinite."); ); ); ); ); /* return */ Set( computedElements); }; /* end of the function Group(A,B). */ getTwoCellBoundaryMatrix() = { /* Compute the differential d^1_{0,2} = CellBoundaryMatrix. */ local( twoCellCounter, OrbitNumber, Sign); CellBoundaryMatrix = matrix( numberOfEdgeOrbits, numberOfTwoCells); twoCellCounter = 0; for( j = 1, numberOf2cells, if( deleteCellFlag[j] == 0, Sign = recordEdgeOrientations(j); twoCellCounter++; for( k = 1, length( edgesOf2cell[j]), /* Record in OrbitNumber the numbers of the edge orbits for edgesOf2cell[j].*/ OrbitNumber = edgeOrbitNumber[ edgesOf2cell[j][k]]; /* Add a matrix entry Sign[k] at ( OrbitNumber, twoCellCounter). */ CellBoundaryMatrix[ OrbitNumber, twoCellCounter] = CellBoundaryMatrix[ OrbitNumber, twoCellCounter] +Sign[k]; ); ); ); }; /* end of procedure getTwoCellBoundaryMatrix */ getEdgeBoundaryMatrices( ) = { /* Record first the bottom row matrix "boundaryMatrix" of the differential, */ /* from the Z-module generated by edge orbits to the one generated by vertex orbits. */ /* Afterwards, collect some edge data to start the 2-primary part computation. */ local( originVertex, endVertex, edgeNumber, trivialStabilizers); EdgeTwoDim = 0; EdgeThreeDim = 0; edge3Label = listcreate( numberOfEdgeOrbits); edge2Label = listcreate( numberOfEdgeOrbits); trivialStabilizers = 0; boundaryMatrix = matrix( numberOfVertexOrbits, numberOfEdgeOrbits); /* For every edge in edgeOrbitRepresentative, record the following information. */ for ( j = 1, numberOfEdgeOrbits, edgeNumber = edgeOrbitRepresentative[j]; /* Record the data about the origin and end points of the edge: */ /* record number in totalPointSet of the origin vertex */ originVertex = setsearch( totalPointSet, component( edgesList:list[edgeNumber], 1)); /* record number in totalPointSet of the end vertex */ endVertex = setsearch( totalPointSet, component( edgesList:list[edgeNumber], 2)); /* At [origin vertex orbit number, edge orbit number] , */ /* put an entry -1 into boundaryMatrix */ boundaryMatrix[vertexOrbitNumber[originVertex], j] --; /* At [end vertex orbit number, edge orbit number] , */ /* put an entry +1 into boundaryMatrix */ boundaryMatrix[vertexOrbitNumber[endVertex],j] ++; /* Now, boundaryMatrix is the zeroeth row differential from edges to vertices.*/ /* Now collect some edge data to start the p-primary part computation. */ if( length( edgeStabilizer[ edgeNumber])/2 == 3, /* This edge contributes to the 3-primary part of E^1_{1,1}. */ EdgeThreeDim++; listput( edge3Label, j); ); if( length( edgeStabilizer[ edgeNumber])/2 == 2, /* This edge contributes to the 2-primary part of E^1_{1,1}. */ EdgeTwoDim++; listput( edge2Label, j); ); if( length( edgeStabilizer[ edgeNumber])/2 == 1, trivialStabilizers++; ); ); print("There are ",trivialStabilizers," edge orbits with trivial stabilizer."); printE2pages(); }; /* end of procedure getEdgeBoundaryMatrices( ) */ printmod2Row(q, cokernelTwoDim, kernelTwoDim) = { local( Output); Output = Str("q = ",q," | "); if( cokernelTwoDim != 0, Output = Str( Output, cokernelTwoDim); , /* else */ Output = Str( Output, " "); ); Output = concat( Output, " "); if( kernelTwoDim != 0, Output = Str( Output, kernelTwoDim); ); Output = Fill(Output); Output = Str( Output, " | "); Output = Str( Output, cokernelTwoDim +kernelTwoDim); print(Output); }; /* end of screen output procedure printmod2row */ Fill(Output) = { local(Space); Space = ""; for( j = 1, 44 -length(Output), Space = concat(Space," "); ); /* return */ concat( Output, Space) }; /* end of screen output function Fill */ printEvenRow( q, Rank) = { local( Output); if( component(q,1) >= 10, Output = Str("q = ",q," | "); , /* else one more space unit */ Output = Str("q = ",q," | "); ); if( Rank != 0, Output = Str( Output, "(Z/2)^{",Rank,"}"); ); print(Output); }; /* end of screen output procedure printEvenRow */ printOddRow( q, cokernelTwoDim, cokernelThreeDim, kernelTwoDim, kernelThreeDim) = { local( Output); if( component(q,1) >= 10, Output = Str("q = ",q," | "); , /* else one more space unit */ Output = Str("q = ",q," | "); ); if( cokernelTwoDim != 0, Output = Str( Output, "(Z/2)^{",cokernelTwoDim,"}"); , /* else */ Output = Str( Output, " "); ); if( cokernelThreeDim > 0, if( cokernelThreeDim == 1, Output = Str( Output, " +Z/3"); ,/* else */ Output = Str( Output, " +(Z/3)^",cokernelThreeDim); ); , /* else */ Output = Str( Output, " "); ); Output = Fill( Output); if( kernelTwoDim != 0, Output = Str( Output, "(Z/2)^",kernelTwoDim); ); if( kernelThreeDim > 0, if( kernelTwoDim > 0, Output = Str( Output, "+"); ); if( kernelThreeDim == 1, Output = Str( Output, "Z/3"); ,/* else */ Output = Str( Output, "(Z/3)^",kernelThreeDim); ); ); print(Output); }; /* end of screen output procedure printOddRow */ printE2pages() = { local( kernelThreeDim1, kernelThreeDim3, cokernelThreeDim1, cokernelThreeDim3); local( KleinOccurencies, AlternatingOccurencies, computedDimensions); local( TwoRank1, TwoRank3, VertexTwoDim1, VertexTwoDim3); computedDimensions = getKleinFourAndAlternatingGroupOccurencies(); KleinOccurencies = computedDimensions[1]; AlternatingOccurencies = computedDimensions[2]; computedDimensions = getThreePrimaryPart(1); kernelThreeDim1 = computedDimensions[1]; cokernelThreeDim1 = computedDimensions[2]; computedDimensions = getThreePrimaryPart(3); kernelThreeDim3 = computedDimensions[1]; cokernelThreeDim3 = computedDimensions[2]; computedDimensions = getTwoPrimaryPart(1); TwoRank1 = computedDimensions[1]; VertexTwoDim1 = computedDimensions[2]; computedDimensions = getTwoPrimaryPart(3); TwoRank3 = computedDimensions[1]; VertexTwoDim3 = computedDimensions[2]; printmod2E2page( TwoRank1, TwoRank3, VertexTwoDim1, VertexTwoDim3, KleinOccurencies, AlternatingOccurencies); output3torsionPoincareSeries( kernelThreeDim1, kernelThreeDim3, cokernelThreeDim1, cokernelThreeDim3); printE2page( kernelThreeDim1, kernelThreeDim3, cokernelThreeDim1, cokernelThreeDim3, KleinOccurencies, AlternatingOccurencies, TwoRank1, TwoRank3, VertexTwoDim1, VertexTwoDim3); }; /* end of screen output procedure printE2pages */ printE2page( kernelThreeDim1, kernelThreeDim3, cokernelThreeDim1, cokernelThreeDim3, KleinOccurencies, AlternatingOccurencies, TwoRank1, TwoRank3, VertexTwoDim1, VertexTwoDim3) = { local( kernelTwoDim, cokernelTwoDim, Output, n='n); print("We obtain the following result for the equivariant Leray/Serre spectral sequence converging to group homology with integer coefficients. \n The q-th even row, q>0, of the E^2-page is concentrated in the zeroth column, ", "with (Z/2)-rank ",KleinOccurencies,"q/2 +",AlternatingOccurencies,"l, ", "where l = k if q = 6k+4 or 6k+6, and l = k+1 if q = 6k+2. ", "The 3-torsion continues as begun below, with period 4 in q. "); print(); print("E^2-page p=0 p=1 p=2"); print("____________________________________________________________________"); print(" | "); kernelTwoDim = EdgeTwoDim -TwoRank3; printEvenRow( 12*n+14, KleinOccurencies*(6*n+7) +AlternatingOccurencies*(2*n+3) ); cokernelTwoDim = VertexTwoDim3 +(6*n+5)*KleinOccurencies +(2*n+1)*AlternatingOccurencies -TwoRank3; printOddRow(12*n+13, cokernelTwoDim, cokernelThreeDim1, kernelTwoDim, kernelThreeDim1); printEvenRow( 12*n+12, KleinOccurencies*(6*n+6) +AlternatingOccurencies*(2*n+2) ); cokernelTwoDim = VertexTwoDim3 +(6*n+4)*KleinOccurencies +(2*n+2)*AlternatingOccurencies -TwoRank3; printOddRow( 12*n+11, cokernelTwoDim, cokernelThreeDim3, kernelTwoDim, kernelThreeDim3); printEvenRow( 12*n+10, KleinOccurencies*(6*n+5) +AlternatingOccurencies*(2*n+1) ); cokernelTwoDim = VertexTwoDim3 +(6*n+3)*KleinOccurencies +(2*n+1)*AlternatingOccurencies -TwoRank3; printOddRow(12*n+9, cokernelTwoDim, cokernelThreeDim1, kernelTwoDim, kernelThreeDim1); printEvenRow(12*n+8, KleinOccurencies*(6*n+4) +(2*n+2)*AlternatingOccurencies); cokernelTwoDim = VertexTwoDim3 +(6*n+2)*KleinOccurencies +(2*n)*AlternatingOccurencies -TwoRank3; printOddRow(12*n+7, cokernelTwoDim, cokernelThreeDim3, kernelTwoDim, kernelThreeDim3); printEvenRow( 12*n+6, KleinOccurencies*(6*n+3) +(2*n+1)*AlternatingOccurencies); cokernelTwoDim = VertexTwoDim3 +(6*n+1)*KleinOccurencies +(2*n+1)*AlternatingOccurencies -TwoRank3; printOddRow(12*n+5, cokernelTwoDim, cokernelThreeDim1, kernelTwoDim, kernelThreeDim1); printEvenRow( 12*n+4, KleinOccurencies*(6*n+2) +(2*n)*AlternatingOccurencies ); cokernelTwoDim = VertexTwoDim3 +(6*n)*KleinOccurencies +(2*n)*AlternatingOccurencies -TwoRank3; printOddRow(12*n+3, cokernelTwoDim, cokernelThreeDim3, kernelTwoDim, kernelThreeDim3); print("q = 2 | Z^",classNumber -1, " +(Z/2)^",KleinOccurencies +AlternatingOccurencies); kernelTwoDim = EdgeTwoDim -TwoRank1; cokernelTwoDim = VertexTwoDim1 -TwoRank1; Output = Str("q = 1 | Z^",2*(classNumber -1)," +(Z/2)^",cokernelTwoDim, " +(Z/3)^",cokernelThreeDim1); Output = Fill( Output); print(Output, "(Z/2)^",kernelTwoDim," +(Z/3)^",kernelThreeDim1); }; /* end of screen output procedure printE2page */ printmod2E2page( TwoRank1, TwoRank3, VertexTwoDim1, VertexTwoDim3, KleinOccurencies, AlternatingOccurencies) = { local( kernelTwoDim, cokernelTwoDim, Mod2homology, n='n); local( E2_00mod2, E2_01mod2, E2_02mod2, rankd1_01, rankd1_02); Mod2homology = vector(8); print("The E^2-page in the spectral sequence with Z/2-coefficients is concentrated as follows, except that we have to add the zeroth row. We only give the dimensions over the field with two elements."); print(); print("E^2-page mod 2 p=0 p=1 p=2 | dim H_q(Gamma; Z/2)"); print("_______________________________________________|"); print(" | |"); kernelTwoDim = EdgeTwoDim -TwoRank3; cokernelTwoDim = VertexTwoDim3 +(6*n+6)*KleinOccurencies +(2*n+2)*AlternatingOccurencies -TwoRank3; printmod2Row(6*n+8, cokernelTwoDim, kernelTwoDim); Mod2homology[8] = cokernelTwoDim +kernelTwoDim; cokernelTwoDim = VertexTwoDim3 +(6*n+5)*KleinOccurencies +(2*n+1)*AlternatingOccurencies -TwoRank3; printmod2Row(6*n+7, cokernelTwoDim, kernelTwoDim); Mod2homology[7] = cokernelTwoDim +kernelTwoDim; cokernelTwoDim = VertexTwoDim3 +(6*n+4)*KleinOccurencies +(2*n+2)*AlternatingOccurencies -TwoRank3; printmod2Row(6*n+6, cokernelTwoDim, kernelTwoDim); Mod2homology[6] = cokernelTwoDim +kernelTwoDim; cokernelTwoDim = VertexTwoDim3 +(6*n+3)*KleinOccurencies +(2*n+1)*AlternatingOccurencies -TwoRank3; printmod2Row(6*n+5, cokernelTwoDim, kernelTwoDim); Mod2homology[5] = cokernelTwoDim +kernelTwoDim; cokernelTwoDim = VertexTwoDim3 +(6*n+2)*KleinOccurencies +(2*n)*AlternatingOccurencies -TwoRank3; printmod2Row(6*n+4, cokernelTwoDim, kernelTwoDim); Mod2homology[4] = cokernelTwoDim +kernelTwoDim; cokernelTwoDim = VertexTwoDim3 +(6*n+1)*KleinOccurencies +(2*n+1)*AlternatingOccurencies -TwoRank3; printmod2Row(6*n+3, cokernelTwoDim, kernelTwoDim); Mod2homology[3] = cokernelTwoDim +kernelTwoDim; cokernelTwoDim = classNumber -1 +VertexTwoDim3 -TwoRank3; print("q = 2 | ",cokernelTwoDim , " ", kernelTwoDim," | ?"); kernelTwoDim = EdgeTwoDim -TwoRank1; Mod2homology[2] = cokernelTwoDim +kernelTwoDim; cokernelTwoDim = 2*(classNumber -1) +VertexTwoDim1 -TwoRank1; print("q = 1 | ",cokernelTwoDim," ", kernelTwoDim," | ?"); rankd1_01 = matrank(Mod(boundaryMatrix,2)); rankd1_02 = matrank(Mod(CellBoundaryMatrix,2)); E2_00mod2 = numberOfVertexOrbits -rankd1_01; E2_01mod2 = numberOfEdgeOrbits -rankd1_02 -rankd1_01; E2_02mod2 = numberOfTwoCells -rankd1_02; print("q = 0 | ",E2_00mod2," ", E2_01mod2," ", E2_02mod2, " | ",E2_00mod2, "\n"); /* If E^3_{2,0} = 0, then dim H_2(Gamma; Z/2) = Mod2homology[2]. */ /* If d^2_{2,0} = 0, then dim H_1(Gamma; Z/2) = cokernelTwoDim +E2_01mod2. */ /* Deduce the Poincare series in dim H_q(Gamma; Z/2) for q greater than or equal 3. */ output2torsionPoincareSeries( Mod2homology ); }; /* end of screen output procedure printmod2E2page */ output2torsionPoincareSeries( Mod2homology ) = { /* Output the Poincare Series in the dimensions over the field with two elements, of the mod 2 homology groups, truncated as follows. Consider only the degrees strictly greater than the virtual cohomological dimension of Gamma (= 2). */ local( PoincareSeries, Summands, Nu, M, t='t); /* These dimensions are periodic of period length 6. */ Summands = vector(6); /* There are six summands of the form */ /* $\sum_{k=0}^\infty (M k +Nu)t^{6k+\eta} = (t^\eta (Nu+t^6 (M -Nu)))/((1-t^6)^2)$, */ /* where \eta runs from 3 through 8. */ for( Eta = 3,8, Nu = component( Mod2homology[Eta], 1); M = component( Mod2homology[Eta], 2); Summands[Eta-2] = (t^Eta *(Nu+t^6 *(M -Nu)))/((1-t^6)^2); ); PoincareSeries = sum( X = 1, 6, Summands[X]); print( "2-torsion Poincare series ",PoincareSeries); }; /* end of screen output procedure output2torsionPoincareSeries */ output3torsionPoincareSeries( kernelThreeDim1, kernelThreeDim3, cokernelThreeDim1, cokernelThreeDim3) = { /* Output the Poincare Series in the dimensions over the field with three elements, of the mod 3 homology groups, truncated as follows. Consider only the degrees strictly greater than the virtual cohomological dimension of Gamma (= 2). */ local( PoincareSeries, Summands, Nu, M, Eta, t='t); /* These dimensions are periodic of period length 4. */ Summands = vector(4); /* There are four summands of the form */ /* $\sum_{k=0}^\infty (M k +Nu)t^{4k+\eta} = (t^\eta (Nu+t^4 (M -Nu)))/((1-t^4)^2)$, */ /* where \eta runs from 3 through 6. */ M = 0; Eta = 3; Nu = cokernelThreeDim3 + kernelThreeDim1; Summands[Eta-2] = (t^Eta *(Nu+t^4 *(M -Nu)))/((1-t^4)^2); Eta = 4; Nu = kernelThreeDim3 +cokernelThreeDim3; Summands[Eta-2] = (t^Eta *(Nu+t^4 *(M -Nu)))/((1-t^4)^2); Eta = 5; Nu = cokernelThreeDim1 +kernelThreeDim3; Summands[Eta-2] = (t^Eta *(Nu+t^4 *(M -Nu)))/((1-t^4)^2); Eta = 6; Nu = kernelThreeDim1 +cokernelThreeDim1; Summands[Eta-2] = (t^Eta *(Nu+t^4 *(M -Nu)))/((1-t^4)^2); PoincareSeries = sum( X = 1, 4, Summands[X]); print( "3-torsion Poincare series ",PoincareSeries,"\n in degrees above the virtual cohomological dimension."); }; /* end of screen output procedure output3torsionPoincareSeries */ findInList( givenList:list, givenElement) = { local( indexFound); indexFound = 0; for( r = 1, length( givenList), if( givenList[r] == givenElement, indexFound = r; ); ); /* return */ indexFound }; /* end of function findInList */ sortAlternatingGroupOnFourObjects(k) = { /* Sort the stabilizer of vertex representative stabilizer no. k in a way that */ /* one conjugacy class of elements occupies places 9 through 16, */ /* and the squares of these elements occupy places 17 through 24. */ /* This will enable us to make identifications of incoming elements (from the */ /* edge stabilizers) modulo the conjugation. */ local( auxiliaryList: list, givenStabilizer, actualElement,oldIndex, elementsRemaining); local( counterIndex, actualElementSquare, order2element); givenStabilizer = stabilizer[ vertexOrbitRepresentative[k]]; auxiliaryList = listcreate( length( givenStabilizer)); /* Find the occurence of the identity matrix in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), 1); listput( auxiliaryList, givenStabilizer[ oldIndex]); /* Find the occurence of minus the identity matrix in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), -1); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining = length( givenStabilizer) -2; /* Record the elements of order 2 on places 3 through 8. */ counterIndex = 1; while( elementsRemaining > 16, actualElement = givenStabilizer[ counterIndex]; actualElementSquare = algMatrix(actualElement)^2; /* Check that this is of order 2 in PSL_2: */ if( actualElementSquare == 1 || actualElementSquare == -1, /* Check that this element is not already in auxiliaryList. */ if( findInList( auxiliaryList, actualElement) == 0, listput( auxiliaryList, actualElement); elementsRemaining--; /* Find the occurence of minus the actualElement */ /* in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), -algMatrix(actualElement)); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining--; ); ); counterIndex++; if( counterIndex > length( givenStabilizer) +1, error("Stabilizer sorting went out of range. Check procedure sortAlternatingGroupOnFourObjects"); ); ); /* Now pick an element of order 3 and record all its conjugates under */ /* elements of order 2. */ counterIndex = 1; while( elementsRemaining > 8, actualElement = givenStabilizer[ counterIndex]; /* Check that this element is not already in auxiliaryList. */ if( findInList( auxiliaryList, actualElement) == 0, listput( auxiliaryList, actualElement); elementsRemaining--; /* Find the occurence of minus the actualElement */ /* in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), -algMatrix(actualElement)); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining--; for( r = 2,4, order2element = auxiliaryList[2*r]; /* Find the occurence of the actualElement conjugated*/ /* by the order2element in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), conjugateMatrixbyg(actualElement, order2element)); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining--; /* Find the occurence of minus the actualElement conjugated*/ /* by the order2element in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), conjugateMatrixbyg(-actualElement, order2element)); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining--; ); ); counterIndex++; if( counterIndex > length( givenStabilizer) +1, error("List sorting went out of range. Check procedure sortAlternatingGroupOnFourObjects"); ); ); /* Now we record the remaining eight elements (which are of order 3 in PSL_2), */ /* on places 17 through 24. */ counterIndex = 1; while( elementsRemaining > 0, actualElement = givenStabilizer[ counterIndex]; /* Check that this element is not already in auxiliaryList. */ if( findInList( auxiliaryList, actualElement) == 0, listput( auxiliaryList, actualElement); elementsRemaining--; /* Find the occurence of minus the actualElement */ /* in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), -algMatrix(actualElement)); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining--; ); counterIndex++; if( counterIndex > length( givenStabilizer) +1, error("List sorting went out of range. Check procedure sortAlternatingGroupOnFourObjects"); ); ); /* Override the given list by the sorted list. */ stabilizer[ vertexOrbitRepresentative[k]] = auxiliaryList; }; /* end of procedure sortAlternatingGroupOnFourObjects(k) */ sortVertexRepresentativeStabilizer(k) = { /* Sort the stabilizer of vertex representative stabilizer no. k in a way that */ /* we obtain a sequence of pairs (A,-A) of elements A. */ /* This will enable us to make identifications of incoming elements (from the */ /* edge stabilizers) modulo the sign. */ local( auxiliaryList: list, givenStabilizer, actualElement,oldIndex, elementsRemaining); local( counterIndex); givenStabilizer = stabilizer[ vertexOrbitRepresentative[k]]; auxiliaryList = listcreate( length( givenStabilizer)); /* Find the occurence of the identity matrix in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), 1); listput( auxiliaryList, givenStabilizer[ oldIndex]); /* Find the occurence of minus the identity matrix in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), -1); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining = length( givenStabilizer) -2; counterIndex = 1; while( elementsRemaining > 0, actualElement = givenStabilizer[ counterIndex]; /* Check that this element is not already in auxiliaryList. */ if( findInList( auxiliaryList, actualElement) == 0, listput( auxiliaryList, actualElement); elementsRemaining--; /* Find the occurence of minus the actualElement */ /* in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), -algMatrix(actualElement)); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining--; ); counterIndex++; if( counterIndex > length( givenStabilizer) +1, error("List sorting went out of range. Check procedure sortVertexRepresentativeStabilizer"); ); ); /* Override the given list by the sorted list. */ stabilizer[ vertexOrbitRepresentative[k]] = auxiliaryList; }; /* end of procedure sortVertexRepresentativeStabilizer. */ sortSymmetricGroupOnThreeObjects(k) = { /* Sort the stabilizer of vertex representative stabilizer no. k in a way that */ /* we obtain a sequence of pairs (A,-A) of elements A, and */ /* the elements of order 3 are put on places 3 through 6. */ /* This will enable us to make identifications of incoming elements (from the */ /* edge stabilizers) modulo the sign. */ local( auxiliaryList: list, givenStabilizer, actualElement,oldIndex, elementsRemaining); local( counterIndex); givenStabilizer = stabilizer[ vertexOrbitRepresentative[k]]; auxiliaryList = listcreate( length( givenStabilizer)); /* Find the occurence of the identity matrix in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), 1); listput( auxiliaryList, givenStabilizer[ oldIndex]); /* Find the occurence of minus the identity matrix in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), -1); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining = length( givenStabilizer) -2; /* Record the elements of order 3 on places 3 through 6. */ counterIndex = 1; while( elementsRemaining > 6, actualElement = givenStabilizer[ counterIndex]; /* Check that this is of order 3 in PSL_2: */ if( algMatrix(actualElement)^3 == 1 || algMatrix(actualElement)^3 == -1, /* Check that this element is not already in auxiliaryList. */ if( findInList( auxiliaryList, actualElement) == 0, listput( auxiliaryList, actualElement); elementsRemaining--; /* Find the occurence of minus the actualElement */ /* in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), -algMatrix(actualElement)); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining--; ); ); counterIndex++; if( counterIndex > length( givenStabilizer) +1, error("Stabilizer sorting went out of range. Check procedure sortSymmetricGroupOnThreeObjects"); ); ); /* Now we record the remaining six elements (which are of order 2 in PSL_2). */ counterIndex = 1; while( elementsRemaining > 0, actualElement = givenStabilizer[ counterIndex]; /* Check that this element is not already in auxiliaryList. */ if( findInList( auxiliaryList, actualElement) == 0, listput( auxiliaryList, actualElement); elementsRemaining--; /* Find the occurence of minus the actualElement */ /* in the list givenStabilizer. */ /* Compare with respect to algMatrix. */ oldIndex = findInList( algMatrixList(givenStabilizer), -algMatrix(actualElement)); listput( auxiliaryList, givenStabilizer[ oldIndex]); elementsRemaining--; ); counterIndex++; if( counterIndex > length( givenStabilizer) +1, error("List sorting went out of range. Check procedure sortSymmetricGroupOnThreeObjects"); ); ); /* Override the given list by the sorted list. */ stabilizer[ vertexOrbitRepresentative[k]] = auxiliaryList; }; /* end of procedure sortSymmetricGroupOnThreeObjects */ conjugateMatrixbyg(A,g) = { /* Conjugate the matrix A by the matrix g. */ /* First, we convert them into POLMOD entry matrices. */ A = algMatrix(A); g = algMatrix(g); /* return */ g*A*g^(-1) }; /* end of function conjugateMatrixbyg */ pickGenerator(j) = { /* Pick a generator of the stabilizer of j-th edge. */ /* We call this for an edge with stabilizer Z/2 or Z/3 so any matrix not +/-1 */ /* is a suitable generator. */ /* Thus it suffices to try the first three matrices. */ local( generator, NotIdentity); NotIdentity = 0; /* Check that this edge is not trivially stabilized. */ if( length( edgeStabilizer[j]) > 2, for( r = 1, 3, if( NotIdentity == 0, generator = eval( edgeStabilizer[j][4-r]); if( algMatrix(generator) != 1 && algMatrix(generator) != -1, NotIdentity = 1, ); ); ); ); if( NotIdentity == 0, print("***Error in function pickGenerator: Did not find any generator for stabilizer ",j); ); /* return */ generator }; /* end of function pickGenerator */ determine3torsionStabilizerInclusion(j, q, originOrEnd) = { /* We determine the morphism in homology induced by the inclusion of the stabilizer */ /* of edge number j, which is assumed to be of order 3, */ /* into the stabilizer of its origin / end, */ /* composed with conjugating into the representative stabilizer of the latter. */ local( generator, g, k, includedElement, targetVertex, inducedMatrixBlock); local( inclusionPosition, index); if( originOrEnd == "origin", k = EdgeOrigin[ j]; ); if( originOrEnd == "end", k = EdgeEnd[ j]; ); /* Pick a generator of the stabilizer of j-th edge. */ generator = pickGenerator(j); /* Pick any matrix g, which sends the origin / end */ /* to its representative. */ targetVertex = vertexOrbitRepresentative[ vertexOrbitNumber[k]]; index = listSearch(equivalentVertices[k], targetVertex); g = identificationMatrices[transportFrom[k][index]][1]; /* Now gAg^(-1) is the included element that we search. */ includedElement = conjugateMatrixbyg( generator, eval(g)); /* We look up its list position in the stabilizer of the target vertex. */ inclusionPosition = findInList( algMatrixList( stabilizer[ targetVertex]), includedElement); /* This makes sense because we have ordered the list with */ /* sort3PrimaryPartInVertexRepresentativeStabilizer(k). */ /* To this position, we associate a matrix entry in (d^1_{1,q})_(3). */ inducedMatrixBlock = vector( length( stabilizer[ targetVertex])); /* For stabilizer type Z/3, this matrix entry is given as follows: */ if( length( stabilizer[ targetVertex])/2 == 3, inducedMatrixBlock[3] = 1; inducedMatrixBlock[4] = 1; inducedMatrixBlock[5] = 2; inducedMatrixBlock[6] = 2; ); /* For the Symmetric Group on three objects, this matrix entry is given as follows: */ if( length( stabilizer[ targetVertex])/2 == 6, if( q == 3, inducedMatrixBlock[3] = 1; inducedMatrixBlock[4] = 1; inducedMatrixBlock[5] = 2; inducedMatrixBlock[6] = 2; ); if( q == 1, inducedMatrixBlock[3] = 0; inducedMatrixBlock[4] = 0; inducedMatrixBlock[5] = 0; inducedMatrixBlock[6] = 0; ); ); /* For the Alternating Group on four objects, this matrix entry is given as follows: */ if( length( stabilizer[ targetVertex])/2 == 12, for( r = 9, 16, inducedMatrixBlock[r] = 1; ); for( r = 17, 24, inducedMatrixBlock[r] = 2; ); );/* The above information relies on arguments of [Schwermer/Vogtmann], */ /* and on the ordering described in the author's PhD thesis. */ /* return */ inducedMatrixBlock[ inclusionPosition] }; /* end of function determine3torsionStabilizerInclusion */ determineEdgeVertexStabilizerInclusion(j, q, originOrEnd) = { /* We determine the morphism in homology induced by the inclusion of the stabilizer */ /* of edge number j into the stabilizer of its origin / end, */ /* composed with conjugating into the representative stabilizer of the latter. */ local( generator, g, k, includedElement, targetVertex, inducedMatrixBlock); local( inclusionPosition, index); if( originOrEnd == "origin", k = EdgeOrigin[ j]; ); if( originOrEnd == "end", k = EdgeEnd[ j]; ); /* Pick a generator of the stabilizer of j-th edge. */ generator = pickGenerator(j); /* Pick any matrix g, which sends the origin / end */ /* to its representative. */ targetVertex = vertexOrbitRepresentative[ vertexOrbitNumber[k]]; index = listSearch(equivalentVertices[k], targetVertex); g = identificationMatrices[transportFrom[k][index]][1]; /* Now gAg^(-1) is the included element that we search. */ includedElement = conjugateMatrixbyg( generator, eval(g)); /* We look up its position in the stabilizer of the target vertex. */ inclusionPosition = findInList( algMatrixList( stabilizer[ targetVertex]), includedElement); /* To this position, we associate a matrix block in (d^1_{1,q})_(2). */ inducedMatrixBlock = vector( length( stabilizer[ targetVertex])); /* For the Klein Four Group, this matrix block is given as follows: */ if( length( stabilizer[ targetVertex])/2 == 4, if( q >= 3, inducedMatrixBlock[3] = [1,0,0]; inducedMatrixBlock[4] = [1,0,0]; inducedMatrixBlock[5] = [0,0,1]; inducedMatrixBlock[6] = [0,0,1]; inducedMatrixBlock[7] = [1,1,1]; inducedMatrixBlock[8] = [1,1,1]; ); if( q == 1, inducedMatrixBlock[3] = [1,0]; inducedMatrixBlock[4] = [1,0]; inducedMatrixBlock[5] = [0,1]; inducedMatrixBlock[6] = [0,1]; inducedMatrixBlock[7] = [1,1]; inducedMatrixBlock[8] = [1,1]; ); /* The above information relies on arguments of [Schwermer/Vogtmann]. */ ); /* return */ inducedMatrixBlock[ inclusionPosition] }; /* end of function determineEdgeVertexStabilizerInclusion */ record3primaryHomologyDimensions(q) = { /* Record the dimensions of the q-th homology groups of the vertex stabilizers, */ /* the sum over which is the (E^1_{1,q})_(3) term of */ /* the equivariant spectral sequence. */ local( VertexThreeDim, numberInLabel, cardinal); VertexThreeDim = 0; numberInLabel = vector( numberOfVertexOrbits); /* Record inversely the numbers of vertex orbits which have 3-primary stabilizers. */ for( k = 1, numberOfVertexOrbits, /* Consider subgroups of PSL_2 (the cardinal is divided by 2). */ cardinal = length( stabilizer[vertexOrbitRepresentative[k]])/2; /* The case of isomorphy type S_3. The Z/3-rank of the homology H_q(S_3) */ /* is 1 for q congruent 3 mod 4, and 0 else. */ if( cardinal == 6, if( Mod(q,4) == Mod(3,4), VertexThreeDim ++; numberInLabel[k] = VertexThreeDim; ); sortSymmetricGroupOnThreeObjects(k); ); /* In case of isomorphy Z/3, the Z/3-rank of the q-th homology groups */ /* is 1 for q odd. */ if( cardinal == 3, if( Mod(q,2) == Mod(1,2), VertexThreeDim ++; numberInLabel[k] = VertexThreeDim; ); sortVertexRepresentativeStabilizer(k); ); /* In case of isomorphy A_4, the Z/3-rank of the q-th homology groups */ /* is 1 for q odd. */ if( cardinal == 12, if( Mod(q,2) == Mod(1,2), VertexThreeDim ++; numberInLabel[k] = VertexThreeDim; ); sortAlternatingGroupOnFourObjects(k); ); ); /* return */ [VertexThreeDim, numberInLabel] }; /* end of function record3primaryHomologyDimensions */ getKleinFourAndAlternatingGroupOccurencies() = { /* Record the occurencies as vertex representative stabilizers, */ /* of the Klein four group and the Alternating group on four objects. */ local( KleinOccurencies, AlternatingOccurencies, cardinal); KleinOccurencies = 0; AlternatingOccurencies = 0; /* Record the number of vertex orbits which have these stabilizers. */ for( k = 1, numberOfVertexOrbits, /* Consider subgroups of PSL_2 (the cardinal is divided by 2). */ cardinal = length( stabilizer[vertexOrbitRepresentative[k]])/2; /* In case of cardinal 4, we have the Klein four group as isomorphy type. */ if( cardinal == 4, KleinOccurencies ++; ); /* In case of cardinal 12, */ /* we have the Alternating group on four objects as isomorphy type. */ if( cardinal == 12, AlternatingOccurencies++; ); ); /* return */ [KleinOccurencies, AlternatingOccurencies] }; /* end of function getKleinFourAndAlternatingGroupOccurencies */ record2primaryHomologyDimensions(q) = { /* Record the dimensions of the q-th homology groups of the vertex stabilizers, */ /* the sum over which is the (E^1_{1,q})_(2) term of */ /* the equivariant spectral sequence. */ local( VertexTwoDim, numberInLabel, cardinal); VertexTwoDim = 0; numberInLabel = vector( numberOfVertexOrbits); if( Mod(q,2) == 0, error("The function record2primaryHomologyDimensions assumes that q is odd.")); /* Record inversely the numbers of vertex orbits which have 2-primary stabilizers. */ for( k = 1, numberOfVertexOrbits, /* Consider subgroups of PSL_2 (the cardinal is divided by 2). */ cardinal = length( stabilizer[vertexOrbitRepresentative[k]])/2; /* In case of isomorphy type Z/2 or S_3, the Z/2-rank of the odd */ /* homology groups is 1. */ if( cardinal == 2 || cardinal == 6, VertexTwoDim ++; numberInLabel[k] = VertexTwoDim; ); /* In case of isomorphy D_2, the Z/2-rank of the q-th */ /* homology groups is (q+3)/2 for q odd. */ if( cardinal == 4, VertexTwoDim ++; numberInLabel[k] = VertexTwoDim; for( j = 2, (q+3)/2, VertexTwoDim ++; ); sortVertexRepresentativeStabilizer(k); ); /* In case of isomorphy A_4, the Z/2-rank of the q-th */ /* homology groups is zero for q = 1, and 1 for q = 3. */ if( cardinal == 12, /* if( q == 1, nothing to add ); */ if( q > 1, /* Z/2-rank at least one. */ VertexTwoDim ++; numberInLabel[k] = VertexTwoDim; ); if( q == 5 || q == 9, /* Z/2-rank two. */ VertexTwoDim ++; ); if( q == 11, /* Z/2-rank three. */ VertexTwoDim ++; VertexTwoDim ++; ); if( q > 11, error("q out of range. Check function record2primaryHomologyDimensions")); ); ); /* return */ [VertexTwoDim, numberInLabel] }; /* end of function record2primaryHomologyDimensions(q). */ getThreePrimaryPart(q, WriteDownMatrix=0) = { /* Record a matrix (d^1_{1,q})_(3) with the 3-primary part of the */ /* differential d^1_{1,q} from edge homology to vertex homology. */ /* We are interested in the cases q = 1 and q = 3, because the rank of the */ /* differential (d^1_{1,q})_(3) is periodic in q, modulo 4. */ local( VertexThreeDim, originVertex, endVertex, edgeNumber, numberInLabel); local( VertexThreeDimAndNumberInLabel, inducedMatrixEntry, threePrimaryMatrix); local( IsNonzeroTarget, Rank); /* Record the Z/3-ranks of the q-th homology groups of the vertex stabilizers. */ VertexThreeDimAndNumberInLabel = record3primaryHomologyDimensions(q); VertexThreeDim = component( VertexThreeDimAndNumberInLabel, 1); numberInLabel = component( VertexThreeDimAndNumberInLabel, 2); /* We now record the d^1_{1,q} matrices restricted to the 3-primary part. */ threePrimaryMatrix = matrix( VertexThreeDim, EdgeThreeDim); /* For every edge in edge3Label, record the following information. */ for ( j = 1, EdgeThreeDim, edgeNumber = edgeOrbitRepresentative[ edge3Label[j]]; if( length( edgeStabilizer[ edgeNumber])/2 != 3, print("***Error in function getThreePrimaryPart: edge3Label does not contain exactly the 3-torsion."); ); /* record number in totalPointSet of the origin vertex */ originVertex = setsearch( totalPointSet, component( edgesList:list[edgeNumber], 1)); /* Exclude the cases where H_q(S_3) = 0. */ IsNonzeroTarget = 1; if( length( stabilizer[ originVertex])/2 == 6, if( Mod(q,4) == Mod(1,4), IsNonzeroTarget = 0; ); ); if( IsNonzeroTarget, inducedMatrixEntry = determine3torsionStabilizerInclusion( edgeNumber, q, "origin"); /* decrease by inducedMatrixEntry the entry in the j'th column and the row number vertexOrbitNumber[originVertex] of the (d^1_{1,3})_(3) matrix. */ threePrimaryMatrix[ numberInLabel[vertexOrbitNumber[ originVertex]], j] = threePrimaryMatrix[ numberInLabel[vertexOrbitNumber[ originVertex]], j] -inducedMatrixEntry; ); /* record number in totalPointSet of the end vertex */ endVertex = setsearch( totalPointSet, component( edgesList:list[edgeNumber], 2)); /* Exclude the cases where H_q(S_3) = 0. */ IsNonzeroTarget = 1; if( length( stabilizer[ endVertex])/2 == 6, if( Mod(q,4) == Mod(1,4), IsNonzeroTarget = 0; ); ); if( IsNonzeroTarget, inducedMatrixEntry = determine3torsionStabilizerInclusion( edgeNumber, q, "end"); /* increase by inducedMatrixEntry the entry in the j'th column and the row number vertexOrbitNumber[endVertex] of the (d^1_{1,3})_(3) matrix. */ threePrimaryMatrix[ numberInLabel[vertexOrbitNumber[ endVertex]], j] = threePrimaryMatrix[ numberInLabel[vertexOrbitNumber[ endVertex]], j] +inducedMatrixEntry; ); ); if( WriteDownMatrix == 1, write(Str("(d^1_{1,",q,"})_(3)-m",m,".tex"), threePrimaryMatrix); ); Rank = matrank( Mod(threePrimaryMatrix,3) ); /* print("(d^1_{1,",q,"})_(3) has rank ", Rank, ", a kernel of dimension ",EdgeThreeDim -Rank, " and cokernel dimension ",VertexThreeDim -Rank); */ /* return */ [EdgeThreeDim -Rank, VertexThreeDim -Rank] }; /* end of function getThreePrimaryPart(q). */ getTwoPrimaryPart(q, WriteDownMatrix=0) = { /* Record a matrix (d^1_{1,q})_(2) with the 2-primary part of the */ /* differential d^1_{1,q} from edge homology to vertex homology. */ /* We are interested in the cases q = 1 and q = 3, because the rank of the */ /* differential (d^1_{1,q})_(2) equals the rank of (d^1_{1,3})_(2) for q > 3 odd. */ local( VertexTwoDim, originVertex, endVertex, edgeNumber, numberInLabel, originCardinality, endCardinality, Rank); local( VertexTwoDimAndNumberInLabel, inducedMatrixBlock, twoPrimaryMatrix); /* Record the Z/2-ranks of the q-th homology groups of the vertex stabilizers. */ VertexTwoDimAndNumberInLabel = record2primaryHomologyDimensions(q); VertexTwoDim = component( VertexTwoDimAndNumberInLabel, 1); numberInLabel = component( VertexTwoDimAndNumberInLabel, 2); /* We now record the d^1_{1,q} matrices restricted to the 2-primary part. */ twoPrimaryMatrix = matrix( VertexTwoDim, EdgeTwoDim); /* For every edge in edge2Label, record the following information. */ for ( j = 1, EdgeTwoDim, edgeNumber = edgeOrbitRepresentative[ edge2Label[j]]; /* Record the data about the origin and end points of the edge orbit: */ /* record number in totalPointSet of the origin vertex */ originVertex = setsearch( totalPointSet, component( edgesList:list[edgeNumber], 1)); /* record number in totalPointSet of the end vertex */ endVertex = setsearch( totalPointSet, component( edgesList:list[edgeNumber], 2)); if( length( edgeStabilizer[ edgeNumber])/2 != 2, print("***Error in function getTwoPrimaryPart(q): edge2Label does not contain exactly the 2-torsion."); ); /* record the stabilizer cardinality of the origin vertex */ originCardinality = length( stabilizer[originVertex])/2; /* Put a single entry into the d^1 matrix for Z/2 and S_3 targets: */ if( originCardinality == 2 || originCardinality == 6, /* decrease by 1 the entry in the j'th column and the rows of numbers vertexOrbitNumber[originVertex] of the d^1 matrix restricted to Z/2 and S_3 targets. */ twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ originVertex]], j]--; ); if( originCardinality == 4, /* Klein Four Group type */ inducedMatrixBlock = determineEdgeVertexStabilizerInclusion( edgeNumber, q, "origin"); if( inducedMatrixBlock[1] == 1, twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ originVertex]], j]--; ); if( inducedMatrixBlock[2] == 1, twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ originVertex]]+1, j]--; ); if( q >= 3, if( inducedMatrixBlock[3] == 1, twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ originVertex]]+2,j]--; ); ); ); if( originCardinality == 12, /* Alternating group on 4 objects target */ if( q > 1, /* then the differential restricted to this edge is injective. */ /* decrease by 1 the entry in the j'th column and the row of numbers vertexOrbitNumber[originVertex] of the (d^1_{1,3})_(2) matrix. */ twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ originVertex]], j]--; /* this gives a matrix block (-1,0,...,0) */ /* as described in the author's thesis. */ ); /* Zero map for q == 1. */ ); /* record the stabilizer cardinality of the end vertex */ endCardinality = length( stabilizer[endVertex])/2; /* Establish the d^1 matrix restricted to Z/2 and S_3 targets: */ if( endCardinality == 2 || endCardinality == 6, /* increase by 1 the entry in the j'th column and the row number vertexOrbitNumber[endVertex] of the d^1 matrix restricted to Z/2 and S_3 targets. */ twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ endVertex]], j]++; ); if( endCardinality == 4,/* Klein Four Group type target */ inducedMatrixBlock = determineEdgeVertexStabilizerInclusion( edgeNumber, q,"end"); if( inducedMatrixBlock[1] == 1, twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ endVertex]], j]++; ); if( inducedMatrixBlock[2] == 1, twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ endVertex]]+1, j]++; ); if( q >= 3, if( inducedMatrixBlock[3] == 1, twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ endVertex]]+2,j]++; ); ); ); if( endCardinality == 12,/* Alternating group on 4 objects target */ if( q > 1, /* then the differential restricted to this edge is injective. */ /* decrease by 1 the entry in the j'th column and the row of number vertexOrbitNumber[endVertex] of the (d^1_{1,3})_(2) matrix. */ twoPrimaryMatrix[ numberInLabel[vertexOrbitNumber[ endVertex]], j]++; /* this gives a matrix block (1,0,...,0) */ /* as described in the author's thesis. */ ); /* Zero map for q == 1. */ ); ); if( WriteDownMatrix == 1, write(Str("(d^1_{1,",q,"})_(2)-m",m,".tex"), twoPrimaryMatrix); ); Rank = matrank( Mod(twoPrimaryMatrix,2) ); /* print("(d^1_{1,",q,"})_(2) has rank ", Rank, ", a kernel of dimension ",EdgeTwoDim -Rank, " and cokernel dimension ",VertexTwoDim -Rank); */ /* return */ [Rank, VertexTwoDim] }; /* end of function getTwoPrimaryPart(q) */