oscar-system / Oscar.jl

A comprehensive open source computer algebra system for computations in algebra, geometry, and number theory.
https://www.oscar-system.org
Other
364 stars 129 forks source link

G Set improvements #4288

Open mjrodgers opened 2 weeks ago

mjrodgers commented 2 weeks ago

This is an overview of the outstanding issues regarding G sets, and is meant to track their current status.

fingolfin commented 2 weeks ago

Regarding the middle point, we currently do this:

    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,
    # or whether the elements of 'acts' are group elements.
    orb = Vector{S}(GAP.Globals.Orbit(GapObj(G), omega, acts, acts, gfun)::GapObj)

How about we replace the first line by

    gfun = gap_action_function(Omega)

and the new function takes care of the details. (Obviously other similar places also need to be changed, e.g. when calling GAP.Globals.Stabilizer).

At first I thought we can't just map on_tuples to GAP.Globals.OnTuples because, we want GAP to use our ^ Julia method instead of its OnPoints. But the GAP kernel function OnPoints is actually implemented by invoking the GAP kernel dispatcher POW, i.e., GAP's ^, which goes through regular GAP method dispatch. And we already have GAP methods there for the case were one argument is a Julia object, doing the right thing.

So I think we can just do something like this:

# 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

An obvious variation (trading a way a little bit of memory for a little bit gained speed) is to compute the gap_action_function when creating the G-set and storing it, but I think overall that's a relatively minor implementation detail.

mjrodgers commented 2 weeks ago

I can't seem to get this to work, I get strange GAP errors:

julia> collect(orbit(G,1))
ERROR: Error thrown by GAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 1st choice method found for `LargestMovedPoint' on 1 arguments at /Users/gek81vuf/.julia/artifacts/7a7471c3a274d605d85c06775fcb6f9962114ff7/share/gap/lib/methsel2.g:250 called from
LargestMovedPoint( gens ) at /Users/gek81vuf/.julia/artifacts/7a7471c3a274d605d85c06775fcb6f9962114ff7/share/gap/lib/grpperm.gi:204 called from
OrbitPerms( acts, pnt ) at /Users/gek81vuf/.julia/artifacts/7a7471c3a274d605d85c06775fcb6f9962114ff7/share/gap/lib/oprtperm.gi:31 called from
orbish( G, pnt, gens, acts, act ) at /Users/gek81vuf/.julia/artifacts/7a7471c3a274d605d85c06775fcb6f9962114ff7/share/gap/lib/oprt.gd:858 called from
<function "Orbit">( <arguments> )
 called from read-eval loop at *defin*:0

Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] ThrowObserver(depth::Int32)
   @ GAP ~/.julia/packages/GAP/m8wkY/src/GAP.jl:91

(oddly enough it works if I don't try to collect it)

fingolfin commented 2 weeks ago

@mjrodgers without seeing the concrete code, hard to comment. Perhaps open a draft PR?

orbit(G, 1) just creates a lazy G-set object, but performs no computation. collect is one way to actually trigger the computations. So that part of it is not surprising.

Actually collect(Omega) calls into iterate which calls elements which calls orbits(Omega) which finally calls orbit(Omega,1) which does the work... talk about layers sigh.

Playing with that a bit, I had to change GapObj(gens(G)) to GapObj(gens(G); recursive=true). Then the orbit computation worked.

Of course this may not what we want if the group acting is a non-GAP group (such as the Weyl groups by @lgoettgens and co, or our finite abelian groups). That's fine in so far as I expect there to be different handling in certain places (to make use of "optimizations" in some). I'd not worry too much about it initially, but of course dealing with those correctly should also be on our road map.