Skip to content
Draft
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
134 changes: 118 additions & 16 deletions experimental/GModule/src/GModule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -385,11 +385,34 @@ function irreducible_modules(k::FinField, G::Oscar.GAPGroup)
return IM
end

function irreducible_modules(G::Oscar.GAPGroup)

@doc raw"""
irreducible_modules(G::Oscar.GAPGroup; algo::Symbol = :auto)

Computes absolutely irreducible representations of $G$ over the
abelian closure of $QQ$. The `algo` can be set to `:auto` (the default),
`:Repsn`, `:Solvable`
or `:BaumClausen`. In case of `:Repsn` Gaps `IrreducibleRepresentations`
is called which can fail.

In case of `:BaumClausen`, the Baum-Clausen method is called which will very
quickly determine some representations.

For `:Solvable` the extension method of Pelsken/ Brueckner is used.

For abelian groups, the representations are written down directly.
"""
function irreducible_modules(G::Oscar.GAPGroup; algo::Symbol = :auto)
if is_abelian(G)
return _abs_irred_abelian(G)
end
im = GAP.Globals.IrreducibleRepresentations(GapObj(G))
if algo == :auto || algo == :Repsn
im = GAP.Globals.IrreducibleRepresentations(GapObj(G))
elseif algo == :BaumClausen
im = GAP.Globals.IrreducibleRepresentationsByBaumClausen(GapObj(G))
elseif algo == :Solvable
return Oscar.RepPc.reps(abelian_closure(QQ)[1], G)
end
IM = GModule[]
K = abelian_closure(QQ)[1]
for m in im
Expand Down Expand Up @@ -433,7 +456,13 @@ function Oscar.gmodule(::Type{AbsSimpleNumField}, M::GModule{<:Oscar.GAPGroup, <
end

function Oscar.gmodule(::Type{AbsSimpleNumField}, M::GModule{<:Oscar.GAPGroup, <:AbstractAlgebra.FPModule{QQAbFieldElem{AbsSimpleNumFieldElem}}})
return gmodule(AbsSimpleNumField, gmodule(CyclotomicField, M))
if ngens(group(M)) == 0
F = free_module(rationals_as_number_field()[1], dim(M))
return gmodule(group(M), [hom(F, F, gens(F)) for x = gens(group(M))])
end
k, mk = sub(base_ring(M), vec(collect(reduce(vcat, map(matrix, M.ac)))))
F = free_module(k, dim(M); cached = true)
return gmodule(group(M), [hom(F, F, map_entries(pseudo_inv(mk), matrix(x))) for x = M.ac])
end

function irreducible_modules(::Type{AbsSimpleNumField}, G::Oscar.GAPGroup; minimal_degree::Bool = false)
Expand All @@ -448,7 +477,6 @@ function irreducible_modules(::Type{AbsSimpleNumField}, G::Oscar.GAPGroup; minim
if !minimal_degree
return Z
else
res = GModule[]
return map(_minimize, Z)
end
end
Expand Down Expand Up @@ -954,6 +982,10 @@ end

gmodule(k::fpField, C::GModule{<:Any, <:AbstractAlgebra.FPModule{fpFieldElem}}) = C

function trace_product(M::T, N::T) where T <: MatElem
return sum((M[i:i, :] * N[:, i:i])[1,1] for i=1:nrows(M))
end

#=
On characters (in char 0)
========================
Expand All @@ -976,15 +1008,75 @@ gmodule(k::fpField, C::GModule{<:Any, <:AbstractAlgebra.FPModule{fpFieldElem}})
n = dim(C)
K = base_ring(C)

chr = []
for c = conjugacy_classes(character_table(G))
r = representative(c)
if isone(r)
push!(chr, (c, K(n)))
continue
Cls = conjugacy_classes(character_table(G))
if has_attribute(C, :action)
chr = []
for c = Cls
r = representative(c)
if isone(r)
push!(chr, (c, K(n)))
continue
end
T = action(C, r)
push!(chr, (c, K(trace(matrix(T)))))
end
elseif base_ring(C) == QQ
n = dim(C)
p = next_prime(2*n)
while order(C.G) % p == 0
p = next_prime(p)
end
Cp = gmodule(Native.GF(p), C)
_c = _character(Cp)
pZ = ZZ(p)
@assert all(Cls[i] == _c[i][1] for i=1:length(_c))
chr = [(x[1], mod_sym(ZZ(lift(x[2])), pZ)) for x = _c]
else
pos = let Cls = Cls
function pos(g)
for i = 1:length(Cls)
if g in Cls[i]
return i
end
end
return nothing
end
end
have = [false for c = Cls]
chr = [(Cls[1], K(0)) for c = Cls]
M = map(matrix, action(C))
Mi = map(matrix, Oscar.GrpCoh.inv_action(C))
for g = 1:ngens(G)
i = pos(G[g])
have[i] && continue
have[i] = true
chr[i] = (Cls[i], K(trace(M[g])))

i = pos(inv(G[g]))
have[i] && continue
have[i] = true
chr[i] = (Cls[i], K(trace(Mi[g])))
end

for g = 1:ngens(G)
for h = 1:ngens(G)
i = pos(G[g]*G[h])
have[i] && continue
have[i] = true
chr[i] = (Cls[i], K(trace_product(M[g], M[h])))
end
end
for i = 1:length(Cls)
have[i] && continue
have[i] = true
r = representative(Cls[i])
if isone(r)
chr[i] = (Cls[i], K(n))
continue
end
T = action(C, r)
chr[i] = (Cls[i], K(trace(matrix(T))))
end
T = action(C, r)
push!(chr, (c, K(trace(matrix(T)))))
end

if !isa(K, SimpleNumField) #no idea is this is correct (in char p)
Expand Down Expand Up @@ -1245,7 +1337,6 @@ function swap_rows!(A::QQMatrix, pi::PermGroupElem)
end
end


function Oscar.mul!(A::T, B::T, C::PermMat{S}) where T <: MatElem{S} where S <: RingElem
A[:, :] = B
swap_cols!(A, C.p)
Expand Down Expand Up @@ -1278,13 +1369,17 @@ for (M, E) in ((QQMatrix, QQFieldElem), (FqMatrix, FqFieldElem))
end

function Oscar.mul!(A::$M, B::PermMat{$E}, C::$M)
A[:, :] = C
if A !== C
A[:, :] = C
end
swap_rows!(A, inv(B.p))
return A
end

function Oscar.mul!(A::$M, B::$M, C::PermMat{$E})
A[:, :] = B
if A !== B
A[:, :] = B
end
swap_cols!(A, C.p)
return A
end
Expand Down Expand Up @@ -1346,8 +1441,15 @@ function permutation_gmodule(G::Group, U::Group, R::Ring)
h = action_homomorphism(rc)
F = free_module(R, Int(divexact(order(G), order(U))); cached = false)
C = gmodule(G, [hom(F, F, PermMat(R, h(g))) for g = gens(G)])
function perm_action(C::GModule, g::GAPGroupElem)
return hom(F, F, PermMat(R, h(g)))
end
function perm_action(C::GModule, g::GAPGroupElem, v::Vector)
h = hom(F, F, PermMat(R, h(g)))
return map(h, v)
end
# C = gmodule(G, [hom(F, F, permutation_matrix(R, h(g))) for g = gens(G)])
set_attribute!(C, :right_cosets => rc, :show => show_permutation_gmodule)
set_attribute!(C, :right_cosets => rc, :show => show_permutation_gmodule, :action => perm_action)
return C
end

Expand Down
Loading
Loading