Skip to content

Commit

Permalink
small additions, mainly about class fusions (#2737)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasBreuer authored Aug 28, 2023
1 parent 2f44b42 commit af9f02a
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 10 deletions.
1 change: 1 addition & 0 deletions docs/src/Groups/group_characters.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ class_multiplication_coefficient
known_class_fusion
order(tbl::GAPGroupCharacterTable)
possible_class_fusions
approximate_class_fusion
```

## Character tables and normal subgroups
Expand Down
2 changes: 2 additions & 0 deletions docs/src/NumberTheory/abelian_closure.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Given the abelian closure, the generator can be recovered as follows:

```@docs
gen(::QQAbField)
atlas_irrationality
atlas_description
```

## Printing
Expand Down
1 change: 1 addition & 0 deletions src/GAP/wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ GAP.@wrap Image(x::Any, y::Any)::GapObj
GAP.@wrap Image(x::Any)::GapObj
GAP.@wrap ImmutableMatrix(x::GapObj, y::GapObj, z::Bool)::GapObj
GAP.@wrap IndependentGeneratorExponents(x::Any, y::Any)::GapObj
GAP.@wrap InitFusion(x::GapObj, y::GapObj)::GapObj
GAP.@wrap Indeterminate(x::GapObj)::GapObj
GAP.@wrap Indeterminate(x::GapObj, y::GAP.Obj)::GapObj
GAP.@wrap IndeterminateNumberOfUnivariateRationalFunction(x::GapObj)::Int
Expand Down
85 changes: 81 additions & 4 deletions src/Groups/group_characters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
##
## Atlas irrationalities
##
"""
@doc raw"""
atlas_irrationality([F::AnticNumberField, ]description::String)
Return the value encoded by `description`.
Expand All @@ -30,6 +30,7 @@ if `F` is not given then the result has type `QQAbElem`.
`description` is assumed to have the format defined in
[CCNPW85](@cite), Chapter 6, Section 10.
# Examples
```jldoctest
julia> Oscar.with_unicode() do
show(atlas_irrationality("r5"))
Expand Down Expand Up @@ -65,6 +66,34 @@ function atlas_irrationality(description::String)
end


@doc raw"""
atlas_description(val::QQAbElem)
Return a string in the format defined in
[CCNPW85](@cite), Chapter 6, Section 10,
describing `val`.
Applying [`atlas_irrationality`](@ref) to the result yields `val`.
# Examples
```jldoctest
julia> K, z = abelian_closure(QQ);
julia> val = z(5) + z(5)^4;
julia> str = Oscar.atlas_description(val)
"b5"
julia> val == atlas_irrationality(str)
true
```
"""
function atlas_description(val::QQAbElem)
iso = Oscar.iso_oscar_gap(parent(val))
val = iso(val)
return string(GAP.Globals.CTblLib.StringOfAtlasIrrationality(val))
end


#############################################################################
##
## character tables
Expand Down Expand Up @@ -1264,10 +1293,50 @@ end

class_multiplication_coefficient(tbl::GAPGroupCharacterTable, i::Int, j::Int, k::Int) = class_multiplication_coefficient(ZZRingElem, tbl, i, j, k)

@doc raw"""
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
```jldoctest
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]]
```
"""
function approximate_class_fusion(subtbl::GAPGroupCharacterTable,
tbl::GAPGroupCharacterTable)
fus = GAPWrap.InitFusion(GAPTable(subtbl), GAPTable(tbl))
res = Union{Int, Vector{Int}}[]
fus == GAP.Globals.fail && return res
for i in 1:length(fus)
if fus[i] isa Int
push!(res, fus[i])
else
push!(res, Vector{Int}(fus[i]))
end
end
return res
end


@doc raw"""
possible_class_fusions(subtbl::GAPGroupCharacterTable,
tbl::GAPGroupCharacterTable;
decompose::Bool = true)
decompose::Bool = true,
fusionmap::Vector = [])
Return the array of possible class fusions from `subtbl` to `tbl`.
Each entry is an array of positive integers, where the value at position `i`
Expand All @@ -1281,6 +1350,9 @@ 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
```jldoctest
julia> possible_class_fusions(character_table("A5"), character_table("A6"))
Expand All @@ -1293,9 +1365,14 @@ julia> possible_class_fusions(character_table("A5"), character_table("A6"))
"""
function possible_class_fusions(subtbl::GAPGroupCharacterTable,
tbl::GAPGroupCharacterTable;
decompose::Bool = true)
decompose::Bool = true,
fusionmap::Vector = [])
cond = Dict{Symbol, Any}(:decompose => decompose)
if length(fusionmap) != 0
cond[:fusionmap] = GapObj(fusionmap, recursive = true)
end
fus = GAPWrap.PossibleClassFusions(GAPTable(subtbl), GAPTable(tbl),
GapObj(Dict(:decompose => decompose)))
GapObj(cond))
return [Vector{Int}(x::GapObj) for x in fus]
end

Expand Down
12 changes: 6 additions & 6 deletions src/Groups/libraries/libraries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ end
function __init_group_libraries()
props = [
is_abelian => GAP.Globals.IsAbelian,
is_almostsimple => GAP.Globals.IsAlmostSimpleGroup,
is_almostsimple => GAP.Globals.IsAlmostSimple,
is_cyclic => GAP.Globals.IsCyclic,
is_nilpotent => GAP.Globals.IsNilpotentGroup,
is_perfect => GAP.Globals.IsPerfectGroup,
is_nilpotent => GAP.Globals.IsNilpotent,
is_perfect => GAP.Globals.IsPerfect,
is_quasisimple => GAP.Globals.IsQuasisimple,
is_simple => GAP.Globals.IsSimpleGroup,
is_simple => GAP.Globals.IsSimple,
is_sporadic_simple => GAP.Globals.IsSporadicSimple,
is_solvable => GAP.Globals.IsSolvableGroup,
is_supersolvable => GAP.Globals.IsSupersolvableGroup,
is_solvable => GAP.Globals.IsSolvable,
is_supersolvable => GAP.Globals.IsSupersolvable,
]

empty!(_group_filter_attrs)
Expand Down
2 changes: 2 additions & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,14 @@ export anti_symmetric_parts
export anticanonical_bundle
export anticanonical_divisor
export anticanonical_divisor_class
export approximate_class_fusion
export archimedean_solid
export as_dictionary
export as_gset
export as_perm_group
export as_polycyclic_group
export associahedron
export atlas_description
export atlas_group
export atlas_irrationality
export atlas_program
Expand Down
4 changes: 4 additions & 0 deletions test/Groups/group_characters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,10 @@ end
fus1 = possible_class_fusions(subtbl, tbl)
fus2 = possible_class_fusions(subtbl, tbl, decompose = false)
@test fus1 == fus2
fus3 = possible_class_fusions(subtbl, tbl, fusionmap = fus1[1])
@test length(fus3) == 1 && fus3[1] == fus1[1]
@test approximate_class_fusion(subtbl, tbl) == [1, 2, [3, 4], [6, 7], [6, 7]]
@test approximate_class_fusion(tbl, subtbl) == []
end

@testset "normal subgroups" begin
Expand Down
2 changes: 2 additions & 0 deletions test/Groups/libraries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
is_cyclic,
is_nilpotent,
is_perfect,
is_quasisimple,
is_simple,
is_sporadic_simple,
is_solvable,
is_supersolvable,
is_transitive,
Expand Down
11 changes: 11 additions & 0 deletions test/Rings/AbelianClosure.jl
Original file line number Diff line number Diff line change
Expand Up @@ -366,4 +366,15 @@ end
@test F isa AnticNumberField
@test dim(F) == 8
end

@testset "Atlas irrationalities" begin
K, z = abelian_closure(QQ)
vals = [z(7) + z(7)^2 + z(7)^4,
z(8) + z(8)^3,
z(9) + z(9)^-1,
z(3) - z(3)^2]
for val in vals
@test atlas_irrationality(atlas_description(val)) == val
end
end
end

0 comments on commit af9f02a

Please sign in to comment.