From 4871c78ca6a243810e5dbdf0ab0608a001bd47ed Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 25 Jan 2024 20:50:58 +0100 Subject: [PATCH] Some group theory changes for the OSCAR book (#3242) * Some group theory changes for the OSCAR book * nicer grunwald_wang interface * more --- experimental/GModule/Cohomology.jl | 9 ++-- experimental/GModule/GModule.jl | 62 ++++++++++++++++-------- experimental/GModule/GaloisCohomology.jl | 14 +++++- 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/experimental/GModule/Cohomology.jl b/experimental/GModule/Cohomology.jl index 62da772a37df..e58d53555905 100644 --- a/experimental/GModule/Cohomology.jl +++ b/experimental/GModule/Cohomology.jl @@ -8,6 +8,8 @@ import Oscar: GAPWrap, pc_group, fp_group, direct_product, direct_sum import AbstractAlgebra: Group, Module import Base: parent +import Oscar: pretty, Lowercase, @show_name, @show_special + function __init__() Hecke.add_verbose_scope(:GroupCohomology) Hecke.add_assert_scope(:GroupCohomology) @@ -104,11 +106,12 @@ Base.hash(a::MultGrpElem, u::UInt = UInt(1235)) = hash(a.data. u) end function Base.show(io::IO, C::GModule) - AbstractAlgebra.@show_name(io, C) - AbstractAlgebra.@show_special(io, C) + @show_name(io, C) + @show_special(io, C) + io = pretty(io) io = IOContext(io, :compact => true) - print(io, "G-module for ", C.G, " acting on ", C.M)# , "\nvia: ", C.ac) + print(io, "G-module for ", Lowercase(), C.G, " acting on ", Lowercase(), C.M)# , "\nvia: ", C.ac) end """ diff --git a/experimental/GModule/GModule.jl b/experimental/GModule/GModule.jl index 8c35169d7937..9aca054d9f06 100644 --- a/experimental/GModule/GModule.jl +++ b/experimental/GModule/GModule.jl @@ -3,6 +3,18 @@ using Oscar using Hecke import Hecke: data +#XXX: clash of names! +# gmodule(k, C) vs gmodule_ver(k, C) +# first does a "restriction of scalars" or blow up with the rep mat +# second tries to conjugate down to k + +import Oscar: gmodule, GAPWrap +import Oscar.GrpCoh: MultGrp, MultGrpElem + +import AbstractAlgebra: Group, Module +import Base: parent + + #XXX: have a type for an implicit field - in Hecke? # add all(?) the other functions to it function relative_field(m::Map{<:AbstractAlgebra.Field, <:AbstractAlgebra.Field}) @@ -59,10 +71,10 @@ julia> C = gmodule(CyclotomicField, C); julia> h = subfields(base_ring(C), degree = 2)[1][2]; julia> restriction_of_scalars(C, h) -G-module for G acting on Vector space of dimension 4 over number field of degree 2 over QQ +G-module for G acting on vector space of dimension 4 over number field of degree 2 over QQ julia> restriction_of_scalars(C, QQ) -G-module for G acting on Vector space of dimension 8 over rational field +G-module for G acting on vector space of dimension 8 over rational field ``` """ @@ -200,17 +212,6 @@ function invariant_lattice_classes(M::GModule, phi::Map) end -#XXX: clash of names! -# gmodule(k, C) vs gmodule_ver(k, C) -# first does a "restriction of scalars" or blow up with the rep mat -# second tries to conjugate down to k - -import Oscar:gmodule, GAPWrap -import Oscar.GrpCoh: MultGrp, MultGrpElem - -import AbstractAlgebra: Group, Module -import Base: parent - function __init__() add_verbose_scope(:BruecknerSQ) set_verbose_level(:BruecknerSQ, 0) @@ -262,8 +263,12 @@ function irreducible_modules(G::Oscar.GAPGroup) return IM end -""" - G acting on M trivially, ie. g(m) == m. +@doc raw""" + trivial_gmodule(G::Group, M::GrpAbFinGen) + trivial_gmodule(G::Group, M::AbstractAlgebra.FPModule) + +Return the `G`-module over the underlying set `M` with trivial `G`-action, +i.e., `g(m) == m` for all $g\in G$ and $m\in M$. """ function trivial_gmodule(G::Oscar.GAPGroup, M::Union{GrpAbFinGen, AbstractAlgebra.FPModule}) I = hom(M, M, gens(M)) @@ -351,6 +356,11 @@ function irreducible_modules(::ZZRing, G::Oscar.GAPGroup) return [gmodule(ZZ, m) for m in z] end +""" + gmodule(k::Field, C::GModule) + +TODO +""" function gmodule(::typeof(CyclotomicField), C::GModule) @assert isa(base_ring(C), QQAbField) d = dim(C) @@ -382,18 +392,16 @@ function gmodule(k::Nemo.fpField, mC::Hecke.MapClassGrp) return gmodule(k, gmodule(ray_class_field(mC))) end - -import Base: ^ -function ^(C::GModule{<:Any, <:AbstractAlgebra.FPModule{nf_elem}}, phi::Map{AnticNumberField, AnticNumberField}) +function Base.:^(C::GModule{<:Any, <:AbstractAlgebra.FPModule{nf_elem}}, phi::Map{AnticNumberField, AnticNumberField}) F = free_module(codomain(phi), dim(C)) return GModule(group(C), [hom(F, F, map_entries(phi, matrix(x))) for x = C.ac]) end -function ^(C::GModule{<:Any, T}, h::Map{S, S}) where T <: S where S +function Base.:^(C::GModule{<:Any, T}, h::Map{S, S}) where T <: S where S return GModule(group(C), [inv(h)*x*h for x = C.ac]) end -function ^(C::GModule{<:Any, <:AbstractAlgebra.FPModule{QQAbElem}}, phi::Map{QQAbField, QQAbField}) +function Base.:^(C::GModule{<:Any, <:AbstractAlgebra.FPModule{QQAbElem}}, phi::Map{QQAbField, QQAbField}) F = free_module(codomain(phi), dim(C)) return GModule(F, group(C), [hom(F, F, map_entries(phi, matrix(x))) for x = C.ac]) end @@ -523,6 +531,12 @@ function Hecke.frobenius(K::FinField, i::Int=1) MapFromFunc(K, K, x->Hecke.frobenius(x, i), y -> Hecke.frobenius(x, degree(K)-i)) end +@doc raw""" + gmodule_minimal_field(C::GModule) + gmodule_minimal_field(k::Field, C::GModule) + +Return TODO +""" function gmodule_minimal_field(C::GModule{<:Any, <:AbstractAlgebra.FPModule{fpFieldElem}}) return C end @@ -545,6 +559,9 @@ function gmodule_minimal_field(C::GModule{<:Any, <:AbstractAlgebra.FPModule{nf_e return _minimize(C) end +""" + gmodule_over(Field) +""" function gmodule_over(k::FinField, C::GModule{<:Any, <:AbstractAlgebra.FPModule{<:FinFieldElem}}; do_error::Bool = false) #mathematically, k needs to contain the character field #only works for irreducible modules @@ -1515,6 +1532,8 @@ export is_decomposable export is_G_hom export restriction_of_scalars export trivial_gmodule +export gmodule_minimal_field +export gmodule_over ## Fill in some stubs for Hecke @@ -1568,4 +1587,5 @@ export is_decomposable export is_G_hom export restriction_of_scalars export trivial_gmodule - +export gmodule_minimal_field +export gmodule_over diff --git a/experimental/GModule/GaloisCohomology.jl b/experimental/GModule/GaloisCohomology.jl index 968da566c175..06b82d68176c 100644 --- a/experimental/GModule/GaloisCohomology.jl +++ b/experimental/GModule/GaloisCohomology.jl @@ -1,5 +1,6 @@ module GaloisCohomology_Mod using Oscar +import Oscar: gmodule import Oscar: GrpCoh import Oscar.GrpCoh: CoChain, MultGrpElem, MultGrp, GModule, is_consistent, Group @@ -1609,7 +1610,7 @@ function relative_brauer_group(K::AnticNumberField, k::Union{QQField, AnticNumbe return B, B.map end -function (B::RelativeBrauerGroup)(M::GModule{PermGroup, AbstractAlgebra.Generic.FreeModule{nf_elem}}) +function (B::RelativeBrauerGroup)(M::GModule{<:Group, AbstractAlgebra.Generic.FreeModule{nf_elem}}) @assert B.K == base_ring(M) c = factor_set(M, B.mG) return preimage(B.map, c) @@ -1664,6 +1665,17 @@ function Hecke.AlgAss(a::RelativeBrauerGroupElem) return A = AlgAss(parent(a).map(a), parent(a).mG, parent(a).mkK) end +function Hecke.grunwald_wang(b::RelativeBrauerGroupElem) + d1 = Dict((x=>Int(order(y))) for (x,y) = b.data if isa(x, NumFieldOrdIdl)) + d2 = Dict((x=>Int(order(y))) for (x,y) = b.data if !isa(x, NumFieldOrdIdl)) + + if length(d2) == 0 + return Hecke.grunwald_wang(d1) + else + return Hecke.grunwald_wang(d1, d2) + end +end + function local_index(C::GModule{<:Oscar.GAPGroup, Generic.FreeModule{nf_elem}}, p::Union{Integer, ZZRingElem}) K = base_ring(C) k, mkK = Oscar.GModuleFromGap._character_field(C)