Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

G Set improvements #4288

Open
3 tasks
mjrodgers opened this issue Nov 7, 2024 · 1 comment
Open
3 tasks

G Set improvements #4288

mjrodgers opened this issue Nov 7, 2024 · 1 comment

Comments

@mjrodgers
Copy link
Collaborator

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

  • We need to improve computation of GAP orbits on Julia objects (see GAP orbits on Julia objects #722). The obstacle here is that GAP deals with Julia objects in a way that does not utilize hashes, and so defaults to slow heuristics. One proposed possibility for dealing with this is using the NewDictionary function to basically inject a wrapper around Julia.hash to use when computing orbits; in the future the NewDictionary function could be modified to turn it into an "operation" (in GAP parlance), which would then return a new type of "dictionary" object (possibly a wrapper around Julia's Dict).
  • We should speed up computation of orbits on integers (see Orbits of permutation groups on integers should be faster #3287). The linked issue has some benchmarks that show that some orbit computations in OSCAR are much slower than in GAP. This is possibly related to the fact that GAP does not directly use OnPoints, but instead a wrapper function calling Julia's ^ operator, which then effectively delegates to OnPoints; in addition to the overhead created, this prevents GAP from detecting some "easy" cases.
  • We should implement G sets arising from the orbit of a matrix group on subspaces of the associated vector space.
@fingolfin
Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants