# Group characters

Let $G$ be a finite group, and let $\rho: G \to GL(n, R)$ be a group homomorphism, for some ring $R$. We call $\chi: G \to R$, defined by $\chi(g) = Trace(\rho(g))$, the character afforded by $\rho$.

Since $\chi$ is constant on conjugacy classes of $G$, it can be represented by an array $l$ of values such that the value on the $i$-th conjugacy class of $G$ (see `conjugacy_classes`

) is stored at $l[i]$. Note that this makes sense only if we assume that the ordering of conjugacy classes of $G$ is fixed once the classes have been computed.

We deal only with the cases that either $R$ can be embedded into some number field, or that $R$ is a finite field.

In the former case, the eigenvalues of the matrix $\rho(g)$, for $g \in G$, are $k$-th roots of unity, where $k$ is the order of $g$, thus all values of $\chi$ can be represented by elements in the abelian closure of the field of rational numbers, see `abelian_closure`

. The characters obtained this way are called *ordinary characters*.

In the latter case, the list of traces of $\rho(g)$ (the so-called *Frobenius character* of $\rho$) is often not so interesting; instead, one considers the *Brauer character* of $\rho$, which is defined on (conjugacy classes of) elements $g$ whose order is coprime to the characteristic of $R$ (the so-called *$p$-regular* elements resp. classes), by first lifting the eigenvalues of $\rho(g)$ to complex roots of unity and then summing up these roots; this way, one gets again a list of values in the abelian closure of the field of rationals.

The pointwise sum and product of two characters are again characters, they are afforded by the direct sum and the tensor product of the underlying representations. A character that is not the sum of two characters is called *absolutely irreducible*.

## Character tables

Putting the values of the absolutely irreducible ordinary characters of a group $G$ into an array such that the rows correspond to the characters and the columns correspond to the conjugacy classes yields the *ordinary character table* of $G$, which is in fact a square matrix. Analogously, the absolutely irreducible Brauer characters of $G$, for a given characteristic $p$, yield a square matrix, the $p$-modular *Brauer character table*.

Ordinary character tables can be computed with `character_table`

from a given group. The computation of $p$-modular Brauer tables is currently restricted to the case of $p$-solvable groups.

Character tables contain a lot of information about their groups, many questions about a finite group can be answered by computations only with its characters. Thus it makes sense to deal also with character tables *without* an explicit labeling of the columns of the table by conjugacy classes of a group. For example, the character tables shown in the Atlas of Finite Groups [CCNPW85] and from the Atlas of Brauer Characters [JLPW95] are available in OSCAR. Such character tables can be fetched with `character_table(id::String, p::Int = 0)`

from the database, via their names. Moreover, the library of character tables can be used similar to group libraries (see Group libraries) in the sense that `all_character_table_names`

returns descriptions of all those available character tables that have certain properties.

In OSCAR, a character table `t`

is identified with the array of absolutely irreducible characters of $G$, in the sense that `t[i]`

yields the `i`

-th irreducible character of $G$, and `t[i, j]`

is the value of this character on the `j`

-th conjugacy class of $G$ (or the `j`

-th conjugacy class of $p$-regular elements in the case of Brauer tables).

Ordinary and $p$-modular Brauer tables in OSCAR are distinguished by their `characteristic(tbl::GAPGroupCharacterTable)`

; its value is `0`

for ordinary tables and $p$ otherwise.

The character table to which a character `chi`

belongs can be fetched as `parent(chi)`

.

`GAPGroupCharacterTable`

— Type`GAPGroupCharacterTable <: GroupCharacterTable`

This is the type of (ordinary or Brauer) character tables that can delegate tasks to an underlying character table object in the GAP system (field `GAPTable`

).

The value of the field `characteristic`

determines whether the table is an ordinary one (value `0`

) or a `p`

-modular one (value `p`

).

A group can (but need not) be stored in the field `group`

. If it is available then also the field `isomorphism`

is available, its value is a bijective map from the `group`

value to a group in GAP.

Objects of type `GAPGroupCharacterTable`

support `get_attribute`

, for example in order to store the already computed `p`

-modular tables in an ordinary table, and to store the corresponding ordinary table in a `p`

-modular table.

`character_table`

— Method`character_table(G::GAPGroup, p::T = 0) where T <: IntegerUnion`

Return the ordinary (if `p == 0`

) or `p`

-modular character table of the finite group `G`

. If the `p`

-modular character table of `G`

cannot be computed by GAP then `nothing`

is returned.

**Examples**

```
julia> Oscar.with_unicode() do
show(stdout, MIME("text/plain"), character_table(symmetric_group(3)))
end;
Character table of permutation group of degree 3 and order 6
2 1 1 .
3 1 . 1
1a 2a 3a
2P 1a 1a 3a
3P 1a 2a 1a
χ₁ 1 -1 1
χ₂ 2 . -1
χ₃ 1 1 1
julia> Oscar.with_unicode() do
show(stdout, MIME("text/plain"), character_table(symmetric_group(3), 2))
end;
2-modular Brauer table of permutation group of degree 3 and order 6
2 1 .
3 1 1
1a 3a
2P 1a 3a
3P 1a 1a
χ₁ 1 1
χ₂ 2 -1
```

`character_table`

— Function`character_table(id::String, p::Int = 0)`

Return the ordinary (if `p == 0`

) or `p`

-modular character table for which `id`

is an admissible name in GAP's library of character tables. If no such table is available then `nothing`

is returned.

**Examples**

```
julia> println(character_table("A5"))
character table of A5
julia> println(character_table("A5", 2))
2-modular Brauer table of A5
julia> println(character_table("J5"))
nothing
```

`character_table`

— Method`character_table(series::Symbol, parameter::Any)`

Return the ordinary character table of the group described by the series `series`

and the parameter `parameter`

.

**Examples**

```
julia> println(character_table(:Symmetric, 5))
character table of Sym(5)
julia> println(character_table(:WeylB, 3))
character table of W(B3)
```

Currently the following series are supported.

Series | Parameter |
---|---|

`:Cyclic` | pos. integer |

`:Dihedral` | even pos. integer |

`:Symmetric` | pos. integer |

`:Alternating` | integer `> 1` |

`:WeylB` | pos. integer |

`:WeylD` | integer `> 1` |

`:DoubleCoverSymmetric` | pos. integer |

`:DoubleCoverAlternating` | pos. integer |

`:GL2` | prime power |

`:SL2odd` | odd prime power |

`:SL2even` | even prime power |

`:PSL2odd` | odd prime power `q` s. t. `(q-1)/2` is odd |

`:PSL2even` | odd prime power `q` s. t. `(q-1)/2` is even |

`:Suzuki` | odd power of 2 |

`:GU3` | prime power |

`:SU3` | prime power |

`Symbol("P:Q")` | vector `[p, q]` with prime `p` and `q` dividing `p-1` |

`:ExtraspecialPlusOdd` | odd power of odd prime |

`show`

— Method`Base.show(io::IO, ::MIME"text/plain", tbl::GAPGroupCharacterTable)`

Display the irreducible characters of `tbl`

and context information as a two-dimensional array.

First a

*header*is shown. If`tbl`

stores a group then the header describes this group, otherwise it is equal to the`identifier(tbl::GAPGroupCharacterTable)`

value of`tbl`

.Then the irreducible characters of

`tbl`

are shown in column portions that fit on the screen, together with*column labels*above each portion and*row labels*on the left of each portion.The column labels consist of the factored centralizer orders (see

`orders_centralizers`

, one row for each prime divisor of the group order), followed by one row showing the class names (see`class_names`

), followed by the power maps (one row for each stored power map).The row labels are

`X_1`

,`X_2`

, ... (or χ with subscripts`1`

,`2`

, ... if unicode output is allowed). If`io`

is an`IOContext`

with key`:indicator`

set to`true`

then a second column of row labels shows the 2nd Frobenius-Schur indicator of the irreducibles (see`indicator`

); analogously, setting the key`:character_field`

to`true`

yields a column showing the degrees of the character fields (see`character_field`

), and setting the key`:OD`

to`true`

yields a column showing the known orthogonal discriminants of those irreducibles that have indicator`+`

and even degree.Depending on the way how irrational character values are shown, a

*footer*may be shown in the end. By default, irrationalities are shown as sums of roots of unity, where`z_n`

(or ζ with subscript`n`

if unicode output is allowed) denotes the primitive`n`

-th root $\exp(2 \pi i/n)$. If`io`

is an`IOContext`

with key`:with_legend`

set to`true`

then irrationalities are abbreviated as`A`

,`B`

, ..., and these names together with the corresponding expression as sums of roots of unity appear in the footer.

Output in $\LaTeX$ syntax can be created by calling `show`

with second argument `MIME("text/latex")`

.

**Examples**

```
julia> tbl = character_table(:Cyclic, 3);
julia> Oscar.with_unicode() do
show(stdout, MIME("text/plain"), tbl)
end;
C3
3 1 1 1
1a 3a 3b
3P 1a 1a 1a
χ₁ 1 1 1
χ₂ 1 ζ₃ -ζ₃ - 1
χ₃ 1 -ζ₃ - 1 ζ₃
julia> Oscar.with_unicode() do
show(IOContext(stdout, :with_legend => true), MIME("text/plain"), tbl)
end;
C3
3 1 1 1
1a 3a 3b
3P 1a 1a 1a
χ₁ 1 1 1
χ₂ 1 A A̅
χ₃ 1 A̅ A
A = ζ₃
A̅ = -ζ₃ - 1
julia> Oscar.with_unicode() do
show(IOContext(stdout, :indicator => true), MIME("text/plain"), tbl)
end;
C3
3 1 1 1
1a 3a 3b
3P 1a 1a 1a
2
χ₁ + 1 1 1
χ₂ o 1 ζ₃ -ζ₃ - 1
χ₃ o 1 -ζ₃ - 1 ζ₃
julia> Oscar.with_unicode() do
show(IOContext(stdout, :character_field => true), MIME("text/plain"), tbl)
end;
C3
3 1 1 1
1a 3a 3b
2P 1a 3b 3a
3P 1a 1a 1a
d
χ₁ 1 1 1 1
χ₂ 2 1 ζ₃ -ζ₃ - 1
χ₃ 2 1 -ζ₃ - 1 ζ₃
julia> Oscar.with_unicode() do
show(IOContext(stdout, :with_legend => true), MIME("text/latex"), tbl)
end;
C3
$\begin{array}{rrrr}
3 & 1 & 1 & 1 \\
& & & \\
& 1a & 3a & 3b \\
2P & 1a & 3b & 3a \\
3P & 1a & 1a & 1a \\
& & & \\
\chi_{1} & 1 & 1 & 1 \\
\chi_{2} & 1 & A & \overline{A} \\
\chi_{3} & 1 & \overline{A} & A \\
\end{array}
\begin{array}{l}
A = \zeta_{3} \\
\overline{A} = -\zeta_{3} - 1 \\
\end{array}
$
```

`characteristic`

— Method`characteristic(::Type{T} = Int, tbl::GAPGroupCharacterTable) where T <: IntegerUnion`

Return `T(0)`

if `tbl`

is an ordinary character table, and `T(p)`

if `tbl`

is a `p`

-modular character table.

**Examples**

```
julia> tbl = character_table("A5");
julia> characteristic(tbl)
0
julia> characteristic(tbl % 2)
2
```

`mod`

— Method```
mod(tbl::GAPGroupCharacterTable, p::T) where T <: IntegerUnion
rem(tbl::GAPGroupCharacterTable, p::T) where T <: IntegerUnion
```

Return the `p`

-modular character table of `tbl`

, or `nothing`

if this table cannot be computed.

The syntax `tbl % p`

is also supported.

An exception is thrown if `tbl`

is not an ordinary character table.

**Examples**

```
julia> show(character_table("A5") % 2)
2-modular Brauer table of A5
```

`quo`

— Method`quo(tbl::GAPGroupCharacterTable, nclasses::Vector{Int})`

Return the pair `(fact, proj)`

where `fact`

is the character table of the factor of `tbl`

modulo the normal subgroup that is the normal closure of the conjugacy classes whose positions are listed in `nclasses`

, and `proj`

is the class fusion from `tbl`

to `fact`

.

**Examples**

```
julia> t = character_table("2.A5");
julia> n = class_positions_of_center(t); println(n)
[1, 2]
julia> fact, proj = quo(t, n);
julia> order(fact)
60
julia> println(proj)
[1, 1, 2, 3, 3, 4, 4, 5, 5]
```

`all_character_table_names`

— Function`all_character_table_names(L...; ordered_by = nothing)`

Return an vector of strings that contains all those names of character tables in the character table library that satisfy the conditions in the vector `L`

.

**Examples**

```
julia> spor_names = all_character_table_names(is_sporadic_simple => true,
is_duplicate_table => false);
julia> println(spor_names[1:5])
["B", "Co1", "Co2", "Co3", "F3+"]
julia> spor_names = all_character_table_names(is_sporadic_simple,
!is_duplicate_table; ordered_by = order);
julia> println(spor_names[1:5])
["M11", "M12", "J1", "M22", "J2"]
julia> length(all_character_table_names(number_conjugacy_classes => 1))
1
```

## Attributes of group characters

`character_field`

— Function`character_field(chi::GAPGroupClassFunction)`

If `chi`

is an ordinary character then return the pair `(F, phi)`

where `F`

is a number field that is generated by the character values of `chi`

, and `phi`

is the embedding of `F`

into `abelian_closure(QQ)`

.

If `chi`

is a Brauer character in characteristic `p`

then return the pair `(F, phi)`

where `F`

is the finite field that is generated by the `p`

-modular reductions of the values of `chi`

, and `phi`

is the identity map on `F`

.

**Examples**

```
julia> t = character_table("A5");
julia> character_field(t[2])[1]
Number field with defining polynomial x^2 + x - 1
over rational field
julia> flds_2 = map(character_field, mod(t, 2));
julia> println([degree(x[1]) for x in flds_2])
[1, 2, 2, 1]
```

`conj`

— Method`conj(chi::GAPGroupClassFunction)`

Return the class function whose values are the complex conjugates of the values of `chi`

.

**Examples**

```
julia> tbl = character_table(alternating_group(4));
julia> println([findfirst(y -> y == conj(x), tbl) for x in tbl])
[1, 3, 2, 4]
```

`degree`

— Method```
degree(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction)
where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem}
```

Return `chi[1]`

, as an instance of `T`

.

`indicator`

— Function`indicator(chi::GAPGroupClassFunction, n::Int = 2)`

Return the `n`

-th Frobenius-Schur indicator of `chi`

, that is, the value $(∑_{g ∈ G} chi(g^n))/|G|$, where $G$ is the group of `chi`

.

If `chi`

is irreducible then `indicator(chi)`

is `0`

if `chi`

is not real-valued, `1`

if `chi`

is afforded by a real representation of $G$, and `-1`

if `chi`

is real-valued but not afforded by a real representation of $G$.

**Examples**

```
julia> tbl = character_table("U3(3)");
julia> println([indicator(chi) for chi in tbl])
[1, -1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0]
```

`is_faithful`

— Method`is_faithful(chi::GAPGroupClassFunction)`

Return `true`

if the value of `chi`

at the identity element does not occur as value of `chi`

at any other element, and `false`

otherwise.

If `chi`

is an ordinary character then `true`

is returned if and only if the representations affording `chi`

have trivial kernel.

**Examples**

```
julia> println(map(is_faithful, character_table(symmetric_group(3))))
Bool[0, 1, 0]
```

`is_rational`

— Method`is_rational(chi::GAPGroupClassFunction)`

Return `true`

if all values of `chi`

are rational, i.e., in `QQ`

, and `false`

otherwise.

**Examples**

```
julia> all(is_rational, character_table(symmetric_group(4)))
true
julia> all(is_rational, character_table(alternating_group(4)))
false
```

`is_irreducible`

— Method`is_irreducible(chi::GAPGroupClassFunction)`

Return `true`

if `chi`

is an irreducible character, and `false`

otherwise.

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 `scalar_product`

. For Brauer characters there is no generic method for checking irreducibility.

**Examples**

```
julia> g = symmetric_group(4);
julia> all(is_irreducible, character_table(g))
true
julia> is_irreducible(natural_character(g))
false
```

`schur_index`

— Function`schur_index(chi::GAPGroupClassFunction) -> Int`

For an ordinary irreducible character `chi`

, return the minimal integer `m`

such that the character `m * chi`

is afforded by a representation over the character field of `chi`

, or throw an exception if the currently used character theoretic criteria do not suffice for computing `m`

.

**Examples**

```
julia> t = character_table(quaternion_group(8));
julia> println(map(schur_index, t))
[1, 1, 1, 1, 2]
```

`det`

— Method`det(chi::GAPGroupClassFunction)`

Return 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`

.

**Examples**

```
julia> t = character_table(symmetric_group(4));
julia> all(chi -> det(chi) == exterior_power(chi, Int(degree(chi))), t)
true
```

`order`

— Method```
order(::Type{T} = ZZRingElem, chi::GAPGroupClassFunction)
where T <: IntegerUnion
```

Return the determinantal order of the character `chi`

. This is defined to be the multiplicative order of `det(chi)`

.

**Examples**

```
julia> println([order(chi) for chi in character_table(symmetric_group(4))])
ZZRingElem[2, 1, 2, 2, 1]
```

`order_field_of_definition`

— Method`order_field_of_definition(::Type{T} = ZZRingElem, chi::GAPGroupClassFunction) where T <: IntegerUnion`

Return $p^n$, as an instance of `T`

, if `chi`

is a $p$-modular Brauer character such that the $p$-modular reductions of the values of `chi`

span the field with $p^n$ elements.

Note that one need not compute the `character_field`

value of `chi`

in order to compute `order_field_of_definition(chi)`

.

**Examples**

```
julia> tbl = character_table("A5", 2);
julia> println([order_field_of_definition(chi) for chi in tbl])
ZZRingElem[2, 4, 4, 2]
```

## Attributes of character tables

`character_parameters`

— Function`character_parameters(tbl::GAPGroupCharacterTable)`

Return a vector of character parameters for the rows of `tbl`

if such parameters are stored, and `nothing`

otherwise.

**Examples**

```
julia> character_parameters(character_table("S5"))
7-element Vector{Vector{Int64}}:
[5]
[1, 1, 1, 1, 1]
[3, 1, 1]
[4, 1]
[2, 1, 1, 1]
[3, 2]
[2, 2, 1]
julia> character_parameters(character_table("M11"))
```

`class_names`

— Method`class_names(tbl::GAPGroupCharacterTable)`

Return a vector of strings corresponding to the columns of `tbl`

. The $i$-th entry consists of the element order for the $i$-th column, followed by at least one distinguishing letter. For example, the classes of elements of order two have class names `"2a", "2b", and so on.

**Examples**

```
julia> println(class_names(character_table("S5")))
["1a", "2a", "3a", "5a", "2b", "4a", "6a"]
```

`class_parameters`

— Function`class_parameters(tbl::GAPGroupCharacterTable)`

Return a vector of class parameters for the columns of `tbl`

if such parameters are stored, and `nothing`

otherwise.

**Examples**

```
julia> class_parameters(character_table("S5"))
7-element Vector{Vector{Int64}}:
[1, 1, 1, 1, 1]
[2, 2, 1]
[3, 1, 1]
[5]
[2, 1, 1, 1]
[4, 1]
[3, 2]
julia> class_parameters(character_table("M11"))
```

`conjugacy_classes`

— Method`conjugacy_classes(tbl::GAPGroupCharacterTable)`

Return the vector of conjugacy classes of `group(tbl)`

, ordered such that they correspond to the columns of `tbl`

and to the `GAPWrap.ConjugacyClasses`

value of the underlying GAP character table. Note that the vector `conjugacy_classes(group(tbl))`

can be independent of the vector of conjugacy classes stored in the group of the underlying GAP character table.

An error is thrown if `tbl`

does not store a group.

**Examples**

```
julia> g = symmetric_group(4); tbl = character_table(g);
julia> [length(c) for c in conjugacy_classes(tbl)] == class_lengths(tbl)
true
```

`decomposition_matrix`

— Function`decomposition_matrix(modtbl::GAPGroupCharacterTable)`

Return the decomposition matrix (of type `ZZMatrix`

) of the Brauer character table `modtbl`

. The rows and columns are indexed by the irreducible characters of the ordinary character table of `modtbl`

and the irreducible characters of `modtbl`

, respectively,

**Examples**

```
julia> t = character_table("A5"); t2 = mod(t, 2);
julia> decomposition_matrix(t2)
[1 0 0 0]
[1 0 1 0]
[1 1 0 0]
[0 0 0 1]
[1 1 1 0]
```

`identifier`

— Function`identifier(tbl::GAPGroupCharacterTable)`

Return a string that identifies `tbl`

. It is used mainly for library tables.

**Examples**

```
julia> identifier(character_table("A5"))
"A5"
```

`induced_cyclic`

— Method`induced_cyclic(tbl::GAPGroupCharacterTable)`

Return the vector of permutation characters of `tbl`

that are induced from cyclic subgroups.

`is_duplicate_table`

— Function`is_duplicate_table(tbl::GAPGroupCharacterTable)`

Return whether `tbl`

is an ordinary table from the character table library that was constructed from another library character table by permuting rows and columns.

One application of this function is to restrict the search with `all_character_table_names`

to only one library character table for each class of permutation equivalent tables.

**Examples**

```
julia> is_duplicate_table(character_table("A5"))
false
julia> is_duplicate_table(character_table("A6M2"))
true
```

`maxes`

— Function`maxes(tbl::GAPGroupCharacterTable)`

Return either nothing (if the value is not known) or a vector of identifiers of the ordinary character tables of all maximal subgroups of `tbl`

. There is no default method to compute this value from `tbl`

.

If the `maxes`

value of `tbl`

is stored then it lists exactly one representative for each conjugacy class of maximal subgroups of the group of `tbl`

, and the character tables of these maximal subgroups are available in the character table library, and compatible class fusions to `tbl`

are stored on these tables.

**Examples**

```
julia> println(maxes(character_table("M11")))
["A6.2_3", "L2(11)", "3^2:Q8.2", "A5.2", "2.S4"]
julia> maxes(character_table("M")) === nothing # not (yet) known
true
```

`names_of_fusion_sources`

— Function`names_of_fusion_sources(tbl::GAPGroupCharacterTable)`

Return the vector of strings that are identifiers of those character tables which store a class fusion to `tbl`

, which must be an ordinary character table.

**Examples**

```
julia> tbl = character_table("A5");
julia> println(maxes(tbl))
["a4", "D10", "S3"]
julia> all(x -> x in names_of_fusion_sources(tbl), maxes(tbl))
true
```

`class_lengths`

— Function`class_lengths(tbl::GAPGroupCharacterTable)`

**Examples**

```
julia> println(class_lengths(character_table("A5")))
ZZRingElem[1, 15, 20, 12, 12]
```

`orders_centralizers`

— Function`orders_centralizers(tbl::GAPGroupCharacterTable)`

Return the vector of the orders of centralizers of conjugacy class representatives for `tbl`

in the group of `tbl`

, ordered according to the columns of `tbl`

.

**Examples**

```
julia> println(orders_centralizers(character_table("A5")))
ZZRingElem[60, 4, 3, 5, 5]
```

`orders_class_representatives`

— Function`orders_class_representatives(tbl::GAPGroupCharacterTable)`

Return the vector of the orders of conjugacy class representatives for `tbl`

, ordered according to the columns of `tbl`

.

**Examples**

```
julia> println(orders_class_representatives(character_table("A5")))
[1, 2, 3, 5, 5]
```

`ordinary_table`

— Method`ordinary_table(tbl::GAPGroupCharacterTable)`

Return the ordinary character table of `tbl`

, provided that `tbl`

is a Brauer character table.

**Examples**

```
julia> tbl = character_table("A5");
julia> ordinary_table(tbl % 2) === tbl
true
```

`trivial_character`

— Method`trivial_character(tbl::GAPGroupCharacterTable)`

Return the character of `tbl`

that has the value `QQAbElem(1)`

in each position.

**Examples**

```
julia> t = character_table(symmetric_group(4));
julia> all(x -> x == 1, trivial_character(t))
true
```

## Construct group characters from groups

`natural_character`

— Method`natural_character(G::PermGroup)`

Return the permutation character of degree `degree(G)`

that maps each element of `G`

to the number of its fixed points.

**Examples**

```
julia> g = symmetric_group(4);
julia> degree(natural_character(g))
4
julia> degree(natural_character(stabilizer(g, 4)[1]))
4
```

`natural_character`

— Method`natural_character(G::Union{MatrixGroup{QQFieldElem}, MatrixGroup{nf_elem}})`

Return the character that maps each element of `G`

to its trace. We assume that the entries of the elements of `G`

are either of type `QQFieldElem`

or contained in a cyclotomic field.

**Examples**

```
julia> g = matrix_group(matrix(ZZ, [0 1; 1 0]));
julia> println(values(natural_character(g)))
QQAbElem{nf_elem}[2, 0]
```

`natural_character(G::MatrixGroup{FinFieldElem})`

Return the character that maps each $p$-regular element of `G`

, where $p$ is the characteristic of the base field of `G`

, to its Brauer character value.

**Examples**

```
julia> g = general_linear_group(2, 2);
julia> println(values(natural_character(g)))
QQAbElem{nf_elem}[2, -1]
```

`natural_character`

— Method`natural_character(G::MatrixGroup{FinFieldElem})`

Return the character that maps each $p$-regular element of `G`

, where $p$ is the characteristic of the base field of `G`

, to its Brauer character value.

**Examples**

```
julia> g = general_linear_group(2, 2);
julia> println(values(natural_character(g)))
QQAbElem{nf_elem}[2, -1]
```

`natural_character`

— Method`natural_character(rho::GAPGroupHomomorphism)`

Return the character of `domain(rho)`

that is afforded by the representation `rho`

, where `codomain(rho)`

must be a permutation group or a matrix group. In the latter case, an ordinary character is returned if the characteristic of the base field is zero, and a $p$-modular Brauer character is returned if the characteristic is $p > 0$.

**Examples**

```
julia> g = symmetric_group(3); h = general_linear_group(2, 2);
julia> mp = hom(g, h, [g([2,1]), g([1, 3, 2])], gens(h));
julia> println(values(natural_character(mp)))
QQAbElem{nf_elem}[2, -1]
```

`trivial_character`

— Method`trivial_character(G::GAPGroup)`

Return the character of (the ordinary character table of) `G`

that has the value `QQAbElem(1)`

in each position.

**Examples**

```
julia> g = symmetric_group(4);
julia> all(x -> x == 1, trivial_character(g))
true
```

## Operations for group characters

length and iteration:

The length of a class function is the number of conjugacy classes of its group, iteration is defined w.r.t. the ordering of conjugacy classes.

arithmetic operations:

`chi == psi`

: two class functions are equal if and only if they belong to the same character table and have the same values,`chi + psi`

and`chi - psi`

are the pointwise sum and difference, respectively, of the two class functions`chi`

,`psi`

,`n*chi`

is the pointwise`n`

-fold sum of`chi`

, for an integer`n`

,`chi*psi`

is the pointwise (tensor) product of`chi`

and`psi`

,`zero(chi)`

is the class function that is zero on all classes,`one(chi)`

is the trivial character of the character table of`chi`

,`chi^n`

is the`n`

-th tensor power of`chi`

, for positive integers`n`

,`chi(g)`

is the value of`chi`

at the element`g`

of the group of`chi`

,`chi^g`

is the conjugate character of`chi`

under the action of a group element`g`

that normalizes the group $G$ of`chi`

; we have`chi^g(x) == chi(g*x*g^-1)`

for all`x`

in $G$,`chi^galaut`

is the Galois conjugate character of`chi`

under the pointwise action of the field automorphism`galaut`

(If`galaut`

was created as`QQAbAutomorphism(k)`

then the action raises each root of unity to its`k`

-th power; this action defines a field automorphism of the`n`

-th cyclotomic field whenever`n`

and`k`

are coprime.)`chi^tbl`

is the character of the character table`tbl`

that is induced from`chi`

, where the group of`chi`

is a subgroup of the group of`tbl`

.

`scalar_product`

— Function```
scalar_product(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction, psi::GAPGroupClassFunction)
where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem}
```

Return $\sum_{g \in G}$ `chi`

($g$) `conj(psi)`

($g$) / $|G|$, where $G$ is the group of both `chi`

and `psi`

. The result is an instance of `T`

.

Note that we do not support `dot(chi, psi)`

and its infix notation because the documentation of `dot`

states that the result is equal to the sum of `dot`

results of corresponding entries, which does not hold for the scalar product of characters.

`coordinates`

— Method```
coordinates(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction)
where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem}
```

Return the vector $[a_1, a_2, \ldots, a_n]$ of scalar products (see `scalar_product`

) of `chi`

with the irreducible characters $[t[1], t[2], \ldots, t[n]]$ of the character table $t$ of `chi`

, that is, `chi`

is equal to $\sum_{i==1}^n a_i t[i]$. The result is an instance of `Vector{T}`

.

**Examples**

```
julia> g = symmetric_group(4)
Permutation group of degree 4 and order 24
julia> chi = natural_character(g);
julia> coordinates(Int, chi)
5-element Vector{Int64}:
0
0
0
1
1
julia> t = parent(chi); t3 = mod(t, 3); chi3 = restrict(chi, t3);
julia> coordinates(Int, chi3)
4-element Vector{Int64}:
0
1
0
1
```

`multiplicities_eigenvalues`

— Function`multiplicities_eigenvalues(::Type{T} = Int, chi::GAPGroupClassFunction, i::Int) where T <: IntegerUnion`

Let $M$ be a representing matrix of an element in the `i`

-th conjugacy class of the character table of `chi`

, in a representation affording the character `chi`

, and let $n$ be the order of the elements in this conjugacy class.

Return the vector $(m_1, m_2, \ldots, m_n)$ of integers of type `T`

such that $m_j$ is the multiplicity of $\zeta_n^j$ as an eigenvalue of $M$.

**Examples**

```
julia> t = character_table("A5"); chi = t[4];
julia> println(values(chi))
QQAbElem{nf_elem}[4, 0, 1, -1, -1]
julia> println(multiplicities_eigenvalues(chi, 5))
[1, 1, 1, 1, 0]
```

`induce`

— Method`induce(chi::GAPGroupClassFunction, tbl::GAPGroupCharacterTable[, fusion::Vector{Int}])`

Return the class function of `tbl`

that is induced from `chi`

, which is a class function of a subgroup of the group of `tbl`

. The default for the class fusion `fus`

is given either by the fusion of the conjugacy classes of the two character tables (if groups are stored in the tables) or by the class fusion given by `known_class_fusion`

for the two tables.

**Examples**

```
julia> s = character_table("A5"); t = character_table("A6");
julia> maps = possible_class_fusions(s, t); length(maps)
4
julia> chi = trivial_character(s);
julia> ind = [induce(chi, t, x) for x in maps];
julia> length(Set(ind))
2
```

`restrict`

— Method`restrict(chi::GAPGroupClassFunction, subtbl::GAPGroupCharacterTable[, fusion::Vector{Int}])`

Return the class function of `subtbl`

that is the restriction of `chi`

, which is a class function of a supergroup of the group of `subtbl`

. The default for the class fusion `fus`

is given either by the fusion of the conjugacy classes of the two character tables (if groups are stored in the tables) or by the class fusion given by `known_class_fusion`

for the two tables.

**Examples**

```
julia> s = character_table("A5"); t = character_table("A6");
julia> maps = possible_class_fusions(s, t); length(maps)
4
julia> chi = t[2]; rest = [restrict(chi, s, x) for x in maps];
julia> length(Set(rest))
2
```

## Symmetrizations of group characters

`symmetrizations`

— Method`symmetrizations(characters::Vector{GAPGroupClassFunction}, n::Int)`

Return the vector of symmetrizations of `characters`

with the ordinary irreducible characters of the symmetric group of degree `n`

.

The symmetrization $\chi^{[\lambda]}$ of the character $\chi$ with the character $\lambda$ of the symmetric group $S_n$ of degree `n`

is defined by

\[\chi^{[\lambda]}(g) = (\sum_{\rho\in S_n} \lambda(\rho) \prod_{k=1}^n \chi(g^k)^{a_k(\rho)} ) / n!,\]

where $a_k(\rho)$ is the number of cycles of length $k$ in $\rho$.

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

For special kinds of symmetrizations, see `symmetric_parts`

, `anti_symmetric_parts`

, `orthogonal_components`

, `symplectic_components`

, `exterior_power`

, `symmetric_power`

.

`symmetric_parts`

— Method`symmetric_parts(characters::Vector{GAPGroupClassFunction}, n::Int)`

Return the vector of symmetrizations of `characters`

with the trivial character of the symmetric group of degree `n`

, see `symmetrizations`

.

`anti_symmetric_parts`

— Method`anti_symmetric_parts(characters::Vector{GAPGroupClassFunction}, n::Int)`

Return the vector of symmetrizations of `characters`

with the sign character of the symmetric group of degree `n`

, see `symmetrizations`

.

`exterior_power`

— Method`exterior_power(chi::GAPGroupClassFunction, n::Int)`

Return the class function of the `n`

-th exterior power of the module that is afforded by `chi`

.

This exterior power is the symmetrization of `chi`

with the sign character of the symmetric group of degree `n`

, see also `symmetrizations`

and `anti_symmetric_parts`

.

`symmetric_power`

— Method`symmetric_power(chi::GAPGroupClassFunction, n::Int)`

Return the class function of the `n`

-th symmetric power of the module that is afforded by `chi`

.

This symmetric power is the symmetrization of `chi`

with the trivial character of the symmetric group of degree `n`

, see also `symmetrizations`

and `symmetric_parts`

.

`orthogonal_components`

— Method`orthogonal_components(characters::Vector{GAPGroupClassFunction}, n::Int)`

Return the vector of the so-called Murnaghan components of the $m$-th tensor powers of the entries of `characters`

, for $m$ up to `n`

, where `n`

must be at least 2 and at most 6 and where we assume that the entries of `characters`

are irreducible characters with Frobenius-Schur indicator +1, see `indicator`

.

`symplectic_components`

— Method`symplectic_components(characters::Vector{GAPGroupClassFunction}, n::Int)`

Return the vector of the Murnaghan components of the $m$-th tensor powers of the entries of `characters`

, for $m$ up to `n`

, where `n`

must be at least 2 and at most 6 and where we assume that the entries of `characters`

are irreducible characters with Frobenius-Schur indicator -1, see `indicator`

.

## Operations for character tables

`class_multiplication_coefficient`

— Function`class_multiplication_coefficient(::Type{T} = ZZRingElem, tbl::GAPGroupCharacterTable, i::Int, j::Int, k::Int) where T <: IntegerUnion`

Return the class multiplication coefficient of the classes `i`

, `j`

, and `k`

of the group $G$ with ordinary character table `tbl`

, as an instance of `T`

.

The class multiplication coefficient $c_{i,j,k}$ of the classes $i, j, k$ equals the number of pairs $(x, y)$ of elements $x, y \in G$ such that $x$ lies in class $i$, $y$ lies in class $j$, and their product $xy$ is a fixed element of class $k$.

In the center of the group algebra of $G$, these numbers are found as coefficients of the decomposition of the product of two class sums $K_i$ and $K_j$ into class sums:

\[K_i K_j = \sum_k c_{ijk} K_k.\]

Given the character table of a finite group $G$, whose classes are $C_1, \ldots, C_r$ with representatives $g_i \in C_i$, the class multiplication coefficient $c_{ijk}$ can be computed with the following formula:

\[ c_{ijk} = |C_i| |C_j| / |G| \sum_{\chi \in Irr(G)} \chi(g_i) \chi(g_j) \chi(g_k^{-1}) / \chi(1).\]

On the other hand the knowledge of the class multiplication coefficients admits the computation of the irreducible characters of $G$.

**Examples**

```
julia> class_multiplication_coefficient(character_table("A5"), 2, 3, 4)
5
julia> class_multiplication_coefficient(character_table("A5"), 2, 4, 4)
0
```

`known_class_fusion`

— Function`known_class_fusion(tbl1::GAPGroupCharacterTable, tbl2::GAPGroupCharacterTable)`

Return `(flag, fus)`

where `flag == true`

if a class fusion to `tbl2`

is stored on `tbl1`

, and `flag == false`

otherwise.

In the former case, `fus`

is the vector of integers, of length `ncols(tbl1)`

, such that the $i$-th conjugacy class of `tbl1`

corresponds to the `fus`

[$i$]-th conjugacy class of `tbl2`

, in the following sense.

If the group of `tbl1`

is a *subgroup* of the group of `tbl2`

then the $i$-th conjugacy class of `tbl1`

is contained in the `fus`

[$i$]-th conjugacy class of `tbl2`

. If the group of `tbl2`

is a *factor group* of the group of `tbl1`

then the image of the $i$-th conjugacy class `tbl1`

under the relevant epimorphism is the `fus`

[$i$]-th conjugacy class of `tbl2`

.

`order`

— Method`order(::Type{T} = ZZRingElem, tbl::GAPGroupCharacterTable) where T <: IntegerUnion`

Return the order of the group for which `tbl`

is the character table, as an instance of `T`

.

**Examples**

```
julia> order(character_table(symmetric_group(4)))
24
```

`possible_class_fusions`

— Function```
possible_class_fusions(subtbl::GAPGroupCharacterTable,
tbl::GAPGroupCharacterTable;
decompose::Bool = true,
fusionmap::Vector = [])
```

Return the vector of possible class fusions from `subtbl`

to `tbl`

. Each entry is an vector of positive integers, where the value at position `i`

is the position of the conjugacy class in `tbl`

that contains the `i`

-th class of `subtbl`

.

If `decompose`

is set to `true`

then the strategy is changed: The decomposability of restricted characters of `tbl`

as integral linear combinations of characters of `subtbl`

(with perhaps negative coefficients) is not checked; this does not change the result, but in certain situations it is faster to omit this step.

If `fusionmap`

is set to a vector of integers and integer vectors then only those maps are returned that are compatible with the prescribed value.

**Examples**

```
julia> possible_class_fusions(character_table("A5"), character_table("A6"))
4-element Vector{Vector{Int64}}:
[1, 2, 3, 6, 7]
[1, 2, 3, 7, 6]
[1, 2, 4, 6, 7]
[1, 2, 4, 7, 6]
```

`approximate_class_fusion`

— Function```
approximate_class_fusion(subtbl::GAPGroupCharacterTable,
tbl::GAPGroupCharacterTable)
```

Compute for each class of `subtbl`

all those classes in `tbl`

to which it can fuse under an embedding of the group of `subtbl`

into the group of `tbl`

, according to element orders and centralizer orders in the two tables.

If no embedding is possible then return an empty vector. Otherwise return a vector of length equal to the number of classes of `subtbl`

, such that the entry at position $i$ either an integer (if there is a unique possible image class) or the vector of the positions of possible image classes.

**Examples**

```
julia> subtbl = character_table("A5"); tbl = character_table("A6");
julia> println(approximate_class_fusion(subtbl, tbl))
Union{Int64, Vector{Int64}}[1, 2, [3, 4], [6, 7], [6, 7]]
```

## Character tables and normal subgroups

Normal subgroups of a group $G$ are unions of conjugacy classes of elements of $G$. Thus one can often turn questions about a normal subgroup $N$ of $G$ into questions about the array of those positions in the list of conjugacy classes of $G$ that contain the elements of $N$.

`center`

— Method`center(chi::GAPGroupClassFunction)`

Return `C, f`

where `C`

is the center of `chi`

(i.e. the largest normal subgroup of the underlying group `G`

of `chi`

such that `chi`

maps each element of `C`

to `chi[1]`

times a root of unity) and `f`

is the embedding morphism of `C`

into `G`

.

**Examples**

```
julia> t = character_table(symmetric_group(4));
julia> chi = t[3]; chi[1]
2
julia> C, f = center(chi); order(C)
4
```

`class_positions_of_center`

— Method`class_positions_of_center(tbl::GAPGroupCharacterTable)`

Return the vector of integers $i$ such that the $i$-th conjugacy class of `tbl`

is contained in the center of the group $G$ of `tbl`

, i.e., the $i$-th class has length `1`

.

**Examples**

```
julia> tbl = character_table(dihedral_group(8));
julia> println(class_positions_of_center(tbl))
[1, 4]
```

`class_positions_of_center`

— Method`class_positions_of_center(chi::GAPGroupClassFunction)`

Return the vector of those integers `i`

such that `chi[i]`

is `chi[1]`

times a root of unity.

**Examples**

```
julia> println(class_positions_of_center(character_table("2.A5")[2]))
[1, 2]
```

`class_positions_of_derived_subgroup`

— Function`class_positions_of_derived_subgroup(tbl::GAPGroupCharacterTable)`

Return the vector of integers $i$ such that the $i$-th conjugacy class of `tbl`

is contained in the derived subgroup of the group $G$ of `tbl`

.

**Examples**

```
julia> tbl = character_table(dihedral_group(8));
julia> println(class_positions_of_derived_subgroup(tbl))
[1, 4]
```

`kernel`

— Method`kernel(chi::GAPGroupClassFunction)`

Return `C, f`

where `C`

is the kernel of `chi`

(i.e. the largest normal subgroup of the underlying group `G`

of `chi`

such that `chi`

maps each element of `C`

to `chi[1]`

) and `f`

is the embedding morphism of `C`

into `G`

.

**Examples**

```
julia> t = character_table(symmetric_group(4));
julia> chi = t[3]; chi[1]
2
julia> C, f = kernel(chi); order(C)
4
```

`class_positions_of_kernel`

— Function`class_positions_of_kernel(chi::GAPGroupClassFunction)`

Return the vector of those integers `i`

such that `chi[i] == chi[1]`

holds.

**Examples**

```
julia> println(class_positions_of_kernel(character_table("2.A5")[2]))
[1, 2]
```

`class_positions_of_normal_subgroups`

— Function`class_positions_of_normal_subgroups(tbl::GAPGroupCharacterTable)`

Return a vector whose entries describe all normal subgroups of the group of `tbl`

. Each entry is a vector of those class positions such that the union of these classes forms a normal subgroup.

**Examples**

```
julia> t = character_table("2.A5");
julia> class_positions_of_normal_subgroups(t)
3-element Vector{Vector{Int64}}:
[1]
[1, 2]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
```

`pcore`

— Method`pcore(tbl::GAPGroupCharacterTable, p::IntegerUnion)`

Return the `p`

-core of the group of `tbl`

, see `pcore(G::GAPGroup, p::IntegerUnion)`

, but computed character-theoretically (see `class_positions_of_pcore`

).

**Examples**

```
julia> order(pcore(character_table(symmetric_group(4)), 2)[1])
4
```

`class_positions_of_pcore`

— Function`class_positions_of_pcore(tbl::GAPGroupCharacterTable, p::IntegerUnion)`

Return the vector of integers $i$ such that the $i$-th conjugacy class of `tbl`

is contained in the `p`

-core of the group of `tbl`

, see `pcore(G::GAPGroup, p::IntegerUnion)`

.

**Examples**

```
julia> println(class_positions_of_pcore(character_table("2.A5"), 2))
[1, 2]
```

`class_positions_of_solvable_residuum`

— Function`class_positions_of_solvable_residuum(tbl::GAPGroupCharacterTable)`

Return the vector of integers $i$ such that the $i$-th conjugacy class of `tbl`

is contained in the solvable residuum of the group $G$ of `tbl`

, i.e., the smallest normal subgroup $N$ of $G$ such that the factor group $G/N$ is solvable. This normal subgroup is equal to the last term of the derived series of $G$, see `derived_series`

.

**Examples**

```
julia> tbl = character_table(symmetric_group(4));
julia> println(class_positions_of_solvable_residuum(tbl))
[1]
```