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 methods.gi Interface to Carat Franz G"ahler ## #Y Copyright (C) 1999-2012 Franz G"ahler, Mathematik, Bielefeld University ## ## Methods for high level functions using Carat ## ############################################################################# ## #M BravaisGroup( grp ) . . . . . . . . . . . . . . . . Bravais group of grp ## InstallMethod( BravaisGroup, "with Carat function Bravais_grp", true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) local grpfile, resfile, gen, data, res; # group must be integer and finite if not IsIntegerMatrixGroup( grp ) then Error( "grp must be an integer matrix group" ); fi; if not IsFinite( grp ) then Error( "grp must be finite" ); fi; # get temporary file names grpfile := CaratTmpFile( "grp" ); resfile := CaratTmpFile( "res" ); # write Carat input to temporary file gen := GeneratorsOfGroup( grp ); if gen = [] then gen := [ One(grp) ]; fi; data := rec( generators := gen, size := Size( grp ) ); CaratWriteBravaisFile( grpfile, data ); # execute Carat program CaratCommand( "Bravais_grp", grpfile, resfile ); # read back result, and remove temporary files data := CaratReadBravaisFile( resfile ); RemoveFile( grpfile ); RemoveFile( resfile ); # convert result to appropriate format res := GroupByGenerators( data.generators, One( grp ) ); if IsBound( data.size ) then SetSize( res, data.size ); fi; return res; end ); ############################################################################# ## #F CaratBravaisInclusions( grp, opt ) . . . . .Bravais inclusions (internal) ## CaratBravaisInclusions := function( grp, opt ) local grpfile, resfile, gen, data, args, output, grps, str, res, g, r; # get temporary file names grpfile := CaratTmpFile( "grp" ); resfile := CaratTmpFile( "res" ); # write Carat input to file gen := GeneratorsOfGroup( grp ); if gen = [] then gen := [ One(grp) ]; fi; data := rec( generators := gen, size := Size( grp ) ); CaratWriteBravaisFile( grpfile, data ); # execute Carat program args := Concatenation( grpfile, " -G", opt ); CaratCommand( "Bravais_inclusions", args, resfile ); # read Carat result from file, and remove temporary files data := CaratReadMultiBravaisFile( resfile ); grps := data.groups; RemoveFile( grpfile ); RemoveFile( resfile ); # convert result into desired format res := []; for r in grps do g := GroupByGenerators( r.generators, One(grp) ); SetSize( g, r.size ); Add( res, g ); od; return res; end; ############################################################################# ## #M BravaisSubgroups( grp ) . . . . Bravais subgroups of Bravais group of grp ## InstallMethod( BravaisSubgroups, "with Carat function Bravais_inclusions", true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) if DimensionOfMatrixGroup( grp ) > 6 then Error( "sorry, only groups of dimension up to 6 are supported" ); fi; return CaratBravaisInclusions( BravaisGroup( grp ), "" ); end ); ############################################################################# ## #M BravaisSupergroups( grp ) . . Bravais supergroups of Bravais group of grp ## InstallMethod( BravaisSupergroups, "with Carat function Bravais_inclusions", true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) if DimensionOfMatrixGroup( grp ) > 6 then Error( "sorry, only groups of dimension up to 6 are supported" ); fi; return CaratBravaisInclusions( BravaisGroup( grp ), " -S" ); end ); ############################################################################# ## #F CaratNormalizerInGLnZFunc( G, opt ) . . . . . normalizer of G in GL(n,Z) ## CaratNormalizerInGLnZFunc := function( grp, opt ) local grpfile, resfile, gen, data, output, res, args; # group must be integer and finite if not IsIntegerMatrixGroup( grp ) then Error( "grp must be an integer matrix group" ); fi; if not IsFinite( grp ) then Error( "grp must be finite" ); fi; # get temporary files grpfile := CaratTmpFile( "grp" ); resfile := CaratTmpFile( "res" ); # write input data gen := GeneratorsOfGroup(grp); if gen = [] then gen := [ One(grp) ]; fi; data := rec( generators := gen, size := Size( grp ) ); CaratWriteBravaisFile( grpfile, data ); # execute Carat command args := Concatenation( grpfile, opt ); CaratCommand( "Normalizer", args, resfile ); # read back the data data := CaratReadBravaisFile( resfile ); RemoveFile( grpfile ); RemoveFile( resfile ); # construct result gen := Concatenation( data.generators, data.normalizer ); res := GroupByGenerators( gen, One( grp ) ); return res; end; ############################################################################# ## #M NormalizerInGLnZ( G ) . . . Normalizer of integer matrix group in GL(n,Z) ## InstallMethod( NormalizerInGLnZ, "with Carat function Normalizer", true, [ IsCyclotomicMatrixGroup ], 0, G -> CaratNormalizerInGLnZFunc( G, "" ) ); InstallMethod( NormalizerInGLnZ, "with Carat function Normalizer", true, [ IsCyclotomicMatrixGroup and IsBravaisGroup ], 0, NormalizerInGLnZBravaisGroup ); InstallMethod( NormalizerInGLnZ, "via Bravais group", true, [ IsCyclotomicMatrixGroup and HasBravaisGroup ], 0, G -> Normalizer( NormalizerInGLnZ( BravaisGroup( G ) ), G ) ); ############################################################################# ## #M NormalizerInGLnZBravaisGroup( G ) norm. of Bravais group of G in GL(n,Z) ## InstallMethod( NormalizerInGLnZBravaisGroup, "with Carat function Normalizer", true, [ IsCyclotomicMatrixGroup ], 0, function(G) local N; N := CaratNormalizerInGLnZFunc( G, " -b" ); if HasBravaisGroup( G ) then SetNormalizerInGLnZ( BravaisGroup( G ), N ); fi; return N; end ); ############################################################################# ## #M CentralizerInGLnZ( G ) . . . . . . . . . . . . . . Centralizer in GL(n,Z) ## InstallMethod( CentralizerInGLnZ, "via NormalizerInGLnZ", true, [ IsCyclotomicMatrixGroup ], 0, function( G ) local N; if HasBravaisGroup( G ) and not HasNormalizerInGLnZ( G ) then N := NormalizerInGLnZ( BravaisGroup( G ) ); else N := NormalizerInGLnZ( G ); fi; return Centralizer( N, G ); end ); ############################################################################# ## #M RepresentativeAction( GL( n, Integers), G1, G2 ) . . . . . . . . . . . . #M returns m in GL(n,Z) with m*G1*m^-1 = G2 ## InstallOtherMethod( RepresentativeActionOp, "with Carat function Z_equiv", true, [ IsNaturalGLnZ, IsCyclotomicMatrixGroup, IsCyclotomicMatrixGroup, IsFunction ], 0, function( glnz, grp1, grp2, opr ) local grp1file, grp2file, resfile, args, gen, data, input, line, res; # groups must be integer if not IsIntegerMatrixGroup( grp1 ) then Error( "grp1 must be an integer matrix group" ); fi; if not IsIntegerMatrixGroup( grp2 ) then Error( "grp2 must be an integer matrix group" ); fi; # groups must be finite if not IsFinite( grp1 ) then Error( "grp1 must be finite" ); fi; if not IsFinite( grp2 ) then Error( "grp2 must be finite" ); fi; # catch the trivial case if grp1 = grp2 then return IdentityMat( DimensionOfMatrixGroup( grp1 ) ); fi; # get temporary file names grp1file := CaratTmpFile( "grp1" ); grp2file := CaratTmpFile( "grp2" ); resfile := CaratTmpFile( "res" ); # write Carat input to temporary files gen := GeneratorsOfGroup( grp1 ); if gen = [] then gen := [ One(grp1) ]; fi; data := rec( generators := gen, size := Size(grp1) ); CaratWriteBravaisFile( grp1file, data ); gen := GeneratorsOfGroup( grp2 ); if gen = [] then gen := [ One(grp2) ]; fi; data := rec( generators := gen, size := Size(grp2) ); CaratWriteBravaisFile( grp2file, data ); # execute Carat program args := Concatenation( grp2file, " ", grp1file ); CaratCommand( "Z_equiv", args, resfile ); # read back the result input := InputTextFile( resfile ); line := CaratReadLine( input ); if line = "the groups are not conjugated in GL_n(Z)\n" then res := fail; else res := CaratReadMatrix( input, line ); fi; CloseStream( input ); # remove temporary files RemoveFile( grp1file ); RemoveFile( grp2file ); RemoveFile( resfile ); return res; end ); ############################################################################# ## #M ZClassRepsQClass( grp ) . . . . . . . . . Z-class reps in Q-class of grp ## InstallMethod( ZClassRepsQClass, "with Carat function QtoZ", true, [ IsCyclotomicMatrixGroup ], 0, function( grp ) local grpfile, resfile, gen, data, output, str, res, g, r; # group must be rational and finite if not IsRationalMatrixGroup( grp ) then Error( "grp must be a rational matrix group" ); fi; if not IsFinite( grp ) then Error( "grp must be finite" ); fi; # get temporary file names grpfile := CaratTmpFile( "grp" ); resfile := CaratTmpFile( "res" ); # write Carat input to file gen := GeneratorsOfGroup( grp ); if gen = [] then gen := [ One(grp) ]; fi; data := rec( generators := gen, size := Size(grp) ); CaratWriteBravaisFile( grpfile, data ); # execute Carat program CaratCommand( "QtoZ", Concatenation( grpfile, " -q" ), resfile ); # read Carat result from file, and remove temporary files data := CaratReadMultiBravaisFile( resfile ); RemoveFile( grpfile ); RemoveFile( resfile ); # convert result into desired format res := []; for r in data.groups do g := GroupByGenerators( r.generators ); SetSize( g, r.size ); Add( res, g ); od; return res; end ); ############################################################################# ## #M CaratCrystalFamilies . . . . . . . . . . .crystal family symbols in Carat ## InstallValue( CaratCrystalFamilies, [ [ "1" ], [ "1,1", "1;1", "2-1", "2-2"], [ "1,1,1", "1,1;1", "1;1;1", "2-1;1", "2-2;1", "3" ], [ "1,1,1,1", "1,1,1;1", "1,1;1,1", "1,1;1;1", "1;1;1;1", "2-1',2-1'", "2-1,2-1", "2-1;1,1", "2-1;1;1", "2-1;2-1", "2-1;2-2", "2-2',2-2'", "2-2,2-2", "2-2;1,1", "2-2;1;1", "2-2;2-2", "3;1", "4-1", "4-1'", "4-2", "4-2'", "4-3", "4-3'" ], [ "1,1,1,1,1", "1,1,1,1;1", "1,1,1;1,1", "1,1,1;1;1", "1,1;1,1;1", "1,1;1;1;1", "1;1;1;1;1", "2-1',2-1';1", "2-1,2-1;1", "2-1;1,1,1", "2-1;1,1;1", "2-1;1;1;1", "2-1;2-1;1", "2-1;2-2;1", "2-2',2-2';1", "2-2,2-2;1", "2-2;1,1,1", "2-2;1,1;1", "2-2;1;1;1", "2-2;2-2;1", "3;1,1", "3;1;1", "3;2-1", "3;2-2", "4-1';1", "4-1;1", "4-2';1", "4-2;1", "4-3';1", "4-3;1", "5-1", "5-2" ], [ "1,1,1,1,1,1", "1,1,1,1,1;1", "1,1,1,1;1,1", "1,1,1,1;1;1", "1,1,1;1,1,1", "1,1,1;1,1;1", "1,1,1;1;1;1", "1,1;1,1;1,1", "1,1;1,1;1;1", "1,1;1;1;1;1", "1;1;1;1;1;1", "2-1',2-1',2-1'", "2-1',2-1';1,1", "2-1',2-1';1;1", "2-1',2-1';2-1", "2-1',2-1';2-2", "2-1,2-1,2-1", "2-1,2-1;1,1", "2-1,2-1;1;1", "2-1,2-1;2-1", "2-1,2-1;2-2", "2-1;1,1,1,1", "2-1;1,1,1;1", "2-1;1,1;1,1", "2-1;1,1;1;1", "2-1;1;1;1;1", "2-1;2-1;1,1", "2-1;2-1;1;1", "2-1;2-1;2-1", "2-1;2-1;2-2", "2-1;2-2',2-2'", "2-1;2-2,2-2", "2-1;2-2;1,1", "2-1;2-2;1;1", "2-1;2-2;2-2", "2-2',2-2',2-2'", "2-2',2-2';1,1", "2-2',2-2';1;1", "2-2',2-2';2-2", "2-2,2-2,2-2", "2-2,2-2;1,1", "2-2,2-2;1;1", "2-2,2-2;2-2", "2-2;1,1,1,1", "2-2;1,1,1;1", "2-2;1,1;1,1", "2-2;1,1;1;1", "2-2;1;1;1;1", "2-2;2-2;1,1", "2-2;2-2;1;1", "2-2;2-2;2-2", "3,3", "3;1,1,1", "3;1,1;1", "3;1;1;1", "3;2-1;1", "3;2-2;1", "3;3", "4-1';1,1", "4-1';1;1", "4-1';2-1", "4-1';2-2", "4-1;1,1", "4-1;1;1", "4-1;2-1", "4-1;2-2", "4-2';1,1", "4-2';1;1", "4-2';2-1", "4-2';2-2", "4-2;1,1", "4-2;1;1", "4-2;2-1", "4-2;2-2", "4-3';1,1", "4-3';1;1", "4-3';2-1", "4-3';2-2", "4-3;1,1", "4-3;1;1", "4-3;2-1", "4-3;2-2", "5-1;1", "5-2;1", "6-1", "6-2", "6-2'", "6-3", "6-3'", "6-4", "6-4'" ] ] ); ############################################################################# ## #M CaratCrystalFamiliesFlat . . flat list of crystal family symbols in Carat ## CaratPermutedSymbols := function( symb ) local str, lst, pos, new, l, i; str := symb; lst := []; pos := Position( str, ';' ); while pos <> fail do Add( lst, str{[1..pos-1]} ); str := str{[pos+1..Length(str)]}; pos := Position( str, ';' ); od; Add( lst, str ); lst := PermutationsList( lst ); new := []; for l in lst do str := l[1]; for i in [2..Length(l)] do str := Concatenation( str, ";", l[i] ); od; Add( new, str ); od; return new; end; InstallValue( CaratCrystalFamiliesFlat, Concatenation( List( Concatenation( CaratCrystalFamilies ), CaratPermutedSymbols ) ) ); ############################################################################# ## #M BravaisGroupsCrystalFamily( symb ) . . . Bravais groups in crystal family ## InstallGlobalFunction( BravaisGroupsCrystalFamily, function( symb ) local resfile, outfile, input, command, program, output, err, data, str, res, g, r; if not symb in CaratCrystalFamiliesFlat then Error("invalid crystal family symbol - please consult Carat manual"); fi; # get temporary file name resfile := CaratTmpFile( "res" ); outfile := CaratTmpFile( "out" ); input := InputTextString( Concatenation( symb, "\ny\n", resfile, "\na\n")); # find executable command := "Bravais_catalog"; program := Filename( CARAT_BIN_DIR, command ); if program = fail then Error( Concatenation( "Carat program ", command, " not found." ) ); fi; # execute command output := OutputTextFile( outfile, false ); err := Process( DirectoryCurrent(), program, input, output, [ ] ); CloseStream( output ); # did it work? if err = 2 then # we used wrong arguments CaratShowFile( resfile ); # contains usage advice fi; if err < 0 then Error( Concatenation( "Carat program ", command, " failed with error code ", String(err) ) ); fi; # read Carat result from file, and remove temporary file data := CaratReadMultiBravaisFile( resfile ); RemoveFile( resfile ); # convert result into desired format res := []; for r in data.groups do g := GroupByGenerators( r.generators ); SetSize( g, r.size ); Add( res, g ); od; return res; end ); ############################################################################# ## #F CaratQClassCatalog( grp, mode ) . . . . . . . . . access QClass catalog ## ## Takes a finite unimodular group <grp> and an integer <mode>, and ## returns a record with one or several of the following components, ## depending on the decomposition of <mode> = <n0> + <n1> * 2 + <n2> * 4 ## into powers of 2: ## ## qclass Q-class symbol - always present ## familysymb crystal family symbol - present if <n0> <> 0 ## trans trafo to standard rep. - present if <n1> <> 0 ## group standard representation - present if <n2> <> 0 ## InstallGlobalFunction( CaratQClassCatalog, function( grp , mode ) local rem, with_symb, with_trans, with_group, grpfile, resfile, gen, res, data, args, input, str; # check options rem := mode mod 2; mode := (mode - rem) / 2; with_symb := rem <> 0; rem := mode mod 2; mode := (mode - rem) / 2; with_trans := rem <> 0; rem := mode mod 2; mode := (mode - rem) / 2; with_group := rem <> 0; # group must be integer and finite if not IsIntegerMatrixGroup( grp ) then Error( "grp must be an integer matrix group" ); fi; if not IsFinite( grp ) then Error( "grp must be finite" ); fi; # get temporary file names grpfile := CaratTmpFile( "grp" ); resfile := CaratTmpFile( "res" ); # write Carat input to temporary file gen := GeneratorsOfGroup( grp ); if gen = [] then gen := [ One(grp) ]; fi; data := rec( generators := gen, size := Size( grp ) ); CaratWriteBravaisFile( grpfile, data ); # add options args := grpfile; if with_symb then args := Concatenation( args, " -s" ); fi; if with_trans then args := Concatenation( args, " -T" ); fi; if with_group then args := Concatenation( args, " -i" ); fi; # execute Carat program CaratCommand( "Q_catalog", args, resfile ); # parse the result file res := rec(); input := InputTextFile( resfile ); # get the QClass name str := CaratReadLine( input ); if str{[1..22]} <> "Name of this Q-class: " then Error( Concatenation( "Carat program Q_catalog failed with message\n", str ) ); fi; res.qclass := str{[23..Length(str)-1]}; # get the family symbol if with_symb then str := CaratReadLine( input ); res.familysymb := str{[21..Length(str)-1]}; fi; # get the transformation matrix if with_trans then str := CaratReadLine( input ); res.trans := CaratReadMatrix( input, str ); fi; # get the equivalent catalog group if with_group then str := CaratReadLine( input ); data := CaratReadBravaisRecord( input, str ); res.group := GroupByGenerators( data.generators, One( grp ) ); if IsBound( data.size ) then SetSize( res.group, data.size ); fi; fi; return res; end ); ############################################################################# ## #F ConjugatorQClass( G1, G2 ) . . . . . .returns C in GL(n,Q) with G1^C = G2 ## InstallGlobalFunction( "ConjugatorQClass", function( G1, G2 ) local R1, R2; if not IsIntegerMatrixGroup( G1 ) or not IsFinite( G1 ) then Error( "G1 must be a finite integer matrix group" ); fi; if not IsIntegerMatrixGroup( G2 ) or not IsFinite( G2 ) then Error( "G2 must be a finite integer matrix group" ); fi; if DimensionOfMatrixGroup( G1 ) <> DimensionOfMatrixGroup( G2 ) then return fail; fi; if Size( G1 ) <> Size( G2 ) then return fail; fi; if DimensionOfMatrixGroup(G1) > 6 or DimensionOfMatrixGroup(G2) > 6 then Error( "ConjugatorQClass: only dimensions up to 6 are supported "); fi; R1 := CaratQClassCatalog( G1, 2 ); R2 := CaratQClassCatalog( G2, 2 ); if R1.qclass <> R2.qclass then return fail; else return R2.trans^-1*R1.trans; fi; end ); ############################################################################# ## #F CaratInvariantFormSpace( grp [, opts] ) . . . . space of invariant forms ## CaratInvariantFormSpace := function( arg ) local grp, opts, optstring, gens, lat, ilat, tilat, grpfile, resfile, forms; # check arguments grp := arg[1]; if not IsRationalMatrixGroup( grp ) then Error( "grp must be a rational matrix group" ); fi; if Length( arg ) > 1 then opts := arg[2]; if not IsRecord( opts ) then Error( "opts must be a record" ); fi; else opts := rec(); fi; # process options optstring := ""; if IsBound( opts.mode ) then if opts.mode = "all" then Append( optstring, " -a" ); elif opts.mode = "skew" then Append( optstring, " -s" ); elif opts.mode <> "sym" then Error( "opts.mode must be \"sym\", \"skew\", or \"all\"" ); fi; fi; if IsBound( opts.prime ) then if not IsPrime( opts.prime ) then Error( "opts.prime must be a prime" ); fi; Append( optstring, " -p=" ); Append( optstring, String( opts.prime ) ); fi; # convert to integer matrix group gens := GeneratorsOfGroup( grp ); if not IsIntegerMatrixGroup( grp ) then lat := InvariantLattice( grp ); if IsBool( lat ) then return fail; fi; ilat := lat^-1; gens := List( gens, m -> TransposedMat( lat * m * ilat ) ); else gens := List( gens, m -> TransposedMat( m ) ); fi; # get temporary file names grpfile := CaratTmpFile( "grp" ); resfile := CaratTmpFile( "res" ); optstring := Concatenation( grpfile, optstring ); # write Carat input to temporary file CaratWriteBravaisFile( grpfile, rec( generators := gens ) ); # execute Carat program CaratCommand( "Form_space", optstring, resfile ); # read back result, and remove temporary files forms := CaratReadMatrixFile( resfile ); RemoveFile( grpfile ); RemoveFile( resfile ); # convert to original basis if not IsIntegerMatrixGroup( grp ) then tilat := TransposedMat( ilat ); forms := List( forms, m -> ilat * m * tilat ); fi; return forms; end;