Sophie

Sophie

distrib > * > 2010.0 > * > by-pkgid > 0c1f9463f03451b5503f0c33beb88a98 > files > 3590

gap-system-4.4.12-5mdv2010.0.x86_64.rpm

% This file was created automatically from ctblfuns.msk.
% DO NOT EDIT!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%A  ctblfuns.msk                GAP documentation               Thomas Breuer
%%
%A  @(#)$Id: ctblfuns.msk,v 1.28.2.5 2008/08/13 08:12:28 gap Exp $
%%
%Y  (C) 1999 School Math and Comp. Sci., University of St.  Andrews, Scotland
%Y  Copyright (C) 2002 The GAP Group
%%
%%  The documentation in this chapter corresponds to the declarations in the
%%  library files `ctblfuns.gd', `ctbllatt.gd', `ctblmoli.gd', `ctblpope.gd'.
%%
\Chapter{Class Functions}

\index{characters}
\index{group characters}
\index{virtual characters}
\index{generalized characters}

This chapter describes operations for *class functions of finite groups*.
For operations concerning *character tables*, see Chapter~"Character Tables".

Several examples in this chapter require the {\GAP} Character Table Library
to be available.
If it is not yet loaded then we load it now.

\beginexample
gap> LoadPackage( "ctbllib" );
true
\endexample

\>IsClassFunction( <obj> ) C

\index{class function}\index{class function objects}
A *class function* (in characteristic $p$) of a finite group $G$ is a map
from the set of ($p$-regular) elements in $G$ to the cyclotomics that is
constant on conjugacy classes of $G$.

Each class function in {\GAP} is represented by an *immutable list*,
where at the $i$-th position the value on the $i$-th conjugacy class of
the character table of $G$ is stored.
The ordering of the conjugacy classes is the one used in the underlying
character table.
Note that if the character table has access to its underlying group then
the ordering of conjugacy classes in the group and in the character table
may differ (see~"The Interface between Character Tables and Groups");
class functions always refer to the ordering of classes in the character
table.

*Class function objects* in {\GAP} are not just plain lists,
they store the character table of the group $G$ as value of the attribute
`UnderlyingCharacterTable' (see~"UnderlyingCharacterTable").
The group $G$ itself is accessible only via the character table
and thus only if the character table stores its group, as value of the
attribute `UnderlyingGroup'.
The reason for this is that many computations with class functions are
possible without using their groups,
for example class functions of character tables in the {\GAP}
character table library do in general not have access to their
underlying groups.

There are (at least) two reasons why class functions in {\GAP} are *not*
implemented as mappings.
First, we want to distinguish class functions in different
characteristics, for example to be able to define the Frobenius character
of a given Brauer character;
viewed as mappings, the trivial characters in all characteristics coprime
to the order of $G$ are equal.
Second, the product of two class functions shall be again a class
function, whereas the product of general mappings is defined as
composition.

A further argument is that the typical operations for mappings such as
`Image' (see~"Image") and `PreImage' (see~"PreImage") play no important
role for class functions.





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Why Class Functions?}

In principle it is possible to represent group characters or more general
class functions by the plain lists of their values,
and in fact many operations for class functions work with plain lists of
class function values.
But this has two disadvantages.

First, it is then necessary to regard a values list explicitly as a class
function of a particular character table, by supplying this character
table as an argument.
In practice this means that with this setup,
the user has the task to put the objects into the right context.
For example, forming the scalar product or the tensor product of two
class functions or forming an induced class function or a conjugate
class function then needs three arguments in this case;
this is particularly inconvenient in cases where infix operations cannot
be used because of the additional argument, as for tensor products and
induced class functions.

Second, when one says that ``$\chi$ is a character of a group $G$''
then this object $\chi$ carries a lot of information.
$\chi$ has certain properties such as being irreducible or not.
Several subgroups of $G$ are related to $\chi$,
such as the kernel and the centre of $\chi$.
Other attributes of characters are the determinant and the central
character.
This knowledge cannot be stored in a plain list.

For dealing with a group together with its characters, and maybe also
subgroups and their characters, it is desirable that {\GAP} keeps track
of the interpretation of characters.
On the other hand, for using characters without accessing their groups,
such as characters of tables from the {\GAP} table library,
dealing just with values lists is often sufficient.
In particular, if one deals with incomplete character tables then it is
often necessary to specify the arguments explicitly,
for example one has to choose a fusion map or power map from a set of
possibilities.

The main idea behind class function objects is that a class function
object is equal to its values list in the sense of `\\=',
so class function objects can be used wherever their values lists
can be used,
but there are operations for class function objects that do not work
just with values lists.
{\GAP} library functions prefer to return class function objects
rather than returning just values lists,
for example `Irr' lists (see~"Irr") consist of class function objects,
and `TrivialCharacter' (see~"TrivialCharacter") returns a class function
object.

Here is an *example* that shows both approaches.
First we define some groups.

\beginexample
gap> S4:= SymmetricGroup( 4 );;  SetName( S4, "S4" );
gap> D8:= SylowSubgroup( S4, 2 );; SetName( D8, "D8" );
\endexample

We do some computations using the functions described later in this
Chapter, first with class function objects.

\beginexample
gap> irrS4:= Irr( S4 );;
gap> irrD8:= Irr( D8 );;
gap> chi:= irrD8[4];
Character( CharacterTable( D8 ), [ 1, -1, 1, -1, 1 ] )
gap> chi * chi;
Character( CharacterTable( D8 ), [ 1, 1, 1, 1, 1 ] )
gap> ind:= chi ^ S4;
Character( CharacterTable( S4 ), [ 3, -1, -1, 0, 1 ] )
gap> List( irrS4, x -> ScalarProduct( x, ind ) );
[ 0, 1, 0, 0, 0 ]
gap> det:= Determinant( ind );
Character( CharacterTable( S4 ), [ 1, 1, 1, 1, 1 ] )
gap> cent:= CentralCharacter( ind );
ClassFunction( CharacterTable( S4 ), [ 1, -2, -1, 0, 2 ] )
gap> rest:= Restricted( cent, D8 );
ClassFunction( CharacterTable( D8 ), [ 1, -2, -1, -1, 2 ] )
\endexample

Now we repeat these calculations with plain lists of character values.
Here we need the character tables in some places.

\beginexample
gap> tS4:= CharacterTable( S4 );;
gap> tD8:= CharacterTable( D8 );;
gap> chi:= ValuesOfClassFunction( irrD8[4] );
[ 1, -1, 1, -1, 1 ]
gap> Tensored( [ chi ], [ chi ] )[1];
[ 1, 1, 1, 1, 1 ]
gap> ind:= InducedClassFunction( tD8, chi, tS4 );
ClassFunction( CharacterTable( S4 ), [ 3, -1, -1, 0, 1 ] )
gap> List( Irr( tS4 ), x -> ScalarProduct( tS4, x, ind ) );
[ 0, 1, 0, 0, 0 ]
gap> det:= DeterminantOfCharacter( tS4, ind );
ClassFunction( CharacterTable( S4 ), [ 1, 1, 1, 1, 1 ] )
gap> cent:= CentralCharacter( tS4, ind );
ClassFunction( CharacterTable( S4 ), [ 1, -2, -1, 0, 2 ] )
gap> rest:= Restricted( tS4, cent, tD8 );
ClassFunction( CharacterTable( D8 ), [ 1, -2, -1, -1, 2 ] )
\endexample

If one deals with character tables from the {\GAP} table library then
one has no access to their groups,
but often the tables provide enough information for computing induced or
restricted class functions, symmetrizations etc.,
because the relevant class fusions and power maps are often stored on
library tables.
In these cases it is possible to use the tables instead of the groups
as arguments.
(If necessary information is not uniquely determined by the tables then
an error is signalled.)

\beginexample
gap> s5 := CharacterTable( "A5.2" );; irrs5 := Irr( s5  );;
gap> m11:= CharacterTable( "M11"  );; irrm11:= Irr( m11 );;
gap> chi:= TrivialCharacter( s5 );
Character( CharacterTable( "A5.2" ), [ 1, 1, 1, 1, 1, 1, 1 ] )
gap> chi ^ m11;
Character( CharacterTable( "M11" ), [ 66, 10, 3, 2, 1, 1, 0, 0, 0, 0 ] )
gap> Determinant( irrs5[4] );
Character( CharacterTable( "A5.2" ), [ 1, 1, 1, 1, -1, -1, -1 ] )
\endexample

Functions that compute *normal* subgroups related to characters
have counterparts that return the list of class positions corresponding
to these groups.

\beginexample
gap> ClassPositionsOfKernel( irrs5[2] );
[ 1, 2, 3, 4 ]
gap> ClassPositionsOfCentre( irrs5[2] );
[ 1, 2, 3, 4, 5, 6, 7 ]
\endexample

Non-normal subgroups cannot be described this way,
so for example inertia subgroups (see~"InertiaSubgroup") can in general
not be computed from character tables without access to their groups.




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Basic Operations for Class Functions}

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



\>UnderlyingCharacterTable( <psi> ) A

For a class function <psi> of the group $G$, say, the character table of
$G$ is stored as value of `UnderlyingCharacterTable'.
The ordering of entries in the list <psi> (see~"ValuesOfClassFunction")
refers to the ordering of conjugacy classes in this character table.

If <psi> is an ordinary class function then the underlying character
table is the ordinary character table of $G$
(see~"OrdinaryCharacterTable"),
if <psi> is a class function in characteristic $p \not= 0$ then the
underlying character table is the $p$-modular Brauer table of $G$
(see~"BrauerTable").
So the underlying characteristic of <psi> can be read off from the
underlying character table.


\>ValuesOfClassFunction( <psi> ) A

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


\beginexample
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 ]
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Comparison of Class Functions}

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


\beginexample
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> irr1:= Irr( grps[1] );
[ Character( t1, [ 1, 1, 1, 1, 1 ] ), Character( t1, [ 1, -1, -1, 1, 1 ] ), 
  Character( t1, [ 1, -1, 1, 1, -1 ] ), Character( t1, [ 1, 1, -1, 1, -1 ] ), 
  Character( t1, [ 2, 0, 0, -2, 0 ] ) ]
gap> irr2:= Irr( grps[2] );
[ Character( t2, [ 1, 1, 1, 1, 1 ] ), Character( t2, [ 1, -1, -1, 1, 1 ] ), 
  Character( t2, [ 1, -1, 1, 1, -1 ] ), Character( t2, [ 1, 1, -1, 1, -1 ] ), 
  Character( t2, [ 2, 0, 0, -2, 0 ] ) ]
gap> irr1 = irr2;
true
gap> IsSSortedList( irr1 );
false
gap> irr1[1] < irr1[2];
false
gap> irr1[2] < irr1[3];
true
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Arithmetic Operations for Class Functions}

Class functions are *row vectors* of cyclotomics.
The *additive* behaviour of class functions is defined such that they are
equal to the plain lists of class function values except that the results
are represented again as class functions whenever this makes sense.
The *multiplicative* behaviour, however, is different.
This is motivated by the fact that the tensor product of class functions
is a more interesting operation than the vector product of plain lists.
(Another candidate for a multiplication of compatible class functions
would have been the inner product, which is implemented via the function
`ScalarProduct', see~"ScalarProduct!for characters".)
In terms of filters, the arithmetic of class functions is based on the
decision that they lie in `IsGeneralizedRowVector',
with additive nesting depth $1$,
but they do *not* lie in `IsMultiplicativeGeneralizedRowVector'
(see~"Filters Controlling the Arithmetic Behaviour of Lists").

More specifically, the scalar multiple of a class function with a
cyclotomic is a class function,
and the sum and the difference of two class functions
of the same underlying character table (see~"UnderlyingCharacterTable")
are again class functions of this table.
The sum and the difference of a class function and a list that is *not*
a class function are plain lists,
as well as the sum and the difference of two class functions of different
character tables.

\beginexample
gap> g:= SymmetricGroup( 4 );;  tbl:= CharacterTable( g );;
gap> SetName( tbl, "S4" );  irr:= Irr( g );
[ Character( S4, [ 1, -1, 1, 1, -1 ] ), Character( S4, [ 3, -1, -1, 0, 1 ] ), 
  Character( S4, [ 2, 0, 2, -1, 0 ] ), Character( S4, [ 3, 1, -1, 0, -1 ] ), 
  Character( S4, [ 1, 1, 1, 1, 1 ] ) ]
gap> 2 * irr[5];
Character( S4, [ 2, 2, 2, 2, 2 ] )
gap> irr[1] / 7;
ClassFunction( S4, [ 1/7, -1/7, 1/7, 1/7, -1/7 ] )
gap> lincomb:= irr[3] + irr[1] - irr[5];
VirtualCharacter( S4, [ 2, -2, 2, -1, -2 ] )
gap> lincomb:= lincomb + 2 * irr[5];
VirtualCharacter( S4, [ 4, 0, 4, 1, 0 ] )
gap> IsCharacter( lincomb );
true
gap> lincomb;
Character( S4, [ 4, 0, 4, 1, 0 ] )
gap> irr[5] + 2;
[ 3, 3, 3, 3, 3 ]
gap> irr[5] + [ 1, 2, 3, 4, 5 ];
[ 2, 3, 4, 5, 6 ]
gap> zero:= 0 * irr[1];
VirtualCharacter( S4, [ 0, 0, 0, 0, 0 ] )
gap> zero + Z(3);
[ Z(3), Z(3), Z(3), Z(3), Z(3) ]
gap> irr[5] + TrivialCharacter( DihedralGroup( 8 ) );
[ 2, 2, 2, 2, 2 ]
\endexample

\index{class functions!as ring elements}
The product of two class functions of the same character table is the
tensor product (pointwise product) of these class functions.
Thus the set of all class functions of a fixed group forms a ring,
and for any field $F$ of cyclotomics, the $F$-span of a given set of
class functions forms an algebra.

The product of two class functions of *different* tables and the product
of a class function and a list that is *not* a class function are not
defined, an error is signalled in these cases.
Note that in this respect, class functions behave differently from their
values lists, for which the product is defined as the standard scalar
product.

\beginexample
gap> tens:= irr[3] * irr[4];
Character( S4, [ 6, 0, -2, 0, 0 ] )
gap> ValuesOfClassFunction( irr[3] ) * ValuesOfClassFunction( irr[4] );
4
\endexample

\index{inverse!of class function}
Class functions without zero values are invertible,
the *inverse* is defined pointwise.
As a consequence, for example groups of linear characters can be formed.

\beginexample
gap> tens / irr[1];
Character( S4, [ 6, 0, -2, 0, 0 ] )
\endexample

Other (somewhat strange) implications of the definition of arithmetic
operations for class functions, together with the general rules of list
arithmetic (see~"Arithmetic for Lists"),
apply to the case of products involving *lists* of class functions.
No inverse of the list of irreducible characters as a matrix is defined;
if one is interested in the inverse matrix then one can compute it from
the matrix of class function values.

\beginexample
gap> Inverse( List( irr, ValuesOfClassFunction ) );
[ [ 1/24, 1/8, 1/12, 1/8, 1/24 ], [ -1/4, -1/4, 0, 1/4, 1/4 ], 
  [ 1/8, -1/8, 1/4, -1/8, 1/8 ], [ 1/3, 0, -1/3, 0, 1/3 ], 
  [ -1/4, 1/4, 0, -1/4, 1/4 ] ]
\endexample

Also the product of a class function with a list of class functions is
*not* a vector-matrix product but the list of pointwise products.

\beginexample
gap> irr[1] * irr{ [ 1 .. 3 ] };
[ Character( S4, [ 1, 1, 1, 1, 1 ] ), Character( S4, [ 3, 1, -1, 0, -1 ] ), 
  Character( S4, [ 2, 0, 2, -1, 0 ] ) ]
\endexample

And the product of two lists of class functions is *not* the matrix
product but the sum of the pointwise products.

\beginexample
gap> irr * irr;
Character( S4, [ 24, 4, 8, 3, 4 ] )
\endexample

\index{character value!of group element using powering operator}
\index{power!meaning for class functions}
\indextt{\^{}!for class functions}
The *powering* operator `\\^' has several meanings for class functions.
The power of a class function by a nonnegative integer is clearly the
tensor power.
The power of a class function by an element that normalizes the
underlying group or by a Galois automorphism is the conjugate class
function.
(As a consequence, the application of the permutation induced by such an
action cannot be denoted by `\\^'; instead one can use `Permuted',
see~"Permuted".)
The power of a class function by a group or a character table is the
induced class function (see~"InducedClassFunction").
The power of a group element by a class function is the class function
value at (the conjugacy class containing) this element.

\beginexample
gap> irr[3] ^ 3;
Character( S4, [ 8, 0, 8, -1, 0 ] )
gap> lin:= LinearCharacters( DerivedSubgroup( g ) );
[ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, 1, 1 ] ), 
  Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3)^2, E(3) ] ), 
  Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] ) ]
gap> List( lin, chi -> chi ^ (1,2) );
[ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, 1, 1 ] ), 
  Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] ), 
  Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3)^2, E(3) ] ) ]
gap> Orbit( GaloisGroup( CF(3) ), lin[2] );
[ Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3)^2, E(3) ] ), 
  Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] ) ]
gap> lin[1]^g;
Character( S4, [ 2, 0, 2, 2, 0 ] )
gap> (1,2,3)^lin[2];
E(3)^2
\endexample

\index{characteristic!for class functions}
The *characteristic* of class functions is zero,
as for all list of cyclotomics.
For class functions of a $p$-modular character table, such as Brauer
characters, the prime $p$ is given by the
`UnderlyingCharacteristic' (see~"UnderlyingCharacteristic") value of
the character table.

\beginexample
gap> Characteristic( irr[1] );
0
gap> irrmod2:= Irr( g, 2 );
[ Character( BrauerTable( Sym( [ 1 .. 4 ] ), 2 ), [ 1, 1 ] ), 
  Character( BrauerTable( Sym( [ 1 .. 4 ] ), 2 ), [ 2, -1 ] ) ]
gap> Characteristic( irrmod2[1] );
0
gap> UnderlyingCharacteristic( UnderlyingCharacterTable( irrmod2[1] ) );
2
\endexample

\indextt{ComplexConjugate!for class functions}
\indextt{GaloisCyc!for class functions}
\indextt{Permuted!for class functions}
The operations `ComplexConjugate', `GaloisCyc', and `Permuted' return
a class function when they are called with a class function;
The complex conjugate of a class function that is known to be a (virtual)
character is again known to be a (virtual) character, and applying an
arbitrary Galois automorphism to an ordinary (virtual) character yields
a (virtual) character.

\beginexample
gap> ComplexConjugate( lin[2] );
Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] )
gap> GaloisCyc( lin[2], 5 );
Character( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, 1, E(3), E(3)^2 ] )
gap> Permuted( lin[2], (2,3,4) );
ClassFunction( CharacterTable( Alt( [ 1 .. 4 ] ) ), [ 1, E(3), 1, E(3)^2 ] )
\endexample

\indextt{Order!of a class function}
By definition of `Order' for arbitrary monoid elements,
the determinantal order (see~"DeterminantOfCharacter") of characters
cannot be the return value of `Order' for characters.
One can use `Order( Determinant( <chi> ) )' to compute the determinantal
order of the class function <chi>.

\beginexample
gap> det:= Determinant( irr[3] );
Character( S4, [ 1, -1, 1, 1, -1 ] )
gap> Order( det );
2
\endexample




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Printing Class Functions}

\indextt{ViewObj!for class functions}
The default `ViewObj' (see~"ViewObj") methods for class functions
print one of the strings `\"ClassFunction\"', `\"VirtualCharacter\"',
`\"Character\"' (depending on whether the class function is known to be a
character or virtual character, see~"IsCharacter", "IsVirtualCharacter"),
followed by the `ViewObj' output for the underlying character table
(see~"Printing Character Tables"), and the list of values.
The table is chosen (and not the group) in order to distinguish class
functions of different underlying characteristic
(see~"UnderlyingCharacteristic").

\indextt{PrintObj!for character tables}
The default `PrintObj' (see~"PrintObj") method for class functions
does the same as `ViewObj',
except that the character table is is `Print'-ed instead of `View'-ed.

*Note* that if a class function is shown only with one of the strings
`\"ClassFunction\"', `\"VirtualCharacter\"',
it may still be that it is in fact a character;
just this was not known at the time when the class function was printed.

In order to reduce the space that is needed to print a class function,
it may be useful to give a name (see~"Name") to the underlying character
table.

\indextt{Display!for character tables}
The default `Display' (see~"Display") method for a class function <chi>
calls `Display' for its underlying character table
(see~"Printing Character Tables"), with <chi> as the only entry in the
`chars' list of the options record.


\beginexample
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
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Creating Class Functions from Values Lists}

\>ClassFunction( <tbl>, <values> ) O
\>ClassFunction( <G>, <values> ) O

In the first form, `ClassFunction' returns the class function of the
character table <tbl> with values given by the list <values> of
cyclotomics.
In the second form, <G> must be a group, and the class function of its
ordinary character table is returned.

Note that <tbl> determines the underying characteristic of the returned
class function (see~"UnderlyingCharacteristic").


\>VirtualCharacter( <tbl>, <values> ) O
\>VirtualCharacter( <G>, <values> ) O

`VirtualCharacter' returns the virtual character
(see~"IsVirtualCharacter") of the character table <tbl> or the group <G>,
respectively, with values given by the list <values>.

It is *not* checked whether the given values really describe a
virtual character.


\>Character( <tbl>, <values> ) O

`Character' returns the character (see~"IsCharacter")
of the character table <tbl> or the group <G>, respectively,
with values given by the list <values>.

It is *not* checked whether the given values really describe a character.


\beginexample
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 ] )
\endexample

\>ClassFunctionSameType( <tbl>, <chi>, <values> ) F

Let <tbl> be a character table, <chi> a class function object
(*not* necessarily a class function of <tbl>),
and <values> a list of cyclotomics.
`ClassFunctionSameType' returns the class function $\psi$ of <tbl> with
values list <values>, constructed with `ClassFunction'
(see~"ClassFunction").

If <chi> is known to be a (virtual) character then $\psi$ is also known
to be a (virtual) character.


\beginexample
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 ] )
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Creating Class Functions using Groups}

\>TrivialCharacter( <tbl> ) A
\>TrivialCharacter( <G> ) A

is the *trivial character* of the group <G> or its character table <tbl>,
respectively.
This is the class function with value equal to $1$ for each class.


\beginexample
gap> TrivialCharacter( CharacterTable( "A5" ) );
Character( CharacterTable( "A5" ), [ 1, 1, 1, 1, 1 ] )
gap> TrivialCharacter( SymmetricGroup( 3 ) );
Character( CharacterTable( Sym( [ 1 .. 3 ] ) ), [ 1, 1, 1 ] )
\endexample

\>NaturalCharacter( <G> ) A
\>NaturalCharacter( <hom> ) A

If the argument is a permutation group <G> then `NaturalCharacter'
returns the (ordinary) character of the natural permutation
representation of <G> on the set of moved points (see~"MovedPoints"),
that is, the value on each class is the number of points among the moved
points of <G> that are fixed by any permutation in that class.

If the argument is a matrix group <G> in characteristic zero then
`NaturalCharacter' returns the (ordinary) character of the natural matrix
representation of <G>, that is, the value on each class is the trace of
any matrix in that class.

If the argument is a group homomorphism <hom> whose image is a
permutation group or a matrix group then `NaturalCharacter' returns the
restriction of the natural character of the image of <hom> to the
preimage of <hom>.


\beginexample
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:= IsomorphismPermGroup( d8 );;
gap> NaturalCharacter( hom );
Character( CharacterTable( <pc group of size 8 with 3 generators> ), 
[ 8, 0, 0, 0, 0 ] )
\endexample

\>PermutationCharacter( <G>, <D>, <opr> ) O
\>PermutationCharacter( <G>, <U> ) O

Called with a group <G>, an action domain or proper set <D>, and an
action function <opr> (see Chapter~"Group Actions"),
`PermutationCharacter' returns the *permutation character* of the action
of <G> on <D> via <opr>,
that is, the value on each class is the number of points in <D> that are
fixed by an element in this class under the action <opr>.

If the arguments are a group <G> and a subgroup <U> of <G> then
`PermutationCharacter' returns the permutation character of the action
of <G> on the right cosets of <U> via right multiplication.

To compute the permutation character of a *transitive permutation group*
<G> on the cosets of a point stabilizer <U>,
the attribute `NaturalCharacter( <G> )' can be used instead of
`PermutationCharacter( <G>, <U> )'.

More facilities concerning permutation characters are the transitivity
test (see Section~"Operations for Class Functions") and several tools for
computing possible permutation characters
(see~"Possible Permutation Characters",
"Computing Possible Permutation Characters").


\beginexample
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 ] )
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Operations for Class Functions}

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



\>IsCharacter( [<tbl>, ]<chi> ) P

\index{ordinary character}
An *ordinary character* of a group $G$ is a class function of $G$ whose
values are the traces of a complex matrix representation of $G$.

\atindex{Brauer character}{@Brauer character}
A *Brauer character* of $G$ in characteristic $p$ is a class function of
$G$ whose values are the complex lifts of a matrix representation of $G$
with image a finite field of characteristic $p$.


\>IsVirtualCharacter( [<tbl>, ]<chi> ) P

\index{virtual character}
A *virtual character* is a class function that can be written as the
difference of two proper characters (see~"IsCharacter").


\>IsIrreducibleCharacter( [<tbl>, ]<chi> ) P

\index{irreducible character}
A character is *irreducible* if it cannot be written as the sum of two
characters.
For ordinary characters this can be checked using the scalar product
of class functions (see~"ScalarProduct!for characters").
For Brauer characters there is no generic method for checking
irreducibility.


\beginexample
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
\endexample

\>DegreeOfCharacter( <chi> ) A

is the value of the character <chi> on the identity element.
This can also be obtained as `<chi>[1]'.


\beginexample
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
\endexample

\index{constituent!of a group character}
\index{decompose!a group character}
\index{multiplicity!of constituents of a group character}
\index{inner product!of group characters}

\>ScalarProduct( [<tbl>, ]<chi>, <psi> )!{for characters} O

For two class functions <chi> and <psi> which belong to the same
character table <tbl>, `ScalarProduct' returns their scalar product.

If <chi> and <psi> are class function objects,
the argument <tbl> is not needed,
but <tbl> is necessary if at least one of <chi>, <psi>
is just a plain list.

The scalar product of two *ordinary* class functions $\chi$, 
$\psi$ of a group $G$ is defined as
$\frac{1}{|G|} \sum_{g \in G} \chi(g) \psi(g^{-1})$.

For two *$p$-modular* class functions,
the scalar product is defined as
$\frac{1}{|G|} \sum_{g \in S} \chi(g) \psi(g^{-1})$.
where $S$ is the set of $p$-regular elements in $G$.


\>MatScalarProducts( [<tbl>, ]<list1>, <list2> ) O
\>MatScalarProducts( [<tbl>, ]<list> ) O

The first form returns the matrix of scalar products (see above) of the
class functions in the list <list1> with the class functions in the list
<list2>.
More precisely, the matrix contains in the $i$-th row the list of scalar
products of $<list2>[i]$ with the entries of <list1>.

The second form returns a lower triangular matrix of scalar products,
containing for ($j \leq i$) in the $i$-th row in column $j$ the value
$`ScalarProduct'( <tbl>, <list>[j], <list>[i] )$.


\>Norm( [<tbl>, ]<chi> )!{of character} A

For an ordinary class function <chi> of the group $G$, say, we have
$<chi> = \sum_{\chi \in Irr(G)} a_{\chi} \chi$,
with complex coefficients $a_{\chi}$.
The *norm* of <chi> is defined as
$\sum_{\chi \in Irr(G)} a_{\chi} \overline{a_{\chi}}$.


\beginexample
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 ]
\endexample

\>ConstituentsOfCharacter( [<tbl>, ]<chi> ) A

is the set of irreducible characters that occur in the decomposition of
the (virtual) character <chi> with nonzero coefficient.


\beginexample
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 ] ) ]
\endexample

\>KernelOfCharacter( [<tbl>, ]<chi> ) A

For a class function <chi> of the group $G$, say,
`KernelOfCharacter' returns the normal subgroup of $G$ that is formed by
those conjugacy classes for which the value of <chi> equals the degree of
<chi>.
If the underlying character table of <chi> does not store the group $G$
then an error is signalled.
(See~"ClassPositionsOfKernel" for a way to handle the kernel implicitly,
by listing the positions of conjugacy classes in the kernel.)

The returned group is the kernel of any representation of $G$ that
affords <chi>.


\>ClassPositionsOfKernel( <chi> ) A

is the list of positions of those conjugacy classes that form the kernel
of the character <chi>, that is, those positions with character value
equal to the character degree.


\beginexample
gap> List( Irr( S4 ), KernelOfCharacter );
[ Group([ (), (1,2)(3,4), (1,2,3) ]), Group(()), 
  Group([ (1,2)(3,4), (1,3)(2,4) ]), Group(()), 
  Group([ (), (1,2), (1,2)(3,4), (1,2,3), (1,2,3,4) ]) ]
gap> List( Irr( S4 ), ClassPositionsOfKernel );
[ [ 1, 3, 4 ], [ 1 ], [ 1, 3 ], [ 1 ], [ 1, 2, 3, 4, 5 ] ]
\endexample

\>CentreOfCharacter( [<tbl>, ]<chi> ) A

\index{centre!of a character}
For a character <chi> of the group $G$, say, `CentreOfCharacter' returns
the *centre* of <chi>, that is,
the normal subgroup of all those elements of $G$ for which the quotient
of the value of <chi> by the degree of <chi> is a root of unity.

If the underlying character table of <psi> does not store the group $G$
then an error is signalled.
(See~"ClassPositionsOfCentre!for characters" for a way to handle the centre
implicitly, by listing the positions of conjugacy classes in the centre.)


\>ClassPositionsOfCentre( <chi> )!{for characters} A

is the list of positions of classes forming the centre of the character
<chi> (see~"CentreOfCharacter").


\beginexample
gap> List( Irr( S4 ), CentreOfCharacter );
[ Group([ (), (1,2), (1,2)(3,4), (1,2,3), (1,2,3,4) ]), Group(()), 
  Group([ (1,2)(3,4), (1,3)(2,4) ]), Group(()), 
  Group([ (), (1,2), (1,2)(3,4), (1,2,3), (1,2,3,4) ]) ]
gap> List( Irr( S4 ), ClassPositionsOfCentre );
[ [ 1, 2, 3, 4, 5 ], [ 1 ], [ 1, 3 ], [ 1 ], [ 1, 2, 3, 4, 5 ] ]
\endexample

\>InertiaSubgroup( [<tbl>, ]<G>, <chi> ) O

Let <chi> be a character of the group $H$, say,
and <tbl> the character table of $H$;
if the argument <tbl> is not given then the underlying character table of
<chi> (see~"UnderlyingCharacterTable") is used instead.
Furthermore, let <G> be a group that contains $H$ as a normal subgroup.

`InertiaSubgroup' returns the stabilizer in <G> of <chi>,
w.r.t.~the action of <G> on the classes of $H$ via conjugation.
In other words, `InertiaSubgroup' returns the group of all those elements
$g \in <G>$ that satisfy $<chi>^g = <chi>$.


\beginexample
gap> der:= DerivedSubgroup( S4 );
Group([ (1,3,2), (2,4,3) ])
gap> List( Irr( der ), chi -> InertiaSubgroup( S4, chi ) );
[ S4, Alt( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), S4 ]
\endexample

\>CycleStructureClass( [<tbl>, ]<chi>, <class> ) O

Let <permchar> be a permutation character, and <class> the position of a
conjugacy class of the character table of <permchar>.
`CycleStructureClass' returns a list describing the cycle structure of
each element in class <class> in the underlying permutation
representation, in the same format as the result of `CycleStructurePerm'
(see~"CycleStructurePerm").


\beginexample
gap> nat:= NaturalCharacter( S4 );
Character( CharacterTable( S4 ), [ 4, 2, 0, 1, 0 ] )
gap> List( [ 1 .. 5 ], i -> CycleStructureClass( nat, i ) );
[ [  ], [ 1 ], [ 2 ], [ , 1 ], [ ,, 1 ] ]
\endexample

\>IsTransitive( [<tbl>, ]<chi> )!{for characters} P

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


\>Transitivity( [<tbl>, ]<chi> )!{for characters} A

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


\beginexample
gap> IsTransitive( nat );  Transitivity( nat );
true
4
gap> Transitivity( 2 * TrivialCharacter( S4 ) );
0
\endexample

\>CentralCharacter( [<tbl>, ]<chi> ) A

\index{central character}
For a character <chi> of the group $G$, say, `CentralCharacter' returns
the *central character* of <chi>.

The central character of $\chi$ is the class function $\omega_{\chi}$
defined by $\omega_{\chi}(g) = |g^G| \cdot \chi(g)/\chi(1)$ for each
$g \in G$.


\>DeterminantOfCharacter( [<tbl>, ]<chi> ) A

\index{determinant character}
`DeterminantOfCharacter' returns the *determinant character* of the
character <chi>.
This is defined to be the character obtained by taking the determinant of
representing matrices of any representation affording <chi>;
the determinant can be computed using `EigenvaluesChar'
(see~"EigenvaluesChar").

It is also possible to call `Determinant' instead of
`DeterminantOfCharacter'.

Note that the determinant character is well-defined for virtual
characters.


\beginexample
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 ] )
\endexample

\>EigenvaluesChar( [<tbl>, ]<chi>, <class> ) O

Let <chi> be a character of the group $G$, say.
For an element $g \in G$ in the <class>-th conjugacy class, of order $n$,
let $M$ be a matrix of a representation affording <chi>.

`EigenvaluesChar( <tbl>, <chi>, <class> )' is the list of length $n$
where at position $k$ the multiplicity
of $`E(<n>)^<k>' = \exp(\frac{2\pi i k}{n})$ as an eigenvalue of $M$
is stored.

We have `<chi>[ <class> ] = List( [ 1 .. <n> ], k -> E(n)^k )
                             * EigenvaluesChar( <tbl>, <chi>, <class> )'.

It is also possible to call `Eigenvalues' instead of
`EigenvaluesChar'.


\beginexample
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 ] ]
\endexample

\>Tensored( <chars1>, <chars2> ) O

Let <chars1> and <chars2> be lists of (values lists of) class functions
of the same character table.
`Tensored' returns the list of tensor products of all entries in <chars1>
with all entries in <chars2>.


\beginexample
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 
     ] ) ]
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Restricted and Induced Class Functions}

For restricting a class function of a group $G$ to a subgroup $H$
and for inducing a class function of $H$ to $G$,
the *class fusion* from $H$ to $G$ must be known
(see~"Class Fusions between Character Tables").

\index{inflated class functions}
If $F$ is the factor group of $G$ by the normal subgroup $N$ then each
class function of $F$ can be naturally regarded as a class function of
$G$, with $N$ in its kernel.
For a class function of $F$, the corresponding class function of $G$ is
called the *inflated* class function.
Restriction and inflation are in principle the same,
namely indirection of a class function by the appropriate fusion map,
and thus no extra operation is needed for this process.
But note that contrary to the case of a subgroup fusion, the factor
fusion can in general not be computed from the groups $G$ and $F$;
either one needs the natural homomorphism or the factor fusion to the
character table of $F$ must be stored on the table of $G$.
This explains the different syntax for computing restricted and inflated
class functions.

In the following,
the meaning of the optional first argument <tbl> is the same as in
Section~"Operations for Class Functions".



\>RestrictedClassFunction( [<tbl>, ]<chi>, <H> ) O
\>RestrictedClassFunction( [<tbl>, ]<chi>, <hom> ) O
\>RestrictedClassFunction( [<tbl>, ]<chi>, <subtbl> ) O

For a class function <chi> of the group $G$, say,
and either a subgroup <H> of $G$
or a homomorphism from <H> to $G$
or the character table <subtbl> of this subgroup,
`RestrictedClassFunction' returns the class function of <H> obtained by
restricting <chi> to <H>.

In the situation that <chi> is a class function of a factor group $F$ of
<H>, the variant where <hom> is a homomorphism can be always used,
the calls with argument <H> or <subtbl> work only if the factor fusion
is stored on the character table.


\>RestrictedClassFunctions( [<tbl>, ]<chars>, <H> ) O
\>RestrictedClassFunctions( [<tbl>, ]<chars>, <hom> ) O
\>RestrictedClassFunctions( [<tbl>, ]<chars>, <subtbl> ) O

`RestrictedClassFunctions' is similar to `RestrictedClassFunction'
(see~"RestrictedClassFunction"),
the only difference is that it takes a list <chars> of class functions
instead of one class function, and returns the list of restricted class
functions.


\beginexample
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 ] ) ]
\endexample

\>InducedClassFunction( [<tbl>, ]<chi>, <H> ) O
\>InducedClassFunction( [<tbl>, ]<chi>, <hom> ) O
\>InducedClassFunction( [<tbl>, ]<chi>, <suptbl> ) O

For a class function <chi> of the group $G$, say,
and either a supergroup <H> of $G$
or a homomorphism from $G$ to <H>
or the character table <suptbl> of this supergroup,
`InducedClassFunction' returns the class function of <H> obtained by
inducing <chi> to <H>.


\>InducedClassFunctions( [<tbl>, ]<chars>, <H> ) O
\>InducedClassFunctions( [<tbl>, ]<chars>, <hom> ) O
\>InducedClassFunctions( [<tbl>, ]<chars>, <suptbl> ) O

`InducedClassFunctions' is similar to `InducedClassFunction'
(see~"InducedClassFunction"),
the only difference is that it takes a list <chars> of class functions
instead of one class function, and returns the list of induced class
functions.


\beginexample
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 ] ) ]
\endexample

\>InducedClassFunctionsByFusionMap( <subtbl>, <tbl>, <chars>, <fusionmap> ) F

Let <subtbl> and <tbl> be two character tables of groups
$H$ and $G$, such that $H$ is a subgroup of $G$,
let <chars> be a list of class functions of <subtbl>, and
let <fusionmap> be a fusion map from <subtbl> to <tbl>.
The function returns the list of induced class functions of <tbl>
that correspond to <chars>, w.r.t. the given fusion map.

`InducedClassFunctionsByFusionMap' is the function that does
the work for `InducedClassFunction' and `InducedClassFunctions',
see "InducedClassFunction" and "InducedClassFunctions".


\beginexample
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 ] ) ]
\endexample

\>InducedCyclic( <tbl> ) O
\>InducedCyclic( <tbl>, \"all\" ) O
\>InducedCyclic( <tbl>, <classes> ) O
\>InducedCyclic( <tbl>, <classes>, \"all\" ) O

`InducedCyclic' calculates characters induced up from cyclic subgroups
of the ordinary character table <tbl> to <tbl>,
and returns the strictly sorted list of the induced characters.

If `\"all\"' is specified then all irreducible characters of these
subgroups are induced,
otherwise only the permutation characters are calculated.

If a list <classes> is specified then only those cyclic subgroups
generated by these classes are considered,
otherwise all classes of <tbl> are considered.


\beginexample
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 ] ) ]
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Reducing Virtual Characters}

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



\>ReducedClassFunctions( [<tbl>, ]<constituents>, <reducibles> ) O
\>ReducedClassFunctions( [<tbl>, ]<reducibles> ) O

Let <reducibles> be a list of ordinary virtual characters of the group
$G$, say.
If <constituents> is given then it must also be a list of ordinary
virtual characters of $G$,
otherwise we have <constituents> equal to <reducibles> in the following.

`ReducedClassFunctions' returns a record with components `remainders' and
`irreducibles', both lists of virtual characters of $G$.
These virtual characters are computed as follows.

Let `rems' be the set of nonzero class functions obtained by subtraction
of
$$
\sum_{\chi} \frac{[<reducibles>[i], \chi]}{[\chi,\chi]} . \chi
$$
from $<reducibles>[i]$,
where the summation runs over <constituents> and $[\chi,\psi]$ denotes
the scalar product of $G$-class functions.
Let `irrs' be the list of irreducible characters in `rems'.

We project `rems' into the orthogonal space of `irrs' and all those
irreducibles found this way until no new irreducibles arise.
Then the `irreducibles' list is the set of all found irreducible
characters, and the `remainders' list is the set of all nonzero
remainders.


\>ReducedCharacters( [<tbl>, ]<constituents>, <reducibles> ) O

`ReducedCharacters' is similar to `ReducedClassFunctions',
the only difference is that <constituents> and <reducibles> are assumed
to be lists of characters.
This means that only those scalar products must be formed where the
degree of the character in <constituents> does not exceed the degree of
the character in <reducibles>.


\beginexample
gap> tbl:= CharacterTable( "A5" );;
gap> chars:= Irr( tbl ){ [ 2 .. 4 ] };;
gap> chars:= Set( Tensored( chars, chars ) );;
gap> red:= ReducedClassFunctions( chars );
rec( remainders := [  ], 
  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 ] ) ] )
\endexample

\>IrreducibleDifferences( <tbl>, <reducibles>, <reducibles2> ) F
\>IrreducibleDifferences( <tbl>, <reducibles>, <reducibles2>, <scprmat> ) F
\>IrreducibleDifferences( <tbl>, <reducibles>, \"triangle\" ) F
\>IrreducibleDifferences( <tbl>, <reducibles>, \"triangle\", <scprmat> ) F

`IrreducibleDifferences' returns the list of irreducible characters which
occur as difference of two elements of <reducibles>
(if `\"triangle\"' is specified)
or of an element of <reducibles> and an element of <reducibles2>.

If <scprmat> is not specified then it will be calculated,
otherwise we must have
`<scprmat> = MatScalarProducts( <tbl>, <reducibles> )' or
`<scprmat> = MatScalarProducts( <tbl>, <reducibles>, <reducibles2> )',
respectively.


\beginexample
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 ] ) ]
\endexample

\>LLL( <tbl>, <characters>[, <y>][, \"sort\"][, \"linearcomb\"] ) F

\atindex{LLL algorithm!for virtual characters}%
{@LLL algorithm!for virtual characters}
\index{short vectors spanning a lattice}%
\index{lattice basis reduction!for virtual characters}

`LLL' calls the LLL algorithm (see~"LLLReducedBasis") in the case of
lattices spanned by the virtual characters <characters>
of the ordinary character table <tbl> (see~"ScalarProduct!for characters").
By finding shorter vectors in the lattice spanned by <characters>,
i.e., virtual characters of smaller norm,
in some cases `LLL' is able to find irreducible characters.

`LLL' returns a record with at least components `irreducibles'
(the list of found irreducible characters),
`remainders' (a list of reducible virtual characters),
and `norms' (the list of norms of the vectors in `remainders').
`irreducibles' together with `remainders' form a basis of the
$\Z$-lattice spanned by <characters>.

Note that the vectors in the `remainders' list are in general *not*
orthogonal (see~"ReducedClassFunctions") to the irreducible characters in
`irreducibles'.

Optional arguments of `LLL' are
\beginitems
<y> &
    controls the sensitivity of the algorithm,
    see~"LLLReducedBasis",

`\"sort\"' &
    `LLL' sorts <characters> and the `remainders' component of the
    result according to the degrees,

`\"linearcomb\"' &
    the returned record contains components `irreddecomp'
    and `reddecomp', which are decomposition matrices of `irreducibles'
    and `remainders', with respect to <characters>.
\enditems


\beginexample
gap> s4:= CharacterTable( "Symmetric", 4 );;
gap> chars:= [ [ 8, 0, 0, -1, 0 ], [ 6, 0, 2, 0, 2 ],
>     [ 12, 0, -4, 0, 0 ], [ 6, 0, -2, 0, 0 ], [ 24, 0, 0, 0, 0 ],
>     [ 12, 0, 4, 0, 0 ], [ 6, 0, 2, 0, -2 ], [ 12, -2, 0, 0, 0 ],
>     [ 8, 0, 0, 2, 0 ], [ 12, 2, 0, 0, 0 ], [ 1, 1, 1, 1, 1 ] ];;
gap> LLL( s4, chars );
rec( 
  irreducibles := [ Character( CharacterTable( "Sym(4)" ), [ 2, 0, 2, -1, 0 
         ] ), Character( CharacterTable( "Sym(4)" ), [ 1, 1, 1, 1, 1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 3, 1, -1, 0, -1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 3, -1, -1, 0, 1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 1, -1, 1, 1, -1 ] ) ], 
  remainders := [  ], norms := [  ] )
\endexample

\>Extract( <tbl>, <reducibles>, <grammat>[, <missing> ] ) F

Let <tbl> be an ordinary character table,
<reducibles> a list of characters of <tbl>,
and <grammat> the matrix of scalar products of <reducibles>
(see~"MatScalarProducts").
`Extract' tries to find irreducible characters by drawing conclusions out
of the scalar products, using combinatorial and backtrack means.

The optional argument <missing> is the maximal number of irreducible
characters that occur as constituents of <reducibles>.
Specification of <missing> may accelerate `Extract'.

`Extract' returns a record <ext> with components `solution' and `choice',
where the value of `solution' is a list $[ M_1, \ldots, M_n ]$ of
decomposition matrices $M_i$ (up to permutations of rows)
with the property that $M_i^{tr} \cdot X$ is equal to
the sublist at the positions `<ext>.choice[i]' of <reducibles>,
for a matrix $X$ of irreducible characters;
the value of `choice' is a list of length $n$ whose entries are lists
of indices.

So the $j$-th column in each matrix $M_i$ corresponds to
$<reducibles>[j]$, and each row in $M_i$ corresponds to an irreducible
character.
`Decreased' (see~"Decreased") can be used to examine the solution for
computable irreducibles.


\beginexample
gap> s4:= CharacterTable( "Symmetric", 4 );;
gap> red:= [ [ 5, 1, 5, 2, 1 ], [ 2, 0, 2, 2, 0 ], [ 3, -1, 3, 0, -1 ],
>            [ 6, 0, -2, 0, 0 ], [ 4, 0, 0, 1, 2 ] ];;
gap> gram:= MatScalarProducts( s4, red, red );
[ [ 6, 3, 2, 0, 2 ], [ 3, 2, 1, 0, 1 ], [ 2, 1, 2, 0, 0 ], [ 0, 0, 0, 2, 1 ], 
  [ 2, 1, 0, 1, 2 ] ]
gap> ext:= Extract( s4, red, gram, 5 );
rec( 
  solution := [ [ [ 1, 1, 0, 0, 2 ], [ 1, 0, 1, 0, 1 ], [ 0, 1, 0, 1, 0 ], [ 
              0, 0, 1, 0, 1 ], [ 0, 0, 0, 1, 0 ] ] ], 
  choice := [ [ 2, 5, 3, 4, 1 ] ] )
gap> dec:= Decreased( s4, red, ext.solution[1], ext.choice[1] );;
gap> Display( dec );
rec(
  irreducibles := 
   [ Character( CharacterTable( "Sym(4)" ), [ 1, 1, 1, 1, 1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 3, -1, -1, 0, 1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 1, -1, 1, 1, -1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 3, 1, -1, 0, -1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 2, 0, 2, -1, 0 ] ) ],
  remainders := [  ],
  matrix := [  ] )
\endexample

\>OrthogonalEmbeddingsSpecialDimension( <tbl>, <reducibles>, <grammat>, %
 [\"positive\", ] <dim> ) F

`OrthogonalEmbeddingsSpecialDimension' is a variant of
`OrthogonalEmbeddings' (see~"OrthogonalEmbeddings") for the situation
that <tbl> is an ordinary character table, <reducibles> is a list of
virtual characters of <tbl>, <grammat> is the matrix of scalar products
(see~"MatScalarProducts"), and <dim> is an upper bound for the number of
irreducible characters of <tbl> that occur as constituents of
<reducibles>;
if the vectors in <reducibles> are known to be proper characters then
the string `\"positive\"' may be entered as fourth argument.
(See~"OrthogonalEmbeddings" for information why this may help.)

`OrthogonalEmbeddingsSpecialDimension' first uses `OrthogonalEmbeddings'
(see~"OrthogonalEmbeddings") to compute all orthogonal embeddings of
<grammat> into a standard lattice of dimension up to <dim>,
and then calls `Decreased' (see~"Decreased") in order to find irreducible
characters of <tbl>.

`OrthogonalEmbeddingsSpecialDimension' returns a record with components

\beginitems
`irreducibles' &
    a list of found irreducibles, the intersection of all lists of
    irreducibles found by `Decreased', for all possible embeddings, and

`remainders' &
    a list of remaining reducible virtual characters.
\enditems


\beginexample
gap> s6:= CharacterTable( "S6" );;
gap> red:= InducedCyclic( s6, "all" );;
gap> Add( red, TrivialCharacter( s6 ) );
gap> lll:= LLL( s6, red );;
gap> irred:= lll.irreducibles;
[ Character( CharacterTable( "A6.2_1" ), [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ] )
    , Character( CharacterTable( "A6.2_1" ), [ 9, 1, 0, 0, 1, -1, -3, -3, 1, 
      0, 0 ] ), Character( CharacterTable( "A6.2_1" ), 
    [ 16, 0, -2, -2, 0, 1, 0, 0, 0, 0, 0 ] ) ]
gap> Set( Flat( MatScalarProducts( s6, irred, lll.remainders ) ) );
[ 0 ]
gap> dim:= NrConjugacyClasses( s6 ) - Length( lll.irreducibles );
8
gap> rem:= lll.remainders;;  Length( rem );
8
gap> gram:= MatScalarProducts( s6, rem, rem );;  RankMat( gram );
8
gap> emb1:= OrthogonalEmbeddings( gram, 8 );
rec( vectors := [ [ -1, 0, 1, 0, 1, 0, 1, 0 ], [ 1, 0, 0, 1, 0, 1, 0, 0 ], 
      [ 0, 1, 1, 0, 0, 0, 1, 1 ], [ 0, 1, 1, 0, 0, 0, 1, 0 ], 
      [ 0, 1, 1, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0, 1, 0 ], 
      [ 0, -1, 0, 0, 0, 0, 0, 1 ], [ 0, 1, 0, 0, 0, 0, 0, 0 ], 
      [ 0, 0, 1, 0, 0, 0, 1, 1 ], [ 0, 0, 1, 0, 0, 0, 0, 1 ], 
      [ 0, 0, 1, 0, 0, 0, 0, 0 ], [ 0, 0, 0, -1, 1, 0, 0, 0 ], 
      [ 0, 0, 0, 0, 0, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 1, 1 ], 
      [ 0, 0, 0, 0, 0, 0, 1, 0 ], [ 0, 0, 0, 0, 0, 0, 0, 1 ] ], 
  norms := [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], 
  solutions := [ [ 1, 2, 3, 7, 11, 12, 13, 15 ], 
      [ 1, 2, 4, 8, 10, 12, 13, 14 ], [ 1, 2, 5, 6, 9, 12, 13, 16 ] ] )
\endexample

In the following example we temporarily decrease the line length limit from
its default value 80 to 62 in order to get a nicer output format.

\beginexample
gap> SizeScreen([ 62, ]);;
gap> emb2:= OrthogonalEmbeddingsSpecialDimension( s6, rem, gram, 8 );
rec( 
  irreducibles := [ Character( CharacterTable( "A6.2_1" ), 
        [ 5, 1, -1, 2, -1, 0, 1, -3, -1, 1, 0 ] ), 
      Character( CharacterTable( "A6.2_1" ), 
        [ 5, 1, 2, -1, -1, 0, -3, 1, -1, 0, 1 ] ), 
      Character( CharacterTable( "A6.2_1" ), 
        [ 10, -2, 1, 1, 0, 0, -2, 2, 0, 1, -1 ] ), 
      Character( CharacterTable( "A6.2_1" ), 
        [ 10, -2, 1, 1, 0, 0, 2, -2, 0, -1, 1 ] ) ], 
  remainders := 
    [ VirtualCharacter( CharacterTable( "A6.2_1" ), 
        [ 0, 0, 3, -3, 0, 0, 4, -4, 0, 1, -1 ] ), 
      VirtualCharacter( CharacterTable( "A6.2_1" ), 
        [ 6, 2, 3, 0, 0, 1, 2, -2, 0, -1, -2 ] ), 
      VirtualCharacter( CharacterTable( "A6.2_1" ), 
        [ 10, 2, 1, 1, 2, 0, 2, 2, -2, -1, -1 ] ), 
      VirtualCharacter( CharacterTable( "A6.2_1" ), 
        [ 14, 2, 2, -1, 0, -1, 6, 2, 0, 0, -1 ] ) ] )
gap> SizeScreen([ 80, ]);;
\endexample

\>Decreased( <tbl>, <chars>, <decompmat>[, <choice>] ) F

Let <tbl> be an ordinary character table,
<chars> a list of virtual characters of <tbl>,
and <decompmat> a decomposition matrix, that is,
a matrix $M$ with the property that $M^{tr} \cdot X = <chars>$ holds,
where $X$ is a list of irreducible characters of <tbl>.
`Decreased' tries to compute the irreducibles in $X$ or at least some of
them.

Usually `Decreased' is applied to the output of `Extract' (see~"Extract")
or `OrthogonalEmbeddings'
(see~"OrthogonalEmbeddings", "OrthogonalEmbeddingsSpecialDimension");
in the case of `Extract', the choice component corresponding to the
decomposition matrix must be entered as argument <choice> of `Decreased'.

`Decreased' returns `fail' if it can prove that no list $X$ of
irreducible characters corresponding to the arguments exists;
otherwise `Decreased' returns a record with components
\beginitems
`irreducibles' &
    the list of found irreducible characters,

`remainders' &
    the remaining reducible characters, and

`matrix' &
    the decomposition matrix of the characters in the `remainders'
    component.
\enditems


\beginexample
gap> s4:= CharacterTable( "Symmetric", 4 );;
gap> x:= Irr( s4 );;
gap> red:= [ x[1]+x[2], -x[1]-x[3], -x[1]+x[3], -x[2]-x[4] ];;
gap> mat:= MatScalarProducts( s4, red, red );
[ [ 2, -1, -1, -1 ], [ -1, 2, 0, 0 ], [ -1, 0, 2, 0 ], [ -1, 0, 0, 2 ] ]
gap> emb:= OrthogonalEmbeddings( mat );
rec( vectors := [ [ -1, 1, 1, 0 ], [ -1, 1, 0, 1 ], [ 1, -1, 0, 0 ], 
      [ -1, 0, 1, 1 ], [ -1, 0, 1, 0 ], [ -1, 0, 0, 1 ], [ 0, -1, 1, 0 ], 
      [ 0, -1, 0, 1 ], [ 0, 1, 0, 0 ], [ 0, 0, -1, 1 ], [ 0, 0, 1, 0 ], 
      [ 0, 0, 0, 1 ] ], norms := [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], 
  solutions := [ [ 1, 6, 7, 12 ], [ 2, 5, 8, 11 ], [ 3, 4, 9, 10 ] ] )
gap> dec:= Decreased( s4, red, emb.vectors{ emb.solutions[1] } );;
gap> Display( dec );
rec(
  irreducibles := 
   [ Character( CharacterTable( "Sym(4)" ), [ 3, -1, -1, 0, 1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 1, -1, 1, 1, -1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 2, 0, 2, -1, 0 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 3, 1, -1, 0, -1 ] ) ],
  remainders := [  ],
  matrix := [  ] )
gap> Decreased( s4, red, emb.vectors{ emb.solutions[2] } );
fail
gap> Decreased( s4, red, emb.vectors{ emb.solutions[3] } );
fail
\endexample

\>DnLattice( <tbl>, <grammat>, <reducibles> ) F

Let <tbl> be an ordinary character table,
and <reducibles> a list of virtual characters of <tbl>.

`DnLattice' searches for sublattices isomorphic to root lattices of type
$D_n$, for $n \geq 4$, in the lattice that is generated by <reducibles>;
each vector in <reducibles> must have norm $2$, and the matrix of scalar
products (see~"MatScalarProducts") of <reducibles> must be entered as
argument <grammat>.

`DnLattice' is able to find irreducible characters if there is a lattice
of type $D_n$ with $n > 4$.
In the case $n = 4$, `DnLattice' may fail to determine irreducibles.

`DnLattice' returns a record with components
\beginitems
`irreducibles' &
    the list of found irreducible characters,

`remainders' &
    the list of remaining reducible virtual characters, and

`gram' &
    the Gram matrix of the vectors in `remainders'.
\enditems

The `remainders' list is transformed in such a way that the `gram'
matrix is a block diagonal matrix that exhibits the structure of the
lattice generated by the vectors in `remainders'.
So `DnLattice' might be useful even if it fails to find irreducible
characters.


\beginexample
gap> s4:= CharacterTable( "Symmetric", 4 );;
gap> red:= [ [ 2, 0, 2, 2, 0 ], [ 4, 0, 0, 1, 2 ],
>            [ 5, -1, 1, -1, 1 ], [ -1, 1, 3, -1, -1 ] ];;
gap> gram:= MatScalarProducts( s4, red, red );
[ [ 2, 1, 0, 0 ], [ 1, 2, 1, -1 ], [ 0, 1, 2, 0 ], [ 0, -1, 0, 2 ] ]
gap> dn:= DnLattice( s4, gram, red );; Display( dn );
rec(
  gram := [  ],
  remainders := [  ],
  irreducibles := 
   [ Character( CharacterTable( "Sym(4)" ), [ 2, 0, 2, -1, 0 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 1, -1, 1, 1, -1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 1, 1, 1, 1, 1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 3, -1, -1, 0, 1 ] ) ] )
\endexample

\>DnLatticeIterative( <tbl>, <reducibles> ) F

Let <tbl> be an ordinary character table,
and <reducibles> either a list of virtual characters of <tbl>
or a record with components `remainders' and `norms',
for example a record returned by `LLL' (see~"LLL").

`DnLatticeIterative' was designed for iterative use of `DnLattice'
(see~"DnLattice").
`DnLatticeIterative' selects the vectors of norm $2$ among the given
virtual character, calls `DnLattice' for them,
reduces the virtual characters with found irreducibles,
calls `DnLattice' again for the remaining virtual characters,
and so on, until no new irreducibles are found.

`DnLatticeIterative' returns a record with the same components and
meaning of components as `LLL' (see~"LLL").


\beginexample
gap> s4:= CharacterTable( "Symmetric", 4 );;
gap> red:= [ [ 2, 0, 2, 2, 0 ], [ 4, 0, 0, 1, 2 ],
>            [ 5, -1, 1, -1, 1 ], [ -1, 1, 3, -1, -1 ] ];;
gap> dn:= DnLatticeIterative( s4, red );; Display( dn );
rec(
  irreducibles := 
   [ Character( CharacterTable( "Sym(4)" ), [ 2, 0, 2, -1, 0 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 1, -1, 1, 1, -1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 1, 1, 1, 1, 1 ] ), 
      Character( CharacterTable( "Sym(4)" ), [ 3, -1, -1, 0, 1 ] ) ],
  remainders := [  ],
  norms := [  ] )
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Symmetrizations of Class Functions}

\index{characters!symmetrizations of}

\>Symmetrizations( [<tbl>, ]<characters>, <n> ) O
\>Symmetrizations( [<tbl>, ]<characters>, <Sn> ) O

`Symmetrizations' returns the list of symmetrizations of the characters
<characters> of the ordinary character table <tbl> with the ordinary
irreducible characters of the symmetric group of degree <n>;
instead of the integer <n>, the table of the symmetric group can be
entered as <Sn>.

The symmetrization $\chi^{[\lambda]}$ of the character $\chi$ of <tbl>
with the character $\lambda$ of the symmetric group $S_n$ of degree $n$
is defined by
$$
\chi^{[\lambda]}(g) = \frac{1}{n!} \sum_{\rho \in S_n}
                      \lambda(\rho) \prod_{k=1}^{n} \chi(g^k)^{a_k(\rho)},
$$
where $a_k(\rho)$ is the number of cycles of length $k$ in $\rho$.

For special kinds of symmetrizations, see~"SymmetricParts",
"AntiSymmetricParts", "MinusCharacter" and "OrthogonalComponents",
"SymplecticComponents".

*Note* that the returned list may contain zero class functions,
and duplicates are not deleted.


\beginexample
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 ] ) ]
\endexample

\>SymmetricParts( <tbl>, <characters>, <n> ) F

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


\beginexample
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 ] ) ]
\endexample

\>AntiSymmetricParts( <tbl>, <characters>, <n> ) F

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


\beginexample
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 ] ) ]
\endexample

\>OrthogonalComponents( <tbl>, <chars>, <m> ) F

\index{symmetrizations!orthogonal}%
\index{Frame}%
\atindex{Murnaghan components}{@Murnaghan components}

If $\chi$ is a nonlinear character with indicator $+1$,
a splitting of the tensor power $\chi^m$ is given by the so-called
Murnaghan functions (see~\cite{Mur58}).
These components in general have fewer irreducible constituents
than the symmetrizations with the symmetric group of degree <m>
(see~"Symmetrizations").

`OrthogonalComponents' returns the Murnaghan components of the
nonlinear characters of the character table <tbl> in the list <chars>
up to the power <m>, where <m> is an integer between 2 and 6.

The Murnaghan functions are implemented as in~\cite{Fra82}.

*Note*:
If <chars> is a list of character objects (see~"IsCharacter") then also
the result consists of class function objects.
It is not checked whether all characters in <chars> do really have
indicator $+1$; if there are characters with indicator $0$ or $-1$,
the result might contain virtual characters
(see also~"SymplecticComponents"),
therefore the entries of the result do in general not know that they are
characters.


\index{symmetrizations!orthogonal}%
\index{Frame}%
\atindex{Murnaghan components}{@Murnaghan components}
\beginexample
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 ] ) ]
\endexample

\>SymplecticComponents( <tbl>, <chars>, <m> ) F

If $\chi$ is a (nonlinear) character with indicator $-1$,
a splitting of the tensor power $\chi^m$ is given in terms of the
so-called Murnaghan functions (see~\cite{Mur58}).
These components in general have fewer irreducible constituents
than the symmetrizations with the symmetric group of degree <m>
(see~"Symmetrizations").

`SymplecticComponents' returns the symplectic symmetrizations of the
nonlinear characters of the character table <tbl> in the list <chars>
up to the power <m>, where <m> is an integer between 2 and 5.

*Note*:
If <chars> is a list of character objects (see~"IsCharacter") then also
the result consists of class function objects.
It is not checked whether all characters in <chars> do really have
indicator $-1$; if there are characters with indicator $0$ or $+1$,
the result might contain virtual characters
(see also~"OrthogonalComponents"),
therefore the entries of the result do in general not know that they are
characters.


\index{symmetrizations!symplectic}%
\atindex{Murnaghan components}{@Murnaghan components}
\beginexample
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 ] ) ]
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Molien Series}\nolabel

\>MolienSeries( <psi> ) F
\>MolienSeries( <psi>, <chi> ) F
\>MolienSeries( <tbl>, <psi> ) F
\>MolienSeries( <tbl>, <psi>, <chi> ) F

The *Molien series* of the character $\psi$, relative to the character
$\chi$, is the rational function given by the series
$$
   M_{\psi,\chi}(z) = \sum_{d=0}^{\infty} [\chi,\psi^{[d]}] z^d
$$
where $\psi^{[d]}$ denotes the symmetrization of $\psi$ with the trivial
character of the symmetric group $S_d$ (see~"SymmetricParts").

`MolienSeries' returns the Molien series of <psi>, relative to <chi>,
where <psi> and <chi> must be characters of the same character table;
this table must be entered as <tbl> if <chi> and <psi> are only lists of
character values.
The default for <chi> is the trivial character of <tbl>.

The return value of `MolienSeries' stores a value for the attribute
`MolienSeriesInfo' (see~"MolienSeriesInfo").
This admits the computation of coefficients of the series with
`ValueMolienSeries' (see~"ValueMolienSeries").
Furthermore, this attribute gives access to numerator and denominator
of the Molien series viewed as rational function,
where the denominator is a product of polynomials of the form
$(1-z^r)^k$; the Molien series is also displayed in this form.
Note that such a representation is not unique, one can use
`MolienSeriesWithGivenDenominator'
(see~"MolienSeriesWithGivenDenominator")
to obtain the series with a prescribed denominator.

For more information about Molien series, see~\cite{NPP84}.


\beginexample
gap> t:= CharacterTable( AlternatingGroup( 5 ) );;
gap> psi:= First( Irr( t ), x -> Degree( x ) = 3 );;
gap> mol:= MolienSeries( psi );
( 1-z^2-z^3+z^6+z^7-z^9 ) / ( (1-z^5)*(1-z^3)*(1-z^2)^2 )
\endexample

\>MolienSeriesInfo( <ratfun> ) A

If the rational function <ratfun> was constructed by `MolienSeries'
(see~"MolienSeries"),
a representation as quotient of polynomials is known such that the
denominator is a product of terms of the form $(1-z^r)^k$.
This information is encoded as value of `MolienSeriesInfo'.
Additionally, there is a special `PrintObj' method for Molien series
based on this.

`MolienSeriesInfo' returns a record that describes the rational function
<ratfun> as a Molien series.
The components of this record are
\beginitems
`numer' &
     numerator of <ratfun> (in general a multiple of the numerator
     one gets by `NumeratorOfRationalFunction'),

`denom' &
     denominator of <ratfun> (in general a multiple of the denominator
     one gets by `NumeratorOfRationalFunction'),

`ratfun' &
     the rational function <ratfun> itself,

`numerstring' &
     string corresponding to the polynomial `numer',
     expressed in terms of `z',

`denomstring' &
     string corresponding to the polynomial `denom',
     expressed in terms of `z',

`denominfo' &
     a list of the form $[ [ r_1, k_1 ], \ldots, [ r_n, k_n ] ]$
     such that `denom' is $\prod_{i=1}^n (1-z^{r_i})^{k_i}$.

`summands' &
     a list of records, each with the components `numer', `r', and `k',
     describing the summand $`numer' / (1-z^r)^k$,

`size' &
     the order of the underlying matrix group,

`degree' &
     the degree of the underlying matrix representation.
\enditems


\beginexample
gap> HasMolienSeriesInfo( mol );
true
gap> MolienSeriesInfo( mol );
rec( summands := [ rec( numer := [ -24, -12, -24 ], r := 5, k := 1 ), 
      rec( numer := [ -20 ], r := 3, k := 1 ), 
      rec( numer := [ -45/4, 75/4, -15/4, -15/4 ], r := 2, k := 2 ), 
      rec( numer := [ -1 ], r := 1, k := 3 ), 
      rec( numer := [ -15/4 ], r := 1, k := 1 ) ], size := 60, degree := 3, 
  numer := -x_1^9+x_1^7+x_1^6-x_1^3-x_1^2+1, 
  denom := x_1^12-2*x_1^10-x_1^9+x_1^8+x_1^7+x_1^5+x_1^4-x_1^3-2*x_1^2+1, 
  denominfo := [ 5, 1, 3, 1, 2, 2 ], numerstring := "1-z^2-z^3+z^6+z^7-z^9", 
  denomstring := "(1-z^5)*(1-z^3)*(1-z^2)^2", 
  ratfun := ( 1-z^2-z^3+z^6+z^7-z^9 ) / ( (1-z^5)*(1-z^3)*(1-z^2)^2 ) )
\endexample

\>ValueMolienSeries( <molser>, <i> ) F

is the <i>-th coefficient of the Molien series <series> computed by
`MolienSeries'.


\beginexample
gap> List( [ 0 .. 20 ], i -> ValueMolienSeries( mol, i ) );
[ 1, 0, 1, 0, 1, 0, 2, 0, 2, 0, 3, 0, 4, 0, 4, 1, 5, 1, 6, 1, 7 ]
\endexample

\>MolienSeriesWithGivenDenominator( <molser>, <list> ) F

is a Molien series equal to <molser> as rational function,
but viewed as quotient with denominator
$\prod_{i=1}^n (1-z^{r_i})$, where $<list> = [ r_1, r_2, \ldots, r_n ]$.
If <molser> cannot be represented this way, `fail' is returned.


\beginexample
gap> MolienSeriesWithGivenDenominator( mol, [ 2, 6, 10 ] );
( 1+z^15 ) / ( (1-z^10)*(1-z^6)*(1-z^2) )
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Possible Permutation Characters}

\index{characters!permutation}%
\index{candidates!for permutation characters}%
\index{possible permutation characters}%
\index{permutation characters!possible}

For groups $H$ and $G$ with $H \leq G$,
the induced character $(1_G)^H$ is called the *permutation character*
of the operation of $G$ on the right cosets of $H$.
If only the character table of $G$ is available and not the group $G$
itself, one can try to get information about possible subgroups of $G$
by inspection of those $G$-class functions that might be
permutation characters, using that such a class function $\pi$ must have
at least the following properties.
(For details, see~\cite{Isa76}, Theorem~5.18.)
\beginlist%ordered{a}
\item{(a)}
    $\pi$ is a character of $G$,
\item{(b)}
    $\pi(g)$ is a nonnegative integer for all $g \in G$,
\item{(c)}
    $\pi(1)$ divides $|G|$,
\item{(d)}
    $\pi(g^n) \geq \pi(g)$ for $g \in G$ and integers $n$,
\item{(e)}
    $[\pi,1_G] = 1$,
\item{(f)}
    the multiplicity of any rational irreducible $G$-character $\psi$
    as a constituent of $\pi$ is at most $\psi(1)/[\psi,\psi]$,
\item{(g)}
    $\pi(g) = 0$ if the order of $g$ does not divide $|G|/\pi(1)$,
\item{(h)}
    $\pi(1) |N_G(g)|$ divides $\pi(g) |G|$ for all $g \in G$,
\item{(i)}
    $\pi(g) \leq (|G| - \pi(1)) / (|g^G| |Gal_G(g)|)$ for all nonidentity
    $g \in G$, where $|Gal_G(g)|$ denotes the number of conjugacy classes
    of $G$ that contain generators of the group $\langle g \rangle$,
\item{(j)}
    if $p$ is a prime that divides $|G|/\pi(1)$ only once then $s/(p-1)$
    divides $|G|/\pi(1)$ and is congruent to $1$ modulo $p$,
    where $s$ is the number of elements of order $p$ in the
    (hypothetical) subgroup $H$ for which $\pi = (1_H)^G$ holds.
    (Note that $s/(p-1)$ equals the number of Sylow $p$ subgroups in
    $H$.)
\endlist
Any $G$-class function with these properties is called a
*possible permutation character* in {\GAP}.

(Condition (d) is checked only for those power maps that are stored in
the character table of $G$;
clearly (d) holds for all integers if it holds for all prime divisors of
the group order $|G|$.)

{\GAP} provides some algorithms to compute
possible permutation characters (see~"PermChars"),
and also provides functions to check a few more criteria whether a
given character can be a transitive permutation character
(see~"TestPerm1").

Some information about the subgroup $U$ can be computed from the
permutation character $(1_U)^G$ using `PermCharInfo'
(see~"PermCharInfo").



\>PermCharInfo( <tbl>, <permchars>[, \"LaTeX\" ] ) F
\>PermCharInfo( <tbl>, <permchars>[, \"HTML\" ] ) F

Let <tbl> be the ordinary character table of the group $G$,
and `permchars' either the permutation character $(1_U)^G$,
for a subgroup $U$ of $G$, or a list of such permutation characters.
`PermCharInfo' returns a record with the following components.
\beginitems
`contained': &
  a list containing, for each character $\psi = (1_U)^G$ in <permchars>,
  a list containing at position $i$ the number
  $\psi[i] |U| / `SizesCentralizers( <tbl> )'[i]$,
  which equals the number of those elements of $U$
  that are contained in class $i$ of <tbl>,

`bound': &
  a list containing, for each character $\psi = (1_U)^G$ in <permchars>,
  a list containing at position $i$ the number
  $|U| / \gcd( |U|, `SizesCentralizers( <tbl> )'[i] )$,
  which divides the class length in $U$ of an element in class $i$
  of <tbl>,

`display': &
  a record that can be used as second argument of `Display'
  to display each permutation character in <permchars> and the
  corresponding components `contained' and `bound',
  for those classes where at least one character of <permchars> is
  nonzero,

`ATLAS': &
  a list of strings describing the decomposition of the permutation
  characters in <permchars> into the irreducible characters of <tbl>,
  given in an {\ATLAS}-like notation.
  This means that the irreducible constituents are indicated by their
  degrees followed by lower case letters `a', `b', `c', $\ldots$,
  which indicate the successive irreducible characters of <tbl>
  of that degree, in the order in which they appear in `Irr( <tbl> )'.
  A sequence of small letters (not necessarily distinct) after a single
  number indicates a sum of irreducible constituents all of the same
  degree, an exponent <n> for the letter <lett> means that <lett>
  is repeated <n> times.
  The default notation for exponentiation is `<lett>^{<n>}',
  this is also chosen if the optional third argument is the string
  `\"LaTeX\"';
  if the third argument is the string `\"HTML\"' then exponentiation is
  denoted by `<lett>\<sup><n>\<\/sup>'.
\enditems


\beginexample
gap> t:= CharacterTable( "A6" );;
gap> psi:= Sum( Irr( t ){ [ 1, 3, 6 ] } );
Character( CharacterTable( "A6" ), [ 15, 3, 0, 3, 1, 0, 0 ] )
gap> info:= PermCharInfo( t, psi );
rec( contained := [ [ 1, 9, 0, 8, 6, 0, 0 ] ], 
  bound := [ [ 1, 3, 8, 8, 6, 24, 24 ] ], 
  display := rec( classes := [ 1, 2, 4, 5 ], 
      chars := [ [ 15, 3, 0, 3, 1, 0, 0 ], [ 1, 9, 0, 8, 6, 0, 0 ], 
          [ 1, 3, 8, 8, 6, 24, 24 ] ], letter := "I" ), 
  ATLAS := [ "1a+5b+9a" ] )
gap> Display( t, info.display );
A6

     2  3  3  .  2
     3  2  .  2  .
     5  1  .  .  .

       1a 2a 3b 4a
    2P 1a 1a 3b 2a
    3P 1a 2a 1a 4a
    5P 1a 2a 3b 4a

Y.1    15  3  3  1
Y.2     1  9  8  6
Y.3     1  3  8  6
gap> j1:= CharacterTable( "J1" );;
gap> psi:= TrivialCharacter( CharacterTable( "7:6" ) )^j1;
Character( CharacterTable( "J1" ), [ 4180, 20, 10, 0, 0, 2, 1, 0, 0, 0, 0, 0, 
  0, 0, 0 ] )
gap> PermCharInfo( j1, psi ).ATLAS;
[ "1a+56aabb+76aaab+77aabbcc+120aaabbbccc+133a^{4}bbcc+209a^{5}" ]
\endexample

\>PermCharInfoRelative( <tbl>, <tbl2>, <permchars> ) F

Let <tbl> and <tbl2> be the ordinary character tables of two groups $H$
and $G$, respectively, where $H$ is of index $2$ in $G$,
and <permchars> either the permutation character $(1_U)^G$,
for a subgroup $U$ of $G$, or a list of such permutation characters.
`PermCharInfoRelative' returns a record with the same components as
`PermCharInfo' (see~"PermCharInfo"), the only exception is that the
entries of the `ATLAS' component are names relative to <tbl>.

More precisely, the $i$-th entry of the `ATLAS' component is a string
describing the decomposition of the $i$-th entry in <permchars>.
The degrees and distinguishing letters of the constituents refer to
the irreducibles of <tbl>, as follows.
The two irreducible characters of <tbl2> of degree $N$, say, that extend
the irreducible character $N `a'$ of <tbl> are denoted by $N `a'^+$ and
$N `a'^-$.
The irreducible character of <tbl2> of degree $2N$, say, whose
restriction to <tbl> is the sum of the irreducible characters $N `a'$ and
$N `b'$ is denoted as $N `ab'$.
Multiplicities larger than $1$ of constituents are denoted by exponents.

(This format is useful mainly for multiplicity free permutation
characters.)


\beginexample
gap> t:= CharacterTable( "A5" );;
gap> t2:= CharacterTable( "A5.2" );;
gap> List( Irr( t2 ), x -> x[1] );
[ 1, 1, 6, 4, 4, 5, 5 ]
gap> List( Irr( t ), x -> x[1] );
[ 1, 3, 3, 4, 5 ]
gap> permchars:= List( [ [1], [1,2], [1,7], [1,3,4,4,6,6,7] ],
>                      l -> Sum( Irr( t2 ){ l } ) );
[ Character( CharacterTable( "A5.2" ), [ 1, 1, 1, 1, 1, 1, 1 ] ), 
  Character( CharacterTable( "A5.2" ), [ 2, 2, 2, 2, 0, 0, 0 ] ), 
  Character( CharacterTable( "A5.2" ), [ 6, 2, 0, 1, 0, 2, 0 ] ), 
  Character( CharacterTable( "A5.2" ), [ 30, 2, 0, 0, 6, 0, 0 ] ) ]
gap> info:= PermCharInfoRelative( t, t2, permchars );;
gap> info.ATLAS;
[ "1a^+", "1a^{\\pm}", "1a^++5a^-", "1a^++3ab+4(a^+)^{2}+5a^{\\pm}a^+" ]
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Computing Possible Permutation Characters}

\index{characters!permutation}%
\index{candidates!for permutation characters}%
\index{possible permutation characters}%
\index{permutation characters!possible}

\>PermChars( <tbl> ) F
\>PermChars( <tbl>, <degree> ) F
\>PermChars( <tbl>, <arec> ) F

{\GAP} provides several algorithms to determine
possible permutation characters from a given character table.
They are described in detail in~\cite{BP98}.
The algorithm is selected from the choice of the record components of the
optional argument record <arec>.
The user is encouraged to try different approaches,
especially if one choice fails to come to an end.

Regardless of the algorithm used in a specific case,
`PermChars' returns a list of *all* possible permutation characters
with the properties described by <arec>.
There is no guarantee that a character of this list is in fact
a permutation character.
But an empty list always means there is no permutation character
with these properties (e.g., of a certain degree).

In the first form `PermChars' returns the list of all
possible permutation characters of the group with character table <tbl>.
This list might be rather long for big groups,
and its computation might take much time.
The algorithm is described in Section~3.2 in~\cite{BP98};
it depends on a preprocessing step, where the inequalities
arising from the condition $\pi(g) \geq 0$ are transformed into
a system of inequalities that guides the search (see~"Inequalities").
So the following commands compute the list of 39 possible permutation
characters of the Mathieu group $M_{11}$.
\beginexample
gap> m11:= CharacterTable( "M11" );;
gap> SetName( m11, "m11" );
gap> perms:= PermChars( m11 );;
gap> Length( perms );
39
\endexample
There are two different search strategies for this algorithm.
The default strategy simply constructs all characters with nonnegative
values and then tests for each such character whether its degree
is a divisor of the order of the group.
The other strategy uses the inequalities to predict
whether a character of a certain degree can lie
in the currently searched part of the search tree.
To choose this strategy, use the third form of `PermChars'
and set the component `degree' to the range of degrees
(which might also be a range containing all divisors of the group order)
you want to look for;
additionally, the record component `ineq' can take the inequalities
computed by `Inequalities' if they are needed more than once.

In the second form `PermChars' returns the list of all
possible permutation characters of <tbl> that have degree <degree>.
For that purpose, a preprocessing step is performed where
essentially the rational character table is inverted
in order to determine boundary points for the simplex
in which the possible permutation characters of the given degree
must lie (see~"PermBounds").
The algorithm is described at the end of Section~3.2 in~\cite{BP98};
Note that inverting big integer matrices needs a lot of time and space.
So this preprocessing is restricted to groups with less than 100 classes,
say.
\beginexample
gap> deg220:= PermChars( m11, 220 );
[ Character( m11, [ 220, 4, 4, 0, 0, 4, 0, 0, 0, 0 ] ), 
  Character( m11, [ 220, 12, 4, 4, 0, 0, 0, 0, 0, 0 ] ), 
  Character( m11, [ 220, 20, 4, 0, 0, 2, 0, 0, 0, 0 ] ) ]
\endexample

In the third form `PermChars' returns the list of all
possible permutation characters that have the properties described by
the argument record <arec>.
One such situation has been mentioned above.
If <arec> contains a degree as value of the record component `degree'
then `PermChars' will behave exactly as in the second form.
\beginexample
gap> deg220 = PermChars( m11, rec( degree:= 220 ) );
true
\endexample
For the meaning of additional components of <arec> besides `degree',
see~"PermComb".

Instead of `degree', <arec> may have the component `torso' bound
to a list that contains some known values of the required characters
at the right positions;
at least the degree `<arec>.torso[1]' must be an integer.
In this case, the algorithm described in Section~3.3 in~\cite{BP98}
is chosen.
The component `chars', if present, holds a list of all those *rational*
irreducible characters of <tbl> that might be constituents of the
required characters.

(*Note*: If `<arec>.chars' is bound and does not contain *all* rational
irreducible characters of <tbl>, {\GAP} checks whether the scalar
products of all class functions in the result list with the omitted
rational irreducible characters of <tbl> are nonnegative;
so there should be nontrivial reasons for excluding a character
that is known to be not a constituent of the desired possible permutation
characters.)
\beginexample
gap> PermChars( m11, rec( torso:= [ 220 ] ) );
[ Character( m11, [ 220, 4, 4, 0, 0, 4, 0, 0, 0, 0 ] ), 
  Character( m11, [ 220, 20, 4, 0, 0, 2, 0, 0, 0, 0 ] ), 
  Character( m11, [ 220, 12, 4, 4, 0, 0, 0, 0, 0, 0 ] ) ]
gap> PermChars( m11, rec( torso:= [ 220,,,,, 2 ] ) );
[ Character( m11, [ 220, 20, 4, 0, 0, 2, 0, 0, 0, 0 ] ) ]
\endexample

An additional restriction on the possible permutation characters computed
can be forced if <arec> contains, in addition to `torso',
the components `normalsubgroup' and `nonfaithful',
with values a list of class positions of a normal subgroup $N$ of the
group $G$ of <tbl> and a possible permutation character $\pi$ of $G$,
respectively, such that $N$ is contained in the kernel of $\pi$.
In this case, `PermChars' returns the list of those possible permutation
characters $\psi$ of <tbl> coinciding with `torso' wherever its values
are bound
and having the property that no irreducible constituent of $\psi-\pi$
has $N$ in its kernel.
If the component `chars' is bound in <arec> then the above statements
apply.
An interpretation of the computed characters is the following.
Suppose there exists a subgroup $V$ of $G$ such that $\pi = (1_V)^G$;
Then $N \leq V$, and if a computed character is of the form $(1_U)^G$
for a subgroup $U$ of $G$ then $V = UN$.
\beginexample
gap> s4:= CharacterTable( "Symmetric", 4 );;
gap> nsg:= ClassPositionsOfDerivedSubgroup( s4 );;
gap> pi:= TrivialCharacter( s4 );;
gap> PermChars( s4, rec( torso:= [ 12 ], normalsubgroup:= nsg,
>                        nonfaithful:= pi ) );
[ Character( CharacterTable( "Sym(4)" ), [ 12, 2, 0, 0, 0 ] ) ]
gap> pi:= Sum( Filtered( Irr( s4 ),
>              chi -> IsSubset( ClassPositionsOfKernel( chi ), nsg ) ) );
Character( CharacterTable( "Sym(4)" ), [ 2, 0, 2, 2, 0 ] )
gap> PermChars( s4, rec( torso:= [ 12 ], normalsubgroup:= nsg,
>                        nonfaithful:= pi ) );
[ Character( CharacterTable( "Sym(4)" ), [ 12, 0, 4, 0, 0 ] ) ]
\endexample

The class functions returned by `PermChars' have the properties tested by
`TestPerm1', `TestPerm2', and `TestPerm3'.
So they are possible permutation characters.
See~"TestPerm1" for criteria whether a possible permutation character can
in fact be a permutation character.



\>TestPerm1( <tbl>, <char> ) F
\>TestPerm2( <tbl>, <char> ) F
\>TestPerm3( <tbl>, <chars> ) F
\>TestPerm4( <tbl>, <chars> ) F
\>TestPerm5( <tbl>, <chars>, <modtbl> ) F

The first three of these functions implement tests of the properties of
possible permutation characters listed in
Section~"Possible Permutation Characters",
The other two implement test of additional properties.
Let <tbl> be the ordinary character table of a group $G$, say,
<char> a rational character of <tbl>,
and <chars> a list of rational characters of <tbl>.
For applying `TestPerm5', the knowledge of a $p$-modular Brauer table
<modtbl> of $G$ is required.
`TestPerm4' and `TestPerm5' expect the characters in <chars> to satisfy
the conditions checked by `TestPerm1' and `TestPerm2' (see below).

The return values of the functions were chosen parallel to the tests
listed in~\cite{NPP84}.

`TestPerm1' return `1' or `2' if <char> fails because of (T1) or (T2),
respectively; this corresponds to the criteria (b) and (d).
Note that only those power maps are considered that are stored on <tbl>.
If <char> satisfies the conditions, `0' is returned.

`TestPerm2' returns `1' if <char> fails because of the criterion (c),
it returns `3', `4', or `5' if <char> fails because of (T3), (T4),
or (T5), respectively;
these tests correspond to (g), a weaker form of (h), and (j).
If <char> satisfies the conditions, `0' is returned.

`TestPerm3' returns the list of all those class functions in the list
<chars> that satisfy criterion (h); this is a stronger version of (T6).

`TestPerm4' returns the list of all those class functions in the list
<chars> that satisfy (T8) and (T9) for each prime divisor $p$ of the
order of $G$;
these tests use modular representation theory but do not require the
knowledge of decomposition matrices (cf.~`TestPerm5' below).

(T8) implements the test of the fact that in the case that $p$ divides
$|G|$ and the degree of a transitive permutation character $\pi$ exactly
once,
the projective cover of the trivial character is a summand of $\pi$.
(This test is omitted if the projective cover cannot be identified.)

Given a permutation character $\pi$ of a group $G$ and a prime integer
$p$, the restriction $\pi_B$ to a $p$-block $B$ of $G$ has the following
property, which is checked by (T9).
For each $g\in G$ such that $g^n$ is a $p$-element of $G$,
$\pi_B(g^n)$ is a nonnegative integer that satisfies
$|\pi_B(g)| \leq \pi_B(g^n) \leq \pi(g^n)$.
(This is Corollary~A on p.~113 of~\cite{Sco73}.)

`TestPerm5' requires the $p$-modular Brauer table <modtbl> of $G$,
for some prime $p$ dividing the order of $G$,
and checks whether those characters in the list <chars> whose degree is
divisible by the $p$-part of the order of $G$ can be decomposed into
projective indecomposable characters;
`TestPerm5' returns the sublist of all those characters in <chars>
that either satisfy this condition or to which the test does not apply.



\beginexample
gap> tbl:= CharacterTable( "A5" );;
gap> rat:= RationalizedMat( Irr( tbl ) );
[ 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" ), [ 5, 1, -1, 0, 0 ] ) ]
gap> tup:= Filtered( Tuples( [ 0, 1 ], 4 ), x -> not IsZero( x ) );
[ [ 0, 0, 0, 1 ], [ 0, 0, 1, 0 ], [ 0, 0, 1, 1 ], [ 0, 1, 0, 0 ], 
  [ 0, 1, 0, 1 ], [ 0, 1, 1, 0 ], [ 0, 1, 1, 1 ], [ 1, 0, 0, 0 ], 
  [ 1, 0, 0, 1 ], [ 1, 0, 1, 0 ], [ 1, 0, 1, 1 ], [ 1, 1, 0, 0 ], 
  [ 1, 1, 0, 1 ], [ 1, 1, 1, 0 ], [ 1, 1, 1, 1 ] ]
gap> lincomb:= List( tup, coeff -> coeff * rat );;
gap> List( lincomb, psi -> TestPerm1( tbl, psi ) );
[ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0 ]
gap> List( lincomb, psi -> TestPerm2( tbl, psi ) );
[ 0, 5, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1 ]
gap> Set( List( TestPerm3( tbl, lincomb ), x -> Position( lincomb, x ) ) );
[ 1, 4, 6, 7, 8, 9, 10, 11, 13 ]
gap> tbl:= CharacterTable( "A7" );
CharacterTable( "A7" )
gap> perms:= PermChars( tbl, rec( degree:= 315 ) );
[ Character( CharacterTable( "A7" ), [ 315, 3, 0, 0, 3, 0, 0, 0, 0 ] ), 
  Character( CharacterTable( "A7" ), [ 315, 15, 0, 0, 1, 0, 0, 0, 0 ] ) ]
gap> TestPerm4( tbl, perms );
[ Character( CharacterTable( "A7" ), [ 315, 15, 0, 0, 1, 0, 0, 0, 0 ] ) ]
gap> perms:= PermChars( tbl, rec( degree:= 15 ) );
[ Character( CharacterTable( "A7" ), [ 15, 3, 0, 3, 1, 0, 0, 1, 1 ] ), 
  Character( CharacterTable( "A7" ), [ 15, 3, 3, 0, 1, 0, 3, 1, 1 ] ) ]
gap> TestPerm5( tbl, perms, tbl mod 5 );
[ Character( CharacterTable( "A7" ), [ 15, 3, 0, 3, 1, 0, 0, 1, 1 ] ) ]
\endexample

\>PermBounds( <tbl>, <d> ) F

Let <tbl> be the ordinary character table of the group $G$.
All $G$-characters $\pi$ satisfying $\pi(g) > 0$ and $\pi(1) = <d>$,
for a given degree <d>, lie in a simplex described by these conditions.
`PermBounds' computes the boundary points of this simplex for  $d = 0$,
from which the boundary points for any other <d> are easily derived.
(Some conditions from the power maps of <tbl> are also involved.)
For this purpose, a matrix similar to the rational character table of $G$
has to be inverted.
These boundary points are used by `PermChars' (see~"PermChars")
to construct all possible permutation characters
(see~"Possible Permutation Characters") of a given degree.
`PermChars' either calls `PermBounds' or takes this information from the
`bounds' component of its argument record.


\>PermComb( <tbl>, <arec> ) F

`PermComb' computes possible permutation characters of the character
table <tbl> by the improved combinatorial approach
described at the end of Section~3.2 in~\cite{BP98}.

For computing the possible linear combinations *without* prescribing
better bounds (i.e., when the computation of bounds shall be suppressed),
enter `<arec>:= rec( degree := <degree>, bounds := false )',
where <degree> is the character degree;
this is useful if the multiplicities are expected to be small,
and if this is forced by high irreducible degrees.

A list of upper bounds on the multiplicities of the rational irreducibles
characters can be explicitly prescribed as a `maxmult' component in
<arec>.


\>Inequalities( <tbl>, <chars>[, <option>] ) O

Let <tbl> be the ordinary character table of a group $G$.
The condition $\pi(g) \geq 0$ for every possible permutation character
$\pi$ of $G$ places restrictions on the multiplicities $a_i$
of the irreducible constituents $\chi_i$
of $\pi = \sum_{i=1}^r a_i \chi_i$.
For every element $g \in G$, we have $\sum_{i=1}^r a_i \chi_i(g) \geq 0$.
The power maps provide even stronger conditions.

This system of inequalities is kind of diagonalized,
resulting in a system of inequalities restricting $a_i$
in terms of $a_j$, $j \< i$.
These inequalities are used to construct characters with nonnegative
values (see~"PermChars").
`PermChars' either calls `Inequalities' or takes this information
from the `ineq' component of its argument record.

The number of inequalities arising in the process of diagonalization may
grow very strongly.

There are two ways to organize the projection.
The first, which is chosen if no <option> argument is present,
is the straight approach which takes the rational irreducible
characters in their original order and by this guarantees the character
with the smallest degree to be considered first.
The other way, which is chosen if the string `\"small\"' is entered as
third argument <option>, tries to keep the number of intermediate
inequalities small by eventually changing the order of characters.



\beginexample
gap> tbl:= CharacterTable( "M11" );;
gap> PermComb( tbl, rec( degree:= 110 ) );
[ Character( CharacterTable( "M11" ), [ 110, 6, 2, 2, 0, 0, 2, 2, 0, 0 ] ), 
  Character( CharacterTable( "M11" ), [ 110, 6, 2, 6, 0, 0, 0, 0, 0, 0 ] ), 
  Character( CharacterTable( "M11" ), [ 110, 14, 2, 2, 0, 2, 0, 0, 0, 0 ] ) ]
gap> # Now compute only multiplicity free permutation characters.
gap> bounds:= List( RationalizedMat( Irr( tbl ) ), x -> 1 );;
gap> PermComb( tbl, rec( degree:= 110, maxmult:= bounds ) );
[ Character( CharacterTable( "M11" ), [ 110, 6, 2, 2, 0, 0, 2, 2, 0, 0 ] ) ]
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Operations for Brauer Characters}

\>FrobeniusCharacterValue( <value>, <p> ) F

Let <value> be a cyclotomic whose coefficients over the rationals are
in the ring $\Z_{<p>}$ of <p>-local numbers,
where <p> is a prime integer.
Assume that <value> lies in $\Z_{<p>}[\zeta]$ for $\zeta = `E'(<p>^n-1)$,
for some positive integer $n$.

`FrobeniusCharacterValue' returns the image of <value> under the ring
homomorphism from $\Z_{<p>}[\zeta]$ to the field with $<p>^n$ elements
that is defined with the help of Conway polynomials
(see~"ConwayPolynomial"), more information can be found in Sections~2--5
of~\cite{JLPW95}.

If <value> is a Brauer character value in characteristic <p> then
the result can be described as the corresponding value of the Frobenius
character, that is, as the trace of a representing matrix with the given
Brauer character value.

If the result of `FrobeniusCharacterValue' cannot be expressed as an
element of a finite field in {\GAP} (see Chapter~"Finite Fields")
then `FrobeniusCharacterValue' returns `fail'.

If the Conway polynomial of degree $n$ is required for the computation
then it is computed only if `IsCheapConwayPolynomial' returns `true'
when it is called with <p> and $n$,
otherwise `fail' is returned.


\>BrauerCharacterValue( <mat> ) A

For an invertible matrix <mat> over a finite field $F$,
`BrauerCharacterValue' returns the Brauer character value of <mat>
if the order of <mat> is coprime to the characteristic of $F$,
and `fail' otherwise.

The *Brauer character value* of a matrix is the sum of complex lifts of
its eigenvalues.


\beginexample
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 ]
\endexample

\>SizeOfFieldOfDefinition( <val>, <p> ) F

For a cyclotomic or a list of cyclotomics <val>, and a prime integer <p>,
`SizeOfFieldOfDefinition' returns the size of the smallest finite field
in characteristic <p> that contains the <p>-modular reduction of <val>.

The reduction map is defined as in~\cite{JLPW95},
that is, the complex $(<p>^d-1)$-th root of unity `E'$(q^d-1)$ is mapped
to the residue class of the indeterminate, modulo the ideal spanned by
the Conway polynomial (see~"ConwayPolynomial") of degree $d$ over the
field with $p$ elements.

If <val> is a Brauer character then the value returned is the size of the
smallest finite field in characteristic <p> over which the corresponding
representation lives.


\>RealizableBrauerCharacters( <matrix>, <q> ) F

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


\beginexample
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 ] ) ]
\endexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\Section{Domains Generated by Class Functions}

{\GAP} supports groups, vector spaces, and algebras generated by class
functions.



%%eginexample
%%.
%%ndexample


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%E