> < ^ Date: Mon, 28 Apr 2003 20:04:23 +0200 (CEST)
> < ^ From: Franz Gaehler <gaehler@itap.physik.uni-stuttgart.de >
> ^ Subject: Re: Crystal lattice and cohomology

Dear Forum

I have to correct part of my recent reply to a posting of John Huesman:

Another option, which is available also for non-solvable groups G,
is to make use of the isomorphism between H^1(G,L) and H^0(G,R^n/L).
This isomorphism holds whenever G is finite, for the same reasons
as the isomorphism between H^2(G,L) and H^1(G,R^n/L).

This isomorphism relies on H^0(G,R^n) being zero. I was under the
impression that this was always the case, but Derek Holt pointed
out to me that this is not true. In fact, H^0(G,R^n) is zero if and
only if there is no vector in R^n left invariant by G. Clearly,
there are groups G with invariant vectors, and for those the method
I proposed does not work. I am sorry for this confusion.

As a little compensation I am offering routines, with the help of which
one can complete the solution proposed by Derek Holt. He posted
functions to compute matrices whose integral kernel, resp. row space,
generate the cocycles and coboundaries of the cohomology group
H^1(G,Z^n). The functions appended below can be used to compute a
basis of the integral row space and integral kernel of an integer
matrix. There is also a function to compute the structure
of the quotient of two row modules over the integers. With these
functions, and the ones posted by Derek Holt, H^1(G,Z^n) is then
computed as follows:

gap> gens := GeneratorsOfGroup(G);
[ [ [ -1, 0, 0 ], [ 0, -1, 0 ], [ 0, 0, -1 ] ], 
  [ [ -1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, -1 ] ] ]
gap> F := Image( IsomorphismFpGroupByGenerators( G, gens ) );
<fp group of size 4 on the generators [ F1, F2 ]>
gap> Z1 := IntegralKernel( Z1Mat( F, gens ) );
[ [ 1, 0, 0, 1, 0, 0 ], [ 0, 1, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 1 ] ]
gap> B1 := IntegralImage( B1GM ( F, gens ) );
[ [ 2, 0, 0, 2, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 0, 2, 0, 0, 2 ] ]
gap> complement( B1, Z1 );
rec( free := [  ], 
  torsion := [ [ 2, 0, 0, 2, 0, 0 ], [ 0, 2, 0, 0, 0, 0 ], [ 0, 0, 2, 0, 0, 2 
         ] ], mods := [ 2, 2, 2 ] )

The quotient Z1/B1 is a pure torsion module here.

Best regards,

Franz Gaehler

_____________________________________________________________________________
Dr. Franz Gähler             Phone  +49 711 / 685 52 60 
ITAP, Universität Stuttgart  Fax    +49 711 / 685 52 71
Pfaffenwaldring 57           Email  gaehler@itap.physik.uni-stuttgart.de
70550 Stuttgart, Germany     http://www.itap.physik.uni-stuttgart.de/~gaehler



############################################################################
#
# basis of integral image of <mat>
#
IntegralImage := function( mat )
  local norm;
  if mat = [] then return mat; fi;
  norm := NormalFormIntMat( mat, 2 );
  return norm.normal{[1..norm.rank]};
end;

############################################################################
#
# basis of integral kernel of <mat>
#
IntegralKernel := function( mat )
  local norm, kern;
  norm := NormalFormIntMat( mat, 4 );
  kern := norm.rowtrans{[norm.rank+1..Length(mat)]};
  return IntegralImage( kern );
end;

############################################################################
#
# basis of intersection of two integral row modules
#
IntegralIntersection := function( M1, M2 )
  local M, Q, r, T;
  if M1 = [] or M2 = [] then return []; fi;
  M := Concatenation( M1, M2 );
  r := NormalFormIntMat( M, 4 );
  T := r.rowtrans{[r.rank+1..Length(M)]}{[1..Length(M1)]} * M1;
  return IntegralImage( T );
end;

############################################################################
#
# complement of <sub> in <full>, two row modules over the integers
#
# returns a record with components free, torsion, and mods, such that:
# - the rows of torsion form a basis of sub
# - the rows of free generate a free complement of sub in full
# - the rows of free and the vectors torsion[i]/mods[i] form a
#   basis of <full>
#
complement := function( sub, full )
    local F, S, M, r, T, R;
    F := IntegralImage( full );
    if IsEmpty( sub ) or IsZero( sub ) then 
      return rec( free := F, torsion := [], mods := [] );
    fi;
    S := IntegralIntersection( F, sub );
    if S <> IntegralImage( sub ) then
        Error( "sub must be submodule of full" );
    fi;
# find unimodular T such that image(T*F) = S
M := Concatenation( F, S );
T := NormalFormIntMat( M, 4 ).rowtrans^-1;
T := T{[Length(F)+1..Length(T)]}{[1..Length(F)]};
    # r.rowtrans * T * F = r.normal * r.coltrans^-1 * F
    r := NormalFormIntMat( T, 13 );
    M := r.coltrans^-1 * F;
    R := rec( free    := IntegralImage( M{[1+r.rank..Length(M)]} ),
              torsion := r.rowtrans * T * F,
              mods    := List( [1..r.rank], i -> r.normal[i][i] ) );
    return R;
end;

> < [top]