Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## #W union.gi Karel Dekimpe #W Bettina Eick ## ############################################################################# ## #F GenericDeterminantMat( mat ) ## GenericDeterminantMat := function( mat ) local d, det, sig, i, sub; # set up d := Length( mat ); if ForAny( mat, x -> Length(x) <> d ) then return fail; fi; # the trivial cases if d = 1 then return mat[1][1]; fi; if d = 2 then return mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1]; fi; # otherwise use first row and recursion det := 0; sig := 1; for i in [1..d] do sub := Concatenation( [1..i-1], [i+1..d] ); sub := mat{[2..d]}{sub}; det := det + sig * mat[1][i] * GenericDeterminantMat( sub ); sig := - sig; od; return det; end; ############################################################################# ## #F NullspaceIntMod( base, vec, p ) . . . . . . . . . . . . b * vec = 0 mod p ## ## computes those elements b in <base> with b * vec = 0 mod p. Returns a ## triangulized basis with respect to <base>. ## NullspaceIntMod := function( base, vec, p ) local imgs, d, null; # get images imgs := List( base, x -> x * vec ); imgs := List( imgs, x -> x mod p ); d := Length( imgs ); if ForAll( imgs, x -> x = 0 ) then return IdentityMat( d ); fi; # compute kernel of imgs vector - must have rank d-1 Add( imgs, p ); null := NullspaceIntMat( TransposedMat( [imgs] ) ); null := List( null, x -> x{[1..d]} ); null := NormalFormIntMat( null, 0 ).normal; # return this images nullspace return Filtered( null, x -> PositionNonZero(x) <= d ); end; ############################################################################# ## #F FindMaximals( sub ) . . . . . . . .subgroups which are maximal within sub ## FindMaximals := function( sub ) local new, i, tmp; new := []; for i in [1..Length(sub)] do if Size( sub[i] ) > 1 then if Length(new) = 0 then Add( new, sub[i] ); elif not ForAny( new, x -> IsSubset( x, sub[i] ) ) then tmp := Filtered( new, x -> not IsSubset( sub[i], x ) ); Add( new, sub[i] ); fi; fi; od; return new; end; if not IsBound( SizeOfUnion ) then SizeOfUnion := false; fi; ############################################################################# ## #F SizeOfUnionRec( sub ) -- recursive version ## SizeOfUnionRec := function( list ) local s, i, int, t, n; if Length( list ) = 0 then return 1; fi; s := Size( list[1] ); n := Length( list ); for i in [2..n] do int := List( list{[1..i-1]}, x -> Intersection( x, list[i])); t := SizeOfUnion( int ); s := s + Size( list[i] ) - t; od; return s; end; ############################################################################# ## #F SizeOfUnionTriv -- trivial version ## SizeOfUnionTriv := function( list ) return Length( Union( List( list, Elements ) ) ); end; ############################################################################# ## #F SizeOfUnion -- main function ## SizeOfUnion := function( sub ) local list; list := FindMaximals( sub ); if Length(list) = 0 then return 1; fi; if Length(list) = 1 then return Size(list[1]); fi; if Sum(List(list, Size)) < 2000 then return SizeOfUnionTriv(list); fi; return SizeOfUnionRec(list); end; ############################################################################# ## #F SizeOfUnionMod( subs, e ) . . . . . . . . .size of the union of subs mod e ## ## <subs> is a list of bases containing (eZ)^d. Compute the size of the union ## of <subs> in (Z/eZ)^d. ## ## This function needs to be profiled. ## SizeOfUnionMod := function( subs, e ) local d, F, V, b, news; # the trivial case if Length( subs ) = 0 then return 1; fi; d := Length( subs[1] ); if IsPrimeInt( e ) then F := GF(e); V := F^d; b := BasisVectors( Basis( V ) ); news := List( subs, x -> x * b ); news := List( news, x -> Subspace( V, x ) ); if ForAny( news, x -> Size(x) = e^d ) then return e^d; fi; # return SizeOfUnion( news ); return Length( Union( List( news, Elements ) ) ); fi; V := AbelianGroup( List( [1..d], x -> e ) ); b := GeneratorsOfGroup(V); news := List( subs, x -> List( x, y -> MappedVector( y, b ) ) ); news := List( news, x -> Subgroup( V, x ) ); if ForAny( news, x -> Size(x) = e^d ) then return e^d; fi; # return SizeOfUnion( news ); return Length( Union( List( news, Elements ) ) ); end;