Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support character_field for a vector of characters #4411

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/GAP/wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ GAP.@wrap FamilyObj(x::GAP.Obj)::GapObj
GAP.@wrap FamilyPcgs(x::GAP.Obj)::GapObj
GAP.@wrap fhmethsel(x::GapObj)::GAP.Obj
GAP.@wrap Field(x::Any)::GapObj
GAP.@wrap Flat(x::GapObj)::GapObj
GAP.@wrap FreeAbelianGroup(x::Int)::GapObj
GAP.@wrap FreeGeneratorsOfFpGroup(x::GapObj)::GapObj
GAP.@wrap FreeGroupOfFpGroup(x::GapObj)::GapObj
Expand Down
37 changes: 34 additions & 3 deletions src/Groups/group_characters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2529,11 +2529,11 @@ multiplicities_eigenvalues(chi::GAPGroupClassFunction, i::Int) = multiplicities_


function Base.:*(n::IntegerUnion, chi::GAPGroupClassFunction)
return GAPGroupClassFunction(parent(chi), n * GapObj(chi))
return GAPGroupClassFunction(parent(chi), GapObj(n) * GapObj(chi))
end

function Base.:^(chi::GAPGroupClassFunction, n::IntegerUnion)
return GAPGroupClassFunction(parent(chi), GapObj(chi) ^ n)
return GAPGroupClassFunction(parent(chi), GapObj(chi) ^ GapObj(n))
end

function Base.:^(chi::GAPGroupClassFunction, tbl::GAPGroupCharacterTable)
Expand Down Expand Up @@ -2828,6 +2828,7 @@ end

@doc raw"""
character_field(chi::GAPGroupClassFunction)
character_field(l::Vector{GAPGroupClassFunction})

If `chi` is an ordinary character then
return the pair `(F, phi)` where `F` is a number field that is generated
Expand All @@ -2839,6 +2840,10 @@ 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`.

If a nonempty vector `l` of characters is given then `(F, phi)` is returned
such that `F` is the smallest field that contains the character fields
of the entries of `l`.

# Examples
```jldoctest
julia> t = character_table("A5");
Expand All @@ -2851,6 +2856,9 @@ julia> flds_2 = map(character_field, mod(t, 2));

julia> println([degree(x[1]) for x in flds_2])
[1, 2, 2, 1]

julia> degree(character_field(collect(t))[1])
2
```
"""
function character_field(chi::GAPGroupClassFunction)
Expand All @@ -2864,8 +2872,31 @@ function character_field(chi::GAPGroupClassFunction)
return (F, identity_map(F))
end

values = GapObj(chi) # a list of GAP cyclotomics
values = GapObj(chi)::GapObj
gapfield = GAPWrap.Field(values)
return _character_field(gapfield)
end

function character_field(l::Vector{GAPGroupClassFunction})
@req length(l) > 0 "need at least one class function"
p = characteristic(l[1])
@req all(chi -> characteristic(chi) == p, l) "all entries must have the same characteristic"

if p != 0
# Brauer characters, construct a finite field
orders = [order_field_of_definition(chi) for chi in l]
exps = [is_prime_power_with_data(q)[2] for q in orders]
e = lcm(exps)
F = GF(p, e)
return (F, identity_map(F))
end

values = GapObj(l, recursive = true)::GapObj
gapfield = GAPWrap.Field(GAPWrap.Flat(values))
return _character_field(gapfield)
end

function _character_field(gapfield::GapObj)
N = GAPWrap.Conductor(gapfield)
FF, _ = abelian_closure(QQ)
if GAPWrap.IsCyclotomicField(gapfield)
Expand Down
6 changes: 6 additions & 0 deletions test/Groups/group_characters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,10 @@ end
@test tr == t[end]
@test tr == trivial_character(g)
@test !is_faithful(tr)
@test 2 * tr == tr + tr
@test ZZ(2) * tr == tr + tr
@test tr^2 == tr
@test tr^ZZ(2) == tr
re = regular_character(g)
@test coordinates(re) == degree.(t)
re = regular_character(t)
Expand Down Expand Up @@ -1052,6 +1056,7 @@ end
tbl = character_table("A5")
@test [degree(character_field(chi)[1]) for chi in tbl] == [1, 2, 2, 1, 1]
@test characteristic(character_field(tbl[1])[1]) == 0
@test degree(character_field(collect(tbl))[1]) == 2

for id in [ "C5", "A5" ] # cyclotomic and non-cyclotomic number fields
for chi in character_table(id)
Expand Down Expand Up @@ -1108,6 +1113,7 @@ end
@test [order(character_field(chi)[1]) for chi in modtbl] == [2, 4, 4, 2]
@test order_field_of_definition(Int, modtbl[1]) isa Int
@test_throws ArgumentError order_field_of_definition(ordtbl[1])
@test degree(character_field(collect(modtbl))[1]) == 2
end

@testset "Schur index" begin
Expand Down
Loading