Skip to content

Commit

Permalink
small additions concerning irrationalities
Browse files Browse the repository at this point in the history
- added `atlas_irrationality`
- added `natural_character`
- moved the `QabElem` constructions for GAP cyclotomics from `experimental/GModule.jl` to `src/GAP` (this code is apparently better than the `QabElem` method that was already available in `src/GAP/gap_to_oscar.jl`)
  • Loading branch information
ThomasBreuer authored and fingolfin committed Jan 28, 2022
1 parent be8679b commit 3488434
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 39 deletions.
13 changes: 13 additions & 0 deletions docs/oscar_references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,19 @@ @MastersThesis{Bhm99
year = {1999}
}

@Book{CCNPW85,
author = {Conway, J. H. and Curtis, R. T. and Norton, S. P. and
Parker, R. A. and Wilson, R. A.},
title = {Atlas of finite groups},
publisher = {Oxford University Press},
address = {Eynsham},
year = {1985},
pages = {xxxiv+252},
note = {Maximal subgroups and ordinary characters for simple
groups, With computational assistance from J. G. Thackray},
mrnumber = {827219 (88g:20025)}
}

@Book{CLS11,
author = {Cox, David A. and Little, John B. and Schenck, Henry K.},
title = {Toric varieties},
Expand Down
15 changes: 0 additions & 15 deletions experimental/GModule/GModule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,6 @@ import Oscar:gmodule, GAPWrap
import AbstractAlgebra: Group, Module
import Base: parent

function GAP.gap_to_julia(::Type{QabElem}, a::GAP.GapObj) #which should be a Cyclotomic
c = GAPWrap.Conductor(a)
E = abelian_closure(QQ)[2](c)
z = parent(E)(0)
co = GAP.Globals.CoeffsCyc(a, c)
for i=1:c
if !iszero(co[i])
z += fmpq(co[i])*E^(i-1)
end
end
return z
end

(::QabField)(a::GAP.GapObj) = GAP.gap_to_julia(QabElem, a)

function irreducible_modules(G::Oscar.GAPGroup)
im = GAP.Globals.IrreducibleRepresentations(G.X)
IM = GModule[]
Expand Down
30 changes: 15 additions & 15 deletions src/GAP/gap_to_oscar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -162,23 +162,23 @@ function (F::AnticNumberField)(obj::GapObj)
end

## single GAP cyclotomic to `QabElem`
function QabElem(cyc::GapInt)
GAPWrap.IsCyc(cyc) || error("cyc must be a GAP cyclotomic")
denom = GAPWrap.DenominatorCyc(cyc)
n = GAPWrap.Conductor(cyc)
coeffs = GAP.Globals.ExtRepOfObj(cyc * denom)
cycpol = GAP.Globals.CyclotomicPol(n)
dim = length(cycpol)-1
GAP.Globals.ReduceCoeffs(coeffs, cycpol)
coeffs = Vector{fmpz}(coeffs)
coeffs = coeffs[1:dim]
denom = fmpz(denom)
FF = abelian_closure(QQ)[1]
F, z = Oscar.AbelianClosure.cyclotomic_field(FF, n)
val = Nemo.elem_from_mat_row(F, Nemo.matrix(Nemo.ZZ, 1, dim, coeffs), 1, denom)
return QabElem(val, n)
function QabElem(a::GapInt)
c = GAPWrap.Conductor(a)
E = abelian_closure(QQ)[2](c)
z = parent(E)(0)
co = GAP.Globals.CoeffsCyc(a, c)
for i=1:c
if !iszero(co[i])
z += fmpq(co[i])*E^(i-1)
end
end
return z
end

GAP.gap_to_julia(::Type{QabElem}, a::GapInt) = QabElem(a)

(::QabField)(a::GAP.GapObj) = GAP.gap_to_julia(QabElem, a)

## nonempty list of GAP matrices over the same cyclotomic field
function matrices_over_cyclotomic_field(gapmats::GapObj)
GAPWrap.IsList(gapmats) || throw(ArgumentError("gapmats is not a GAP list"))
Expand Down
87 changes: 80 additions & 7 deletions src/Groups/group_characters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
# character values are elements from QabField

export
atlas_irrationality,
character_field,
character_table,
decomposition_matrix,
indicator,
induced_cyclic,
natural_character,
scalar_product,
schur_index,
trivial_character
Expand All @@ -28,6 +30,49 @@ export
conj(elm::QabElem) = elm^QabAutomorphism(-1)


#############################################################################
##
## Atlas irrationalities
##
"""
atlas_irrationality([F::AnticNumberField, ]description::String)
Return the value encoded by `description`.
If `F` is given and is a cyclotomic field that contains the value then
the result is in `F`,
if `F` is not given then the result has type `QabElem`.
`description` is assumed to have the format defined in
[CCNPW85](@cite), Chapter 6, Section 10.
```jldoctest
julia> atlas_irrationality("r5")
-2*ζ(5)^3 - 2*ζ(5)^2 - 1
julia> atlas_irrationality(CyclotomicField(5)[1], "r5")
-2*z_5^3 - 2*z_5^2 - 1
julia> atlas_irrationality("i")
ζ(4)
julia> atlas_irrationality("b7*3")
-ζ(7)^4 - ζ(7)^2 - ζ(7) - 1
julia> atlas_irrationality("3y'''24*13-2&5")
-5*ζ(24)^7 - 2*ζ(24)^5 + 2*ζ(24)^3 - 3*ζ(24)
```
"""
function atlas_irrationality(F::AnticNumberField, description::String)
return F(GAP.Globals.AtlasIrrationality(GAP.GapObj(description)))
end

function atlas_irrationality(description::String)
F = abelian_closure(QQ)[1]
return F(GAP.Globals.AtlasIrrationality(GAP.GapObj(description)))
end


#############################################################################
##
## character tables
Expand Down Expand Up @@ -555,7 +600,35 @@ end

function trivial_character(G::GAPGroup)
val = QabElem(1)
return group_class_function(G, [val for i in 1:GAP.Globals.NrConjugacyClasses(G.X)])
return group_class_function(G, [val for i in 1:Int(number_conjugacy_classes(G))])
end

@doc Markdown.doc"""
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.
"""
function natural_character(G::PermGroup)
ccl = conjugacy_classes(G)
FF = abelian_closure(QQ)[1]
n = degree(G)
vals = [FF(n - number_moved_points(representative(x))) for x in ccl]
return group_class_function(G, vals)
end

@doc Markdown.doc"""
natural_character(G::Union{MatrixGroup{fmpq}, 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 `fmpq`
or contained in a cyclotomic field.
"""
function natural_character(G::Union{MatrixGroup{fmpq}, MatrixGroup{nf_elem}})
ccl = conjugacy_classes(G)
FF = abelian_closure(QQ)[1]
vals = [FF(tr(representative(x))) for x in ccl]
return group_class_function(G, vals)
end

@doc Markdown.doc"""
Expand Down Expand Up @@ -634,12 +707,12 @@ function conj(chi::GAPGroupClassFunction)
return GAPGroupClassFunction(chi.table, GAP.Globals.ComplexConjugate(chi.values))
end

# apply a class function to a group element
# Apply a class function to a group element.
function(chi::GAPGroupClassFunction)(g::BasicGAPGroupElem)
# Identify the conjugacy class of `g`.
ccl = GAP.Globals.ConjugacyClasses(GAP.Globals.UnderlyingGroup(chi.table.GAPTable))
ccl = conjugacy_classes(chi.table.GAPGroup)
for i in 1:length(ccl)
if g.X in ccl[i]
if g in ccl[i]
return chi[i]
end
end
Expand Down Expand Up @@ -668,8 +741,8 @@ If `chi` is irreducible then `indicator(chi)` is
`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$.
"""
function indicator(chi::GAPGroupClassFunction, n::Int = 2)::Int
return GAP.Globals.Indicator(chi.table.GAPTable, GAP.GapObj([chi.values]), n)[1]
function indicator(chi::GAPGroupClassFunction, n::Int = 2)
return GAP.Globals.Indicator(chi.table.GAPTable, GAP.GapObj([chi.values]), n)[1]::Int
end

@doc Markdown.doc"""
Expand Down Expand Up @@ -810,5 +883,5 @@ function schur_index(chi::GAPGroupClassFunction, recurse::Bool = true)
end

# For the moment, we do not have more character theoretic criteria.
return
return nothing
end
7 changes: 5 additions & 2 deletions test/GAP/gap_to_oscar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,11 @@ end
@test x == fmpz(2)^64

F, z = abelian_closure(QQ)
x = QabElem(GAP.evalstr("EB(5)"))
val = GAP.evalstr("EB(5)")
x = QabElem(val)
@test x == z(5) + z(5)^4
@test F(val) == x
@test GAP.gap_to_julia(QabElem, val) == x

# not supported conversions
F, z = quadratic_field(5)
Expand All @@ -195,7 +198,7 @@ end
a = GAP.Globals.PrimitiveElement(gapF)
@test_throws ArgumentError F(a)

@test_throws ErrorException QabElem(GAP.evalstr("[ E(3) ]"))
@test_throws GAP.ConversionError QabElem(GAP.evalstr("[ E(3) ]"))
end

@testset "matrices over a cyclotomic field" begin
Expand Down
26 changes: 26 additions & 0 deletions test/Groups/group_characters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,32 @@ end
@test mod(t, 2) == nothing
end

@testset "natural characters" begin
G = symmetric_group(4)
chi = Oscar.natural_character(G)
@test degree(chi) == 4
psi = chi
@test scalar_product(chi, psi) == 2
@test scalar_product(chi, chi) == 2
@test scalar_product(chi, trivial_character(G)) == 1

K, a = CyclotomicField(5, "a")
L, b = CyclotomicField(3, "b")

inputs = [
#[ matrix(ZZ, [0 1 0; -1 0 0; 0 0 -1]) ],
[ matrix(QQ, [0 1 0; -1 0 0; 0 0 -1]) ],
[ matrix(K, [a 0; 0 a]) ],
[ matrix(L, 2, 2, [b, 0, -b - 1, 1]), matrix(L, 2, 2, [1, b + 1, 0, b]) ],
]

@testset "... over ring $(base_ring(mats[1]))" for mats in inputs
G = matrix_group(mats)
chi = Oscar.natural_character(G)
@test degree(chi) == degree(G)
end
end

@testset "character fields" begin
for id in [ "C5", "A5" ] # cyclotomic and non-cyclotomic number fields
for chi in character_table(id)
Expand Down

0 comments on commit 3488434

Please sign in to comment.