#############################################################################
##
#W  ctblfuns.gd                 GAP library                     Thomas Breuer
##
#H  @(#)$Id: ctblfuns.gd,v 4.54.2.3 2005/08/29 08:06:35 gap Exp $
##
#Y  Copyright (C)  1997,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
#Y  (C) 1998 School Math and Comp. Sci., University of St.  Andrews, Scotland
#Y  Copyright (C) 2002 The GAP Group
##
##  This file contains the definition of categories of class functions,
##  and the corresponding properties, attributes, and operations.
##
##  1. Why Class Functions?
##  2. Basic Operations for Class Functions
##  3. Comparison of Class Functions
##  4. Arithmetic Operations for Class Functions
##  5. Printing Class Functions
##  6. Creating Class Functions from Values Lists
##  7. Creating Class Functions using Groups
##  8. Operations for Class Functions
##  9. Restricted and Induced Class Functions
##  10. Reducing Virtual Characters
##  11. Symmetrizations of Class Functions
##  12. Operations for Brauer Characters
##  13. Domains Generated by Class Functions
##  14. Auxiliary operations
##
Revision.ctblfuns_gd :=
    "@(#)$Id: ctblfuns.gd,v 4.54.2.3 2005/08/29 08:06:35 gap Exp $";


#############################################################################
##
#C  IsClassFunction( <obj> )
##
##  \index{class function}\index{class function objects}
##  A *class function* (in characteristic $p$) of a finite group $G$ is a map
##  from the set of ($p$-regular) elements in $G$ to the cyclotomics that is
##  constant on conjugacy classes of $G$.
##
##  Each class function in {\GAP} is represented by an *immutable list*,
##  where at the $i$-th position the value on the $i$-th conjugacy class of
##  the character table of $G$ is stored.
##  The ordering of the conjugacy classes is the one used in the underlying
##  character table.
##  Note that if the character table has access to its underlying group then
##  the ordering of conjugacy classes in the group and in the character table
##  may differ (see~"The Interface between Character Tables and Groups");
##  class functions always refer to the ordering of classes in the character
##  table.
##
##  *Class function objects* in {\GAP} are not just plain lists,
##  they store the character table of the group $G$ as value of the attribute
##  `UnderlyingCharacterTable' (see~"UnderlyingCharacterTable").
##  The group $G$ itself is accessible only via the character table
##  and thus only if the character table stores its group, as value of the
##  attribute `UnderlyingGroup'.
##  The reason for this is that many computations with class functions are
##  possible without using their groups,
##  for example class functions of character tables in the {\GAP}
##  character table library do in general not have access to their
##  underlying groups.
##
##  There are (at least) two reasons why class functions in {\GAP} are *not*
##  implemented as mappings.
##  First, we want to distinguish class functions in different
##  characteristics, for example to be able to define the Frobenius character
##  of a given Brauer character;
##  viewed as mappings, the trivial characters in all characteristics coprime
##  to the order of $G$ are equal.
##  Second, the product of two class functions shall be again a class
##  function, whereas the product of general mappings is defined as
##  composition.
##
##  A further argument is that the typical operations for mappings such as
##  `Image' (see~"Image") and `PreImage' (see~"PreImage") play no important
##  role for class functions.
##
##
DeclareCategory( "IsClassFunction",
    IsScalar and IsCommutativeElement and IsAssociativeElement
             and IsHomogeneousList and IsScalarCollection and IsFinite
             and IsGeneralizedRowVector );


#############################################################################
##
#F  CharacterString( <char>, <str> )
##
DeclareGlobalFunction( "CharacterString" );


#############################################################################
##
##  1. Why Class Functions?
#1
##  In principle it is possible to represent group characters or more general
##  class functions by the plain lists of their values,
##  and in fact many operations for class functions work with plain lists of
##  class function values.
##  But this has two disadvantages.
##
##  First, it is then necessary to regard a values list explicitly as a class
##  function of a particular character table, by supplying this character
##  table as an argument.
##  In practice this means that with this setup,
##  the user has the task to put the objects into the right context.
##  For example, forming the scalar product or the tensor product of two
##  class functions or forming an induced class function or a conjugate
##  class function then needs three arguments in this case;
##  this is particularly inconvenient in cases where infix operations cannot
##  be used because of the additional argument, as for tensor products and
##  induced class functions.
##
##  Second, when one says that ``$\chi$ is a character of a group $G$''
##  then this object $\chi$ carries a lot of information.
##  $\chi$ has certain properties such as being irreducible or not.
##  Several subgroups of $G$ are related to $\chi$,
##  such as the kernel and the centre of $\chi$.
##  Other attributes of characters are the determinant and the central
##  character.
##  This knowledge cannot be stored in a plain list.
##
##  For dealing with a group together with its characters, and maybe also
##  subgroups and their characters, it is desirable that {\GAP} keeps track
##  of the interpretation of characters.
##  On the other hand, for using characters without accessing their groups,
##  such as characters of tables from the {\GAP} table library,
##  dealing just with values lists is often sufficient.
##  In particular, if one deals with incomplete character tables then it is
##  often necessary to specify the arguments explicitly,
##  for example one has to choose a fusion map or power map from a set of
##  possibilities.
##
##  The main idea behind class function objects is that a class function
##  object is equal to its values list in the sense of `\\=',
##  so class function objects can be used wherever their values lists
##  can be used,
##  but there are operations for class function objects that do not work
##  just with values lists.
#T Note that a class function object lies in the same family as its list of
#T values.
#T As a consequence, there is no filter `IsClassFunctionCollection',
#T so we have no special treatment of spaces and algebras without hacks.
##  {\GAP} library functions prefer to return class function objects
##  rather than returning just values lists,
##  for example `Irr' lists (see~"Irr") consist of class function objects,
##  and `TrivialCharacter' (see~"TrivialCharacter") returns a class function
##  object.
##
##  Here is an *example* that shows both approaches.
##  First we define some groups.
##
##  \beginexample
##  gap> S4:= SymmetricGroup( 4 );;  SetName( S4, "S4" );
##  gap> D8:= SylowSubgroup( S4, 2 );; SetName( D8, "D8" );
##  \endexample
##
##  We do some computations using the functions described later in this
##  Chapter, first with class function objects.
##
##  \beginexample
##  gap> irrS4:= Irr( S4 );;
##  gap> irrD8:= Irr( D8 );;
##  gap> chi:= irrD8[4];
##  Character( CharacterTable( D8 ), [ 1, -1, 1, -1, 1 ] )
##  gap> chi * chi;
##  Character( CharacterTable( D8 ), [ 1, 1, 1, 1, 1 ] )
##  gap> ind:= chi ^ S4;
##  Character( CharacterTable( S4 ), [ 3, -1, -1, 0, 1 ] )
##  gap> List( irrS4, x -> ScalarProduct( x, ind ) );
##  [ 0, 1, 0, 0, 0 ]
##  gap> det:= Determinant( ind );
##  Character( CharacterTable( S4 ), [ 1, 1, 1, 1, 1 ] )
##  gap> cent:= CentralCharacter( ind );
##  ClassFunction( CharacterTable( S4 ), [ 1, -2, -1, 0, 2 ] )
##  gap> rest:= Restricted( cent, D8 );
##  ClassFunction( CharacterTable( D8 ), [ 1, -2, -1, -1, 2 ] )
##  \endexample
##
##  Now we repeat these calculations with plain lists of character values.
##  Here we need the character tables in some places.
##
##  \beginexample
##  gap> tS4:= CharacterTable( S4 );;
##  gap> tD8:= CharacterTable( D8 );;
##  gap> chi:= ValuesOfClassFunction( irrD8[4] );
##  [ 1, -1, 1, -1, 1 ]
##  gap> Tensored( [ chi ], [ chi ] )[1];
##  [ 1, 1, 1, 1, 1 ]
##  gap> ind:= InducedClassFunction( tD8, chi, tS4 );
##  ClassFunction( CharacterTable( S4 ), [ 3, -1, -1, 0, 1 ] )
##  gap> List( Irr( tS4 ), x -> ScalarProduct( tS4, x, ind ) );
##  [ 0, 1, 0, 0, 0 ]
##  gap> det:= DeterminantOfCharacter( tS4, ind );
##  ClassFunction( CharacterTable( S4 ), [ 1, 1, 1, 1, 1 ] )
##  gap> cent:= CentralCharacter( tS4, ind );
##  ClassFunction( CharacterTable( S4 ), [ 1, -2, -1, 0, 2 ] )
##  gap> rest:= Restricted( tS4, cent, tD8 );
##  ClassFunction( CharacterTable( D8 ), [ 1, -2, -1, -1, 2 ] )
##  \endexample
##
##  If one deals with character tables from the {\GAP} table library then
##  one has no access to their groups,
##  but often the tables provide enough information for computing induced or
##  restricted class functions, symmetrizations etc.,
##  because the relevant class fusions and power maps are often stored on
##  library tables.
##  In these cases it is possible to use the tables instead of the groups
##  as arguments.
##  (If necessary information is not uniquely determined by the tables then
##  an error is signalled.)
##
##  \beginexample
##  gap> s5 := CharacterTable( "A5.2" );; irrs5 := Irr( s5  );;
##  gap> m11:= CharacterTable( "M11"  );; irrm11:= Irr( m11 );;
##  gap> chi:= TrivialCharacter( s5 );
##  Character( CharacterTable( "A5.2" ), [ 1, 1, 1, 1, 1, 1, 1 ] )
##  gap> chi ^ m11;
##  Character( CharacterTable( "M11" ), [ 66, 10, 3, 2, 1, 1, 0, 0, 0, 0 ] )
##  gap> Determinant( irrs5[4] );
##  Character( CharacterTable( "A5.2" ), [ 1, 1, 1, 1, -1, -1, -1 ] )
##  \endexample
##
##  Functions that compute *normal* subgroups related to characters
##  have counterparts that return the list of class positions corresponding
##  to these groups.
##
##  \beginexample
##  gap> ClassPositionsOfKernel( irrs5[2] );
##  [ 1, 2, 3, 4 ]
##  gap> ClassPositionsOfCentre( irrs5[2] );
##  [ 1, 2, 3, 4, 5, 6, 7 ]
##  \endexample
##
##  Non-normal subgroups cannot be described this way,
##  so for example inertia subgroups (see~"InertiaSubgroup") can in general
##  not be computed from character tables without access to their groups.
##


#############################################################################
##
##  2. Basic Operations for Class Functions
#2
##  Basic operations for class functions are
##  `UnderlyingCharacterTable' (see~"UnderlyingCharacterTable"),
##  `ValuesOfClassFunction' (see~"ValuesOfClassFunction"),
##  and the basic operations for lists (see~"Basic Operations for Lists").
##


#############################################################################
##
#A  UnderlyingCharacterTable( <psi> )
##
##  For a class function <psi> of the group $G$, say, the character table of
##  $G$ is stored as value of `UnderlyingCharacterTable'.
##  The ordering of entries in the list <psi> (see~"ValuesOfClassFunction")
##  refers to the ordering of conjugacy classes in this character table.
##
##  If <psi> is an ordinary class function then the underlying character
##  table is the ordinary character table of $G$
##  (see~"OrdinaryCharacterTable"),
##  if <psi> is a class function in characteristic $p \not= 0$ then the
##  underlying character table is the $p$-modular Brauer table of $G$
##  (see~"BrauerTable").
##  So the underlying characteristic of <psi> can be read off from the
##  underlying character table.
##
DeclareAttribute( "UnderlyingCharacterTable", IsClassFunction );


#############################################################################
##
#A  ValuesOfClassFunction( <psi> ) . . . . . . . . . . . . . . list of values
##
##  is the list of values of the class function <psi>, the $i$-th entry
##  being the value on the $i$-th conjugacy class of the underlying
##  character table (see~"UnderlyingCharacterTable").
##
DeclareAttribute( "ValuesOfClassFunction", IsClassFunction );


#############################################################################
##
##  3. Comparison of Class Functions
#3
##  With respect to `\\=' and `\\\<', class functions behave equally to their
##  lists of values (see~"ValuesOfClassFunction").
##  So two class functions are equal if and only if their lists of values are
##  equal, no matter whether they are class functions of the same character
##  table, of the same group but w.r.t.~different class ordering,
##  or of different groups.
##


#############################################################################
##
##  4. Arithmetic Operations for Class Functions
#4
##  Class functions are *row vectors* of cyclotomics.
##  The *additive* behaviour of class functions is defined such that they are
##  equal to the plain lists of class function values except that the results
##  are represented again as class functions whenever this makes sense.
##  The *multiplicative* behaviour, however, is different.
##  This is motivated by the fact that the tensor product of class functions
##  is a more interesting operation than the vector product of plain lists.
##  (Another candidate for a multiplication of compatible class functions
##  would have been the inner product, which is implemented via the function
##  `ScalarProduct', see~"ScalarProduct!for characters".)
##  In terms of filters, the arithmetic of class functions is based on the
##  decision that they lie in `IsGeneralizedRowVector',
##  with additive nesting depth $1$,
##  but they do *not* lie in `IsMultiplicativeGeneralizedRowVector'
##  (see~"Filters Controlling the Arithmetic Behaviour of Lists").
##
##  More specifically, the scalar multiple of a class function with a
##  cyclotomic is a class function,
##  and the sum and the difference of two class functions
##  of the same underlying character table (see~"UnderlyingCharacterTable")
##  are again class functions of this table.
##  The sum and the difference of a class function and a list that is *not*
##  a class function are plain lists,
##  as well as the sum and the difference of two class functions of different
##  character tables.
##
##  \beginexample
##  gap> g:= SymmetricGroup( 4 );;  tbl:= CharacterTable( g );;
##  gap> SetName( tbl, "S4" );  irr:= Irr( g );
##  [ Character( S4, [ 1, -1, 1, 1, -1 ] ), Character( S4, [ 3, -1, -1, 0, 1 ] ), 
##    Character( S4, [ 2, 0, 2, -1, 0 ] ), Character( S4, [ 3, 1, -1, 0, -1 ] ), 
##    Character( S4, [ 1, 1, 1, 1, 1 ] ) ]
##  gap> 2 * irr[5];
##  Character( S4, [ 2, 2, 2, 2, 2 ] )
##  gap> irr[1] / 7;
##  ClassFunction( S4, [ 1/7, -1/7, 1/7, 1/7, -1/7 ] )
##  gap> lincomb:= irr[3] + irr[1] - irr[5];
##  VirtualCharacter( S4, [ 2, -2, 2, -1, -2 ] )
##  gap> lincomb:= lincomb + 2 * irr[5];
##  VirtualCharacter( S4, [ 4, 0, 4, 1, 0 ] )
##  gap> IsCharacter( lincomb );
##  true
##  gap> lincomb;
##  Character( S4, [ 4, 0, 4, 1, 0 ] )
##  gap> irr[5] + 2;
##  [ 3, 3, 3, 3, 3 ]
##  gap> irr[5] + [ 1, 2, 3, 4, 5 ];
##  [ 2, 3, 4, 5, 6 ]
##  gap> zero:= 0 * irr[1];
##  VirtualCharacter( S4, [ 0, 0, 0, 0, 0 ] )
##  gap> zero + Z(3);
##  [ Z(3), Z(3), Z(3), Z(3), Z(3) ]
##  gap> irr[5] + TrivialCharacter( DihedralGroup( 8 ) );
##  [ 2, 2, 2, 2, 2 ]
##  \endexample
##
##  \index{class functions!as ring elements}
##  The product of two class functions of the same character table is the
##  tensor product (pointwise product) of these class functions.
##  Thus the set of all class functions of a fixed group forms a ring,
##  and for any field $F$ of cyclotomics, the $F$-span of a given set of
##  class functions forms an algebra.
##
##  The product of two class functions of *different* tables and the product
##  of a class function and a list that is *not* a class function are not
##  defined, an error is signalled in these cases.
##  Note that in this respect, class functions behave differently from their
##  values lists, for which the product is defined as the standard scalar
##  product.
##
##  \beginexample
##  gap> tens:= irr[3] * irr[4];
##  Character( S4, [ 6, 0, -2, 0, 0 ] )
##  gap> ValuesOfClassFunction( irr[3] ) * ValuesOfClassFunction( irr[4] );
##  4
##  \endexample
##
##  \index{inverse!of class function}
##  Class functions without zero values are invertible,
##  the *inverse* is defined pointwise.
##  As a consequence, for example groups of linear characters can be formed.
##
##  \beginexample
##  gap> tens / irr[1];
##  Character( S4, [ 6, 0, -2, 0, 0 ] )
##  \endexample
##
##  Other (somewhat strange) implications of the definition of arithmetic
##  operations for class functions, together with the general rules of list
##  arithmetic (see~"Arithmetic for Lists"),
##  apply to the case of products involving *lists* of class functions.
##  No inverse of the list of irreducible characters as a matrix is defined;
##  if one is interested in the inverse matrix then one can compute it from
##  the matrix of class function values.
##
##  \beginexample
##  gap> Inverse( List( irr, ValuesOfClassFunction ) );
##  [ [ 1/24, 1/8, 1/12, 1/8, 1/24 ], [ -1/4, -1/4, 0, 1/4, 1/4 ], 
##    [ 1/8, -1/8, 1/4, -1/8, 1/8 ], [ 1/3, 0, -1/3, 0, 1/3 ], 
##    [ -1/4, 1/4, 0, -1/4, 1/4 ] ]
##  \endexample
##
##  Also the product of a class function with a list of class functions is
##  *not* a vector-matrix product but the list of pointwise products.
##
##  \beginexample
##  gap> irr[1] * irr{ [ 1 .. 3 ] };
##  [ Character( S4, [ 1, 1, 1, 1, 1 ] ), Character( S4, [ 3, 1, -1, 0, -1 ] ), 
##    Character( S4, [ 2, 0, 2, -1, 0 ] ) ]
##  \endexample
##
##  And the product of two lists of class functions is *not* the matrix
##  product but the sum of the pointwise products.
##
##  \beginexample
##  gap> irr * irr;
##  Character( S4, [ 24, 4, 8, 3, 4 ] )
##  \endexample
##
##  \index{character value!of group element using powering operator}
##  \index{power!meaning for class functions}
##  \indextt{\^{}!for class functions}
##  The *powering* operator `\\^' has several meanings for class functions.
##  The power of a class function by a nonnegative integer is clearly the
##  tensor power.
##  The power of a class function by an element that normalizes the
##  underlying group or by a Galois automorphism is the conjugate class
##  function.
##  (As a consequence, the application of the permutation induced by such an
##  action cannot be denoted by `\\^'; instead one can use `Permuted',
##  see~"Permuted".)
##  The power of a class function by a group or a character table is the
##  induced class function (see~"InducedClassFunction").
##  The power of a group element by a class function is the class function
##  value at (the conjugacy class containing) this element.
##
##  \beginexample
##  gap> irr[3] ^ 3;
##  Character( S4, [ 8, 0, 8, -1, 0 ] )
##  gap> lin:= LinearCharacters( DerivedSubgroup( g ) );
##  [ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, 1, 1 ] ), 
##    Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3)^2, E(3) ] ), 
##    Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] ) ]
##  gap> List( lin, chi -> chi ^ (1,2) );
##  [ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, 1, 1 ] ), 
##    Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] ), 
##    Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3)^2, E(3) ] ) ]
##  gap> Orbit( GaloisGroup( CF(3) ), lin[2] );
##  [ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3)^2, E(3) ] ), 
##    Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] ) ]
##  gap> lin[1]^g;
##  Character( S4, [ 2, 0, 2, 2, 0 ] )
##  gap> (1,2,3)^lin[2];
##  E(3)^2
##  \endexample
##
##  \index{characteristic!for class functions}
##  The *characteristic* of class functions is zero,
##  as for all list of cyclotomics.
##  For class functions of a $p$-modular character table, such as Brauer
##  characters, the prime $p$ is given by the
##  `UnderlyingCharacteristic' (see~"UnderlyingCharacteristic") value of
##  the character table.
##
##  \beginexample
##  gap> Characteristic( irr[1] );
##  0
##  gap> irrmod2:= Irr( g, 2 );
##  [ Character( BrauerTable( Sym( [ 1 .. 4 ] ), 2 ), [ 1, 1 ] ), 
##    Character( BrauerTable( Sym( [ 1 .. 4 ] ), 2 ), [ 2, -1 ] ) ]
##  gap> Characteristic( irrmod2[1] );
##  0
##  gap> UnderlyingCharacteristic( UnderlyingCharacterTable( irrmod2[1] ) );
##  2
##  \endexample
##
##  \indextt{ComplexConjugate!for class functions}
##  \indextt{GaloisCyc!for class functions}
##  \indextt{Permuted!for class functions}
##  The operations `ComplexConjugate', `GaloisCyc', and `Permuted' return
##  a class function when they are called with a class function;
##  The complex conjugate of a class function that is known to be a (virtual)
##  character is again known to be a (virtual) character, and applying an
##  arbitrary Galois automorphism to an ordinary (virtual) character yields
##  a (virtual) character.
##
##  \beginexample
##  gap> ComplexConjugate( lin[2] );
##  Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] )
##  gap> GaloisCyc( lin[2], 5 );
##  Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] )
##  gap> Permuted( lin[2], (2,3,4) );
##  ClassFunction( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, E(3), 1, E(3)^2 ] )
##  \endexample
##
##  \indextt{Order!of a class function}
##  By definition of `Order' for arbitrary monoid elements,
##  the determinantal order (see~"DeterminantOfCharacter") of characters
##  cannot be the return value of `Order' for characters.
##  One can use `Order( Determinant( <chi> ) )' to compute the determinantal
##  order of the class function <chi>.
##
##  \beginexample
##  gap> det:= Determinant( irr[3] );
##  Character( S4, [ 1, -1, 1, 1, -1 ] )
##  gap> Order( det );
##  2
##  \endexample
##


#############################################################################
##
#A  GlobalPartitionOfClasses( <tbl> )
##
##  Let <n> be the number of conjugacy classes of the character table <tbl>.
##  `GlobalPartitionOfClasses( <tbl> )' is a list of subsets of the range
##  `[ 1 .. <n> ]' that forms a partition of `[ 1 .. <n> ]'.
##  This partition is respected by each table automorphism of <tbl>
##  (see~"AutomorphismsOfTable");
##  *note* that also fixed points occur.
##
##  This is useful for the computation of table automorphisms
##  and of conjugate class functions.
##
##  Since group automorphisms induce table automorphisms, the partition is
##  also respected by the permutation group that occurs in the computation
##  of inertia groups and conjugate class functions.
##
##  If the group of table automorphisms is already known then its orbits
##  form the finest possible global partition.
##
##  Otherwise the subsets in the partition are the sets of classes with
##  same centralizer order and same element order,
##  and --if more about the character table is known-- also with the same
##  number of $p$-th root classes, for all $p$ for which the power maps
##  are stored.
##
DeclareAttribute( "GlobalPartitionOfClasses", IsNearlyCharacterTable );


#############################################################################
##
#O  CorrespondingPermutations( <tbl>, <elms> )
#O  CorrespondingPermutations( <tbl>, <chi>, <elms> )
##
##  In the first form, `CorrespondingPermutations' returns the list of those
##  permutations of conjugacy classes of the character table <tbl>
##  that are induced by the action of the group elements in the list <elms>.
##  If an element of <elms> does *not* act on the classes of <tbl> then
##  either `fail' or a (meaningless) permutation is returned.
##
##  In the second form, <chi> must be (the values list of) a class function
##  of <tbl>, and the returned permutations will at least yield the same
##  conjugate class functions as the permutations of classes that are induced
##  by <elms>,
##  that is, the images are not necessarily the same for orbits on which
##  <chi> is constant.
##
##  This function is used for computing conjugate class functions.
##
DeclareOperation( "CorrespondingPermutations",
    [ IsOrdinaryTable, IsHomogeneousList ] );
DeclareOperation( "CorrespondingPermutations",
    [ IsOrdinaryTable, IsClassFunction, IsHomogeneousList ] );


#############################################################################
##
##  5. Printing Class Functions
#5
##  \indextt{ViewObj!for class functions}
##  The default `ViewObj' (see~"ViewObj") methods for class functions
##  print one of the strings `\"ClassFunction\"', `\"VirtualCharacter\"',
##  `\"Character\"' (depending on whether the class function is known to be a
##  character or virtual character, see~"IsCharacter", "IsVirtualCharacter"),
##  followed by the `ViewObj' output for the underlying character table
##  (see~"Printing Character Tables"), and the list of values.
##  The table is chosen (and not the group) in order to distinguish class
##  functions of different underlying characteristic
##  (see~"UnderlyingCharacteristic").
##
##  \indextt{PrintObj!for character tables}
##  The default `PrintObj' (see~"PrintObj") method for class functions
##  does the same as `ViewObj',
##  except that the character table is is `Print'-ed instead of `View'-ed.
##
##  *Note* that if a class function is shown only with one of the strings
##  `\"ClassFunction\"', `\"VirtualCharacter\"',
##  it may still be that it is in fact a character;
##  just this was not known at the time when the class function was printed.
##
##  In order to reduce the space that is needed to print a class function,
##  it may be useful to give a name (see~"Name") to the underlying character
##  table.
##
##  \indextt{Display!for character tables}
##  The default `Display' (see~"Display") method for a class function <chi>
##  calls `Display' for its underlying character table
##  (see~"Printing Character Tables"), with <chi> as the only entry in the
##  `chars' list of the options record.
##


#############################################################################
##
##  6. Creating Class Functions from Values Lists
##


#############################################################################
##
#O  ClassFunction( <tbl>, <values> )
#O  ClassFunction( <G>, <values> )
##
##  In the first form, `ClassFunction' returns the class function of the
##  character table <tbl> with values given by the list <values> of
##  cyclotomics.
##  In the second form, <G> must be a group, and the class function of its
##  ordinary character table is returned.
##
##  Note that <tbl> determines the underying characteristic of the returned
##  class function (see~"UnderlyingCharacteristic").
##
DeclareOperation( "ClassFunction", [ IsNearlyCharacterTable, IsDenseList ] );
DeclareOperation( "ClassFunction", [ IsGroup, IsDenseList ] );


#############################################################################
##
#O  VirtualCharacter( <tbl>, <values> )
#O  VirtualCharacter( <G>, <values> )
##
##  `VirtualCharacter' returns the virtual character
##  (see~"IsVirtualCharacter") of the character table <tbl> or the group <G>,
##  respectively, with values given by the list <values>.
##
##  It is *not* checked whether the given values really describe a
##  virtual character.
##
DeclareOperation( "VirtualCharacter",
    [ IsNearlyCharacterTable, IsDenseList ] );
DeclareOperation( "VirtualCharacter", [ IsGroup, IsDenseList ] );


#############################################################################
##
#O  Character( <tbl>, <values> )
##
##  `Character' returns the character (see~"IsCharacter")
##  of the character table <tbl> or the group <G>, respectively,
##  with values given by the list <values>.
##
##  It is *not* checked whether the given values really describe a character.
##
DeclareOperation( "Character", [ IsNearlyCharacterTable, IsDenseList ] );
DeclareOperation( "Character", [ IsGroup, IsDenseList ] );


#############################################################################
##
#F  ClassFunctionSameType( <tbl>, <chi>, <values> )
##
##  Let <tbl> be a character table, <chi> a class function object
##  (*not* necessarily a class function of <tbl>),
##  and <values> a list of cyclotomics.
##  `ClassFunctionSameType' returns the class function $\psi$ of <tbl> with
##  values list <values>, constructed with `ClassFunction'
##  (see~"ClassFunction").
##
##  If <chi> is known to be a (virtual) character then $\psi$ is also known
##  to be a (virtual) character.
##
DeclareGlobalFunction( "ClassFunctionSameType" );


#############################################################################
##
##  7. Creating Class Functions using Groups
##


#############################################################################
##
#A  TrivialCharacter( <tbl> )
#A  TrivialCharacter( <G> )
##
##  is the *trivial character* of the group <G> or its character table <tbl>,
##  respectively.
##  This is the class function with value equal to $1$ for each class.
##
DeclareAttribute( "TrivialCharacter", IsNearlyCharacterTable );
DeclareAttribute( "TrivialCharacter", IsGroup );


#############################################################################
##
#A  NaturalCharacter( <G> )
#A  NaturalCharacter( <hom> )
##
##  If the argument is a permutation group <G> then `NaturalCharacter'
##  returns the (ordinary) character of the natural permutation
##  representation of <G> on the set of moved points (see~"MovedPoints"),
##  that is, the value on each class is the number of points among the moved
##  points of <G> that are fixed by any permutation in that class.
##
##  If the argument is a matrix group <G> in characteristic zero then
##  `NaturalCharacter' returns the (ordinary) character of the natural matrix
##  representation of <G>, that is, the value on each class is the trace of
##  any matrix in that class.
##
##  If the argument is a group homomorphism <hom> whose image is a
##  permutation group or a matrix group then `NaturalCharacter' returns the
##  restriction of the natural character of the image of <hom> to the
##  preimage of <hom>.
##
DeclareAttribute( "NaturalCharacter", IsGroup );
DeclareAttribute( "NaturalCharacter", IsGeneralMapping );


#############################################################################
##
#O  PermutationCharacter( <G>, <D>, <opr> )
#O  PermutationCharacter( <G>, <U> )
##
##  Called with a group <G>, an action domain or proper set <D>, and an
##  action function <opr> (see Chapter~"Group Actions"),
##  `PermutationCharacter' returns the *permutation character* of the action
##  of <G> on <D> via <opr>,
##  that is, the value on each class is the number of points in <D> that are
##  fixed by an element in this class under the action <opr>.
##
##  If the arguments are a group <G> and a subgroup <U> of <G> then
##  `PermutationCharacter' returns the permutation character of the action
##  of <G> on the right cosets of <U> via right multiplication.
##
##  To compute the permutation character of a *transitive permutation group*
##  <G> on the cosets of a point stabilizer <U>,
##  the attribute `NaturalCharacter( <G> )' can be used instead of
##  `PermutationCharacter( <G>, <U> )'.
##
##  More facilities concerning permutation characters are the transitivity
##  test (see Section~"Operations for Class Functions") and several tools for
##  computing possible permutation characters
##  (see~"Possible Permutation Characters",
##  "Computing Possible Permutation Characters").
##
DeclareOperation( "PermutationCharacter",
    [ IsGroup, IsCollection, IsFunction ] );
DeclareOperation( "PermutationCharacter", [ IsGroup, IsGroup ] );


#############################################################################
##
##  8. Operations for Class Functions
#6
##  In the description of the following operations,
##  the optional first argument <tbl> is needed only if the argument <chi> is
##  a plain list and not a class function object.
##  In this case, <tbl> must always be the character table of which <chi>
##  shall be regarded as a class function.
##


#############################################################################
##
#P  IsCharacter( [<tbl>, ]<chi> )
##
##  \index{ordinary character}
##  An *ordinary character* of a group $G$ is a class function of $G$ whose
##  values are the traces of a complex matrix representation of $G$.
##
##  \atindex{Brauer character}{@Brauer character}
##  A *Brauer character* of $G$ in characteristic $p$ is a class function of
##  $G$ whose values are the complex lifts of a matrix representation of $G$
##  with image a finite field of characteristic $p$.
##
DeclareProperty( "IsCharacter", IsClassFunction );
DeclareOperation( "IsCharacter", [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#P  IsVirtualCharacter( [<tbl>, ]<chi> )
##
##  \index{virtual character}
##  A *virtual character* is a class function that can be written as the
##  difference of two proper characters (see~"IsCharacter").
##
DeclareProperty( "IsVirtualCharacter", IsClassFunction );
DeclareOperation( "IsVirtualCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#M  IsVirtualCharacter( <chi> ) . . . . . . . . . . . . . . . for a character
##
##  Each character is of course a virtual character.
##
InstallTrueMethod( IsVirtualCharacter, IsCharacter and IsClassFunction );


#############################################################################
##
#P  IsIrreducibleCharacter( [<tbl>, ]<chi> )
##
##  \index{irreducible character}
##  A character is *irreducible* if it cannot be written as the sum of two
##  characters.
##  For ordinary characters this can be checked using the scalar product
##  of class functions (see~"ScalarProduct!for characters").
##  For Brauer characters there is no generic method for checking
##  irreducibility.
##
DeclareProperty( "IsIrreducibleCharacter", IsClassFunction );
DeclareOperation( "IsIrreducibleCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#O  ScalarProduct( [<tbl>, ]<chi>, <psi> )
##
##  For two class functions <chi> and <psi> of the same ordinary character
##  table <tbl>, `ScalarProduct' returns the scalar product.
##
##  If $G$ is the underlying group of <tbl> and the two class functions are
##  $\chi$ and $\psi$ then this is defined as
##  $\frac{1}{|G|} \sum_{g \in G} \chi(g) \psi(g^{-1})$.
##
DeclareOperation( "ScalarProduct",
    [ IsOrdinaryTable, IsRowVector, IsRowVector ] );


#############################################################################
##
#O  MatScalarProducts( [<tbl>, ]<list1>, <list2> )
#O  MatScalarProducts( [<tbl>, ]<list> )
##
##  The first form returns the matrix of scalar products (see above) of the
##  class functions in the list <list1> with the class functions in the list
##  <list2>.
##  More precisely, the matrix contains in the $i$-th row the list of scalar
##  products of $<list2>[i]$ with the entries of <list1>.
##
##  The second form returns a lower triangular matrix of scalar products,
##  containing for ($j \leq i$) in the $i$-th row in column $j$ the value
##  $`ScalarProduct'( <tbl>, <list>[j], <list>[i] )$.
##
DeclareOperation( "MatScalarProducts",
    [ IsHomogeneousList, IsHomogeneousList ] );
DeclareOperation( "MatScalarProducts",
    [ IsOrdinaryTable, IsHomogeneousList, IsHomogeneousList ] );
DeclareOperation( "MatScalarProducts", [ IsHomogeneousList ] );
DeclareOperation( "MatScalarProducts",
    [ IsOrdinaryTable, IsHomogeneousList ] );


#############################################################################
##
#A  Norm( [<tbl>, ]<chi> )
##
##  For an ordinary class function <chi> of the group $G$, say, we have
##  $<chi> = \sum_{\chi \in Irr(G)} a_{\chi} \chi$,
##  with complex coefficients $a_{\chi}$.
##  The *norm* of <chi> is defined as
##  $\sum_{\chi \in Irr(G)} a_{\chi} \overline{a_{\chi}}$.
##
DeclareAttribute( "Norm", IsClassFunction );
DeclareOperation( "Norm", [ IsOrdinaryTable, IsHomogeneousList ] );


#############################################################################
##
#A  CentreOfCharacter( [<tbl>, ]<chi> )
##
##  \index{centre!of a character}
##  For a character <chi> of the group $G$, say, `CentreOfCharacter' returns
##  the *centre* of <chi>, that is,
##  the normal subgroup of all those elements of $G$ for which the quotient
##  of the value of <chi> by the degree of <chi> is a root of unity.
##
##  If the underlying character table of <psi> does not store the group $G$
##  then an error is signalled.
##  (See~"ClassPositionsOfCentre!for characters" for a way to handle the centre
##  implicitly, by listing the positions of conjugacy classes in the centre.)
##
DeclareAttribute( "CentreOfCharacter", IsClassFunction );
DeclareOperation( "CentreOfCharacter",
    [ IsOrdinaryTable, IsHomogeneousList ] );

DeclareSynonym( "CenterOfCharacter", CentreOfCharacter );


#############################################################################
##
#A  ClassPositionsOfCentre( <chi> )
##
##  is the list of positions of classes forming the centre of the character
##  <chi> (see~"CentreOfCharacter").
##
DeclareAttribute( "ClassPositionsOfCentre", IsHomogeneousList );


#############################################################################
##
#A  ConstituentsOfCharacter( [<tbl>, ]<chi> )
##
##  is the set of irreducible characters that occur in the decomposition of
##  the (virtual) character <chi> with nonzero coefficient.
##
DeclareAttribute( "ConstituentsOfCharacter", IsClassFunction );
DeclareOperation( "ConstituentsOfCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#A  DegreeOfCharacter( <chi> )
##
##  is the value of the character <chi> on the identity element.
##  This can also be obtained as `<chi>[1]'.
##
DeclareAttribute( "DegreeOfCharacter", IsClassFunction );


#############################################################################
##
#O  InertiaSubgroup( [<tbl>, ]<G>, <chi> )
##
##  Let <chi> be a character of the group $H$, say,
##  and <tbl> the character table of $H$;
##  if the argument <tbl> is not given then the underlying character table of
##  <chi> (see~"UnderlyingCharacterTable") is used instead.
##  Furthermore, let <G> be a group that contains $H$ as a normal subgroup.
##
##  `InertiaSubgroup' returns the stabilizer in <G> of <chi>,
##  w.r.t.~the action of <G> on the classes of $H$ via conjugation.
##  In other words, `InertiaSubgroup' returns the group of all those elements
##  $g \in <G>$ that satisfy $<chi>^g = <chi>$.
##
DeclareOperation( "InertiaSubgroup", [ IsGroup, IsClassFunction ] );
DeclareOperation( "InertiaSubgroup",
    [ IsOrdinaryTable, IsGroup, IsHomogeneousList ] );


#############################################################################
##
#A  KernelOfCharacter( [<tbl>, ]<chi> )
##
##  For a class function <chi> of the group $G$, say,
##  `KernelOfCharacter' returns the normal subgroup of $G$ that is formed by
##  those conjugacy classes for which the value of <chi> equals the degree of
##  <chi>.
##  If the underlying character table of <chi> does not store the group $G$
##  then an error is signalled.
##  (See~"ClassPositionsOfKernel" for a way to handle the kernel implicitly,
##  by listing the positions of conjugacy classes in the kernel.)
##
##  The returned group is the kernel of any representation of $G$ that
##  affords <chi>.
##
DeclareAttribute( "KernelOfCharacter", IsClassFunction );
DeclareOperation( "KernelOfCharacter",
    [ IsOrdinaryTable, IsHomogeneousList ] );


#############################################################################
##
#A  ClassPositionsOfKernel( <chi> )
##
##  is the list of positions of those conjugacy classes that form the kernel
##  of the character <chi>, that is, those positions with character value
##  equal to the character degree.
##
DeclareAttribute( "ClassPositionsOfKernel", IsHomogeneousList );


#############################################################################
##
#O  CycleStructureClass( [<tbl>, ]<chi>, <class> )
##
##  Let <permchar> be a permutation character, and <class> the position of a
##  conjugacy class of the character table of <permchar>.
##  `CycleStructureClass' returns a list describing the cycle structure of
##  each element in class <class> in the underlying permutation
##  representation, in the same format as the result of `CycleStructurePerm'
##  (see~"CycleStructurePerm").
##
DeclareOperation( "CycleStructureClass",
    [ IsOrdinaryTable, IsHomogeneousList, IsPosInt ] );
DeclareOperation( "CycleStructureClass", [ IsClassFunction, IsPosInt ] );


#############################################################################
##
#P  IsTransitive( [<tbl>, ]<chi> )
##
##  \indextt{IsTransitive!for class functions}
##  For a permutation character <chi> of the group $G$ that corresponds
##  to an action on the $G$-set $\Omega$ (see~"PermutationCharacter"),
##  `IsTransitive' returns `true' if the action of $G$ on $\Omega$ is
##  transitive, and `false' otherwise.
##
DeclareProperty( "IsTransitive", IsClassFunction );
DeclareOperation( "IsTransitive", [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#A  Transitivity( [<tbl>, ]<chi> )
##
##  \indextt{Transitivity!for class functions}
##  For a permutation character <chi> of the group $G$ that corresponds
##  to an action on the $G$-set $\Omega$ (see~"PermutationCharacter"),
##  `Transitivity' returns the maximal nonnegative integer $k$ such that
##  the action of $G$ on $\Omega$ is $k$-transitive.
##
DeclareAttribute( "Transitivity", IsClassFunction );
DeclareOperation( "Transitivity", [ IsOrdinaryTable, IsHomogeneousList ] );


#############################################################################
##
#A  CentralCharacter( [<tbl>, ]<chi> )
##
##  \index{central character}
##  For a character <chi> of the group $G$, say, `CentralCharacter' returns
##  the *central character* of <chi>.
##
##  The central character of $\chi$ is the class function $\omega_{\chi}$
##  defined by $\omega_{\chi}(g) = |g^G| \cdot \chi(g)/\chi(1)$ for each
##  $g \in G$.
##
DeclareAttribute( "CentralCharacter", IsClassFunction );
DeclareOperation( "CentralCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#A  DeterminantOfCharacter( [<tbl>, ]<chi> )
##
##  \index{determinant character}
##  `DeterminantOfCharacter' returns the *determinant character* of the
##  character <chi>.
##  This is defined to be the character obtained by taking the determinant of
##  representing matrices of any representation affording <chi>;
##  the determinant can be computed using `EigenvaluesChar'
##  (see~"EigenvaluesChar").
##
##  It is also possible to call `Determinant' instead of
##  `DeterminantOfCharacter'.
##
##  Note that the determinant character is well-defined for virtual
##  characters.
##
DeclareAttribute( "DeterminantOfCharacter", IsClassFunction );
DeclareOperation( "DeterminantOfCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#O  EigenvaluesChar( [<tbl>, ]<chi>, <class> )
##
##  Let <chi> be a character of the group $G$, say.
##  For an element $g \in G$ in the <class>-th conjugacy class, of order $n$,
##  let $M$ be a matrix of a representation affording <chi>.
##
##  `EigenvaluesChar( <tbl>, <chi>, <class> )' is the list of length $n$
##  where at position $k$ the multiplicity
##  of $`E(<n>)^<k>' = \exp(\frac{2\pi i k}{n})$ as an eigenvalue of $M$
##  is stored.
##
##  We have `<chi>[ <class> ] = List( [ 1 .. <n> ], k -> E(n)^k )
##                               * EigenvaluesChar( <tbl>, <chi>, <class> )'.
##
##  It is also possible to call `Eigenvalues' instead of
##  `EigenvaluesChar'.
##
DeclareOperation( "EigenvaluesChar", [ IsClassFunction, IsPosInt ] );
DeclareOperation( "EigenvaluesChar",
    [ IsCharacterTable, IsHomogeneousList, IsPosInt ] );


#############################################################################
##
#O  Tensored( <chars1>, <chars2> )
##
##  Let <chars1> and <chars2> be lists of (values lists of) class functions
##  of the same character table.
##  `Tensored' returns the list of tensor products of all entries in <chars1>
##  with all entries in <chars2>.
##
DeclareOperation( "Tensored", [ IsHomogeneousList, IsHomogeneousList ] );


#############################################################################
##
##  9. Restricted and Induced Class Functions
#7
##  For restricting a class function of a group $G$ to a subgroup $H$
##  and for inducing a class function of $H$ to $G$,
##  the *class fusion* from $H$ to $G$ must be known
##  (see~"Class Fusions between Character Tables").
##
##  \index{inflated class functions}
##  If $F$ is the factor group of $G$ by the normal subgroup $N$ then each
##  class function of $F$ can be naturally regarded as a class function of
##  $G$, with $N$ in its kernel.
##  For a class function of $F$, the corresponding class function of $G$ is
##  called the *inflated* class function.
##  Restriction and inflation are in principle the same,
##  namely indirection of a class function by the appropriate fusion map,
##  and thus no extra operation is needed for this process.
##  But note that contrary to the case of a subgroup fusion, the factor
##  fusion can in general not be computed from the groups $G$ and $F$;
##  either one needs the natural homomorphism or the factor fusion to the
##  character table of $F$ must be stored on the table of $G$.
##  This explains the different syntax for computing restricted and inflated
##  class functions.
##
##  In the following,
##  the meaning of the optional first argument <tbl> is the same as in
##  Section~"Operations for Class Functions".
##


#############################################################################
##
#O  RestrictedClassFunction( [<tbl>, ]<chi>, <H> )
#O  RestrictedClassFunction( [<tbl>, ]<chi>, <hom> )
#O  RestrictedClassFunction( [<tbl>, ]<chi>, <subtbl> )
##
##  For a class function <chi> of the group $G$, say,
##  and either a subgroup <H> of $G$
##  or a homomorphism from <H> to $G$
##  or the character table <subtbl> of this subgroup,
##  `RestrictedClassFunction' returns the class function of <H> obtained by
##  restricting <chi> to <H>.
##
##  In the situation that <chi> is a class function of a factor group $F$ of
##  <H>, the variant where <hom> is a homomorphism can be always used,
##  the calls with argument <H> or <subtbl> work only if the factor fusion
##  is stored on the character table.
##
DeclareOperation( "RestrictedClassFunction", [ IsClassFunction, IsGroup ] );
DeclareOperation( "RestrictedClassFunction",
    [ IsNearlyCharacterTable, IsHomogeneousList, IsGroup ] );
DeclareOperation( "RestrictedClassFunction",
    [ IsClassFunction, IsGeneralMapping ] );
DeclareOperation( "RestrictedClassFunction",
    [ IsNearlyCharacterTable, IsHomogeneousList, IsGeneralMapping ] );
DeclareOperation( "RestrictedClassFunction",
    [ IsClassFunction, IsNearlyCharacterTable ] );
DeclareOperation( "RestrictedClassFunction",
    [ IsNearlyCharacterTable, IsHomogeneousList, IsNearlyCharacterTable ] );


#############################################################################
##
#O  RestrictedClassFunctions( [<tbl>, ]<chars>, <H> )
#O  RestrictedClassFunctions( [<tbl>, ]<chars>, <hom> )
#O  RestrictedClassFunctions( [<tbl>, ]<chars>, <subtbl> )
##
##  `RestrictedClassFunctions' is similar to `RestrictedClassFunction'
##  (see~"RestrictedClassFunction"),
##  the only difference is that it takes a list <chars> of class functions
##  instead of one class function, and returns the list of restricted class
##  functions.
##
DeclareOperation( "RestrictedClassFunctions", [ IsList, IsGroup ] );
DeclareOperation( "RestrictedClassFunctions",
    [ IsNearlyCharacterTable, IsList, IsGroup ] );
DeclareOperation( "RestrictedClassFunctions", [ IsList, IsGeneralMapping ] );
DeclareOperation( "RestrictedClassFunctions",
    [ IsNearlyCharacterTable, IsList, IsGeneralMapping ] );
DeclareOperation( "RestrictedClassFunctions",
    [ IsList, IsNearlyCharacterTable ] );
DeclareOperation( "RestrictedClassFunctions",
    [ IsNearlyCharacterTable, IsList, IsNearlyCharacterTable ] );


#############################################################################
##
#O  Restricted( <tbl>, <subtbl>, <chars> )
#O  Restricted( <tbl>, <subtbl>, <chars>, <specification> )
#O  Restricted( <chars>, <fusionmap> )
#O  Restricted( [<tbl>, ]<chi>, <H> )
#O  Restricted( [<tbl>, ]<chi>, <hom> )
#O  Restricted( [<tbl>, ]<chi>, <subtbl> )
#O  Restricted( [<tbl>, ]<chars>, <H> )
#O  Restricted( [<tbl>, ]<chars>, <hom> )
#O  Restricted( [<tbl>, ]<chars>, <subtbl> )
##
##  This is mainly for convenience and compatibility with {\GAP}~3.
##
DeclareOperation( "Restricted", [ IsObject, IsObject ] );
DeclareOperation( "Restricted", [ IsObject, IsObject, IsObject ] );
DeclareOperation( "Restricted", [ IsObject, IsObject, IsObject, IsObject ] );
DeclareSynonym( "Inflated", Restricted );


#############################################################################
##
#O  InducedClassFunction( [<tbl>, ]<chi>, <H> )
#O  InducedClassFunction( [<tbl>, ]<chi>, <hom> )
#O  InducedClassFunction( [<tbl>, ]<chi>, <suptbl> )
##
##  For a class function <chi> of the group $G$, say,
##  and either a supergroup <H> of $G$
##  or a homomorphism from $G$ to <H>
##  or the character table <suptbl> of this supergroup,
##  `InducedClassFunction' returns the class function of <H> obtained by
##  inducing <chi> to <H>.
##
DeclareOperation( "InducedClassFunction", [ IsClassFunction, IsGroup ] );
DeclareOperation( "InducedClassFunction",
    [ IsNearlyCharacterTable, IsHomogeneousList, IsGroup ] );
DeclareOperation( "InducedClassFunction",
    [ IsClassFunction, IsGeneralMapping ] );
DeclareOperation( "InducedClassFunction",
    [ IsNearlyCharacterTable, IsHomogeneousList, IsGeneralMapping ] );
DeclareOperation( "InducedClassFunction",
    [ IsClassFunction, IsNearlyCharacterTable ] );
DeclareOperation( "InducedClassFunction",
    [ IsNearlyCharacterTable, IsHomogeneousList, IsNearlyCharacterTable ] );


#############################################################################
##
#O  InducedClassFunctions( [<tbl>, ]<chars>, <H> )
#O  InducedClassFunctions( [<tbl>, ]<chars>, <hom> )
#O  InducedClassFunctions( [<tbl>, ]<chars>, <suptbl> )
##
##  `InducedClassFunctions' is similar to `InducedClassFunction'
##  (see~"InducedClassFunction"),
##  the only difference is that it takes a list <chars> of class functions
##  instead of one class function, and returns the list of induced class
##  functions.
##
DeclareOperation( "InducedClassFunctions", [ IsList, IsGroup ] );
DeclareOperation( "InducedClassFunctions",
    [ IsNearlyCharacterTable, IsList, IsGroup ] );
DeclareOperation( "InducedClassFunctions",
    [ IsList, IsGeneralMapping ] );
DeclareOperation( "InducedClassFunctions",
    [ IsNearlyCharacterTable, IsList, IsGeneralMapping ] );
DeclareOperation( "InducedClassFunctions",
    [ IsList, IsNearlyCharacterTable ] );
DeclareOperation( "InducedClassFunctions",
    [ IsNearlyCharacterTable, IsList, IsNearlyCharacterTable ] );


#############################################################################
##
#O  Induced( <subtbl>, <tbl>, <chars> )
#O  Induced( <subtbl>, <tbl>, <chars>, <specification> )
#O  Induced( <subtbl>, <tbl>, <chars>, <fusionmap> )
#O  Induced( [<tbl>, ]<chi>, <H> )
#O  Induced( [<tbl>, ]<chi>, <hom> )
#O  Induced( [<tbl>, ]<chi>, <suptbl> )
#O  Induced( [<tbl>, ]<chars>, <H> )
#O  Induced( [<tbl>, ]<chars>, <hom> )
#O  Induced( [<tbl>, ]<chars>, <suptbl> )
##
##  This is mainly for convenience and compatibility with {\GAP}~3.
##
DeclareOperation( "Induced", [ IsObject, IsObject ] );
DeclareOperation( "Induced", [ IsObject, IsObject, IsObject ] );
DeclareOperation( "Induced", [ IsObject, IsObject, IsObject, IsObject ] );


#############################################################################
##
#O  InducedCyclic( <tbl> )
#O  InducedCyclic( <tbl>, \"all\" )
#O  InducedCyclic( <tbl>, <classes> )
#O  InducedCyclic( <tbl>, <classes>, \"all\" )
##
##  `InducedCyclic' calculates characters induced up from cyclic subgroups
##  of the ordinary character table <tbl> to <tbl>,
##  and returns the strictly sorted list of the induced characters.
##
##  If `\"all\"' is specified then all irreducible characters of these
##  subgroups are induced,
##  otherwise only the permutation characters are calculated.
##
##  If a list <classes> is specified then only those cyclic subgroups
##  generated by these classes are considered,
##  otherwise all classes of <tbl> are considered.
##
DeclareOperation( "InducedCyclic", [ IsOrdinaryTable ] );
DeclareOperation( "InducedCyclic", [ IsOrdinaryTable, IsList ] );
DeclareOperation( "InducedCyclic", [ IsOrdinaryTable, IsList, IsString ] );


#############################################################################
##
##  10. Reducing Virtual Characters
#8
##  The following operations are intended for the situation that one is
##  given a list of virtual characters of a character table and is interested
##  in the irreducible characters of this table.
##  The idea is to compute virtual characters of small norm from the given
##  ones, hoping to get eventually virtual characters of norm $1$.
##


#############################################################################
##
#O  ReducedClassFunctions( [<tbl>, ]<constituents>, <reducibles> )
#O  ReducedClassFunctions( [<tbl>, ]<reducibles> )
##
##  Let <reducibles> be a list of ordinary virtual characters of the group
##  $G$, say.
##  If <constituents> is given then it must also be a list of ordinary
##  virtual characters of $G$,
##  otherwise we have <constituents> equal to <reducibles> in the following.
##
##  `ReducedClassFunctions' returns a record with components `remainders' and
##  `irreducibles', both lists of virtual characters of $G$.
##  These virtual characters are computed as follows.
##
##  Let `rems' be the set of nonzero class functions obtained by subtraction
##  of
##  $$
##  \sum_{\chi} \frac{[<reducibles>[i], \chi]}{[\chi,\chi]} . \chi
##  $$
##  from $<reducibles>[i]$,
##  where the summation runs over <constituents> and $[\chi,\psi]$ denotes
##  the scalar product of $G$-class functions.
##  Let `irrs' be the list of irreducible characters in `rems'.
##
##  We project `rems' into the orthogonal space of `irrs' and all those
##  irreducibles found this way until no new irreducibles arise.
##  Then the `irreducibles' list is the set of all found irreducible
##  characters, and the `remainders' list is the set of all nonzero
##  remainders.
##
DeclareOperation( "ReducedClassFunctions",
    [ IsHomogeneousList, IsHomogeneousList ] );
DeclareOperation( "ReducedClassFunctions",
    [ IsOrdinaryTable, IsHomogeneousList, IsHomogeneousList ] );
DeclareOperation( "ReducedClassFunctions",
    [ IsHomogeneousList ] );
DeclareOperation( "ReducedClassFunctions",
    [ IsOrdinaryTable, IsHomogeneousList ] );

DeclareSynonym( "Reduced", ReducedClassFunctions );


#############################################################################
##
#O  ReducedCharacters( [<tbl>, ]<constituents>, <reducibles> )
##
##  `ReducedCharacters' is similar to `ReducedClassFunctions',
##  the only difference is that <constituents> and <reducibles> are assumed
##  to be lists of characters.
##  This means that only those scalar products must be formed where the
##  degree of the character in <constituents> does not exceed the degree of
##  the character in <reducibles>.
##
DeclareOperation( "ReducedCharacters",
    [ IsHomogeneousList, IsHomogeneousList ] );
DeclareOperation( "ReducedCharacters",
    [ IsOrdinaryTable, IsHomogeneousList, IsHomogeneousList ] );

DeclareSynonym( "ReducedOrdinary", ReducedCharacters );


#############################################################################
##
#F  IrreducibleDifferences( <tbl>, <reducibles>, <reducibles2> )
#F  IrreducibleDifferences( <tbl>, <reducibles>, <reducibles2>, <scprmat> )
#F  IrreducibleDifferences( <tbl>, <reducibles>, \"triangle\" )
#F  IrreducibleDifferences( <tbl>, <reducibles>, \"triangle\", <scprmat> )
##
##  `IrreducibleDifferences' returns the list of irreducible characters which
##  occur as difference of two elements of <reducibles>
##  (if `\"triangle\"' is specified)
##  or of an element of <reducibles> and an element of <reducibles2>.
##
##  If <scprmat> is not specified then it will be calculated,
##  otherwise we must have
##  `<scprmat> = MatScalarProducts( <tbl>, <reducibles> )' or
##  `<scprmat> = MatScalarProducts( <tbl>, <reducibles>, <reducibles2> )',
##  respectively.
##
DeclareGlobalFunction( "IrreducibleDifferences" );


#############################################################################
##
##  11. Symmetrizations of Class Functions
##


#############################################################################
##
#O  Symmetrizations( [<tbl>, ]<characters>, <n> )
#O  Symmetrizations( [<tbl>, ]<characters>, <Sn> )
##
##  `Symmetrizations' returns the list of symmetrizations of the characters
##  <characters> of the ordinary character table <tbl> with the ordinary
##  irreducible characters of the symmetric group of degree <n>;
##  instead of the integer <n>, the table of the symmetric group can be
##  entered as <Sn>.
##
##  The symmetrization $\chi^{[\lambda]}$ of the character $\chi$ of <tbl>
##  with the character $\lambda$ of the symmetric group $S_n$ of degree $n$
##  is defined by
##  $$
##  \chi^{[\lambda]}(g) = \frac{1}{n!} \sum_{\rho \in S_n}
##                        \lambda(\rho) \prod_{k=1}^{n} \chi(g^k)^{a_k(\rho)},
##  $$
##  where $a_k(\rho)$ is the number of cycles of length $k$ in $\rho$.
##
##  For special kinds of symmetrizations, see~"SymmetricParts",
##  "AntiSymmetricParts", "MinusCharacter" and "OrthogonalComponents",
##  "SymplecticComponents".
##
##  *Note* that the returned list may contain zero class functions,
##  and duplicates are not deleted.
#T describe the succession!!
##
DeclareOperation( "Symmetrizations",
    [ IsNearlyCharacterTable, IsHomogeneousList, IsInt ] );
DeclareOperation( "Symmetrizations",
    [ IsNearlyCharacterTable, IsHomogeneousList, IsCharacterTable ] );
DeclareOperation( "Symmetrizations", [ IsHomogeneousList, IsInt ] );
DeclareOperation( "Symmetrizations",
    [ IsHomogeneousList, IsCharacterTable ] );

DeclareSynonym( "Symmetrisations", Symmetrizations );


#############################################################################
##
#F  SymmetricParts( <tbl>, <characters>, <n> )
##
##  is the list of symmetrizations of the characters <characters>
##  of the character table <tbl> with the trivial character of
##  the symmetric group of degree <n> (see~"Symmetrizations").
##
DeclareGlobalFunction( "SymmetricParts" );


#############################################################################
##
#F  AntiSymmetricParts( <tbl>, <characters>, <n> )
##
##  is the list of symmetrizations of the characters <characters>
##  of the character table <tbl> with the alternating character of
##  the symmetric group of degree <n> (see~"Symmetrizations").
##
DeclareGlobalFunction( "AntiSymmetricParts" );


#############################################################################
##
#F  RefinedSymmetrizations( <tbl>, <chars>, <m>, <func> )
##
##  is the list of Murnaghan components for orthogonal
##  ('<func>(x,y)=x', see~"OrthogonalComponents")
##  or symplectic ('<func>(x,y)=x-y', see~"SymplecticComponents")
##  symmetrizations.
##
DeclareGlobalFunction( "RefinedSymmetrizations" );
DeclareSynonym( "RefinedSymmetrisations", RefinedSymmetrizations );


#############################################################################
##
#F  OrthogonalComponents( <tbl>, <chars>, <m> )
##
##  \index{symmetrizations!orthogonal}%
##  \index{Frame}%
##  \atindex{Murnaghan components}{@Murnaghan components}
##
##  If $\chi$ is a nonlinear character with indicator $+1$,
##  a splitting of the tensor power $\chi^m$ is given by the so-called
##  Murnaghan functions (see~\cite{Mur58}).
##  These components in general have fewer irreducible constituents
##  than the symmetrizations with the symmetric group of degree <m>
##  (see~"Symmetrizations").
##
##  `OrthogonalComponents' returns the Murnaghan components of the
##  nonlinear characters of the character table <tbl> in the list <chars>
##  up to the power <m>, where <m> is an integer between 2 and 6.
##
##  The Murnaghan functions are implemented as in~\cite{Fra82}.
##
##  *Note*:
##  If <chars> is a list of character objects (see~"IsCharacter") then also
##  the result consists of class function objects.
##  It is not checked whether all characters in <chars> do really have
##  indicator $+1$; if there are characters with indicator $0$ or $-1$,
##  the result might contain virtual characters
##  (see also~"SymplecticComponents"),
##  therefore the entries of the result do in general not know that they are
##  characters.
##
DeclareGlobalFunction( "OrthogonalComponents" );


#############################################################################
##
#F  SymplecticComponents( <tbl>, <chars>, <m> )
##
##  If $\chi$ is a (nonlinear) character with indicator $-1$,
##  a splitting of the tensor power $\chi^m$ is given in terms of the
##  so-called Murnaghan functions (see~\cite{Mur58}).
##  These components in general have fewer irreducible constituents
##  than the symmetrizations with the symmetric group of degree <m>
##  (see~"Symmetrizations").
##
##  `SymplecticComponents' returns the symplectic symmetrizations of the
##  nonlinear characters of the character table <tbl> in the list <chars>
##  up to the power <m>, where <m> is an integer between 2 and 5.
##
##  *Note*:
##  If <chars> is a list of character objects (see~"IsCharacter") then also
##  the result consists of class function objects.
##  It is not checked whether all characters in <chars> do really have
##  indicator $-1$; if there are characters with indicator $0$ or $+1$,
##  the result might contain virtual characters
##  (see also~"OrthogonalComponents"),
##  therefore the entries of the result do in general not know that they are
##  characters.
##
DeclareGlobalFunction( "SymplecticComponents" );


#############################################################################
##
##  12. Operations for Brauer Characters
##


#############################################################################
##
#F  FrobeniusCharacterValue( <value>, <p> )
##
##  Let <value> be a cyclotomic whose coefficients over the rationals are
##  in the ring $\Z_{<p>}$ of <p>-local numbers,
##  where <p> is a prime integer.
##  Assume that <value> lies in $\Z_{<p>}[\zeta]$ for $\zeta = `E'(<p>^n)$.
##
##  `FrobeniusCharacterValue' returns the image of <value> under the ring
##  homomorphism from $\Z_{<p>}[\zeta]$ to the field with $<p>^n$ elements
##  that is defined with the help of Conway polynomials
##  (see~"ConwayPolynomial"), more information can be found in Sections~2--5
##  of~\cite{JLPW95}.
##
##  If <value> is a Brauer character value in characteristic <p> then
##  the result can be described as the corresponding value of the Frobenius
##  character, that is, as the trace of a representing matrix with the given
##  Brauer character value.
##
##  If the result of `FrobeniusCharacterValue' cannot be expressed as an
##  element of a finite field in {\GAP} (see Chapter~"Finite Fields")
##  then `FrobeniusCharacterValue' returns `fail'.
##
##  If the Conway polynomial of degree $n$ is required for the computation
##  then it is computed only if `IsCheapConwayPolynomial' returns `true'
##  when it is called with <p> and $n$,
##  otherwise `fail' is returned.
##
DeclareGlobalFunction( "FrobeniusCharacterValue" );


#############################################################################
##
#A  BrauerCharacterValue( <mat> )
##
##  For an invertible matrix <mat> over a finite field $F$,
##  `BrauerCharacterValue' returns the Brauer character value of <mat>
##  if the order of <mat> is coprime to the characteristic of $F$,
##  and `fail' otherwise.
##
##  The *Brauer character value* of a matrix is the sum of complex lifts of
##  its eigenvalues.
##
DeclareAttribute( "BrauerCharacterValue", IsMatrix );


#############################################################################
##
#V  ZEV_DATA
#F  ZevData( <q>, <n> )
#F  ZevData( <q>, <n>, <listofpairs> )
#F  ZevDataValue( <q>, <n> )
##
##  These variables are used for a database that speeds up the computation of
##  Brauer character values.
##
##  `ZEV_DATA' is a list of length $2$, at position $1$ storing a list of
##  prime powers $q$, and at position $2$ a corresponding list of lists $l$.
##  For given $q$, the list $l$ is again a list of length $2$,
##  at position $1$ storing a list of positive integers $n$, at position $2$
##  a corresponding list of lists, the entry for fixed ($q$ and) $n$ being
##  a list of pairs $[ c, y ]$ as needed by `ZevData'.
##
##  For a prime power <q> and a positive integer <n>, `ZevData' returns
##  a list of pairs $[ c, y ]$ where $c$ is the coefficient list of a
##  polynomial $f$ over the field $F$ with <q> elements,
##  and $y$ a complex value.
##  These pairs are used to compute Brauer character values of matrices $M$
##  over $F$, of order <n>;
##  a $d$-dimensional nullspace of the matrix obtained by evaluating $f$ at
##  $M$ contributes the summand $y$ with multiplicity $d / `Degree'( f )$.
##
##  `ZevData' checks whether the required data are already stored in the
##  global list `ZEV_DATA';
##  if not then `ZevDataValue' is called, which does the real work.
##
##  Called with three arguments, `ZevData' *stores* the third argument in the
##  global list `ZEV_DATA', at the position where the call with the first two
##  arguments will fetch it.
##
##  (The names of these functions reflect that the corresponding command in
##  the C-{\MeatAxe} is `zev'.)
##
DeclareGlobalVariable( "ZEV_DATA", "nested list of length 2" );
DeclareGlobalFunction( "ZevData" );
DeclareGlobalFunction( "ZevDataValue" );


#############################################################################
##
#F  SizeOfFieldOfDefinition( <val>, <p> )
##
##  For a cyclotomic or a list of cyclotomics <val>, and a prime integer <p>,
##  `SizeOfFieldOfDefinition' returns the size of the smallest finite field
##  in characteristic <p> that contains the <p>-modular reduction of <val>.
##
##  The reduction map is defined as in~\cite{JLPW95},
##  that is, the complex $(<p>^d-1)$-th root of unity `E'$(q^d-1)$ is mapped
##  to the residue class of the indeterminate, modulo the ideal spanned by
##  the Conway polynomial (see~"ConwayPolynomial") of degree $d$ over the
##  field with $p$ elements.
##
##  If <val> is a Brauer character then the value returned is the size of the
##  smallest finite field in characteristic <p> over which the corresponding
##  representation lives.
##
DeclareGlobalFunction( "SizeOfFieldOfDefinition" );


#############################################################################
##
#F  RealizableBrauerCharacters( <matrix>, <q> )
##
##  For a list <matrix> of absolutely irreducible Brauer characters
##  in characteristic $p$, and a power <q> of $p$,
##  `RealizableBrauerCharacters' returns a duplicate-free list of sums of
##  Frobenius conjugates of the rows of <matrix>,
##  each irreducible over the field with <q> elements.
##
DeclareGlobalFunction( "RealizableBrauerCharacters" );


#############################################################################
##
##  13. Domains Generated by Class Functions
#9
##  {\GAP} supports groups, vector spaces, and algebras generated by class
##  functions.
##


#############################################################################
##
#F  IsClassFunctionsSpace( <V> )
##
##  If an $F$-vector space <V> is in the filter `IsClassFunctionsSpace' then
##  this expresses that <V> consists of class functions, and that <V> is
##  handled via the mechanism of nice bases (see~"...") in the following way.
##  Let $T$ be the underlying character table of the elements of <V>.
##  Then the `NiceFreeLeftModuleInfo' value of <V> is $T$,
##  and the `NiceVector' value of $v \in <V>$ is defined as
##  $`ValueOfclassFunction'( v )$.
##
DeclareHandlingByNiceBasis( "IsClassFunctionsSpace",
    "for free left modules of class functions" );


#############################################################################
##
##  14. Auxiliary operations
##


##############################################################################
##
#F  OrbitChar( <chi>, <linear> )
##
##  is the orbit of the character values list <chi> under the action of
##  Galois automorphisms and multiplication with the linear characters in
##  the list <linear>.
##
##  It is assumed that <linear> is closed under Galois automorphisms and
##  tensoring.
##  (This means that we can first form the orbit under Galois action, and
##  then apply the linear characters to all Galois conjugates.)
##
DeclareGlobalFunction( "OrbitChar" );


##############################################################################
##
#F  OrbitsCharacters( <chars> )
##
##  is a list of orbits of the characters in the list <chars>
##  under the action of Galois automorphisms
##  and multiplication with the linear characters in <chars>.
##
##  (Note that the image of an ordinary character under a Galois automorphism
##  is always a character; this is in general not true for Brauer characters.)
##
DeclareGlobalFunction( "OrbitsCharacters" );


##############################################################################
##
#F  OrbitRepresentativesCharacters( <irr> )
##
##  is a list of representatives of the orbits of the characters <irr>
##  under the action of Galois automorphisms and multiplication with linear
##  characters.
##
DeclareGlobalFunction( "OrbitRepresentativesCharacters" );


#T where to put the following two functions?
#############################################################################
##
#F  CollapsedMat( <mat>, <maps> )
##
##  is a record with components
##
##  \beginitems
##  `fusion'&
##     fusion that collapses those columns of <mat> that are equal in <mat>
##     and also for all maps in the list <maps>,
##
##  `mat'&
##     the image of <mat> under that fusion.
##  \enditems
##
DeclareGlobalFunction( "CollapsedMat" );


#############################################################################
##
#F  CharacterTableQuaternionic( <4n> )
##
##  is the ordinary character table of the generalized quaternion group
##  of order <4n>.
##
DeclareGlobalFunction( "CharacterTableQuaternionic" );


#############################################################################
##
#E

