Skip to content
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
3 changes: 3 additions & 0 deletions docs/src/Groups/action.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ on_indeterminates
on_lines
on_echelon_form_mats
on_subgroups
induced_action(::Function, ::GAPGroupHomomorphism)
```


Expand Down Expand Up @@ -74,6 +75,8 @@ rank_action(Omega::GSet)
is_primitive(Omega::GSet)
is_regular(Omega::GSet)
is_semiregular(Omega::GSet)
induce(Omega::GSetByElements{T, S}, phi::GAPGroupHomomorphism{U, T}) where {T<:Group, U<:Group, S}
induced_action_function(Omega::GSetByElements{T, S}, phi::GAPGroupHomomorphism{U, T}) where {T<:Group, U<:Group, S}
```

## Block systems of a G-set
Expand Down
7 changes: 1 addition & 6 deletions src/Groups/GrpAb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,7 @@ function action_homomorphism(Omega::GSetByElements{FinGenAbGroup, S}) where S
G = codomain(phi)

# Let `G` act on `Omega` as `A` does.
phiinv = inv(phi)
actfun = action_function(Omega)
fun = function(omega::S, g::PermGroupElem)
return actfun(omega, phiinv(g))
end
OmegaG = GSetByElements(G, fun, Omega, closed = true, check = false)
OmegaG = induce(Omega, inv(phi))

# Compute the permutation action on `1:length(Omega)`
# corresponding to the action of `A` on `Omega`.
Expand Down
26 changes: 26 additions & 0 deletions src/Groups/action.jl
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,32 @@ function on_echelon_form_mats(m::MatElem{T}, x::MatrixGroupElem) where T <: FinF
return echelon_form(m * x)
end

@doc raw"""
induced_action(actfun::Function, phi::GAPGroupHomomorphism)

Return the action function that is obtained by inducing `actfun` along `phi`.

That means, given a groups ``G`` and ``H``, a set ``\Omega`` with action function ``f: \Omega \times G \to \Omega``
and a homomorphism ``\phi: H \to G``, construct the action function
$\Omega \times H \to \Omega, (\omega, h) \mapsto f(\omega, \phi(h))$.
"""
function induced_action(actfun::Function, phi::GAPGroupHomomorphism)
return _induced_action(actfun, phi)
end

# This method is not documented as we need `phi` to be a group homomorphism, but in many cases
# there is no dedicated type for this (WeylGroup, FinGenAbGroup, etc.).
# This should be restricted to group homomorphisms once we have a type for them.
function induced_action(actfun::Function, phi::Map{<:Union{Group,FinGenAbGroup}, <:Union{Group,FinGenAbGroup}})
return _induced_action(actfun, phi)
end

function _induced_action(actfun::Function, phi::Map{<:Union{Group,FinGenAbGroup}, <:Union{Group,FinGenAbGroup}})
return function (omega, g)
return actfun(omega, phi(g))
end
end

@doc raw"""
stabilizer(G::GAPGroup, pnt::Any[, actfun::Function])

Expand Down
57 changes: 57 additions & 0 deletions src/Groups/gsets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,63 @@ end
as_gset(G::T, Omega) where T<:Union{GAPGroup,FinGenAbGroup} = as_gset(G, ^, Omega)


#############################################################################
##
## induce G-sets along homomorphisms

@doc raw"""
induced_action_function(Omega::GSetByElements{T, S}, phi::GAPGroupHomomorphism{U, T}) where {T<:Group, U<:Group, S}

Return the action function of the G-set that is obtained by inducing the G-set `Omega` along `phi`.

That means, given a ``G``-set ``\Omega`` with action function ``f: \Omega \times G \to \Omega``
and a homomorphism ``\phi: H \to G``, construct the action function
$\Omega \times H \to \Omega, (\omega, h) \mapsto f(\omega, \phi(h))$.

This function is semantically equivalent to `action_function(induce(Omega, phi))`,
but it is more efficient as it avoids the construction of the induced G-set.
"""
function induced_action_function(Omega::GSetByElements{T, S}, phi::GAPGroupHomomorphism{U, T}) where {T<:Group, U<:Group, S}
return _induced_action_function(Omega, phi)
end

# This method is not documented as we need `phi` to be a group homomorphism, but in many cases
# there is no dedicated type for this (WeylGroup, FinGenAbGroup, etc.).
# This should be restricted to group homomorphisms once we have a type for them.
function induced_action_function(Omega::GSetByElements{T, S}, phi::Map{U, T}) where {T<:Union{Group,FinGenAbGroup}, U<:Union{Group,FinGenAbGroup}, S}
return _induced_action_function(Omega, phi)
end

function _induced_action_function(Omega::GSetByElements{T, S}, phi::Map{U, T}) where {T<:Union{Group,FinGenAbGroup}, U<:Union{Group,FinGenAbGroup}, S}
@req acting_group(Omega) == codomain(phi) "acting group of Omega must be the codomain of phi"
return induced_action(action_function(Omega), phi)
end

@doc raw"""
induce(Omega::GSetByElements{T, S}, phi::GAPGroupHomomorphism{U, T}) where {T<:Group, U<:Group, S}

Return the G-set that is obtained by inducing the G-set `Omega` along `phi`.

That means, given a ``G``-set ``\Omega`` with action function ``f: \Omega \times G \to \Omega``
and a homomorphism ``\phi: H \to G``, construct the ``H``-set ``\Omega'`` with action function
$\Omega' \times H \to \Omega', (\omega, h) \mapsto f(\omega, \phi(h))$.
"""
function induce(Omega::GSetByElements{T, S}, phi::GAPGroupHomomorphism{U, T}) where {T<:Group, U<:Group, S}
return _induce(Omega, phi)
end

# This method is not documented as we need `phi` to be a group homomorphism, but in many cases
# there is no dedicated type for this (WeylGroup, FinGenAbGroup, etc.).
# This should be restricted to group homomorphisms once we have a type for them.
function induce(Omega::GSetByElements{T, S}, phi::Map{U, T}) where {T<:Union{Group,FinGenAbGroup}, U<:Union{Group,FinGenAbGroup}, S}
return _induce(Omega, phi)
end

function _induce(Omega::GSetByElements{T, S}, phi::Map{U, T}) where {T<:Union{Group,FinGenAbGroup}, U<:Union{Group,FinGenAbGroup}, S}
@req acting_group(Omega) == codomain(phi) "acting group of Omega must be the codomain of phi"
return GSetByElements(domain(phi), induced_action_function(Omega, phi), Omega; closed=true, check=false)
end

#############################################################################
##
## wrapper objects for elements of G-sets,
Expand Down
2 changes: 2 additions & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,8 @@ export index_of_leading_term
export indicator
export induce
export induce_shift
export induced_action
export induced_action_function
export induced_automorphism
export induced_cyclic
export induced_map_on_exterior_power
Expand Down
27 changes: 27 additions & 0 deletions test/Groups/gsets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -581,3 +581,30 @@ end
@test describe(image(acthom)[1]) == "C3"
@test all(x -> permutation(o, x) == acthom(x), gens(u))
end

@testset "inducing G-sets" begin
G = symmetric_group(4)
Omega = gset(G, permuted, [[1,1,2,3]])
H = permutation_group(8, [cperm([1,3], [2,4]), cperm([1,5], [2,6], [3,7], [4,8])])
phi = hom(H, G, [cperm([1,2]), cperm([1,3], [2,4])])

# This check is a bit surprising that it works, but it does.
# We just need that the two functions are same as mathematical functions, not as objects.
@test induced_action_function(Omega, phi) == induced_action(action_function(Omega), phi)

orb = orbit(H, induced_action_function(Omega, phi), [1,1,2,3])
@test acting_group(orb) == H
@test length(orb) == 4
stab = stabilizer(orb)[1]
@test order(stab) == 2
@test cperm([1,3], [2,4]) in stab

Omega2 = induce(Omega, phi)
@test acting_group(Omega2) == H
@test elements(Omega2) == elements(Omega)
@test length(orbits(Omega2)) == 2
@test issetequal(length.(orbits(Omega2)), [4, 8])
stab2 = stabilizer(Omega2)[1]
@test order(stab2) == 2
@test cperm([1,3], [2,4]) in stab2
end
Loading