From 147aedc3c6de28fa802b10faac34869592c67cd3 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Mon, 11 Nov 2024 13:37:15 +0100 Subject: [PATCH 01/21] testing some speed improvements --- src/Groups/gsets.jl | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index f1a3b910b64c..c96f54fa3ea6 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -332,6 +332,17 @@ orbit(G::GAPGroup, omega) = gset_by_type(G, [omega], typeof(omega)) orbit(G::Union{GAPGroup, FinGenAbGroup}, fun::Function, omega) = GSetByElements(G, fun, [omega]) +# common code +function gap_action_function(Omega::GSet) + f = action_function(Omega) + (f == ^) && return GAP.Globals.OnPoints + # f == on_tuples && return GAP.Globals.OnTuples + # f == on_sets && return GAP.Globals.OnSets + # etc. + return GapObj(f) # generic fallback +end + + """ orbit(Omega::GSet, omega) @@ -351,8 +362,9 @@ julia> length(orbit(Omega, 1)) """ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S G = acting_group(Omega) - acts = GapObj(gens(G)) - gfun = GapObj(action_function(Omega)) + acts = GapObj(gens(G); recursive=true) + gfun = gap_action_function(Omega) + # gfun = GapObj(action_function(Omega)) # The following works only because GAP does not check # whether the given (dummy) group 'GapObj(G)' fits to the given generators, From 8f1123905a1f609491882a555b657bf2a647d252 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Wed, 13 Nov 2024 14:36:08 +0100 Subject: [PATCH 02/21] remove unneeded comment --- src/Groups/gsets.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index c96f54fa3ea6..29696f0770a1 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -332,7 +332,7 @@ orbit(G::GAPGroup, omega) = gset_by_type(G, [omega], typeof(omega)) orbit(G::Union{GAPGroup, FinGenAbGroup}, fun::Function, omega) = GSetByElements(G, fun, [omega]) -# common code + function gap_action_function(Omega::GSet) f = action_function(Omega) (f == ^) && return GAP.Globals.OnPoints From db7c47217e431ad01172bd867be862b7ab2b94b8 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Wed, 13 Nov 2024 15:05:33 +0100 Subject: [PATCH 03/21] uncomment some things/ delete some unneeded comments --- src/Groups/gsets.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index 29696f0770a1..60dfc43e4190 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -336,8 +336,8 @@ orbit(G::Union{GAPGroup, FinGenAbGroup}, fun::Function, omega) = GSetByElements( function gap_action_function(Omega::GSet) f = action_function(Omega) (f == ^) && return GAP.Globals.OnPoints - # f == on_tuples && return GAP.Globals.OnTuples - # f == on_sets && return GAP.Globals.OnSets + f == on_tuples && return GAP.Globals.OnTuples + f == on_sets && return GAP.Globals.OnSets # etc. return GapObj(f) # generic fallback end @@ -364,7 +364,6 @@ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S G = acting_group(Omega) acts = GapObj(gens(G); recursive=true) gfun = gap_action_function(Omega) - # gfun = GapObj(action_function(Omega)) # The following works only because GAP does not check # whether the given (dummy) group 'GapObj(G)' fits to the given generators, From e65abe745bc0fda9275a21ea9004f44bf56709fa Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Wed, 20 Nov 2024 14:03:59 +0100 Subject: [PATCH 04/21] add test --- test/Groups/gsets.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/Groups/gsets.jl b/test/Groups/gsets.jl index 86377eef8bdd..d02d9efb7c9b 100644 --- a/test/Groups/gsets.jl +++ b/test/Groups/gsets.jl @@ -365,6 +365,17 @@ end f = x^2 + y orb = orbit(G, f) @test length(orb) == 3 + + + K = algebraic_closure(QQ) + e = one(K) + s, c = sincospi(2 * e / 3) + mat_rot = matrix([c -s; s c]) + G = matrix_group(mat_rot) + p = K.([1, 0]) + orb = orbit(G, *, p) + + end @testset "G-sets by right transversals" begin From 0fcacb17b2adb41902a7392fc051e8390e0f4712 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Fri, 22 Nov 2024 09:55:05 +0100 Subject: [PATCH 05/21] fix new test --- test/Groups/gsets.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Groups/gsets.jl b/test/Groups/gsets.jl index d02d9efb7c9b..f1b5011d077d 100644 --- a/test/Groups/gsets.jl +++ b/test/Groups/gsets.jl @@ -367,13 +367,13 @@ end @test length(orb) == 3 - K = algebraic_closure(QQ) - e = one(K) + e = one(QQBar) s, c = sincospi(2 * e / 3) mat_rot = matrix([c -s; s c]) G = matrix_group(mat_rot) - p = K.([1, 0]) + p = QQBar.([1, 0]) orb = orbit(G, *, p) + @test length(orb) == 3 end From 329e0087c0802626583e65dbb351a3b35f9ee5fe Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 27 Nov 2024 13:46:17 +0100 Subject: [PATCH 06/21] add some special `orbit` methods --- src/Groups/gsets.jl | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index 60dfc43e4190..b8ecf1437e06 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -362,7 +362,7 @@ julia> length(orbit(Omega, 1)) """ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S G = acting_group(Omega) - acts = GapObj(gens(G); recursive=true) + acts = GapObj(gens(G)) gfun = gap_action_function(Omega) # The following works only because GAP does not check @@ -377,6 +377,22 @@ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S end #T check whether omega lies in Omega? +# special cases where we convert the objects to GAP, +# in order to use better methods on the GAP side: +# - orbit of a perm. group on integers +# - orbit of a perm. group on vectors of integers +# - orbit of a perm. group on sets of integers +function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: Union{IntegerUnion, Vector{<: IntegerUnion}, Set{<: IntegerUnion}} + G = acting_group(Omega) + gfun = gap_action_function(Omega) + orb = Vector{S}(GAP.Globals.Orbit(GapObj(G), GapObj(omega), gfun)::GapObj) + + res = as_gset(acting_group(Omega), action_function(Omega), orb) + # We know that this G-set is transitive. + set_attribute!(res, :orbits => [orb]) + return res +end + function orbit(Omega::GSetByElements{FinGenAbGroup}, omega::T) where T return orbit_via_Julia(Omega, omega) end From 2daefdd3d7a7fe513606c2b7fe74791db629c7df Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 27 Nov 2024 17:02:07 +0100 Subject: [PATCH 07/21] fix the generic method, add comments --- src/Groups/gsets.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index b8ecf1437e06..27182d379e6e 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -361,9 +361,11 @@ julia> length(orbit(Omega, 1)) ``` """ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S + # In this generic function, we delegate the loop to GAP, but we act + # with Julia group elements on Julia objects via Julia functions. G = acting_group(Omega) acts = GapObj(gens(G)) - gfun = gap_action_function(Omega) + gfun = GapObj(action_function(Omega)) # The following works only because GAP does not check # whether the given (dummy) group 'GapObj(G)' fits to the given generators, @@ -377,7 +379,8 @@ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S end #T check whether omega lies in Omega? -# special cases where we convert the objects to GAP, +# special cases where we convert the objects to GAP +# (the group elements as well as the objects they act on), # in order to use better methods on the GAP side: # - orbit of a perm. group on integers # - orbit of a perm. group on vectors of integers From 597a3b22d90bcf8185e5317c313b0c9b542f2632 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Thu, 28 Nov 2024 15:07:06 +0100 Subject: [PATCH 08/21] o.k., we have to check that the action function fits (This is something we cannot decide on the level of types.) --- src/Groups/gsets.jl | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index 27182d379e6e..e6c4437ae3a3 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -360,7 +360,9 @@ julia> length(orbit(Omega, 1)) 4 ``` """ -function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S +orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S = _orbit_generic(Omega, omega) + +function _orbit_generic(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S # In this generic function, we delegate the loop to GAP, but we act # with Julia group elements on Julia objects via Julia functions. G = acting_group(Omega) @@ -382,10 +384,25 @@ end # special cases where we convert the objects to GAP # (the group elements as well as the objects they act on), # in order to use better methods on the GAP side: -# - orbit of a perm. group on integers -# - orbit of a perm. group on vectors of integers -# - orbit of a perm. group on sets of integers -function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: Union{IntegerUnion, Vector{<: IntegerUnion}, Set{<: IntegerUnion}} +# - orbit of a perm. group on integers via `^` +# - orbit of a perm. group on vectors of integers via `on_tuples` +# - orbit of a perm. group on sets of integers via `on_sets` +function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: IntegerUnion + (action_function(Omega) == ^) || return _orbit_generic(Omega, omega) + return _orbit_special_GAP(Omega, omega) +end + +function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: Vector{<: IntegerUnion} + action_function(Omega) == on_tuples || return _orbit_generic(Omega, omega) + return _orbit_special_GAP(Omega, omega) +end + +function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: Set{<: IntegerUnion} + action_function(Omega) == on_sets || return _orbit_generic(Omega, omega) + return _orbit_special_GAP(Omega, omega) +end + +function _orbit_special_GAP(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S G = acting_group(Omega) gfun = gap_action_function(Omega) orb = Vector{S}(GAP.Globals.Orbit(GapObj(G), GapObj(omega), gfun)::GapObj) From 72db49d8ded2a5955b5d31b64355c14946e48f17 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Thu, 28 Nov 2024 20:37:20 +0100 Subject: [PATCH 09/21] avoid deprecated `QQBar` --- test/Groups/gsets.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Groups/gsets.jl b/test/Groups/gsets.jl index f1b5011d077d..5fc31b2f3867 100644 --- a/test/Groups/gsets.jl +++ b/test/Groups/gsets.jl @@ -366,12 +366,12 @@ end orb = orbit(G, f) @test length(orb) == 3 - - e = one(QQBar) + F = QQBarField() + e = one(F) s, c = sincospi(2 * e / 3) mat_rot = matrix([c -s; s c]) G = matrix_group(mat_rot) - p = QQBar.([1, 0]) + p = F.([1, 0]) orb = orbit(G, *, p) @test length(orb) == 3 From a72a176e0020be47bda29817311f669611fa118d Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Mon, 11 Nov 2024 13:37:15 +0100 Subject: [PATCH 10/21] testing some speed improvements --- src/Groups/gsets.jl | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index f1a3b910b64c..c96f54fa3ea6 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -332,6 +332,17 @@ orbit(G::GAPGroup, omega) = gset_by_type(G, [omega], typeof(omega)) orbit(G::Union{GAPGroup, FinGenAbGroup}, fun::Function, omega) = GSetByElements(G, fun, [omega]) +# common code +function gap_action_function(Omega::GSet) + f = action_function(Omega) + (f == ^) && return GAP.Globals.OnPoints + # f == on_tuples && return GAP.Globals.OnTuples + # f == on_sets && return GAP.Globals.OnSets + # etc. + return GapObj(f) # generic fallback +end + + """ orbit(Omega::GSet, omega) @@ -351,8 +362,9 @@ julia> length(orbit(Omega, 1)) """ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S G = acting_group(Omega) - acts = GapObj(gens(G)) - gfun = GapObj(action_function(Omega)) + acts = GapObj(gens(G); recursive=true) + gfun = gap_action_function(Omega) + # gfun = GapObj(action_function(Omega)) # The following works only because GAP does not check # whether the given (dummy) group 'GapObj(G)' fits to the given generators, From 18a9c06a10a440d6d99fe8b28ff1812b7747e0cd Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Wed, 13 Nov 2024 14:36:08 +0100 Subject: [PATCH 11/21] remove unneeded comment --- src/Groups/gsets.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index c96f54fa3ea6..29696f0770a1 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -332,7 +332,7 @@ orbit(G::GAPGroup, omega) = gset_by_type(G, [omega], typeof(omega)) orbit(G::Union{GAPGroup, FinGenAbGroup}, fun::Function, omega) = GSetByElements(G, fun, [omega]) -# common code + function gap_action_function(Omega::GSet) f = action_function(Omega) (f == ^) && return GAP.Globals.OnPoints From 876161a50547504d17cdec237bb1ceb0305e77c5 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Wed, 13 Nov 2024 15:05:33 +0100 Subject: [PATCH 12/21] uncomment some things/ delete some unneeded comments --- src/Groups/gsets.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index 29696f0770a1..60dfc43e4190 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -336,8 +336,8 @@ orbit(G::Union{GAPGroup, FinGenAbGroup}, fun::Function, omega) = GSetByElements( function gap_action_function(Omega::GSet) f = action_function(Omega) (f == ^) && return GAP.Globals.OnPoints - # f == on_tuples && return GAP.Globals.OnTuples - # f == on_sets && return GAP.Globals.OnSets + f == on_tuples && return GAP.Globals.OnTuples + f == on_sets && return GAP.Globals.OnSets # etc. return GapObj(f) # generic fallback end @@ -364,7 +364,6 @@ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S G = acting_group(Omega) acts = GapObj(gens(G); recursive=true) gfun = gap_action_function(Omega) - # gfun = GapObj(action_function(Omega)) # The following works only because GAP does not check # whether the given (dummy) group 'GapObj(G)' fits to the given generators, From a6a14d38d4f0a725080c94f57504c8e250c5e5f2 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Wed, 20 Nov 2024 14:03:59 +0100 Subject: [PATCH 13/21] add test --- test/Groups/gsets.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/Groups/gsets.jl b/test/Groups/gsets.jl index 86377eef8bdd..d02d9efb7c9b 100644 --- a/test/Groups/gsets.jl +++ b/test/Groups/gsets.jl @@ -365,6 +365,17 @@ end f = x^2 + y orb = orbit(G, f) @test length(orb) == 3 + + + K = algebraic_closure(QQ) + e = one(K) + s, c = sincospi(2 * e / 3) + mat_rot = matrix([c -s; s c]) + G = matrix_group(mat_rot) + p = K.([1, 0]) + orb = orbit(G, *, p) + + end @testset "G-sets by right transversals" begin From 0b14f0add8aab989ed8e383a6cfec7c7602af4d4 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Fri, 22 Nov 2024 09:55:05 +0100 Subject: [PATCH 14/21] fix new test --- test/Groups/gsets.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Groups/gsets.jl b/test/Groups/gsets.jl index d02d9efb7c9b..f1b5011d077d 100644 --- a/test/Groups/gsets.jl +++ b/test/Groups/gsets.jl @@ -367,13 +367,13 @@ end @test length(orb) == 3 - K = algebraic_closure(QQ) - e = one(K) + e = one(QQBar) s, c = sincospi(2 * e / 3) mat_rot = matrix([c -s; s c]) G = matrix_group(mat_rot) - p = K.([1, 0]) + p = QQBar.([1, 0]) orb = orbit(G, *, p) + @test length(orb) == 3 end From 35f7b58ba6feccd639fb55e42dd09c0ddf636d6f Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 27 Nov 2024 13:46:17 +0100 Subject: [PATCH 15/21] add some special `orbit` methods --- src/Groups/gsets.jl | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index 60dfc43e4190..b8ecf1437e06 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -362,7 +362,7 @@ julia> length(orbit(Omega, 1)) """ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S G = acting_group(Omega) - acts = GapObj(gens(G); recursive=true) + acts = GapObj(gens(G)) gfun = gap_action_function(Omega) # The following works only because GAP does not check @@ -377,6 +377,22 @@ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S end #T check whether omega lies in Omega? +# special cases where we convert the objects to GAP, +# in order to use better methods on the GAP side: +# - orbit of a perm. group on integers +# - orbit of a perm. group on vectors of integers +# - orbit of a perm. group on sets of integers +function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: Union{IntegerUnion, Vector{<: IntegerUnion}, Set{<: IntegerUnion}} + G = acting_group(Omega) + gfun = gap_action_function(Omega) + orb = Vector{S}(GAP.Globals.Orbit(GapObj(G), GapObj(omega), gfun)::GapObj) + + res = as_gset(acting_group(Omega), action_function(Omega), orb) + # We know that this G-set is transitive. + set_attribute!(res, :orbits => [orb]) + return res +end + function orbit(Omega::GSetByElements{FinGenAbGroup}, omega::T) where T return orbit_via_Julia(Omega, omega) end From 93ad9f832be0272147825a0a0b63235217aa38ca Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Wed, 27 Nov 2024 17:02:07 +0100 Subject: [PATCH 16/21] fix the generic method, add comments --- src/Groups/gsets.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index b8ecf1437e06..27182d379e6e 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -361,9 +361,11 @@ julia> length(orbit(Omega, 1)) ``` """ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S + # In this generic function, we delegate the loop to GAP, but we act + # with Julia group elements on Julia objects via Julia functions. G = acting_group(Omega) acts = GapObj(gens(G)) - gfun = gap_action_function(Omega) + gfun = GapObj(action_function(Omega)) # The following works only because GAP does not check # whether the given (dummy) group 'GapObj(G)' fits to the given generators, @@ -377,7 +379,8 @@ function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S end #T check whether omega lies in Omega? -# special cases where we convert the objects to GAP, +# special cases where we convert the objects to GAP +# (the group elements as well as the objects they act on), # in order to use better methods on the GAP side: # - orbit of a perm. group on integers # - orbit of a perm. group on vectors of integers From 706ca4a30311db9e2c64953a507aad8c6cec19d2 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Thu, 28 Nov 2024 15:07:06 +0100 Subject: [PATCH 17/21] o.k., we have to check that the action function fits (This is something we cannot decide on the level of types.) --- src/Groups/gsets.jl | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index 27182d379e6e..e6c4437ae3a3 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -360,7 +360,9 @@ julia> length(orbit(Omega, 1)) 4 ``` """ -function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S +orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S = _orbit_generic(Omega, omega) + +function _orbit_generic(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S # In this generic function, we delegate the loop to GAP, but we act # with Julia group elements on Julia objects via Julia functions. G = acting_group(Omega) @@ -382,10 +384,25 @@ end # special cases where we convert the objects to GAP # (the group elements as well as the objects they act on), # in order to use better methods on the GAP side: -# - orbit of a perm. group on integers -# - orbit of a perm. group on vectors of integers -# - orbit of a perm. group on sets of integers -function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: Union{IntegerUnion, Vector{<: IntegerUnion}, Set{<: IntegerUnion}} +# - orbit of a perm. group on integers via `^` +# - orbit of a perm. group on vectors of integers via `on_tuples` +# - orbit of a perm. group on sets of integers via `on_sets` +function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: IntegerUnion + (action_function(Omega) == ^) || return _orbit_generic(Omega, omega) + return _orbit_special_GAP(Omega, omega) +end + +function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: Vector{<: IntegerUnion} + action_function(Omega) == on_tuples || return _orbit_generic(Omega, omega) + return _orbit_special_GAP(Omega, omega) +end + +function orbit(Omega::GSetByElements{PermGroup, S}, omega::S) where S <: Set{<: IntegerUnion} + action_function(Omega) == on_sets || return _orbit_generic(Omega, omega) + return _orbit_special_GAP(Omega, omega) +end + +function _orbit_special_GAP(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S G = acting_group(Omega) gfun = gap_action_function(Omega) orb = Vector{S}(GAP.Globals.Orbit(GapObj(G), GapObj(omega), gfun)::GapObj) From a492b17c33d1e7ec9680fcfa75814599e6421841 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Thu, 28 Nov 2024 20:37:20 +0100 Subject: [PATCH 18/21] avoid deprecated `QQBar` --- test/Groups/gsets.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Groups/gsets.jl b/test/Groups/gsets.jl index f1b5011d077d..5fc31b2f3867 100644 --- a/test/Groups/gsets.jl +++ b/test/Groups/gsets.jl @@ -366,12 +366,12 @@ end orb = orbit(G, f) @test length(orb) == 3 - - e = one(QQBar) + F = QQBarField() + e = one(F) s, c = sincospi(2 * e / 3) mat_rot = matrix([c -s; s c]) G = matrix_group(mat_rot) - p = QQBar.([1, 0]) + p = F.([1, 0]) orb = orbit(G, *, p) @test length(orb) == 3 From e13e033ceec465011283506c3f18c6b3e03f0acd Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Thu, 12 Dec 2024 13:19:23 +0100 Subject: [PATCH 19/21] special treatment for `stabilizer(Omega, ...)` --- src/Groups/action.jl | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Groups/action.jl b/src/Groups/action.jl index 776c4469fc7c..487d1058bf05 100644 --- a/src/Groups/action.jl +++ b/src/Groups/action.jl @@ -526,7 +526,9 @@ julia> S = stabilizer(G, [1, 1, 2, 2, 3], permuted); order(S[1]) 4 ``` """ -function stabilizer(G::GAPGroup, pnt::Any, actfun::Function) +stabilizer(G::GAPGroup, pnt::Any, actfun::Function) = _stabilizer_generic(G, pnt, actfun) + +function _stabilizer_generic(G::GAPGroup, pnt::Any, actfun::Function) return Oscar._as_subgroup(G, GAPWrap.Stabilizer(GapObj(G), pnt, GapObj(gens(G), recursive = true), GapObj(gens(G)), GapObj(actfun))) @@ -535,7 +537,10 @@ end # natural stabilizers in permutation groups # Construct the arguments on the GAP side such that GAP's method selection # can choose the special method. -function stabilizer(G::PermGroup, pnt::T) where T <: Oscar.IntegerUnion +# - stabilizer in a perm. group of an integer via `^` +# - stabilizer in a perm. group of a vector of integers via `on_tuples` +# - stabilizer in a perm. group of a set of integers via `on_sets` +function stabilizer(G::PermGroup, pnt::T) where T <: IntegerUnion return Oscar._as_subgroup(G, GAPWrap.Stabilizer(GapObj(G), GapObj(pnt), GAP.Globals.OnPoints)) # Do not use GAPWrap.OnPoints! @@ -553,6 +558,20 @@ function stabilizer(G::PermGroup, pnt::AbstractSet{T}) where T <: Oscar.IntegerU GAP.Globals.OnSets)) # Do not use GAPWrap.OnSets! end +# now the same with given action function, +# these calls may come from delegations from G-sets +function stabilizer(G::PermGroup, pnt::T, actfun::Function) where T <: IntegerUnion + return (actfun == ^) ? stabilizer(G, pnt) : _stabilizer_generic(G, pnt, actfun) +end + +function stabilizer(G::PermGroup, pnt::Vector{T}, actfun::Function) where T <: IntegerUnion + return actfun == on_tuples ? stabilizer(G, pnt) : _stabilizer_generic(G, pnt, actfun) +end + +function stabilizer(G::PermGroup, pnt::AbstractSet{T}, actfun::Function) where T <: IntegerUnion + return actfun == on_sets ? stabilizer(G, pnt) : _stabilizer_generic(G, pnt, actfun) +end + # natural stabilizers in matrix groups stabilizer(G::MatrixGroup{ET,MT}, pnt::AbstractAlgebra.Generic.FreeModuleElem{ET}) where {ET,MT} = stabilizer(G, pnt, *) From 220b216a7ed257382680009f3255c6570a901c4e Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Thu, 12 Dec 2024 13:27:37 +0100 Subject: [PATCH 20/21] Add timing tests (preliminary) --- examples/GSets_timing.jl | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 examples/GSets_timing.jl diff --git a/examples/GSets_timing.jl b/examples/GSets_timing.jl new file mode 100644 index 000000000000..5472eb1de01a --- /dev/null +++ b/examples/GSets_timing.jl @@ -0,0 +1,42 @@ +# "G-sets of permutation groups" + + + # natural constructions (determined by the types of the seeds) + G = symmetric_group(10) + + Omega = gset(G) + # @benchmark order(stabilizer(Omega, 1)[1]) + @benchmark order(stabilizer(Omega, Set([1, 2]))[1]) + @benchmark order(stabilizer(Omega, [1, 2])[1]) + @benchmark order(stabilizer(Omega, (1, 2))[1]) + + Omega = gset(G, [Set([1, 2])]) # action on unordered pairs + @benchmark order(stabilizer(Omega, Set([1, 2]))[1]) + @benchmark order(stabilizer(Omega, Set([Set([1, 2]), Set([1, 3])]))[1]) + @benchmark order(stabilizer(Omega, [Set([1, 2]), Set([1, 3])])[1]) + @benchmark order(stabilizer(Omega, (Set([1, 2]), Set([1, 3])))[1]) + + + Omega = gset(G, [[1, 2]]) # action on ordered pairs + @benchmark order(stabilizer(Omega, [1, 2])[1]) + @benchmark order(stabilizer(Omega, Set([[1, 2], [1, 3]]))[1]) + @benchmark order(stabilizer(Omega, [[1, 2], [1, 3]])[1]) + @benchmark order(stabilizer(Omega, ([1, 2], [1, 3]))[1]) + + + Omega = gset(G, [(1, 2)]) # action on ordered pairs (repres. by tuples) + @benchmark order(stabilizer(Omega, (1, 2))[1]) + @benchmark order(stabilizer(Omega, Set([(1, 2), (1, 3)]))[1]) + @benchmark order(stabilizer(Omega, [(1, 2), (1, 3)])[1]) + @benchmark order(stabilizer(Omega, ((1, 2), (1, 3)))[1]) + + + # constructions by explicit action functions + G = symmetric_group(6) + omega = [0,1,0,1,0,1] + Omega = gset(G, permuted, [omega, [1,2,3,4,5,6]]) + + @benchmark order(stabilizer(Omega, omega)[1]) + @benchmark order(stabilizer(Omega, Set([omega, [1,0,0,1,0,1]]))[1]) + @benchmark order(stabilizer(Omega, [omega, [1,0,0,1,0,1]])[1]) + @benchmark order(stabilizer(Omega, (omega, [1,0,0,1,0,1]))[1]) From 70189c0dd22a76e3bf080fdd683a3cc6cbb03294 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Thu, 12 Dec 2024 13:31:39 +0100 Subject: [PATCH 21/21] oops re: commented benchmark --- examples/GSets_timing.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/GSets_timing.jl b/examples/GSets_timing.jl index 5472eb1de01a..bc980067ede7 100644 --- a/examples/GSets_timing.jl +++ b/examples/GSets_timing.jl @@ -5,7 +5,7 @@ G = symmetric_group(10) Omega = gset(G) - # @benchmark order(stabilizer(Omega, 1)[1]) + @benchmark order(stabilizer(Omega, 1)[1]) @benchmark order(stabilizer(Omega, Set([1, 2]))[1]) @benchmark order(stabilizer(Omega, [1, 2])[1]) @benchmark order(stabilizer(Omega, (1, 2))[1])