############################################################################# ## #W carat.gi Interface to Carat Franz G"ahler ## #Y Copyright (C) 1999-2012 Franz G"ahler, Mathematik, Bielefeld University ## ## Input/Output routines for interfacing with Carat data files ##
############################################################################# ## #F CaratTmpFile( name ) . . . . . returns file 'name' in Carat tmp directory ##
InstallGlobalFunction( CaratTmpFile, function( name ) # if Carat temporary directory has disappeared, recreate it if not IsDirectoryPath( CARAT_TMP_DIR![1] ) then
MakeReadWriteGlobal( "CARAT_TMP_DIR" );
UnbindGlobal( "CARAT_TMP_DIR" );
BindGlobal( "CARAT_TMP_DIR", DirectoryTemporary() ); fi;
return Filename( CARAT_TMP_DIR, name ); end );
############################################################################# ## #F CaratReadLine( input ) . . . . . . . . . . read line and discard comment ##
BindGlobal( "CaratReadLine", function( input )
local str, pos;
str := ReadLine( input ); if str = fail then
return fail; fi;
pos := Position( str, '%' ); if pos <> fail then
return str{[1..pos-1]}; else
return str; fi; end );
############################################################################# ## #F CaratNextNumber( str, start ) next number in string after position start ##
# this is a hack needed in CaratNextNumber, CaratReadNumbers
CaratReadPosition := 1;
len := Length( str );
pos1 := start; while pos1 <= len and not IsDigitChar( str[pos1] ) do
pos1 := pos1 + 1;
od; if pos1 > len then
return fail; elif pos1 > 1 and str[pos1-1] = '-'then
pos1 := pos1 - 1; fi;
pos2 := pos1 + 1; while pos2 <= len and IsDigitChar( str[pos2] ) do
pos2 := pos2 + 1;
od;
CaratReadPosition := pos2;
str := ReadLine( input );
n := CaratNextNumber( str, 1 ); while n <> fail do
Add( res, n );
nread := nread + 1;
n := CaratNextNumber( str, CaratReadPosition );
od;
od;
return res;
end );
############################################################################# ## #F CaratReadMatrixScalar( input, dim ) . . . . read scalar matrix from input ##
BindGlobal( "CaratReadMatrixScalar", function( input, dim )
local lst;
lst := CaratReadNumbers( input, 1 );
return lst[1] * IdentityMat( dim ); end );
############################################################################# ## #F CaratReadMatrixDiagonal( input, dim ) . . read diagonal matrix from input ##
BindGlobal( "CaratReadMatrixDiagonal", function( input, dim )
local lst, mat, i;
lst := CaratReadNumbers( input, dim );
mat := List( [1..dim], i -> List( [1..dim], j -> 0 ) ); for i in [1..dim] do
mat[i][i] := lst[i];
od;
return mat; end );
############################################################################# ## #F CaratReadMatrixSymmetric( input, dim ) . read symmetric matrix from input ##
BindGlobal( "CaratReadMatrixSymmetric", function( input, dim )
local lst, mat, pos, i, j;
lst := CaratReadNumbers( input, dim*(dim+1)/2 );
mat := [];
pos := 1; for i in [1..dim] do
Add( mat, lst{[pos..pos+i-1]} );
pos := pos + i;
od; for i in [1..dim-1] do for j in [i+1..dim] do
mat[i][j] := mat[j][i];
od;
od;
return mat; end );
############################################################################# ## #F CaratReadMatrixFull( input, n, m ) . . . . . . read nxm matrix from input ##
BindGlobal( "CaratReadMatrixFull", function( input, n, m )
local lst;
lst := CaratReadNumbers( input, n*m );
return List( [1..n], i -> lst{[ (i-1)*m+1 .. i*m ]}); end );
# is matrix rational?
pos := Position( str, '/' ); if pos <> fail then
den := CaratNextNumber( str, pos + 1 ); else
den := 1; fi;
# matrix format with 'x'
pos := Position( str, 'x' ); if pos <> fail then
m := CaratNextNumber( str, pos + 1 ); if m > 0then
return CaratReadMatrixFull( input, n, m ) / den; else
return CaratReadMatrixSymmetric( input, n ) / den; fi; fi;
# matrix format with 'd'
pos := Position( str, 'd' ); if pos <> fail then
m := CaratNextNumber( str, pos + 1 ); if m = 1then
return CaratReadMatrixDiagonal( input, n ) / den; else
return CaratReadMatrixScalar( input, n ) / den; fi;
fi;
# full square matrix
return CaratReadMatrixFull( input, n, n ) / den;
end );
############################################################################# ## #F CaratReadMatrices( input, n ) . .. . . . . . . read n matrices from input ##
BindGlobal( "CaratReadMatrices", function( input, n )
local res, i, str;
res := []; for i in [1..n] do
str := CaratReadLine( input );
Add( res, CaratReadMatrix( input, str ) );
od;
return res;
# several matrices if pos <> fail then
n := CaratNextNumber( str, pos + 1 );
res := CaratReadMatrices( input, n );
# just one matrix else
res := CaratReadMatrix( input, str ); fi;
CloseStream( input );
return res;
end );
############################################################################# ## ## A bravais record is a record with components ## ## generators: generators of the group ## formspace: basis of space of invariant forms (optional) ## centerings: basis of centering matrices (optional) ## normalizer: additional generators of normalizer in GL(n,Z) (optional) ## centralizer: additional generators of centralizer in GL(n,Z) (optional) ## size: size of the group ##
# read group generators
pos := Position( str, 'g' );
# normal Bravais file format if pos <> fail then
n := CaratNextNumber( str, pos + 1 );
res.generators := CaratReadMatrices( input, n );
# just generators, matrix file format # could the size also be given? else
n := CaratNextNumber( str, 2 );
res.generators := CaratReadMatrices( input, n );
return res; fi;
# read form space basis
pos := Position( str, 'f' ); if pos <> fail then
n := CaratNextNumber( str, pos + 1 );
res.formspace := CaratReadMatrices( input, n ); fi;
# read centering matrices
pos := Position( str, 'z' ); if pos <> fail then
n := CaratNextNumber( str, pos + 1 );
res.centerings := CaratReadMatrices( input, n ); fi;
# read normalizer generators
pos := Position( str, 'n' ); if pos <> fail then
n := CaratNextNumber( str, pos + 1 );
res.normalizer := CaratReadMatrices( input, n ); fi;
# read centralizer generators
pos := Position( str, 'c' ); if pos <> fail then
n := CaratNextNumber( str, pos + 1 );
res.centralizer := CaratReadMatrices( input, n ); fi;
# read size of the group; is optional, but not announced in the header
line := ReadLine( input ); if line <> fail then
pos := Position( line, '=' ); if pos <> fail then
res.size := CaratNextNumber( line, pos + 1 ); fi; fi;
input := InputTextFile( filename );
str := CaratReadLine( input );
res := rec( info := [], groups := [] );
# read comments until first Bravais record starts while Length( str ) < 2 or str{[1..2]} <> "#g" do
Add( res.info, str );
str := CaratReadLine( input );
od;
# read the Bravais records while str <> fail and Length( str ) >= 2 and str{[1..2]} = "#g" do
Add( res.groups, CaratReadBravaisRecord( input, str ) );
str := CaratReadLine( input );
od;
CloseStream( input );
return res;
end );
############################################################################# ## #F CaratWriteMatrix( output, mat ) . . . . . . write Carat matrix to stream ##
BindGlobal( "CaratWriteMatrix", function( output, mat )
local d, str, i, j;
# for simplicity, we always write in full format
d := DimensionsMat( mat ); if d[1]=d[2] then
str := String( d[1] ); else
str := Concatenation( String( d[1] ), "x", String( d[2] ) ); fi;
WriteLine( output, str ); for i in [1..d[1]] do
str := "";
Append( str, String( mat[i][1] ) ); for j in [2..d[2]] do
Append( str, " " );
Append( str, String( mat[i][j] ) );
od;
WriteLine( output, str );
od;
end );
############################################################################# ## #F CaratWriteMatrixFile( filename, data ) . write Carat matrix data to file ##
InstallGlobalFunction( CaratWriteMatrixFile, function( filename, data )
local output, header, mat;
output := OutputTextFile( filename, false );
# one matrix if IsMatrix( data ) then
CaratWriteMatrix( output, data );
# list of matrices else
header := Concatenation( "#", String( Length( data ) ) );
WriteLine( output, header ); for mat in data do
CaratWriteMatrix( output, mat );
od; fi;
CloseStream( output );
end );
############################################################################# ## #F CaratFactorString( n ) . . . . factorization of n in Carat string format ##
BindGlobal( "CaratFactorString", function( n )
local fac, set, ExpStr, str, p;
fac := FactorsInt( n );
set := Set( fac );
ExpStr := function( n )
return String( Number( fac, x -> x = n ) ); end;
# did it work? if err > 0then if err = 2 and args <> "-h"then# we used wrong arguments
CaratShowFile( outfile ); # contains usage advice else
CaratShowFile( outfile );
Error( "Carat program ", command, " failed with error code ", err, " and the above output" ); fi; fi; if err < 0 and args <> "-h"then
Error( "Carat program ", command, " failed with error code ", err ); fi;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.