Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  ctblfuns.gd   Sprache: unbekannt

 
Spracherkennung für: .gd vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Thomas Breuer.
##
##  Copyright of GAP belongs to its developers, whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-2.0-or-later
##
##  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
##


#############################################################################
##
#C  IsClassFunction( <obj> )
##
##  <#GAPDoc Label="IsClassFunction">
##  <ManSection>
##  <Filt Name="IsClassFunction" Arg='obj' Type='Category'/>
##
##  <Description>
##  <Index>class function</Index><Index>class function objects</Index>
##  A <E>class function</E> (in characteristic <M>p</M>) of a finite group
##  <M>G</M> is a map from the set of (<M>p</M>-regular) elements in <M>G</M>
##  to the field of cyclotomics
##  that is constant on conjugacy classes of <M>G</M>.
##  <P/>
##  Each class function in &GAP; is represented by an <E>immutable list</E>,
##  where at the <M>i</M>-th position the value on the <M>i</M>-th conjugacy
##  class of the character table of <M>G</M> 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 <Ref Sect="The Interface between Character Tables and Groups"/>);
##  class functions always refer to the ordering of classes in the character
##  table.
##  <P/>
##  <E>Class function objects</E> in &GAP; are not just plain lists,
##  they store the character table of the group <M>G</M> as value of the
##  attribute <Ref Attr="UnderlyingCharacterTable"/>.
##  The group <M>G</M> itself is accessible only via the character table
##  and thus only if the character table stores its group, as value of the
##  attribute <Ref Attr="UnderlyingGroup" Label="for character tables"/>.
##  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.
##  <P/>
##  There are (at least) two reasons why class functions in &GAP; are
##  <E>not</E> 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 <M>G</M> 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.
##  <P/>
##  A further argument is that the typical operations for mappings such as
##  <Ref Func="Image" Label="set of images of the source of a general mapping"/>
##  and
##  <Ref Func="PreImage" Label="set of preimages of the range of a general mapping"/>
##  play no important role for class functions.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareCategory( "IsClassFunction",
    IsScalar and IsCommutativeElement and IsAssociativeElement
             and IsHomogeneousList and IsScalarCollection and IsFinite
             and IsGeneralizedRowVector );


#############################################################################
##
#F  CharacterString( <char>, <str> )
##
##  <ManSection>
##  <Func Name="CharacterString" Arg='char, str'/>
##
##  <Description>
##  </Description>
##  </ManSection>
##
DeclareGlobalFunction( "CharacterString" );


#############################################################################
##
##  1. Why Class Functions?
##
##  <#GAPDoc Label="[1]{ctblfuns}">
##  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.
##  <P/>
##  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.
##  <P/>
##  Second, when one says that
##  <Q><M>\chi</M> is a character of a group <M>G</M></Q>
##  then this object <M>\chi</M> carries a lot of information.
##  <M>\chi</M> has certain properties such as being irreducible or not.
##  Several subgroups of <M>G</M> are related to <M>\chi</M>,
##  such as the kernel and the centre of <M>\chi</M>.
##  Other attributes of characters are the determinant and the central
##  character.
##  This knowledge cannot be stored in a plain list.
##  <P/>
##  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.
##  <P/>
##  The main idea behind class function objects is that a class function
##  object is equal to its values list in the sense of <Ref Oper="\="/>,
##  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.
##  <!-- Note that a class function object lies in the same family as its list of-->
##  <!-- values.-->
##  <!-- As a consequence, there is no filter <C>IsClassFunctionCollection</C>,-->
##  <!-- 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 <Ref Attr="Irr" Label="for a group"/> lists
##  consist of class function objects,
##  and <Ref Attr="TrivialCharacter" Label="for a group"/>
##  returns a class function object.
##  <P/>
##  Here is an <E>example</E> that shows both approaches.
##  First we define some groups.
##  <P/>
##  <Example><![CDATA[
##  gap> S4:= SymmetricGroup( 4 );;  SetName( S4, "S4" );
##  gap> D8:= SylowSubgroup( S4, 2 );; SetName( D8, "D8" );
##  ]]></Example>
##  <P/>
##  We do some computations using the functions described later in this
##  Chapter, first with class function objects.
##  <P/>
##  <Example><![CDATA[
##  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 ] )
##  ]]></Example>
##  <P/>
##  Now we repeat these calculations with plain lists of character values.
##  Here we need the character tables in some places.
##  <P/>
##  <Example><![CDATA[
##  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 ] )
##  ]]></Example>
##  <P/>
##  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.)
##  <P/>
##  <Example><![CDATA[
##  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 ] )
##  ]]></Example>
##  <P/>
##  Functions that compute <E>normal</E> subgroups related to characters
##  have counterparts that return the list of class positions corresponding
##  to these groups.
##  <P/>
##  <Example><![CDATA[
##  gap> ClassPositionsOfKernel( irrs5[2] );
##  [ 1, 2, 3, 4 ]
##  gap> ClassPositionsOfCentre( irrs5[2] );
##  [ 1, 2, 3, 4, 5, 6, 7 ]
##  ]]></Example>
##  <P/>
##  Non-normal subgroups cannot be described this way,
##  so for example inertia subgroups (see <Ref Oper="InertiaSubgroup"/>)
##  can in general not be computed from character tables without access to
##  their groups.
##  <#/GAPDoc>
##


#############################################################################
##
##  2. Basic Operations for Class Functions
##
##  <#GAPDoc Label="[2]{ctblfuns}">
##  Basic operations for class functions are
##  <Ref Attr="UnderlyingCharacterTable"/>,
##  <Ref Attr="ValuesOfClassFunction"/>,
##  and the basic operations for lists
##  (see <Ref Sect="Basic Operations for Lists"/>).
##  <#/GAPDoc>
##


#############################################################################
##
#A  UnderlyingCharacterTable( <psi> )
##
##  <#GAPDoc Label="UnderlyingCharacterTable">
##  <ManSection>
##  <Attr Name="UnderlyingCharacterTable" Arg='psi'/>
##
##  <Description>
##  For a class function <A>psi</A> of a group <M>G</M>
##  the character table of <M>G</M> is stored as value of
##  <Ref Attr="UnderlyingCharacterTable"/>.
##  The ordering of entries in the list <A>psi</A>
##  (see <Ref Attr="ValuesOfClassFunction"/>)
##  refers to the ordering of conjugacy classes in this character table.
##  <P/>
##  If <A>psi</A> is an ordinary class function then the underlying character
##  table is the ordinary character table of <M>G</M>
##  (see <Ref Attr="OrdinaryCharacterTable" Label="for a group"/>),
##  if <A>psi</A> is a class function in characteristic <M>p \neq 0</M> then
##  the underlying character table is the <M>p</M>-modular Brauer table of
##  <M>G</M>
##  (see <Ref Oper="BrauerTable"
##  Label="for a group, and a prime integer"/>).
##  So the underlying characteristic of <A>psi</A> can be read off from the
##  underlying character table.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "UnderlyingCharacterTable", IsClassFunction );


#############################################################################
##
#A  ValuesOfClassFunction( <psi> ) . . . . . . . . . . . . . . list of values
##
##  <#GAPDoc Label="ValuesOfClassFunction">
##  <ManSection>
##  <Attr Name="ValuesOfClassFunction" Arg='psi'/>
##
##  <Description>
##  is the list of values of the class function <A>psi</A>,
##  the <M>i</M>-th entry being the value on the <M>i</M>-th conjugacy class
##  of the underlying character table
##  (see <Ref Attr="UnderlyingCharacterTable"/>).
##  <P/>
##  <Example><![CDATA[
##  gap> g:= SymmetricGroup( 4 );
##  Sym( [ 1 .. 4 ] )
##  gap> psi:= TrivialCharacter( g );
##  Character( CharacterTable( Sym( [ 1 .. 4 ] ) ), [ 1, 1, 1, 1, 1 ] )
##  gap> UnderlyingCharacterTable( psi );
##  CharacterTable( Sym( [ 1 .. 4 ] ) )
##  gap> ValuesOfClassFunction( psi );
##  [ 1, 1, 1, 1, 1 ]
##  gap> IsList( psi );
##  true
##  gap> psi[1];
##  1
##  gap> Length( psi );
##  5
##  gap> IsBound( psi[6] );
##  false
##  gap> Concatenation( psi, [ 2, 3 ] );
##  [ 1, 1, 1, 1, 1, 2, 3 ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "ValuesOfClassFunction", IsClassFunction );


#############################################################################
##
##  3. Comparison of Class Functions
##
##  <#GAPDoc Label="[3]{ctblfuns}">
##  With respect to <Ref Oper="\="/> and <Ref Oper="\<"/>,
##  class functions behave equally to their lists of values
##  (see <Ref Attr="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.
##  <P/>
##  <Example><![CDATA[
##  gap> grps:= Filtered( AllSmallGroups( 8 ), g -> not IsAbelian( g ) );
##  [ <pc group of size 8 with 3 generators>,
##    <pc group of size 8 with 3 generators> ]
##  gap> t1:= CharacterTable( grps[1] );  SetName( t1, "t1" );
##  CharacterTable( <pc group of size 8 with 3 generators> )
##  gap> t2:= CharacterTable( grps[2] );  SetName( t2, "t2" );
##  CharacterTable( <pc group of size 8 with 3 generators> )
##  gap> CharacterDegrees( t1 );
##  [ [ 1, 4 ], [ 2, 1 ] ]
##  gap> irr1:= Irr( grps[1] );;
##  gap> irr2:= Irr( grps[2] );;
##  gap> irr1 = irr2;
##  true
##  gap> irr1[1];
##  Character( t1, [ 1, 1, 1, 1, 1 ] )
##  gap> irr1[5];
##  Character( t1, [ 2, 0, 0, -2, 0 ] )
##  gap> irr2[1];
##  Character( t2, [ 1, 1, 1, 1, 1 ] )
##  gap> IsSSortedList( irr1 );
##  false
##  gap> irr1[1] < irr1[2];  # the triv. character has no '-1'
##  false
##  gap> irr1[2] < irr1[5];
##  true
##  ]]></Example>
##  <#/GAPDoc>
##


#############################################################################
##
##  4. Arithmetic Operations for Class Functions
##
##  <#GAPDoc Label="[4]{ctblfuns}">
##  Class functions are <E>row vectors</E> of cyclotomics.
##  The <E>additive</E> 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 <E>multiplicative</E> 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
##  <Ref Oper="ScalarProduct" Label="for characters"/>.
##  In terms of filters, the arithmetic of class functions is based on the
##  decision that they lie in <Ref Filt="IsGeneralizedRowVector"/>,
##  with additive nesting depth <M>1</M>, but they do <E>not</E> lie in
##  <Ref Filt="IsMultiplicativeGeneralizedRowVector"/>.
##  <P/>
##  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 <Ref Attr="UnderlyingCharacterTable"/>)
##  are again class functions of this table.
##  The sum and the difference of a class function and a list that is
##  <E>not</E> a class function are plain lists,
##  as well as the sum and the difference of two class functions of different
##  character tables.
##  <P/>
##  <Example><![CDATA[
##  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 ]
##  ]]></Example>
##  <P/>
##  <Index Subkey="as ring elements">class functions</Index>
##  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 <M>F</M> of cyclotomics, the <M>F</M>-span of a given
##  set of class functions forms an algebra.
##  <P/>
##  The product of two class functions of <E>different</E> tables and the
##  product of a class function and a list that is <E>not</E> 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.
##  <P/>
##  <Example><![CDATA[
##  gap> tens:= irr[3] * irr[4];
##  Character( S4, [ 6, 0, -2, 0, 0 ] )
##  gap> ValuesOfClassFunction( irr[3] ) * ValuesOfClassFunction( irr[4] );
##  4
##  ]]></Example>
##  <P/>
##  <Index Subkey="of class function">inverse</Index>
##  Class functions without zero values are invertible,
##  the <E>inverse</E> is defined pointwise.
##  As a consequence, for example groups of linear characters can be formed.
##  <P/>
##  <Example><![CDATA[
##  gap> tens / irr[1];
##  Character( S4, [ 6, 0, -2, 0, 0 ] )
##  ]]></Example>
##  <P/>
##  Other (somewhat strange) implications of the definition of arithmetic
##  operations for class functions, together with the general rules of list
##  arithmetic (see <Ref Sect="Arithmetic for Lists"/>),
##  apply to the case of products involving <E>lists</E> 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.
##  <P/>
##  <Example><![CDATA[
##  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 ] ]
##  ]]></Example>
##  <P/>
##  Also the product of a class function with a list of class functions is
##  <E>not</E> a vector-matrix product but the list of pointwise products.
##  <P/>
##  <Example><![CDATA[
##  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 ] ) ]
##  ]]></Example>
##  <P/>
##  And the product of two lists of class functions is <E>not</E> the matrix
##  product but the sum of the pointwise products.
##  <P/>
##  <Example><![CDATA[
##  gap> irr * irr;
##  Character( S4, [ 24, 4, 8, 3, 4 ] )
##  ]]></Example>
##  <P/>
##  <Index Subkey="of group element using powering operator">character value</Index>
##  <Index Subkey="meaning for class functions">power</Index>
##  <Index Key="^" Subkey="for class functions"><C>^</C></Index>
##  The <E>powering</E> operator <Ref Oper="\^"/> 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 <Ref Oper="\^"/>; instead one can use
##  <Ref Oper="Permuted"/>.)
##  The power of a class function by a group or a character table is the
##  induced class function (see <Ref Oper="InducedClassFunction"
##  Label="for the character table of a supergroup"/>).
##  The power of a group element by a class function is the class function
##  value at (the conjugacy class containing) this element.
##  <P/>
##  <Example><![CDATA[
##  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), E(3)^2 ] ),
##    Character( CharacterTable( Alt( [ 1 .. 4 ] ) ),
##    [ 1, 1, E(3)^2, E(3) ] ) ]
##  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)^2, E(3) ] ),
##    Character( CharacterTable( Alt( [ 1 .. 4 ] ) ),
##    [ 1, 1, E(3), E(3)^2 ] ) ]
##  gap> Orbit( GaloisGroup( CF(3) ), lin[2] );
##  [ 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> lin[1]^g;
##  Character( S4, [ 2, 0, 2, 2, 0 ] )
##  gap> (1,2,3)^lin[2];
##  E(3)
##  ]]></Example>
##
##  <ManSection>
##  <Attr Name="Characteristic" Arg='chi' Label="for a class function"/>
##
##  <Description>
##  The <E>characteristic</E> of class functions is zero,
##  as for all list of cyclotomics.
##  For class functions of a <M>p</M>-modular character table, such as Brauer
##  characters, the prime <M>p</M> is given by the
##  <Ref Attr="UnderlyingCharacteristic" Label="for a character table"/>
##  value of the character table.
##  <P/>
##  <Example><![CDATA[
##  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
##  ]]></Example>
##  </Description>
##  </ManSection>
##
##  <ManSection>
##  <Attr Name="ComplexConjugate" Arg='chi' Label="for a class function"/>
##  <Oper Name="GaloisCyc" Arg='chi, k' Label="for a class function"/>
##  <Meth Name="Permuted" Arg='chi, pi' Label="for a class function"/>
##
##  <Description>
##  The operations
##  <Ref Attr="ComplexConjugate" Label="for a class function"/>,
##  <Ref Oper="GaloisCyc" Label="for a class function"/>,
##  and <Ref Meth="Permuted" Label="for a class function"/> 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.
##  <P/>
##  <Example><![CDATA[
##  gap> ComplexConjugate( lin[2] );
##  Character( CharacterTable( Alt( [ 1 .. 4 ] ) ),
##   [ 1, 1, E(3)^2, E(3) ] )
##  gap> GaloisCyc( lin[2], 5 );
##  Character( CharacterTable( Alt( [ 1 .. 4 ] ) ),
##   [ 1, 1, E(3)^2, E(3) ] )
##  gap> Permuted( lin[2], (2,3,4) );
##  ClassFunction( CharacterTable( Alt( [ 1 .. 4 ] ) ),
##   [ 1, E(3)^2, 1, E(3) ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <P/>
##  <ManSection>
##  <Attr Name="Order" Arg='chi' Label="for a class function"/>
##
##  <Description>
##  By definition of <Ref Attr="Order"/> for arbitrary monoid elements,
##  the return value of <Ref Attr="Order"/> for a character must be its
##  multiplicative order.
##  The <E>determinantal order</E>
##  (see <Ref Attr="DeterminantOfCharacter"/>) of a character <A>chi</A>
##  can be computed as <C>Order( Determinant( <A>chi</A> ) )</C>.
##  <P/>
##  <Example><![CDATA[
##  gap> det:= Determinant( irr[3] );
##  Character( S4, [ 1, -1, 1, 1, -1 ] )
##  gap> Order( det );
##  2
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##


#############################################################################
##
#A  GlobalPartitionOfClasses( <tbl> )
##
##  <ManSection>
##  <Attr Name="GlobalPartitionOfClasses" Arg='tbl'/>
##
##  <Description>
##  Let <M>n</M> be the number of conjugacy classes of the character table
##  <A>tbl</A>.
##  <Ref Func="GlobalPartitionOfClasses"/> returns a list of subsets of the
##  range <M>[ 1 .. n ]</M> that forms a partition of <M>[ 1 .. n ]</M>.
##  This partition is respected by each table automorphism of <A>tbl</A>
##  (see <Ref Func="AutomorphismsOfTable"/>);
##  <E>note</E> that also fixed points occur.
##  <P/>
##  This is useful for the computation of table automorphisms
##  and of conjugate class functions.
##  <P/>
##  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.
##  <P/>
##  If the group of table automorphisms is already known then its orbits
##  form the finest possible global partition.
##  <P/>
##  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 <M>p</M>-th root classes,
##  for all <M>p</M> for which the power maps are stored.
##  </Description>
##  </ManSection>
##
DeclareAttribute( "GlobalPartitionOfClasses", IsNearlyCharacterTable );


#############################################################################
##
#O  CorrespondingPermutations( <tbl>[, <chi>], <elms> )
##
##  <ManSection>
##  <Oper Name="CorrespondingPermutations" Arg='tbl[, chi], elms'/>
##
##  <Description>
##  Called with two arguments <A>tbl</A> and <A>elms</A>,
##  <Ref Oper="CorrespondingPermutations"/> returns the list of those
##  permutations of conjugacy classes of the character table <A>tbl</A>
##  that are induced by the action of the group elements in the list
##  <A>elms</A>.
##  If an element of <A>elms</A> does <E>not</E> act on the classes of
##  <A>tbl</A> then either <K>fail</K> or a (meaningless) permutation
##  is returned.
##  <P/>
##  In the call with three arguments, the second argument <A>chi</A> must be
##  (the values list of) a class function of <A>tbl</A>,
##  and the returned permutations will at least yield the same
##  conjugate class functions as the permutations of classes that are induced
##  by <A>elms</A>,
##  that is, the images are not necessarily the same for orbits on which
##  <A>chi</A> is constant.
##  <P/>
##  This function is used for computing conjugate class functions.
##  </Description>
##  </ManSection>
##
DeclareOperation( "CorrespondingPermutations",
    [ IsOrdinaryTable, IsHomogeneousList ] );
DeclareOperation( "CorrespondingPermutations",
    [ IsOrdinaryTable, IsClassFunction, IsHomogeneousList ] );


#############################################################################
##
##  5. Printing Class Functions
##
##  <#GAPDoc Label="[5]{ctblfuns}">
##  <ManSection>
##  <Meth Name="ViewObj" Arg='chi' Label="for class functions"/>
##
##  <Description>
##  The default <Ref Oper="ViewObj"/> methods for class functions
##  print one of the strings <C>"ClassFunction"</C>,
##  <C>"VirtualCharacter"</C>, <C>"Character"</C> (depending on whether the
##  class function is known to be a character or virtual character,
##  see <Ref Prop="IsCharacter"/>, <Ref Prop="IsVirtualCharacter"/>),
##  followed by the <Ref Oper="ViewObj"/> output for the underlying character
##  table (see <Ref Sect="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 <Ref Attr="UnderlyingCharacteristic" Label="for a character"/>).
##  </Description>
##  </ManSection>
##
##  <ManSection>
##  <Meth Name="PrintObj" Arg='chi' Label="for class functions"/>
##
##  <Description>
##  The default <Ref Oper="PrintObj"/> method for class functions
##  does the same as <Ref Oper="ViewObj"/>,
##  except that the character table is <Ref Func="Print"/>-ed instead of
##  <Ref Func="View"/>-ed.
##  <P/>
##  <E>Note</E> that if a class function is shown only with one of the
##  strings <C>"ClassFunction"</C>, <C>"VirtualCharacter"</C>,
##  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.
##  <P/>
##  In order to reduce the space that is needed to print a class function,
##  it may be useful to give a name (see <Ref Attr="Name"/>) to the
##  underlying character table.
##  </Description>
##  </ManSection>
##
##  <ManSection>
##  <Meth Name="Display" Arg='chi' Label="for class functions"/>
##
##  <Description>
##  The default <Ref Oper="Display"/> method for a class function <A>chi</A>
##  calls <Ref Oper="Display"/> for its underlying character table
##  (see <Ref Sect="Printing Character Tables"/>),
##  with <A>chi</A> as the only entry in the <C>chars</C> list of the options
##  record.
##  <P/>
##  <Example><![CDATA[
##  gap> chi:= TrivialCharacter( CharacterTable( "A5" ) );
##  Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] )
##  gap> Display( chi );
##  A5
##
##       2  2  2  .  .  .
##       3  1  .  1  .  .
##       5  1  .  .  1  1
##
##         1a 2a 3a 5a 5b
##      2P 1a 1a 3a 5b 5a
##      3P 1a 2a 1a 5b 5a
##      5P 1a 2a 3a 1a 1a
##
##  Y.1     1  1  1  1  1
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##


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


#############################################################################
##
#O  ClassFunction( <tbl>, <values> )
#O  ClassFunction( <G>, <values> )
##
##  <#GAPDoc Label="ClassFunction">
##  <ManSection>
##  <Oper Name="ClassFunction" Arg='tbl, values'
##   Label="for a character table and a list"/>
##  <Oper Name="ClassFunction" Arg='G, values'
##   Label="for a group and a list"/>
##
##  <Description>
##  In the first form,
##  <Ref Oper="ClassFunction" Label="for a character table and a list"/>
##  returns the class function of the character table <A>tbl</A> with values
##  given by the list <A>values</A> of cyclotomics.
##  In the second form, <A>G</A> must be a group,
##  and the class function of its ordinary character table is returned.
##  <P/>
##  Note that <A>tbl</A> determines the underlying characteristic of the
##  returned class function
##  (see <Ref Attr="UnderlyingCharacteristic" Label="for a character"/>).
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "ClassFunction", [ IsNearlyCharacterTable, IsDenseList ] );
DeclareOperation( "ClassFunction", [ IsGroup, IsDenseList ] );


#############################################################################
##
#O  VirtualCharacter( <tbl>, <values> )
#O  VirtualCharacter( <G>, <values> )
##
##  <#GAPDoc Label="VirtualCharacter">
##  <ManSection>
##  <Oper Name="VirtualCharacter" Arg='tbl, values'
##   Label="for a character table and a list"/>
##  <Oper Name="VirtualCharacter" Arg='G, values'
##   Label="for a group and a list"/>
##
##  <Description>
##  <Ref Oper="VirtualCharacter" Label="for a character table and a list"/>
##  returns the virtual character
##  (see <Ref Prop="IsVirtualCharacter"/>)
##  of the character table <A>tbl</A> or the group <A>G</A>,
##  respectively, with values given by the list <A>values</A>.
##  <P/>
##  It is <E>not</E> checked whether the given values really describe a
##  virtual character.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "VirtualCharacter",
    [ IsNearlyCharacterTable, IsDenseList ] );
DeclareOperation( "VirtualCharacter", [ IsGroup, IsDenseList ] );


#############################################################################
##
#O  Character( <tbl>, <values> )
##
##  <#GAPDoc Label="Character">
##  <ManSection>
##  <Oper Name="Character" Arg='tbl, values'
##   Label="for a character table and a list"/>
##  <Oper Name="Character" Arg='G, values'
##   Label="for a group and a list"/>
##
##  <Description>
##  <Ref Oper="Character" Label="for a character table and a list"/>
##  returns the character (see <Ref Prop="IsCharacter"/>)
##  of the character table <A>tbl</A> or the group <A>G</A>,
##  respectively, with values given by the list <A>values</A>.
##  <P/>
##  It is <E>not</E> checked whether the given values really describe a
##  character.
##  <Example><![CDATA[
##  gap> g:= DihedralGroup( 8 );  tbl:= CharacterTable( g );
##  <pc group of size 8 with 3 generators>
##  CharacterTable( <pc group of size 8 with 3 generators> )
##  gap> SetName( tbl, "D8" );
##  gap> phi:= ClassFunction( g, [ 1, -1, 0, 2, -2 ] );
##  ClassFunction( D8, [ 1, -1, 0, 2, -2 ] )
##  gap> psi:= ClassFunction( tbl,
##  >              List( Irr( g ), chi -> ScalarProduct( chi, phi ) ) );
##  ClassFunction( D8, [ -3/8, 9/8, 5/8, 1/8, -1/4 ] )
##  gap> chi:= VirtualCharacter( g, [ 0, 0, 8, 0, 0 ] );
##  VirtualCharacter( D8, [ 0, 0, 8, 0, 0 ] )
##  gap> reg:= Character( tbl, [ 8, 0, 0, 0, 0 ] );
##  Character( D8, [ 8, 0, 0, 0, 0 ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "Character", [ IsNearlyCharacterTable, IsDenseList ] );
DeclareOperation( "Character", [ IsGroup, IsDenseList ] );


#############################################################################
##
#F  ClassFunctionSameType( <tbl>, <chi>, <values> )
##
##  <#GAPDoc Label="ClassFunctionSameType">
##  <ManSection>
##  <Func Name="ClassFunctionSameType" Arg='tbl, chi, values'/>
##
##  <Description>
##  Let <A>tbl</A> be a character table, <A>chi</A> a class function object
##  (<E>not</E> necessarily a class function of <A>tbl</A>),
##  and <A>values</A> a list of cyclotomics.
##  <Ref Func="ClassFunctionSameType"/> returns the class function
##  <M>\psi</M> of <A>tbl</A> with values list <A>values</A>,
##  constructed with
##  <Ref Oper="ClassFunction" Label="for a character table and a list"/>.
##  <P/>
##  If <A>chi</A> is known to be a (virtual) character then <M>\psi</M>
##  is also known to be a (virtual) character.
##  <P/>
##  <Example><![CDATA[
##  gap> h:= Centre( g );;
##  gap> centbl:= CharacterTable( h );;  SetName( centbl, "C2" );
##  gap> ClassFunctionSameType( centbl, phi, [ 1, 1 ] );
##  ClassFunction( C2, [ 1, 1 ] )
##  gap> ClassFunctionSameType( centbl, chi, [ 1, 1 ] );
##  VirtualCharacter( C2, [ 1, 1 ] )
##  gap> ClassFunctionSameType( centbl, reg, [ 1, 1 ] );
##  Character( C2, [ 1, 1 ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "ClassFunctionSameType" );


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


#############################################################################
##
#A  TrivialCharacter( <tbl> )
#A  TrivialCharacter( <G> )
##
##  <#GAPDoc Label="TrivialCharacter">
##  <ManSection>
##  <Heading>TrivialCharacter</Heading>
##  <Attr Name="TrivialCharacter" Arg='tbl' Label="for a character table"/>
##  <Attr Name="TrivialCharacter" Arg='G' Label="for a group"/>
##
##  <Description>
##  is the <E>trivial character</E> of the group <A>G</A>
##  or its character table <A>tbl</A>, respectively.
##  This is the class function with value equal to <M>1</M> for each class.
##  <P/>
##  <Example><![CDATA[
##  gap> TrivialCharacter( CharacterTable( "A5" ) );
##  Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] )
##  gap> TrivialCharacter( SymmetricGroup( 3 ) );
##  Character( CharacterTable( Sym( [ 1 .. 3 ] ) ), [ 1, 1, 1 ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "TrivialCharacter", IsNearlyCharacterTable );
DeclareAttribute( "TrivialCharacter", IsGroup );


#############################################################################
##
#A  NaturalCharacter( <G> )
#A  NaturalCharacter( <hom> )
##
##  <#GAPDoc Label="NaturalCharacter">
##  <ManSection>
##  <Attr Name="NaturalCharacter" Arg='G' Label="for a group"/>
##  <Attr Name="NaturalCharacter" Arg='hom' Label="for a homomorphism"/>
##
##  <Description>
##  If the argument is a permutation group <A>G</A> then
##  <Ref Attr="NaturalCharacter" Label="for a group"/>
##  returns the (ordinary) character of the natural permutation
##  representation of <A>G</A> on the set of moved points (see
##  <Ref Attr="MovedPoints" Label="for a list or collection of permutations"/>),
##  that is, the value on each class is the number of points among the moved
##  points of <A>G</A> that are fixed by any permutation in that class.
##  <P/>
##  If the argument is a matrix group <A>G</A> in characteristic zero then
##  <Ref Attr="NaturalCharacter" Label="for a group"/> returns the
##  (ordinary) character of the natural matrix representation of <A>G</A>,
##  that is, the value on each class is the trace of any matrix in that class.
##  <P/>
##  If the argument is a group homomorphism <A>hom</A> whose image is a
##  permutation group or a matrix group then
##  <Ref Attr="NaturalCharacter" Label="for a homomorphism"/> returns the
##  restriction of the natural character of the image of <A>hom</A> to the
##  preimage of <A>hom</A>.
##  <P/>
##  <Example><![CDATA[
##  gap> NaturalCharacter( SymmetricGroup( 3 ) );
##  Character( CharacterTable( Sym( [ 1 .. 3 ] ) ), [ 3, 1, 0 ] )
##  gap> NaturalCharacter( Group( [ [ 0, -1 ], [ 1, -1 ] ] ) );
##  Character( CharacterTable( Group([ [ [ 0, -1 ], [ 1, -1 ] ] ]) ),
##  [ 2, -1, -1 ] )
##  gap> d8:= DihedralGroup( 8 );;  hom:= RegularActionHomomorphism( d8 );;
##  gap> NaturalCharacter( hom );
##  Character( CharacterTable( <pc group of size 8 with 3 generators> ),
##  [ 8, 0, 0, 0, 0 ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "NaturalCharacter", IsGroup );
DeclareAttribute( "NaturalCharacter", IsGeneralMapping );


#############################################################################
##
#O  PermutationCharacter( <G>, <D>, <opr> )
#O  PermutationCharacter( <G>, <U> )
##
##  <#GAPDoc Label="PermutationCharacter">
##  <ManSection>
##  <Heading>PermutationCharacter</Heading>
##  <Oper Name="PermutationCharacter" Arg='G, D, opr'
##   Label="for a group, an action domain, and a function"/>
##  <Oper Name="PermutationCharacter" Arg='G, U' Label="for two groups"/>
##
##  <Description>
##  Called with a group <A>G</A>, an action domain or proper set <A>D</A>,
##  and an action function <A>opr</A>
##  (see Chapter <Ref Chap="Group Actions"/>),
##  <Ref Oper="PermutationCharacter"
##  Label="for a group, an action domain, and a function"/>
##  returns the <E>permutation character</E> of the action
##  of <A>G</A> on <A>D</A> via <A>opr</A>,
##  that is, the value on each class is the number of points in <A>D</A>
##  that are fixed by an element in this class under the action <A>opr</A>.
##  <P/>
##  If the arguments are a group <A>G</A> and a subgroup <A>U</A> of <A>G</A>
##  then <Ref Oper="PermutationCharacter" Label="for two groups"/> returns
##  the permutation character of the action of <A>G</A> on the right cosets
##  of <A>U</A> via right multiplication.
##  <P/>
##  To compute the permutation character of a
##  <E>transitive permutation group</E>
##  <A>G</A> on the cosets of a point stabilizer <A>U</A>,
##  the attribute <Ref Attr="NaturalCharacter" Label="for a group"/>
##  of <A>G</A> can be used instead of
##  <C>PermutationCharacter( <A>G</A>, <A>U</A> )</C>.
##  <P/>
##  More facilities concerning permutation characters are the transitivity
##  test (see Section <Ref Sect="Operations for Class Functions"/>)
##  and several tools for computing possible permutation characters
##  (see <Ref Sect="Possible Permutation Characters"/>,
##  <Ref Sect="Computing Possible Permutation Characters"/>).
##  <P/>
##  <Example><![CDATA[
##  gap> PermutationCharacter( GL(2,2), AsSSortedList( GF(2)^2 ), OnRight );
##  Character( CharacterTable( SL(2,2) ), [ 4, 2, 1 ] )
##  gap> s3:= SymmetricGroup( 3 );;  a3:= DerivedSubgroup( s3 );;
##  gap> PermutationCharacter( s3, a3 );
##  Character( CharacterTable( Sym( [ 1 .. 3 ] ) ), [ 2, 0, 2 ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "PermutationCharacter",
    [ IsGroup, IsCollection, IsFunction ] );
DeclareOperation( "PermutationCharacter", [ IsGroup, IsGroup ] );


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


#############################################################################
##
#P  IsCharacter( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="IsCharacter">
##  <ManSection>
##  <Prop Name="IsCharacter" Arg='[tbl, ]chi'/>
##
##  <Description>
##  <Index>ordinary character</Index>
##  An <E>ordinary character</E> of a group <M>G</M> is a class function of
##  <M>G</M> whose values are the traces of a complex matrix representation
##  of <M>G</M>.
##  <P/>
##  <Index>Brauer character</Index>
##  A <E>Brauer character</E> of <M>G</M> in characteristic <M>p</M> is
##  a class function of <M>G</M> whose values are the complex lifts of a
##  matrix representation of <M>G</M> with image a finite field of
##  characteristic <M>p</M>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareProperty( "IsCharacter", IsClassFunction );
DeclareOperation( "IsCharacter", [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#P  IsVirtualCharacter( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="IsVirtualCharacter">
##  <ManSection>
##  <Prop Name="IsVirtualCharacter" Arg='[tbl, ]chi'/>
##
##  <Description>
##  <Index>virtual character</Index>
##  A <E>virtual character</E> is a class function that can be written as the
##  difference of two proper characters (see <Ref Prop="IsCharacter"/>).
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareProperty( "IsVirtualCharacter", IsClassFunction );
InstallTrueMethod( IsClassFunction, IsVirtualCharacter );
DeclareOperation( "IsVirtualCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


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


#############################################################################
##
#P  IsIrreducibleCharacter( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="IsIrreducibleCharacter">
##  <ManSection>
##  <Prop Name="IsIrreducibleCharacter" Arg='[tbl, ]chi'/>
##
##  <Description>
##  <Index>irreducible character</Index>
##  A character is <E>irreducible</E> 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 <Ref Oper="ScalarProduct" Label="for characters"/>).
##  For Brauer characters there is no generic method for checking
##  irreducibility.
##  <P/>
##  <Example><![CDATA[
##  gap> S4:= SymmetricGroup( 4 );;  SetName( S4, "S4" );
##  gap> psi:= ClassFunction( S4, [ 1, 1, 1, -2, 1 ] );
##  ClassFunction( CharacterTable( S4 ), [ 1, 1, 1, -2, 1 ] )
##  gap> IsVirtualCharacter( psi );
##  true
##  gap> IsCharacter( psi );
##  false
##  gap> chi:= ClassFunction( S4, SizesCentralizers( CharacterTable( S4 ) ) );
##  ClassFunction( CharacterTable( S4 ), [ 24, 4, 8, 3, 4 ] )
##  gap> IsCharacter( chi );
##  true
##  gap> IsIrreducibleCharacter( chi );
##  false
##  gap> IsIrreducibleCharacter( TrivialCharacter( S4 ) );
##  true
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareProperty( "IsIrreducibleCharacter", IsClassFunction );
DeclareOperation( "IsIrreducibleCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#O  ScalarProduct( [<tbl>, ]<chi>, <psi> )
##
##  <#GAPDoc Label="ScalarProduct:ctblfuns">
##  <ManSection>
##  <Oper Name="ScalarProduct" Arg='[tbl, ]chi, psi' Label="for characters"/>
##
##  <Returns>
##  the scalar product of the class functions <A>chi</A> and <A>psi</A>,
##  which belong to the same character table <A>tbl</A>.
##  </Returns>
##  <Description>
##  <Index Subkey="of a group character">constituent</Index>
##  <Index Subkey="a group character">decompose</Index>
##  <Index Subkey="of constituents of a group character">multiplicity</Index>
##  <Index Subkey="of group characters">inner product</Index>
##  If <A>chi</A> and <A>psi</A> are class function objects,
##  the argument <A>tbl</A> is not needed,
##  but <A>tbl</A> is necessary if at least one of <A>chi</A>, <A>psi</A>
##  is just a plain list.
##  <P/>
##  The scalar product of two <E>ordinary</E> class functions <M>\chi</M>,
##  <M>\psi</M> of a group <M>G</M> is defined as
##  <P/>
##  <M>( \sum_{{g \in G}} \chi(g) \psi(g^{{-1}}) ) / |G|</M>.
##  <P/>
##  For two <E><M>p</M>-modular</E> class functions,
##  the scalar product is defined as
##  <M>( \sum_{{g \in S}} \chi(g) \psi(g^{{-1}}) ) / |G|</M>,
##  where <M>S</M> is the set of <M>p</M>-regular elements in <M>G</M>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "ScalarProduct",
    [ IsCharacterTable, IsRowVector, IsRowVector ] );


#############################################################################
##
#O  MatScalarProducts( [<tbl>, ]<list>[, <list2>] )
##
##  <#GAPDoc Label="MatScalarProducts">
##  <ManSection>
##  <Oper Name="MatScalarProducts" Arg='[tbl, ]list[, list2]'/>
##
##  <Description>
##  Called with two lists <A>list</A>, <A>list2</A> of class functions of the
##  same character table (which may be given as the argument <A>tbl</A>),
##  <Ref Oper="MatScalarProducts"/> returns the matrix of scalar products
##  (see <Ref Oper="ScalarProduct" Label="for characters"/>)
##  More precisely, this matrix contains in the <M>i</M>-th row the list of
##  scalar products of <M><A>list2</A>[i]</M>
##  with the entries of <A>list</A>.
##  <P/>
##  If only one list <A>list</A> of class functions is given then
##  a lower triangular matrix of scalar products is returned,
##  containing (for <M>j \leq i</M>) in the <M>i</M>-th row in column
##  <M>j</M> the value
##  <C>ScalarProduct</C><M>( <A>tbl</A>, <A>list</A>[j], <A>list</A>[i] )</M>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "MatScalarProducts",
    [ IsHomogeneousList, IsHomogeneousList ] );
DeclareOperation( "MatScalarProducts",
    [ IsOrdinaryTable, IsHomogeneousList, IsHomogeneousList ] );
DeclareOperation( "MatScalarProducts", [ IsHomogeneousList ] );
DeclareOperation( "MatScalarProducts",
    [ IsOrdinaryTable, IsHomogeneousList ] );


#############################################################################
##
#A  Norm( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="Norm:ctblfuns">
##  <ManSection>
##  <Attr Name="Norm" Arg='[tbl, ]chi' Label="for a class function"/>
##
##  <Description>
##  <Index Subkey="of character" Key="Norm"><C>Norm</C></Index>
##  For an ordinary class function <A>chi</A> of a group <M>G</M>
##  we have <M><A>chi</A> = \sum_{{\chi \in Irr(G)}} a_{\chi} \chi</M>,
##  with complex coefficients <M>a_{\chi}</M>.
##  The <E>norm</E> of <A>chi</A> is defined as
##  <M>\sum_{{\chi \in Irr(G)}} a_{\chi} \overline{{a_{\chi}}}</M>.
##  <P/>
##  <Example><![CDATA[
##  gap> tbl:= CharacterTable( "A5" );;
##  gap> ScalarProduct( TrivialCharacter( tbl ), Sum( Irr( tbl ) ) );
##  1
##  gap> ScalarProduct( tbl, [ 1, 1, 1, 1, 1 ], Sum( Irr( tbl ) ) );
##  1
##  gap> tbl2:= tbl mod 2;
##  BrauerTable( "A5", 2 )
##  gap> chi:= Irr( tbl2 )[1];
##  Character( BrauerTable( "A5", 2 ), [ 1, 1, 1, 1 ] )
##  gap> ScalarProduct( chi, chi );
##  3/4
##  gap> ScalarProduct( tbl2, [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] );
##  3/4
##  gap> chars:= Irr( tbl ){ [ 2 .. 4 ] };;
##  gap> chars:= Set( Tensored( chars, chars ) );;
##  gap> MatScalarProducts( Irr( tbl ), chars );
##  [ [ 0, 0, 0, 1, 1 ], [ 1, 1, 0, 0, 1 ], [ 1, 0, 1, 0, 1 ],
##    [ 0, 1, 0, 1, 1 ], [ 0, 0, 1, 1, 1 ], [ 1, 1, 1, 1, 1 ] ]
##  gap> MatScalarProducts( tbl, chars );
##  [ [ 2 ], [ 1, 3 ], [ 1, 2, 3 ], [ 2, 2, 1, 3 ], [ 2, 1, 2, 2, 3 ],
##    [ 2, 3, 3, 3, 3, 5 ] ]
##  gap> List( chars, Norm );
##  [ 2, 3, 3, 3, 3, 5 ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "Norm", IsClassFunction );
DeclareOperation( "Norm", [ IsOrdinaryTable, IsHomogeneousList ] );


#############################################################################
##
#A  CentreOfCharacter( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="CentreOfCharacter">
##  <ManSection>
##  <Attr Name="CentreOfCharacter" Arg='[tbl, ]chi'/>
##
##  <Description>
##  <Index Subkey="of a character">centre</Index>
##  For a character <A>chi</A> of a group <M>G</M>,
##  <Ref Attr="CentreOfCharacter"/> returns the <E>centre</E> of <A>chi</A>,
##  that is, the normal subgroup of all those elements of <M>G</M> for which
##  the quotient of the value of <A>chi</A> by the degree of <A>chi</A> is
##  a root of unity.
##  <P/>
##  If the underlying character table of <A>psi</A> does not store the group
##  <M>G</M> then an error is signalled.
##  (See <Ref Attr="ClassPositionsOfCentre" Label="for a character"/>
##  for a way to handle the centre implicitly,
##  by listing the positions of conjugacy classes in the centre.)
##  <P/>
##  <Example><![CDATA[
##  gap> List( Irr( S4 ), chi -> StructureDescription(CentreOfCharacter(chi)) );
##  [ "S4", "1", "C2 x C2", "1", "S4" ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "CentreOfCharacter", IsClassFunction );
DeclareOperation( "CentreOfCharacter",
    [ IsOrdinaryTable, IsHomogeneousList ] );

DeclareSynonym( "CenterOfCharacter", CentreOfCharacter );


#############################################################################
##
#A  ClassPositionsOfCentre( <chi> )
##
##  <#GAPDoc Label="ClassPositionsOfCentre:ctblfuns">
##  <ManSection>
##  <Attr Name="ClassPositionsOfCentre" Arg='chi' Label="for a character"/>
##
##  <Description>
##  is the list of positions of classes forming the centre of the character
##  <A>chi</A> (see <Ref Attr="CentreOfCharacter"/>).
##  <P/>
##  <Example><![CDATA[
##  gap> List( Irr( S4 ), ClassPositionsOfCentre );
##  [ [ 1, 2, 3, 4, 5 ], [ 1 ], [ 1, 3 ], [ 1 ], [ 1, 2, 3, 4, 5 ] ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "ClassPositionsOfCentre", IsHomogeneousList );


#############################################################################
##
#A  ConstituentsOfCharacter( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="ConstituentsOfCharacter">
##  <ManSection>
##  <Attr Name="ConstituentsOfCharacter" Arg='[tbl, ]chi'/>
##
##  <Description>
##  Let <A>chi</A> be an ordinary or modular (virtual) character.
##  If an ordinary or modular character table <A>tbl</A> is given then
##  <A>chi</A> may also be a list of character values.
##  <P/>
##  <Ref Attr="ConstituentsOfCharacter"/> returns
##  the set of those irreducible characters that occur in the decomposition
##  of <A>chi</A> with nonzero coefficient.
##  <P/>
##  <Example><![CDATA[
##  gap> nat:= NaturalCharacter( S4 );
##  Character( CharacterTable( S4 ), [ 4, 2, 0, 1, 0 ] )
##  gap> ConstituentsOfCharacter( nat );
##  [ Character( CharacterTable( S4 ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( S4 ), [ 3, 1, -1, 0, -1 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "ConstituentsOfCharacter", IsClassFunction );
DeclareOperation( "ConstituentsOfCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#A  DegreeOfCharacter( <chi> )
##
##  <#GAPDoc Label="DegreeOfCharacter">
##  <ManSection>
##  <Attr Name="DegreeOfCharacter" Arg='chi'/>
##
##  <Description>
##  is the value of the character <A>chi</A> on the identity element.
##  This can also be obtained as <A>chi</A><C>[1]</C>.
##  <P/>
##  <Example><![CDATA[
##  gap> List( Irr( S4 ), DegreeOfCharacter );
##  [ 1, 3, 2, 3, 1 ]
##  gap> nat:= NaturalCharacter( S4 );
##  Character( CharacterTable( S4 ), [ 4, 2, 0, 1, 0 ] )
##  gap> nat[1];
##  4
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "DegreeOfCharacter", IsClassFunction );


#############################################################################
##
#O  InertiaSubgroup( [<tbl>, ]<G>, <chi> )
##
##  <#GAPDoc Label="InertiaSubgroup">
##  <ManSection>
##  <Oper Name="InertiaSubgroup" Arg='[tbl, ]G, chi'/>
##
##  <Description>
##  Let <A>chi</A> be a character of a group <M>H</M>
##  and <A>tbl</A> the character table of <M>H</M>;
##  if the argument <A>tbl</A> is not given then the underlying character
##  table of <A>chi</A> (see <Ref Attr="UnderlyingCharacterTable"/>) is
##  used instead.
##  Furthermore, let <A>G</A> be a group that contains <M>H</M> as a normal
##  subgroup.
##  <P/>
##  <Ref Oper="InertiaSubgroup"/> returns the stabilizer in <A>G</A> of
##  <A>chi</A>, w.r.t. the action of <A>G</A> on the classes of <M>H</M>
##  via conjugation.
##  In other words, <Ref Oper="InertiaSubgroup"/> returns the group of all
##  those elements <M>g \in <A>G</A></M> that satisfy
##  <M><A>chi</A>^g = <A>chi</A></M>.
##  <P/>
##  <Example><![CDATA[
##  gap> der:= DerivedSubgroup( S4 );
##  Alt( [ 1 .. 4 ] )
##  gap> List( Irr( der ), chi -> InertiaSubgroup( S4, chi ) );
##  [ S4, S4, Alt( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "InertiaSubgroup", [ IsGroup, IsClassFunction ] );
DeclareOperation( "InertiaSubgroup",
    [ IsOrdinaryTable, IsGroup, IsHomogeneousList ] );


#############################################################################
##
#A  KernelOfCharacter( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="KernelOfCharacter">
##  <ManSection>
##  <Attr Name="KernelOfCharacter" Arg='[tbl, ]chi'/>
##
##  <Description>
##  For a class function <A>chi</A> of a group <M>G</M>,
##  <Ref Attr="KernelOfCharacter"/> returns the normal subgroup of <M>G</M>
##  that is formed by those conjugacy classes for which the value of
##  <A>chi</A> equals the degree of <A>chi</A>.
##  If the underlying character table of <A>chi</A> does not store the group
##  <M>G</M> then an error is signalled.
##  (See <Ref Attr="ClassPositionsOfKernel"/> for a way to handle the
##  kernel implicitly,
##  by listing the positions of conjugacy classes in the kernel.)
##  <P/>
##  The returned group is the kernel of any representation of <M>G</M> that
##  affords <A>chi</A>.
##  <P/>
##  <Example><![CDATA[
##  gap> List( Irr( S4 ), chi -> StructureDescription(KernelOfCharacter(chi)) );
##  [ "A4", "1", "C2 x C2", "1", "S4" ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "KernelOfCharacter", IsClassFunction );
DeclareOperation( "KernelOfCharacter",
    [ IsOrdinaryTable, IsHomogeneousList ] );


#############################################################################
##
#A  ClassPositionsOfKernel( <chi> )
##
##  <#GAPDoc Label="ClassPositionsOfKernel">
##  <ManSection>
##  <Attr Name="ClassPositionsOfKernel" Arg='chi'/>
##
##  <Description>
##  is the list of positions of those conjugacy classes that form the kernel
##  of the character <A>chi</A>, that is, those positions with character
##  value equal to the character degree.
##  <P/>
##  <Example><![CDATA[
##  gap> List( Irr( S4 ), ClassPositionsOfKernel );
##  [ [ 1, 3, 4 ], [ 1 ], [ 1, 3 ], [ 1 ], [ 1, 2, 3, 4, 5 ] ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "ClassPositionsOfKernel", IsHomogeneousList );


#############################################################################
##
#O  CycleStructureClass( [<tbl>, ]<chi>, <class> )
##
##  <#GAPDoc Label="CycleStructureClass">
##  <ManSection>
##  <Oper Name="CycleStructureClass" Arg='[tbl, ]chi, class'/>
##
##  <Description>
##  Let <A>permchar</A> be a permutation character, and <A>class</A> be the
##  position of a conjugacy class of the character table of <A>permchar</A>.
##  <Ref Oper="CycleStructureClass"/> returns a list describing
##  the cycle structure of each element in class <A>class</A> in the
##  underlying permutation representation, in the same format as the result
##  of <Ref Attr="CycleStructurePerm"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> nat:= NaturalCharacter( S4 );
##  Character( CharacterTable( S4 ), [ 4, 2, 0, 1, 0 ] )
##  gap> List( [ 1 .. 5 ], i -> CycleStructureClass( nat, i ) );
##  [ [  ], [ 1 ], [ 2 ], [ , 1 ], [ ,, 1 ] ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "CycleStructureClass",
    [ IsOrdinaryTable, IsHomogeneousList, IsPosInt ] );
DeclareOperation( "CycleStructureClass", [ IsClassFunction, IsPosInt ] );


#############################################################################
##
#P  IsTransitive( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="IsTransitive:ctblfuns">
##  <ManSection>
##  <Prop Name="IsTransitive" Arg='[tbl, ]chi' Label="for a character"/>
##
##  <Description>
##  For a permutation character <A>chi</A> of the group <M>G</M> that
##  corresponds to an action on the <M>G</M>-set <M>\Omega</M>
##  (see <Ref Oper="PermutationCharacter"
##  Label="for a group, an action domain, and a function"/>),
##  <Ref Oper="IsTransitive" Label="for a group, an action domain, etc."/>
##  returns <K>true</K> if the action of <M>G</M> on <M>\Omega</M> is
##  transitive, and <K>false</K> otherwise.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareProperty( "IsTransitive", IsClassFunction );
DeclareOperation( "IsTransitive", [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#A  Transitivity( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="Transitivity:ctblfuns">
##  <ManSection>
##  <Attr Name="Transitivity" Arg='[tbl, ]chi' Label="for a character"/>
##
##  <Description>
##  For a permutation character <A>chi</A> of the group <M>G</M>
##  that corresponds to an action on the <M>G</M>-set <M>\Omega</M>
##  (see <Ref Oper="PermutationCharacter"
##  Label="for a group, an action domain, and a function"/>),
##  <Ref Attr="Transitivity" Label="for a character"/> returns the maximal
##  nonnegative integer <M>k</M> such that the action of <M>G</M> on
##  <M>\Omega</M> is <M>k</M>-transitive.
##  <P/>
##  <Example><![CDATA[
##  gap> IsTransitive( nat );  Transitivity( nat );
##  true
##  4
##  gap> Transitivity( 2 * TrivialCharacter( S4 ) );
##  0
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "Transitivity", IsClassFunction );
DeclareOperation( "Transitivity", [ IsOrdinaryTable, IsHomogeneousList ] );


#############################################################################
##
#A  CentralCharacter( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="CentralCharacter">
##  <ManSection>
##  <Attr Name="CentralCharacter" Arg='[tbl, ]chi'/>
##
##  <Description>
##  <Index>central character</Index>
##  For a character <A>chi</A> of a group <M>G</M>,
##  <Ref Attr="CentralCharacter"/> returns
##  the <E>central character</E> of <A>chi</A>.
##  <P/>
##  The central character of <M>\chi</M> is the class function
##  <M>\omega_{\chi}</M> defined by
##  <M>\omega_{\chi}(g) = |g^G| \cdot \chi(g)/\chi(1)</M> for each
##  <M>g \in G</M>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "CentralCharacter", IsClassFunction );
DeclareOperation( "CentralCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#A  DeterminantOfCharacter( [<tbl>, ]<chi> )
##
##  <#GAPDoc Label="DeterminantOfCharacter">
##  <ManSection>
##  <Attr Name="DeterminantOfCharacter" Arg='[tbl, ]chi'/>
##
##  <Description>
##  <Index>determinant character</Index>
##  <Ref Attr="DeterminantOfCharacter"/> returns the
##  <E>determinant character</E> of the character <A>chi</A>.
##  This is defined to be the character obtained by taking the determinant of
##  representing matrices of any representation affording <A>chi</A>;
##  the determinant can be computed using <Ref Oper="EigenvaluesChar"/>.
##  <P/>
##  It is also possible to call <Ref Oper="Determinant"/> instead of
##  <Ref Attr="DeterminantOfCharacter"/>.
##  <P/>
##  Note that the determinant character is well-defined for virtual
##  characters.
##  <P/>
##  <Example><![CDATA[
##  gap> CentralCharacter( TrivialCharacter( S4 ) );
##  ClassFunction( CharacterTable( S4 ), [ 1, 6, 3, 8, 6 ] )
##  gap> DeterminantOfCharacter( Irr( S4 )[3] );
##  Character( CharacterTable( S4 ), [ 1, -1, 1, 1, -1 ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "DeterminantOfCharacter", IsClassFunction );
DeclareOperation( "DeterminantOfCharacter",
    [ IsCharacterTable, IsHomogeneousList ] );


#############################################################################
##
#O  EigenvaluesChar( [<tbl>, ]<chi>, <class> )
##
##  <#GAPDoc Label="EigenvaluesChar">
##  <ManSection>
##  <Oper Name="EigenvaluesChar" Arg='[tbl, ]chi, class'/>
##
##  <Description>
##  Let <A>chi</A> be a character of a group <M>G</M>.
##  For an element <M>g \in G</M> in the <A>class</A>-th conjugacy class,
##  of order <M>n</M>, let <M>M</M> be a matrix of a representation affording
##  <A>chi</A>.
##  <P/>
##  <Ref Oper="EigenvaluesChar"/> returns the list of length <M>n</M>
##  where at position <M>k</M> the multiplicity
##  of <C>E</C><M>(n)^k = \exp(2 \pi i k / n)</M>
##  as an eigenvalue of <M>M</M> is stored.
##  <P/>
##  We have
##  <C><A>chi</A>[ <A>class</A> ] = List( [ 1 .. n ], k -> E(n)^k )
##           * EigenvaluesChar( <A>tbl</A>, <A>chi</A>, <A>class</A> )</C>.
##  <P/>
##  It is also possible to call <Ref Oper="Eigenvalues"/> instead of
##  <Ref Oper="EigenvaluesChar"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> chi:= Irr( CharacterTable( "A5" ) )[2];
##  Character( CharacterTable( "A5" ),
##  [ 3, -1, 0, -E(5)-E(5)^4, -E(5)^2-E(5)^3 ] )
##  gap> List( [ 1 .. 5 ], i -> Eigenvalues( chi, i ) );
##  [ [ 3 ], [ 2, 1 ], [ 1, 1, 1 ], [ 0, 1, 1, 0, 1 ], [ 1, 0, 0, 1, 1 ] ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "EigenvaluesChar", [ IsClassFunction, IsPosInt ] );
DeclareOperation( "EigenvaluesChar",
    [ IsCharacterTable, IsHomogeneousList, IsPosInt ] );


#############################################################################
##
#O  Tensored( <chars1>, <chars2> )
##
##  <#GAPDoc Label="Tensored">
##  <ManSection>
##  <Oper Name="Tensored" Arg='chars1, chars2'/>
##
##  <Description>
##  Let <A>chars1</A> and <A>chars2</A> be lists of (values lists of) class
##  functions of the same character table.
##  <Ref Oper="Tensored"/> returns the list of tensor products of all entries
##  in <A>chars1</A> with all entries in <A>chars2</A>.
##  <P/>
##  <Example><![CDATA[
##  gap> irra5:= Irr( CharacterTable( "A5" ) );;
##  gap> chars1:= irra5{ [ 1 .. 3 ] };;  chars2:= irra5{ [ 2, 3 ] };;
##  gap> Tensored( chars1, chars2 );
##  [ Character( CharacterTable( "A5" ),
##      [ 3, -1, 0, -E(5)-E(5)^4, -E(5)^2-E(5)^3 ] ),
##    Character( CharacterTable( "A5" ),
##      [ 3, -1, 0, -E(5)^2-E(5)^3, -E(5)-E(5)^4 ] ),
##    Character( CharacterTable( "A5" ),
##      [ 9, 1, 0, -2*E(5)-E(5)^2-E(5)^3-2*E(5)^4,
##        -E(5)-2*E(5)^2-2*E(5)^3-E(5)^4 ] ),
##    Character( CharacterTable( "A5" ), [ 9, 1, 0, -1, -1 ] ),
##    Character( CharacterTable( "A5" ), [ 9, 1, 0, -1, -1 ] ),
##    Character( CharacterTable( "A5" ),
##      [ 9, 1, 0, -E(5)-2*E(5)^2-2*E(5)^3-E(5)^4,
##        -2*E(5)-E(5)^2-E(5)^3-2*E(5)^4 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "Tensored", [ IsHomogeneousList, IsHomogeneousList ] );


#############################################################################
##
#O  TensorProduct( <chi>, <psi> )
##
##  <#GAPDoc Label="TensorProduct_characters">
##  <ManSection>
##  <Oper Name="TensorProduct" Arg='chi, psi' Label="for characters"/>
##
##  <Description>
##  For two characters <A>chi</A> and <A>psi</A> afforded by the modules
##  <M>V</M> and <M>W</M>,
##  <Ref Oper="TensorProduct" Label="for characters"/> returns the character
##  that is afforded by the tensor product of <M>V</M> and <M>W</M>.
##  <P/>
##  The result can also be computed as <A>chi</A><C>*</C><A>psi</A>,
##  see also <Ref Oper="Tensored"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> t:= CharacterTable( "A5" );;
##  gap> chi:= Irr( t )[2];
##  Character( CharacterTable( "A5" ),
##   [ 3, -1, 0, -E(5)-E(5)^4, -E(5)^2-E(5)^3 ] )
##  gap> psi:= Irr( t )[3];
##  Character( CharacterTable( "A5" ),
##   [ 3, -1, 0, -E(5)^2-E(5)^3, -E(5)-E(5)^4 ] )
##  gap> TensorProduct( chi, psi );
##  Character( CharacterTable( "A5" ), [ 9, 1, 0, -1, -1 ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "TensorProductOp", [ IsDenseList, IsClassFunction ] );


#############################################################################
##
##  9. Restricted and Induced Class Functions
##
##  <#GAPDoc Label="[7]{ctblfuns}">
##  For restricting a class function of a group <M>G</M> to a subgroup
##  <M>H</M> and for inducing a class function of <M>H</M> to <M>G</M>,
##  the <E>class fusion</E> from <M>H</M> to <M>G</M> must be known
##  (see <Ref Sect="Class Fusions between Character Tables"/>).
##  <P/>
##  <Index>inflated class functions</Index>
##  If <M>F</M> is the factor group of <M>G</M> by the normal subgroup
##  <M>N</M> then each class function of <M>F</M> can be naturally regarded
##  as a class function of <M>G</M>, with <M>N</M> in its kernel.
##  For a class function of <M>F</M>, the corresponding class function of
##  <M>G</M> is called the <E>inflated</E> 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 <M>G</M> and
##  <M>F</M>;
##  either one needs the natural homomorphism, or the factor fusion to the
##  character table of <M>F</M> must be stored on the table of <M>G</M>.
##  This explains the different syntax for computing restricted and inflated
##  class functions.
##  <P/>
##  In the following,
##  the meaning of the optional first argument <A>tbl</A> is the same as in
##  Section <Ref Sect="Operations for Class Functions"/>.
##  <#/GAPDoc>
##


#############################################################################
##
#O  RestrictedClassFunction( [<tbl>, ]<chi>, <H> )
#O  RestrictedClassFunction( [<tbl>, ]<chi>, <hom> )
#O  RestrictedClassFunction( [<tbl>, ]<chi>, <subtbl> )
##
##  <#GAPDoc Label="RestrictedClassFunction">
##  <ManSection>
##  <Oper Name="RestrictedClassFunction" Arg='[tbl, ]chi, target'/>
##
##  <Description>
##  Let <A>chi</A> be a class function of a group <M>G</M>
##  and let <A>target</A> be either a subgroup <M>H</M> of <M>G</M>
##  or an injective homomorphism from <M>H</M> to <M>G</M>
##  or the character table of <A>H</A>.
##  Then <Ref Oper="RestrictedClassFunction"/> returns the class function of
##  <M>H</M> obtained by restricting <A>chi</A> to <M>H</M>.
##  <P/>
##  If <A>chi</A> is a class function of a <E>factor group</E> <M>G</M> of
##  <M>H</M>, where <A>target</A> is either the group <M>H</M>
##  or a homomorphism from <M>H</M> to <M>G</M>
##  or the character table of <M>H</M>
##  then the restriction can be computed in the case of the homomorphism;
##  in the other cases, this is possible only if the factor fusion from
##  <M>H</M> to <M>G</M> is stored on the character table of <M>H</M>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
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> )
##
##  <#GAPDoc Label="RestrictedClassFunctions">
##  <ManSection>
##  <Oper Name="RestrictedClassFunctions" Arg='[tbl, ]chars, target'/>
##
##  <Description>
##  <Ref Oper="RestrictedClassFunctions"/> is similar to
##  <Ref Oper="RestrictedClassFunction"/>,
##  the only difference is that it takes a list <A>chars</A> of class
##  functions instead of one class function,
##  and returns the list of restricted class functions.
##  <P/>
##  <Example><![CDATA[
##  gap> a5:= CharacterTable( "A5" );;  s5:= CharacterTable( "S5" );;
##  gap> RestrictedClassFunction( Irr( s5 )[2], a5 );
##  Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] )
##  gap> RestrictedClassFunctions( Irr( s5 ), a5 );
##  [ Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 6, -2, 0, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 4, 0, 1, -1, -1 ] ),
##    Character( CharacterTable( "A5" ), [ 4, 0, 1, -1, -1 ] ),
##    Character( CharacterTable( "A5" ), [ 5, 1, -1, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 5, 1, -1, 0, 0 ] ) ]
##  gap> hom:= NaturalHomomorphismByNormalSubgroup( S4, der );;
##  gap> RestrictedClassFunctions( Irr( Image( hom ) ), hom );
##  [ Character( CharacterTable( S4 ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( S4 ), [ 1, -1, 1, 1, -1 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
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> )
##
##  <ManSection>
##  <Oper Name="Restricted" Arg='tbl, subtbl, chars'/>
##  <Oper Name="Restricted" Arg='tbl, subtbl, chars, specification'/>
##  <Oper Name="Restricted" Arg='chars, fusionmap'/>
##  <Oper Name="Restricted" Arg='[tbl, ]chi, H'/>
##  <Oper Name="Restricted" Arg='[tbl, ]chi, hom'/>
##  <Oper Name="Restricted" Arg='[tbl, ]chi, subtbl'/>
##  <Oper Name="Restricted" Arg='[tbl, ]chars, H'/>
##  <Oper Name="Restricted" Arg='[tbl, ]chars, hom'/>
##  <Oper Name="Restricted" Arg='[tbl, ]chars, subtbl'/>
##
##  <Description>
##  This is mainly for convenience and compatibility with &GAP; 3.
##  </Description>
##  </ManSection>
##
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> )
##
##  <#GAPDoc Label="InducedClassFunction">
##  <ManSection>
##  <Heading>InducedClassFunction</Heading>
##  <Oper Name="InducedClassFunction" Arg='[tbl, ]chi, H'
##   Label="for a supergroup"/>
##  <Oper Name="InducedClassFunction" Arg='[tbl, ]chi, hom'
##   Label="for a given monomorphism"/>
##  <Oper Name="InducedClassFunction" Arg='[tbl, ]chi, suptbl'
##   Label="for the character table of a supergroup"/>
##
##  <Description>
##  Let <A>chi</A> be a class function of a group <M>G</M>
##  and let <A>target</A> be either a supergroup <M>H</M> of <M>G</M>
##  or an injective homomorphism from <M>H</M> to <M>G</M>
##  or the character table of <A>H</A>.
##  Then <Ref Oper="InducedClassFunction" Label="for a supergroup"/>
##  returns the class function of <M>H</M> obtained by inducing <A>chi</A>
##  to <M>H</M>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
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> )
##
##  <#GAPDoc Label="InducedClassFunctions">
##  <ManSection>
##  <Oper Name="InducedClassFunctions" Arg='[tbl, ]chars, target'/>
##
##  <Description>
##  <Ref Oper="InducedClassFunctions"/> is similar to
##  <Ref Oper="InducedClassFunction" Label="for a supergroup"/>,
##  the only difference is that it takes a list <A>chars</A> of class
##  functions instead of one class function,
##  and returns the list of induced class functions.
##  <P/>
##  <Example><![CDATA[
##  gap> InducedClassFunctions( Irr( a5 ), s5 );
##  [ Character( CharacterTable( "A5.2" ), [ 2, 2, 2, 2, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5.2" ), [ 6, -2, 0, 1, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5.2" ), [ 6, -2, 0, 1, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5.2" ), [ 8, 0, 2, -2, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5.2" ), [ 10, 2, -2, 0, 0, 0, 0 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
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 ] );


#############################################################################
##
#F  InducedClassFunctionsByFusionMap( <subtbl>, <tbl>, <chars>, <fusionmap> )
##
##  <#GAPDoc Label="InducedClassFunctionsByFusionMap">
##  <ManSection>
##  <Func Name="InducedClassFunctionsByFusionMap"
##   Arg='subtbl, tbl, chars, fusionmap'/>
##
##  <Description>
##  Let <A>subtbl</A> and <A>tbl</A> be two character tables of groups
##  <M>H</M> and <M>G</M>, such that <M>H</M> is a subgroup of <M>G</M>,
##  let <A>chars</A> be a list of class functions of <A>subtbl</A>, and
##  let <A>fusionmap</A> be a fusion map from <A>subtbl</A> to <A>tbl</A>.
##  The function returns the list of induced class functions of <A>tbl</A>
##  that correspond to <A>chars</A>, w.r.t. the given fusion map.
##  <P/>
##  <Ref Func="InducedClassFunctionsByFusionMap"/> is the function that does
##  the work for <Ref Oper="InducedClassFunction"
##  Label="for the character table of a supergroup"/> and
##  <Ref Oper="InducedClassFunctions"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> fus:= PossibleClassFusions( a5, s5 );
##  [ [ 1, 2, 3, 4, 4 ] ]
##  gap> InducedClassFunctionsByFusionMap( a5, s5, Irr( a5 ), fus[1] );
##  [ Character( CharacterTable( "A5.2" ), [ 2, 2, 2, 2, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5.2" ), [ 6, -2, 0, 1, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5.2" ), [ 6, -2, 0, 1, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5.2" ), [ 8, 0, 2, -2, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5.2" ), [ 10, 2, -2, 0, 0, 0, 0 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "InducedClassFunctionsByFusionMap" );


#############################################################################
##
#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> )
##
##  <ManSection>
##  <Oper Name="Induced" Arg='subtbl, tbl, chars'/>
##  <Oper Name="Induced" Arg='subtbl, tbl, chars, specification'/>
##  <Oper Name="Induced" Arg='subtbl, tbl, chars, fusionmap'/>
##  <Oper Name="Induced" Arg='[tbl, ]chi, H'/>
##  <Oper Name="Induced" Arg='[tbl, ]chi, hom'/>
##  <Oper Name="Induced" Arg='[tbl, ]chi, suptbl'/>
##  <Oper Name="Induced" Arg='[tbl, ]chars, H'/>
##  <Oper Name="Induced" Arg='[tbl, ]chars, hom'/>
##  <Oper Name="Induced" Arg='[tbl, ]chars, suptbl'/>
##
##  <Description>
##  This is mainly for convenience and compatibility with &GAP; 3.
##  </Description>
##  </ManSection>
##
DeclareOperation( "Induced", [ IsObject, IsObject ] );
DeclareOperation( "Induced", [ IsObject, IsObject, IsObject ] );
DeclareOperation( "Induced", [ IsObject, IsObject, IsObject, IsObject ] );


#############################################################################
##
#O  InducedCyclic( <tbl>[, <classes>][, "all"] )
##
##  <#GAPDoc Label="InducedCyclic">
##  <ManSection>
##  <Oper Name="InducedCyclic" Arg='tbl[, classes][, "all"]'/>
##
##  <Description>
##  <Ref Oper="InducedCyclic"/> calculates characters induced up from
##  cyclic subgroups of the ordinary character table <A>tbl</A>
##  to <A>tbl</A>, and returns the strictly sorted list of the induced
##  characters.
##  <P/>
##  If the string <C>"all"</C> is specified then all irreducible characters
##  of these subgroups are induced,
##  otherwise only the permutation characters are calculated.
##  <P/>
##  If a list <A>classes</A> is specified then only those cyclic subgroups
##  generated by these classes are considered,
##  otherwise all classes of <A>tbl</A> are considered.
##  <P/>
##  <Example><![CDATA[
##  gap> InducedCyclic( a5, "all" );
##  [ Character( CharacterTable( "A5" ), [ 12, 0, 0, 2, 2 ] ),
##    Character( CharacterTable( "A5" ),
##      [ 12, 0, 0, E(5)^2+E(5)^3, E(5)+E(5)^4 ] ),
##    Character( CharacterTable( "A5" ),
##      [ 12, 0, 0, E(5)+E(5)^4, E(5)^2+E(5)^3 ] ),
##    Character( CharacterTable( "A5" ), [ 20, 0, -1, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 20, 0, 2, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 30, -2, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 30, 2, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 60, 0, 0, 0, 0 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "InducedCyclic", [ IsOrdinaryTable ] );
DeclareOperation( "InducedCyclic", [ IsOrdinaryTable, IsList ] );
DeclareOperation( "InducedCyclic", [ IsOrdinaryTable, IsList, IsString ] );


#############################################################################
##
##  10. Reducing Virtual Characters
##
##  <#GAPDoc Label="[8]{ctblfuns}">
##  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 <M>1</M>.
##  <#/GAPDoc>
##


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

DeclareSynonym( "Reduced", ReducedClassFunctions );


#############################################################################
##
#O  ReducedCharacters( [<tbl>, ]<constituents>, <reducibles> )
##
##  <#GAPDoc Label="ReducedCharacters">
##  <ManSection>
##  <Oper Name="ReducedCharacters" Arg='[tbl, ]constituents, reducibles'/>
##
##  <Description>
##  <Ref Oper="ReducedCharacters"/> is similar to
##  <Ref Oper="ReducedClassFunctions"/>,
##  the only difference is that <A>constituents</A> and <A>reducibles</A>
##  are assumed to be lists of characters.
##  This means that only those scalar products must be formed where the
##  degree of the character in <A>constituents</A> does not exceed the degree
##  of the character in <A>reducibles</A>.
##  <P/>
##  <Example><![CDATA[
##  gap> tbl:= CharacterTable( "A5" );;
##  gap> chars:= Irr( tbl ){ [ 2 .. 4 ] };;
##  gap> chars:= Set( Tensored( chars, chars ) );;
##  gap> red:= ReducedClassFunctions( chars );
##  rec(
##    irreducibles :=
##      [ Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##        Character( CharacterTable( "A5" ),
##          [ 3, -1, 0, -E(5)-E(5)^4, -E(5)^2-E(5)^3 ] ),
##        Character( CharacterTable( "A5" ),
##          [ 3, -1, 0, -E(5)^2-E(5)^3, -E(5)-E(5)^4 ] ),
##        Character( CharacterTable( "A5" ), [ 4, 0, 1, -1, -1 ] ),
##        Character( CharacterTable( "A5" ), [ 5, 1, -1, 0, 0 ] ) ],
##    remainders := [  ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "ReducedCharacters",
    [ IsHomogeneousList, IsHomogeneousList ] );
DeclareOperation( "ReducedCharacters",
    [ IsOrdinaryTable, IsHomogeneousList, IsHomogeneousList ] );

DeclareSynonym( "ReducedOrdinary", ReducedCharacters );


#############################################################################
##
#F  IrreducibleDifferences( <tbl>, <reducibles>, <reducibles2>[, <scprmat>] )
#F  IrreducibleDifferences( <tbl>, <reducibles>, "triangle"[, <scprmat>] )
##
##  <#GAPDoc Label="IrreducibleDifferences">
##  <ManSection>
##  <Func Name="IrreducibleDifferences"
##   Arg='tbl, reducibles, reducibles2[, scprmat]'/>
##
##  <Description>
##  <Ref Func="IrreducibleDifferences"/> returns the list of irreducible
##  characters which occur as difference of an element of <A>reducibles</A>
##  and an element of <A>reducibles2</A>,
##  where these two arguments are lists of class functions of the character
##  table <A>tbl</A>.
##  <P/>
##  If <A>reducibles2</A> is the string <C>"triangle"</C> then the
##  differences of elements in <A>reducibles</A> are considered.
##  <P/>
##  If <A>scprmat</A> is not specified then it will be calculated,
##  otherwise we must have
##  <C><A>scprmat</A> =
##  MatScalarProducts( <A>tbl</A>, <A>reducibles</A>, <A>reducibles2</A> )</C>
##  or <C><A>scprmat</A> =
##  MatScalarProducts( <A>tbl</A>, <A>reducibles</A> )</C>,
##  respectively.
##  <P/>
##  <Example><![CDATA[
##  gap> IrreducibleDifferences( a5, chars, "triangle" );
##  [ Character( CharacterTable( "A5" ),
##      [ 3, -1, 0, -E(5)-E(5)^4, -E(5)^2-E(5)^3 ] ),
##    Character( CharacterTable( "A5" ),
##      [ 3, -1, 0, -E(5)^2-E(5)^3, -E(5)-E(5)^4 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "IrreducibleDifferences" );


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


#############################################################################
##
#O  Symmetrizations( [<tbl>, ]<characters>, <n> )
##
##  <#GAPDoc Label="Symmetrizations">
##  <ManSection>
##  <Oper Name="Symmetrizations" Arg='[tbl, ]characters, n'/>
##
##  <Description>
##  <Index Subkey="symmetrizations of">characters</Index>
##  <Ref Oper="Symmetrizations"/> returns the list of symmetrizations
##  of the characters <A>characters</A> of the ordinary character table
##  <A>tbl</A> with the ordinary irreducible characters of the symmetric
##  group of degree <A>n</A>;
##  instead of the integer <A>n</A>,
##  the character table of the symmetric group can be entered.
##  <P/>
##  The symmetrization <M>\chi^{[\lambda]}</M> of the character <M>\chi</M>
##  of <A>tbl</A> with the character <M>\lambda</M> of the symmetric group
##  <M>S_n</M> of degree <M>n</M> is defined by
##  <Display Mode="M">
##  \chi^{[\lambda]}(g) = \left( \sum_{{\rho \in S_n}}
##      \lambda(\rho) \prod_{{k=1}}^n \chi(g^k)^{{a_k(\rho)}} \right) / n! ,
##  </Display>
##  where <M>a_k(\rho)</M> is the number of cycles of length <M>k</M>
##  in <M>\rho</M>.
##  <P/>
##  <E>Note</E> that the returned list may contain zero class functions,
##  and duplicates are not deleted.
##  <!-- describe the succession!!-->
##  <P/>
##  For special kinds of symmetrizations,
##  see <Ref Func="SymmetricParts"/>, <Ref Func="AntiSymmetricParts"/>,
##  <Ref Func="MinusCharacter"/> and <Ref Func="OrthogonalComponents"/>,
##  <Ref Func="SymplecticComponents"/>,
##  <Ref Oper="ExteriorPower" Label="for a character"/>,
##  <Ref Oper="SymmetricPower" Label="for a character"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> tbl:= CharacterTable( "A5" );;
##  gap> Symmetrizations( Irr( tbl ){ [ 1 .. 3 ] }, 3 );
##  [ VirtualCharacter( CharacterTable( "A5" ), [ 0, 0, 0, 0, 0 ] ),
##    VirtualCharacter( CharacterTable( "A5" ), [ 0, 0, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ),
##      [ 8, 0, -1, -E(5)-E(5)^4, -E(5)^2-E(5)^3 ] ),
##    Character( CharacterTable( "A5" ), [ 10, -2, 1, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ),
##      [ 8, 0, -1, -E(5)^2-E(5)^3, -E(5)-E(5)^4 ] ),
##    Character( CharacterTable( "A5" ), [ 10, -2, 1, 0, 0 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
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> )
##
##  <#GAPDoc Label="SymmetricParts">
##  <ManSection>
##  <Func Name="SymmetricParts" Arg='tbl, characters, n'/>
##
##  <Description>
##  <Index>symmetric power</Index>
##  is the list of symmetrizations of the characters <A>characters</A>
##  of the character table <A>tbl</A> with the trivial character of
##  the symmetric group of degree <A>n</A>
##  (see <Ref Oper="Symmetrizations"/>).
##  <P/>
##  <Example><![CDATA[
##  gap> tbl:= CharacterTable( "A5" );;
##  gap> SymmetricParts( tbl, Irr( tbl ), 3 );
##  [ Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 10, -2, 1, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 10, -2, 1, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 20, 0, 2, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 35, 3, 2, 0, 0 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "SymmetricParts" );


#############################################################################
##
#F  AntiSymmetricParts( <tbl>, <characters>, <n> )
##
##  <#GAPDoc Label="AntiSymmetricParts">
##  <ManSection>
##  <Func Name="AntiSymmetricParts" Arg='tbl, characters, n'/>
##
##  <Description>
##  <Index>exterior power</Index>
##  is the list of symmetrizations of the characters <A>characters</A>
##  of the character table <A>tbl</A> with the sign character of
##  the symmetric group of degree <A>n</A>
##  (see <Ref Oper="Symmetrizations"/>).
##  <P/>
##  <Example><![CDATA[
##  gap> tbl:= CharacterTable( "A5" );;
##  gap> AntiSymmetricParts( tbl, Irr( tbl ), 3 );
##  [ VirtualCharacter( CharacterTable( "A5" ), [ 0, 0, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 4, 0, 1, -1, -1 ] ),
##    Character( CharacterTable( "A5" ), [ 10, -2, 1, 0, 0 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "AntiSymmetricParts" );


#############################################################################
##
#O  ExteriorPower( <chi>, <n> )
##
##  <#GAPDoc Label="ExteriorPower_character">
##  <ManSection>
##  <Oper Name="ExteriorPower" Arg='chi, n' Label="for a character"/>
##
##  <Description>
##  For a character <A>chi</A> afforded by the module <M>V</M>
##  and a positive integer <A>n</A>,
##  <Ref Oper="ExteriorPower" Label="for a character"/> returns the class
##  function that is afforded by the <A>n</A>-th exterior power of <M>V</M>.
##  <P/>
##  This exterior power is the symmetrization of <A>chi</A> with the
##  sign character of the symmetric group of degree <A>n</A>,
##  see also <Ref Oper="Symmetrizations"/> and
##  <Ref Func="AntiSymmetricParts"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> t:= CharacterTable( "A5" );;
##  gap> List( Irr( t ), chi -> ExteriorPower( chi, 3 ) );
##  [ VirtualCharacter( CharacterTable( "A5" ), [ 0, 0, 0, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 4, 0, 1, -1, -1 ] ),
##    Character( CharacterTable( "A5" ), [ 10, -2, 1, 0, 0 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "ExteriorPower", [ IsClassFunction, IsPosInt ] );


#############################################################################
##
#O  SymmetricPower( <chi>, <n> )
##
##  <#GAPDoc Label="SymmetricPower_character">
##  <ManSection>
##  <Oper Name="SymmetricPower" Arg='chi, n' Label="for a character"/>
##
##  <Description>
##  For a character <A>chi</A> afforded by the module <M>V</M>
##  and a positive integer <A>n</A>,
##  <Ref Oper="SymmetricPower" Label="for a character"/> returns the class
##  function that is afforded by the <A>n</A>-th symmetric power of <M>V</M>.
##  <P/>
##  This symmetric power is the symmetrization of <A>chi</A> with the
##  trivial character of the symmetric group of degree <A>n</A>,
##  see also <Ref Oper="Symmetrizations"/> and
##  <Ref Func="SymmetricParts"/>.
##  <P/>
##  <Example><![CDATA[
##  gap> t:= CharacterTable( "A5" );;
##  gap> List( Irr( t ), chi -> SymmetricPower( chi, 3 ) );
##  [ Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] ),
##    Character( CharacterTable( "A5" ), [ 10, -2, 1, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 10, -2, 1, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 20, 0, 2, 0, 0 ] ),
##    Character( CharacterTable( "A5" ), [ 35, 3, 2, 0, 0 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareOperation( "SymmetricPower", [ IsClassFunction, IsPosInt ] );


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


#############################################################################
##
#F  OrthogonalComponents( <tbl>, <chars>, <m> )
##
##  <#GAPDoc Label="OrthogonalComponents">
##  <ManSection>
##  <Func Name="OrthogonalComponents" Arg='tbl, chars, m'/>
##
##  <Description>
##  <Index Subkey="orthogonal">symmetrizations</Index>
##  <Index>Frame</Index>
##  <Index>Murnaghan components</Index>
##  If <M>\chi</M> is a nonlinear character with indicator <M>+1</M>,
##  a splitting of the tensor power <M>\chi^m</M> is given by the so-called
##  Murnaghan functions (see <Cite Key="Mur58"/>).
##  These components in general have fewer irreducible constituents
##  than the symmetrizations with the symmetric group of degree <A>m</A>
##  (see <Ref Oper="Symmetrizations"/>).
##  <P/>
##  <Ref Func="OrthogonalComponents"/> returns the Murnaghan components
##  of the nonlinear characters of the character table <A>tbl</A>
##  in the list <A>chars</A> up to the power <A>m</A>,
##  where <A>m</A> is an integer between 2 and 6.
##  <P/>
##  The Murnaghan functions are implemented as in <Cite Key="Fra82"/>.
##  <P/>
##  <E>Note</E>:
##  If <A>chars</A> is a list of character objects
##  (see <Ref Prop="IsCharacter"/>) then also
##  the result consists of class function objects.
##  It is not checked whether all characters in <A>chars</A> do really have
##  indicator <M>+1</M>;
##  if there are characters with indicator <M>0</M> or <M>-1</M>,
##  the result might contain virtual characters
##  (see also <Ref Func="SymplecticComponents"/>),
##  therefore the entries of the result do in general not know that they are
##  characters.
##  <P/>
##  <Example><![CDATA[
##  gap> tbl:= CharacterTable( "A8" );;  chi:= Irr( tbl )[2];
##  Character( CharacterTable( "A8" ), [ 7, -1, 3, 4, 1, -1, 1, 2, 0, -1,
##    0, 0, -1, -1 ] )
##  gap> OrthogonalComponents( tbl, [ chi ], 3 );
##  [ ClassFunction( CharacterTable( "A8" ),
##      [ 21, -3, 1, 6, 0, 1, -1, 1, -2, 0, 0, 0, 1, 1 ] ),
##    ClassFunction( CharacterTable( "A8" ),
##      [ 27, 3, 7, 9, 0, -1, 1, 2, 1, 0, -1, -1, -1, -1 ] ),
##    ClassFunction( CharacterTable( "A8" ),
##      [ 105, 1, 5, 15, -3, 1, -1, 0, -1, 1, 0, 0, 0, 0 ] ),
##    ClassFunction( CharacterTable( "A8" ),
##      [ 35, 3, -5, 5, 2, -1, -1, 0, 1, 0, 0, 0, 0, 0 ] ),
##    ClassFunction( CharacterTable( "A8" ),
##      [ 77, -3, 13, 17, 2, 1, 1, 2, 1, 0, 0, 0, 2, 2 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "OrthogonalComponents" );


#############################################################################
##
#F  SymplecticComponents( <tbl>, <chars>, <m> )
##
##  <#GAPDoc Label="SymplecticComponents">
##  <ManSection>
##  <Func Name="SymplecticComponents" Arg='tbl, chars, m'/>
##
##  <Description>
##  <Index Subkey="symplectic">symmetrizations</Index>
##  <Index>Murnaghan components</Index>
##  If <M>\chi</M> is a (nonlinear) character with indicator <M>-1</M>,
##  a splitting of the tensor power <M>\chi^m</M> is given in terms of the
##  so-called Murnaghan functions (see <Cite Key="Mur58"/>).
##  These components in general have fewer irreducible constituents
##  than the symmetrizations with the symmetric group of degree <A>m</A>
##  (see <Ref Oper="Symmetrizations"/>).
##  <P/>
##  <Ref Func="SymplecticComponents"/> returns the symplectic symmetrizations
##  of the nonlinear characters of the character table <A>tbl</A>
##  in the list <A>chars</A> up to the power <A>m</A>,
##  where <A>m</A> is an integer between <M>2</M> and <M>5</M>.
##  <P/>
##  <E>Note</E>:
##  If <A>chars</A> is a list of character objects
##  (see <Ref Prop="IsCharacter"/>) then also
##  the result consists of class function objects.
##  It is not checked whether all characters in <A>chars</A> do really have
##  indicator <M>-1</M>;
##  if there are characters with indicator <M>0</M> or <M>+1</M>,
##  the result might contain virtual characters
##  (see also <Ref Func="OrthogonalComponents"/>),
##  therefore the entries of the result do in general not know that they are
##  characters.
##  <P/>
##  <Example><![CDATA[
##  gap> tbl:= CharacterTable( "U3(3)" );;  chi:= Irr( tbl )[2];
##  Character( CharacterTable( "U3(3)" ),
##  [ 6, -2, -3, 0, -2, -2, 2, 1, -1, -1, 0, 0, 1, 1 ] )
##  gap> SymplecticComponents( tbl, [ chi ], 3 );
##  [ ClassFunction( CharacterTable( "U3(3)" ),
##      [ 14, -2, 5, -1, 2, 2, 2, 1, 0, 0, 0, 0, -1, -1 ] ),
##    ClassFunction( CharacterTable( "U3(3)" ),
##      [ 21, 5, 3, 0, 1, 1, 1, -1, 0, 0, -1, -1, 1, 1 ] ),
##    ClassFunction( CharacterTable( "U3(3)" ),
##      [ 64, 0, -8, -2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 ] ),
##    ClassFunction( CharacterTable( "U3(3)" ),
##      [ 14, 6, -4, 2, -2, -2, 2, 0, 0, 0, 0, 0, -2, -2 ] ),
##    ClassFunction( CharacterTable( "U3(3)" ),
##      [ 56, -8, 2, 2, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "SymplecticComponents" );


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


#############################################################################
##
#F  FrobeniusCharacterValue( <value>, <p> )
##
##  <#GAPDoc Label="FrobeniusCharacterValue">
##  <ManSection>
##  <Func Name="FrobeniusCharacterValue" Arg='value, p'/>
##
##  <Description>
##  Let <A>value</A> be a cyclotomic whose coefficients over the rationals
##  are in the ring <M>&ZZ;_{<A>p</A>}</M> of <A>p</A>-local numbers,
##  where <A>p</A> is a prime integer.
##  Assume that <A>value</A> lies in <M>&ZZ;_{<A>p</A>}[\zeta]</M>
##  for <M>\zeta = \exp(<A>p</A>^n-1)</M>,
##  for some positive integer <M>n</M>.
##  <P/>
##  <Ref Func="FrobeniusCharacterValue"/> returns the image of <A>value</A>
##  under the ring homomorphism from <M>&ZZ;_{<A>p</A>}[\zeta]</M>
##  to the field with <M><A>p</A>^n</M> elements
##  that is defined with the help of Conway polynomials
##  (see <Ref Func="ConwayPolynomial"/>), more information can be found
##  in <Cite Key="JLPW95" Where="Sections 2-5"/>.
##  <P/>
##  If <A>value</A> is a Brauer character value in characteristic <A>p</A>
##  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.
##  <P/>
##  If the result of <Ref Func="FrobeniusCharacterValue"/> cannot be
##  expressed as an element of a finite field in &GAP;
##  (see Chapter <Ref Chap="Finite Fields"/>)
##  then <Ref Func="FrobeniusCharacterValue"/> returns <K>fail</K>.
##  <P/>
##  If the Conway polynomial of degree <M>n</M> is required for the
##  computation then it is computed only if
##  <Ref Func="IsCheapConwayPolynomial"/> returns <K>true</K> when it is
##  called with <A>p</A> and <M>n</M>,
##  otherwise <K>fail</K> is returned.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "FrobeniusCharacterValue" );


##############################################################################
##
#F  ReductionToFiniteField( <value>, <p> )
##
##  If this function shall become documented, this can be done in the manual
##  section for FrobeniusCharacterValue.
##
##  <Func Name="ReductionToFiniteField" Arg='value, p'/>
##
##  <Description>
##  Let <A>value</A> be a cyclotomic whose coefficients over the rationals
##  are in the ring <M>&ZZ;_{<A>p</A>}</M> of <A>p</A>-local numbers,
##  where <A>p</A> is a prime integer.
##  <Ref Func="ReductionToFiniteField"/> returns a pair <C>[ pol, m ]</C>
##  where <C>pol</C> is a polynomial over the field with <A>p</A> elements
##  and <C>m</C> is an integer such that the field with <A>p</A><C>^m</C>
##  elements is the minimal field that contains the reduction under the ring
##  homomorphism defined above.
##  The reduction of <A>value</A> is represented by <C>pol</C> modulo
##  the ideal spanned by the Conway polynomial
##  (see <Ref Func="ConwayPolynomial"/>) of degree <C>m</C>.
##  <P/>
##  <K>fail</K> is returned if ...
##  </Description>
##
DeclareGlobalFunction( "ReductionToFiniteField" );


#############################################################################
##
#A  BrauerCharacterValue( <mat> )
##
##  <#GAPDoc Label="BrauerCharacterValue">
##  <ManSection>
##  <Attr Name="BrauerCharacterValue" Arg='mat'/>
##
##  <Description>
##  For an invertible matrix <A>mat</A> over a finite field <M>F</M>,
##  <Ref Attr="BrauerCharacterValue"/> returns the Brauer character value
##  of <A>mat</A> if the order of <A>mat</A> is coprime to the characteristic
##  of <M>F</M>, and <K>fail</K> otherwise.
##  <P/>
##  The <E>Brauer character value</E> of a matrix is the sum of complex lifts
##  of its eigenvalues.
##  <P/>
##  <Example><![CDATA[
##  gap> g:= SL(2,4);;           # 2-dim. irreducible representation of A5
##  gap> ccl:= ConjugacyClasses( g );;
##  gap> rep:= List( ccl, Representative );;
##  gap> List( rep, Order );
##  [ 1, 2, 5, 5, 3 ]
##  gap> phi:= List( rep, BrauerCharacterValue );
##  [ 2, fail, E(5)^2+E(5)^3, E(5)+E(5)^4, -1 ]
##  gap> List( phi{ [ 1, 3, 4, 5 ] }, x -> FrobeniusCharacterValue( x, 2 ) );
##  [ 0*Z(2), Z(2^2), Z(2^2)^2, Z(2)^0 ]
##  gap> List( rep{ [ 1, 3, 4, 5 ] }, TraceMat );
##  [ 0*Z(2), Z(2^2), Z(2^2)^2, Z(2)^0 ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareAttribute( "BrauerCharacterValue", IsMatrix );


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


#############################################################################
##
#F  SizeOfFieldOfDefinition( <val>, <p> )
##
##  <#GAPDoc Label="SizeOfFieldOfDefinition">
##  <ManSection>
##  <Func Name="SizeOfFieldOfDefinition" Arg='val, p'/>
##
##  <Description>
##  For a cyclotomic or a list of cyclotomics <A>val</A>,
##  and a prime integer <A>p</A>, <Ref Func="SizeOfFieldOfDefinition"/>
##  returns the size of the smallest finite field
##  in characteristic <A>p</A> that contains the <A>p</A>-modular reduction
##  of <A>val</A> if this can be determined, and <K>fail</K> otherwise.
##  <P/>
##  The latter happens if <A>val</A> is not closed under Galois conjugacy
##  and if the <A>p</A>-modular reduction of some value cannot be determined
##  via the function <Ref Func="FrobeniusCharacterValue"/>.
##  Note that the reduction map is defined as in <Cite Key="JLPW95"/>,
##  that is, the complex <M>(<A>p</A>^d-1)</M>-th root of unity
##  <M>\exp(<A>p</A>^d-1)</M> is mapped to the residue class of the
##  indeterminate, modulo the ideal spanned by the Conway polynomial
##  (see <Ref Func="ConwayPolynomial"/>) of degree <M>d</M> over the
##  field with <M>p</M> elements.
##  <P/>
##  If <A>val</A> is closed under Galois conjugacy then the result can be
##  determined without explicitly computing the <A>p</A>-modular reduction
##  of <A>val</A>.
##  This happens for example if <A>val</A> is a Brauer character.
##  <P/>
##  If <A>val</A> is an irreducible Brauer character then the value returned
##  is the size of the smallest finite field in characteristic <A>p</A>
##  over which the corresponding representation lives.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "SizeOfFieldOfDefinition" );


#############################################################################
##
#F  RealizableBrauerCharacters( <matrix>, <q> )
##
##  <#GAPDoc Label="RealizableBrauerCharacters">
##  <ManSection>
##  <Func Name="RealizableBrauerCharacters" Arg='matrix, q'/>
##
##  <Description>
##  For a list <A>matrix</A> of absolutely irreducible Brauer characters
##  in characteristic <M>p</M>, and a power <A>q</A> of <M>p</M>,
##  <Ref Func="RealizableBrauerCharacters"/> returns a duplicate-free list of
##  sums of Frobenius conjugates of the rows of <A>matrix</A>,
##  each irreducible over the field with <A>q</A> elements.
##  <P/>
##  <Example><![CDATA[
##  gap> irr:= Irr( CharacterTable( "A5" ) mod 2 );
##  [ Character( BrauerTable( "A5", 2 ), [ 1, 1, 1, 1 ] ),
##    Character( BrauerTable( "A5", 2 ),
##      [ 2, -1, E(5)+E(5)^4, E(5)^2+E(5)^3 ] ),
##    Character( BrauerTable( "A5", 2 ),
##      [ 2, -1, E(5)^2+E(5)^3, E(5)+E(5)^4 ] ),
##    Character( BrauerTable( "A5", 2 ), [ 4, 1, -1, -1 ] ) ]
##  gap> List( irr, phi -> SizeOfFieldOfDefinition( phi, 2 ) );
##  [ 2, 4, 4, 2 ]
##  gap> RealizableBrauerCharacters( irr, 2 );
##  [ Character( BrauerTable( "A5", 2 ), [ 1, 1, 1, 1 ] ),
##    ClassFunction( BrauerTable( "A5", 2 ), [ 4, -2, -1, -1 ] ),
##    Character( BrauerTable( "A5", 2 ), [ 4, 1, -1, -1 ] ) ]
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "RealizableBrauerCharacters" );


#############################################################################
##
##  13. Domains Generated by Class Functions
##
##  <#GAPDoc Label="[9]{ctblfuns}">
##  &GAP; supports groups, vector spaces, and algebras generated by class
##  functions.
##  <!-- add examples:
##  gap> d8:= DihedralGroup( 8 );
##  <pc group of size 8 with 3 generators>
##  gap> lin:= LinearCharacters( d8 );;
##  gap> irr:= Irr( d8 );;
##  gap> g:= Group( lin, lin[1] );
##  <group with 4 generators>
##  gap> Size( g );
##  4
##  gap> IdGroup( g );
##  [ 4, 2 ]
##  gap> v:= VectorSpace( Rationals, lin );;
##  gap> w:= VectorSpace( Rationals, irr );;
##  gap> Dimension( v );
##  4
##  gap> Dimension( w );
##  5
##
##  Note that for generating a group of class functions,
##  one should use the two-argument version of
##  <Ref Func="Group" Label="for a list of generators (and an identity element)"/>,
##  because a call of the one-argument version will return the cyclic matrix
##  group generated by the matrix of the intended generating class functions
##  if this matrix is invertible.
##  % Otherwise it seems to work, but why?
##
##  gap> g:= CyclicGroup( 4 );;
##  gap> irr:= Irr( g );;
##  gap> Size( Group( irr ) );
##  infinity
##  gap> Size( Group( irr, TrivialCharacter( g ) ) );
##  4
##  -->
##  <#/GAPDoc>
##


#############################################################################
##
#F  IsClassFunctionsSpace( <V> )
##
##  <ManSection>
##  <Func Name="IsClassFunctionsSpace" Arg='V'/>
##
##  <Description>
##  If an <M>F</M>-vector space <A>V</A> is in the filter
##  <Ref Func="IsClassFunctionsSpace"/> then this expresses that <A>V</A>
##  consists of class functions, and that <A>V</A> is
##  handled via the mechanism of nice bases (see <Ref ???="..."/>),
##  in the following way.
##  Let <M>T</M> be the underlying character table of the elements of <A>V</A>.
##  Then the <C>NiceFreeLeftModuleInfo</C> value of <A>V</A> is <M>T</M>,
##  and the <C>NiceVector</C> value of <M>v \in <A>V</A></M> is defined as
##  <C>ValueOfClassFunction</C><M>( v )</M>.
##  </Description>
##  </ManSection>
##
DeclareHandlingByNiceBasis( "IsClassFunctionsSpace",
    "for free left modules of class functions" );


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


##############################################################################
##
#F  OrbitChar( <chi>, <linear> )
##
##  <ManSection>
##  <Func Name="OrbitChar" Arg='chi, linear'/>
##
##  <Description>
##  is the orbit of the character values list <A>chi</A> under the action of
##  Galois automorphisms and multiplication with the linear characters in
##  the list <A>linear</A>.
##  <P/>
##  It is assumed that <A>linear</A> 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.)
##  </Description>
##  </ManSection>
##
DeclareGlobalFunction( "OrbitChar" );


##############################################################################
##
#F  OrbitsCharacters( <chars> )
##
##  <ManSection>
##  <Func Name="OrbitsCharacters" Arg='chars'/>
##
##  <Description>
##  is a list of orbits of the characters in the list <A>chars</A>
##  under the action of Galois automorphisms
##  and multiplication with the linear characters in <A>chars</A>.
##  <P/>
##  (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.)
##  </Description>
##  </ManSection>
##
DeclareGlobalFunction( "OrbitsCharacters" );


##############################################################################
##
#F  OrbitRepresentativesCharacters( <irr> )
##
##  <ManSection>
##  <Func Name="OrbitRepresentativesCharacters" Arg='irr'/>
##
##  <Description>
##  is a list of representatives of the orbits of the characters <A>irr</A>
##  under the action of Galois automorphisms and multiplication with linear
##  characters.
##  </Description>
##  </ManSection>
##
DeclareGlobalFunction( "OrbitRepresentativesCharacters" );


#T where to put the following two functions?
#############################################################################
##
#F  CollapsedMat( <mat>, <maps> )
##
##  <#GAPDoc Label="CollapsedMat">
##  <ManSection>
##  <Func Name="CollapsedMat" Arg='mat, maps'/>
##
##  <Description>
##  is a record with the components
##  <P/>
##  <List>
##  <Mark><C>fusion</C></Mark>
##  <Item>
##     fusion that collapses those columns of <A>mat</A> that are equal in
##     <A>mat</A> and also for all maps in the list <A>maps</A>,
##  </Item>
##  <Mark><C>mat</C></Mark>
##  <Item>
##     the image of <A>mat</A> under that fusion.
##  </Item>
##  </List>
##  <P/>
##  <Example><![CDATA[
##  gap> mat:= [ [ 1, 1, 1, 1 ], [ 2, -1, 0, 0 ], [ 4, 4, 1, 1 ] ];;
##  gap> coll:= CollapsedMat( mat, [] );
##  rec( fusion := [ 1, 2, 3, 3 ],
##    mat := [ [ 1, 1, 1 ], [ 2, -1, 0 ], [ 4, 4, 1 ] ] )
##  gap> List( last.mat, x -> x{ last.fusion } ) = mat;
##  true
##  gap> coll:= CollapsedMat( mat, [ [ 1, 1, 1, 2 ] ] );
##  rec( fusion := [ 1, 2, 3, 4 ],
##    mat := [ [ 1, 1, 1, 1 ], [ 2, -1, 0, 0 ], [ 4, 4, 1, 1 ] ] )
##  ]]></Example>
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
DeclareGlobalFunction( "CollapsedMat" );


#############################################################################
##
#F  CharacterTableQuaternionic( <4n> )
##
##  <ManSection>
##  <Func Name="CharacterTableQuaternionic" Arg='4n'/>
##
##  <Description>
##  is the ordinary character table of the generalized quaternion group
##  of order <A>4n</A>.
##  </Description>
##  </ManSection>
##
DeclareGlobalFunction( "CharacterTableQuaternionic" );

[Konzepte0.47Was zu einem Entwurf gehörtWie die Entwicklung von Software durchgeführt wird2026-04-25]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge