diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index f5ce457194a4..a1a5b9277963 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -450,17 +450,29 @@ julia> map(length, orbs) """ stabilizer(Omega::GSet{T,S}) stabilizer(Omega::GSet{T,S}, omega::S = representative(Omega); check::Bool = true) where {T,S} + stabilizer(Omega::GSet{T,S}, omega::Set{S}; check::Bool = true) where {T,S} + stabilizer(Omega::GSet{T,S}, omega::Vector{S}; check::Bool = true) where {T,S} + stabilizer(Omega::GSet{T,S}, omega::Tuple{Vararg{S}}; check::Bool = true) where {T,S} Return the subgroup of `G = acting_group(Omega)` that fixes `omega`, together with the embedding of this subgroup into `G`. + +If `omega` is a `Set` of points in `Omega` +then `stabilizer` means the setwise stabilizer of the entries in `omega`. +If `omega` is a `Vector` or a `Tuple` of points in `Omega` +then `stabilizer` means the pointwise stabilizer of the entries in `omega`. + If `check` is `false` then it is not checked whether `omega` is in `Omega`. # Examples ```jldoctest -julia> Omega = gset(symmetric_group(3)); +julia> Omega = gset(symmetric_group(4)); julia> stabilizer(Omega) -(Permutation group of degree 3 and order 2, Hom: permutation group -> Sym(3)) +(Permutation group of degree 4 and order 6, Hom: permutation group -> Sym(4)) + +julia> stabilizer(Omega, [1, 2]) +(Permutation group of degree 4 and order 2, Hom: permutation group -> Sym(4)) ``` """ @attr Tuple{sub_type(T), Map{sub_type(T), T}} function stabilizer(Omega::GSet{T,S}) where {T,S} @@ -474,6 +486,35 @@ function stabilizer(Omega::GSet{T,S}, omega::S; check::Bool = true) where {T,S} return stabilizer(G, omega, gfun) end +# support `stabilizer` under "derived" actions: +# If the given point is a set of the element type of the G-set +# then compute the setwise stabilizer. +# If the given point is a tuple or vector of the element type of the G-set +# then compute the pointwise stabilizer. + +function stabilizer(Omega::GSet{T,S}, omega::Set{S}; check::Bool = true) where {T,S} + check && @req all(in(Omega), omega) "omega must be a set of elements of Omega" + G = acting_group(Omega) + gfun = action_function(Omega) + derived_fun = function(x, g) return Set(gfun(y, g) for y in x); end + return stabilizer(G, omega, derived_fun) +end + +function stabilizer(Omega::GSet{T,S}, omega::Vector{S}; check::Bool = true) where {T,S} + check && @req all(in(Omega), omega) "omega must be a vector of elements of Omega" + G = acting_group(Omega) + gfun = action_function(Omega) + derived_fun = function(x, g) return [gfun(y, g) for y in x]; end + return stabilizer(G, omega, derived_fun) +end + +function stabilizer(Omega::GSet{T,S}, omega::Tuple{Vararg{S}}; check::Bool = true) where {T,S} + check && @req all(in(Omega), omega) "omega must be a tuple of elements of Omega" + G = acting_group(Omega) + gfun = action_function(Omega) + derived_fun = function(x, g) return Tuple([gfun(y, g) for y in x]); end + return stabilizer(G, omega, derived_fun) +end ############################################################################# ## diff --git a/test/Groups/gsets.jl b/test/Groups/gsets.jl index f8fd31d602d1..046588fb1148 100644 --- a/test/Groups/gsets.jl +++ b/test/Groups/gsets.jl @@ -12,20 +12,34 @@ @test ! is_semiregular(Omega) @test collect(Omega) == 1:6 # ordering is kept @test order(stabilizer(Omega)[1]) * length(Omega) == order(G) + @test order(stabilizer(Omega, 1)[1]) == 120 + @test order(stabilizer(Omega, Set([1, 2]))[1]) == 48 + @test order(stabilizer(Omega, [1, 2])[1]) == 24 + @test order(stabilizer(Omega, (1, 2))[1]) == 24 Omega = gset(G, [Set([1, 2])]) # action on unordered pairs @test isa(Omega, GSet) @test length(Omega) == 15 - @test order(stabilizer(Omega)[1]) * length(Omega) == order(G) @test length(orbits(Omega)) == 1 @test is_transitive(Omega) @test ! is_regular(Omega) @test ! is_semiregular(Omega) + @test order(stabilizer(Omega)[1]) * length(Omega) == order(G) + @test order(stabilizer(Omega, Set([1, 3]))[1]) == 48 + @test order(stabilizer(Omega, Set([Set([1, 2]), Set([1, 3])]))[1]) == 12 + @test order(stabilizer(Omega, [Set([1, 2]), Set([1, 3])])[1]) == 6 + @test order(stabilizer(Omega, (Set([1, 2]), Set([1, 3])))[1]) == 6 + @test_throws MethodError stabilizer(Omega, [1, 2]) Omega = gset(G, [[1, 2]]) # action on ordered pairs @test isa(Omega, GSet) @test length(Omega) == 30 @test order(stabilizer(Omega)[1]) * length(Omega) == order(G) + @test order(stabilizer(Omega, [1, 3])[1]) == 24 + @test order(stabilizer(Omega, Set([[1, 2], [1, 3]]))[1]) == 12 + @test order(stabilizer(Omega, [[1, 2], [1, 3]])[1]) == 6 + @test order(stabilizer(Omega, ([1, 2], [1, 3]))[1]) == 6 + @test_throws MethodError stabilizer(Omega, Set([1, 2])) @test length(orbits(Omega)) == 1 @test is_transitive(Omega) @test ! is_regular(Omega) @@ -46,6 +60,10 @@ @test isa(Omega, GSet) @test length(Omega) == 740 @test order(stabilizer(Omega, omega)[1]) * length(orbit(Omega, omega)) == order(G) + @test order(stabilizer(Omega, Set([omega, [1,0,0,1,0,1]]))[1]) == 8 + @test order(stabilizer(Omega, [omega, [1,0,0,1,0,1]])[1]) == 4 + @test order(stabilizer(Omega, (omega, [1,0,0,1,0,1]))[1]) == 4 + @test_throws MethodError stabilizer(Omega, Set(omega)) @test length(orbits(Omega)) == 2 @test ! is_transitive(Omega) @test ! is_regular(Omega)