Skip to content

Comments

Transfer more properties (such as IsNaturalSL, InvariantQuadraticForm etc.) when conjugating matrix groups#6183

Merged
fingolfin merged 6 commits intogap-system:masterfrom
lgoettgens:lg/matgrp-conjugate
Jan 16, 2026
Merged

Transfer more properties (such as IsNaturalSL, InvariantQuadraticForm etc.) when conjugating matrix groups#6183
fingolfin merged 6 commits intogap-system:masterfrom
lgoettgens:lg/matgrp-conjugate

Conversation

@lgoettgens
Copy link
Member

Resolves #5635.

If I am not mistaken the formula for adapting the forms from #5635 (comment) does not work. The one present in this PR might work, but I would prefer if this would be double-checked.

@lgoettgens lgoettgens added kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements topic: library release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes labels Dec 19, 2025
@fingolfin
Copy link
Member

@lgoettgens thanks! I just had asked a student of mine to look into this. I am not surprised if any of the formulas I wrote there were not quite right (or dead wrong), it was written off the cuff without too much thought; the goal was more to convey the general idea. Sorry if this caused any extra work, and thank you for correcting it!

@chseeger ping -- perhaps you can see if this matches what you need, and/or work with Lars to get it over the finishing line.

I guess there are a few more things we could / should transfer:

  • IsGL aka IsGeneralLinearGroup
  • IsNaturalGL
  • IsSL aka IsSpecialLinearGroup
  • IsNaturalSL
  • IsSubgroupSL

lib/grpmat.gi Outdated
ginv := g^-1;
fi;
if HasInvariantBilinearForm( G ) then
m := ginv * InvariantBilinearForm(G).matrix * TransposedMat(ginv);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have test cases covering this.

I think the easiest and also most thorough way will be to modify tst/testinstall/grp/classic-forms.tst.

When it does e.g.

gap> grps:=[];;
gap> for d in [3,5,7] do
>   for q in [2,3,4,5,7,8,9,16,17,25,27] do
>     Add(grps, GO(d,q));
>   od;
> od;

the innermost loop could be changed to also add a conjugate copy of the group, i.e.

>     Add(grps, GO(d,q));
>     Add(grps, GO(d,q) ^ RandomInvertibleMat(d,GF(q));

In light of what I write in my other comment, perhaps we should also test conjugation over different fields, e.g.

Add(grps, GO(d,q) ^ RandomInvertibleMat(d,GF(q^2));

and for the unitary case deliberately over fields such as q^3 (instead of q^2)

lib/grpmat.gi Outdated
SetInvariantBilinearForm( H, rec( matrix := m ) );
fi;
if HasInvariantSesquilinearForm( G ) then
m := ginv * InvariantSesquilinearForm(G).matrix * TransposedMat(ginv);
Copy link
Member

@fingolfin fingolfin Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect that the "right" Frobenius automorphism needs to be used here, too?

But actually, that's a problem now that I think about it. Or rather, two problems:

First off, conceptually, GAP does not actually specify over which field the group is sesquilinear. The documentation for InvariantSesquilinearForm says "over over the field F with q^2 elements" but which field is that? Perhaps over the DefaultFieldOfMatrixGroup(G) ? But strictly speaking that is not really well-defined. Or FieldOfMatrixGroup(G) ? That's well-defined but may be too small (think of the case where q = p^2 is the square of a prime, and we by "accident" are looking at a subgroup of G < GU(d,q) < GL(d,q^2) which has all entries in GF(q) then we might think the right Frobenius exponent is $p$ instead of $q=p^2$.

Second, assuming we have determined $F$ resp. $q$ correctly, we need to be aware of the case were $g$ is not defined over GF(q^2) but rather over field that's not a subfield of GF(q^2) (so over a larger field; or if $q=p^2$ then it could be defined over GF(p^3)$; etc.). Should we perhaps error out then? Because the resulting group may be defined over a larger field and then the assumptions about the former don't necessarily hold anymore...

Copy link
Member Author

@lgoettgens lgoettgens Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I'll remove everything concerning sesquilinear forms from this PR.

For IsFullSubgroupGLorSLRespectingBilinearForm and IsFullSubgroupGLorSLRespectingQuadraticForm, there is also the question over which field this should hold. But since the only places where these are used (

gap/lib/grpmat.gi

Lines 841 to 865 in 8177f1e

InstallMethod( \in, "respecting quadratic form", IsElmsColls,
[ IsMatrix, IsFullSubgroupGLorSLRespectingQuadraticForm ],
{} -> RankFilter( IsHandledByNiceMonomorphism ), # override nice mon. method
# this method is better than the one using a nice monom.;
# it has the same rank as the method based on the inv.
# bilinear form, which is cheaper to check,
# thus we install the current method first
function( mat, G )
return IsSubset( FieldOfMatrixGroup( G ), FieldOfMatrixList( [ mat ] ) )
and ( not IsSubgroupSL( G ) or IsOne( DeterminantMat( mat ) ) )
and RespectsQuadraticForm( InvariantQuadraticForm( G ).matrix, mat );
end );
InstallMethod( \in, "respecting bilinear form", IsElmsColls,
[ IsMatrix, IsFullSubgroupGLorSLRespectingBilinearForm ],
{} -> RankFilter( IsHandledByNiceMonomorphism ), # override nice mon. method
function( mat, G )
local inv;
if not IsSubset( FieldOfMatrixGroup( G ), FieldOfMatrixList( [ mat ] ) )
or ( IsSubgroupSL( G ) and not IsOne( DeterminantMat( mat ) ) ) then
return false;
fi;
inv:= InvariantBilinearForm(G).matrix;
return mat * inv * TransposedMat( mat ) = inv;
end );
) assume it is FieldOfGroup, I added this to the docstrings of these two functions as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, in the same place we learn something about how these sesquilinear forms are supposed to work:

gap/lib/grpmat.gi

Lines 841 to 865 in 8177f1e

InstallMethod( \in, "respecting quadratic form", IsElmsColls,
[ IsMatrix, IsFullSubgroupGLorSLRespectingQuadraticForm ],
{} -> RankFilter( IsHandledByNiceMonomorphism ), # override nice mon. method
# this method is better than the one using a nice monom.;
# it has the same rank as the method based on the inv.
# bilinear form, which is cheaper to check,
# thus we install the current method first
function( mat, G )
return IsSubset( FieldOfMatrixGroup( G ), FieldOfMatrixList( [ mat ] ) )
and ( not IsSubgroupSL( G ) or IsOne( DeterminantMat( mat ) ) )
and RespectsQuadraticForm( InvariantQuadraticForm( G ).matrix, mat );
end );
InstallMethod( \in, "respecting bilinear form", IsElmsColls,
[ IsMatrix, IsFullSubgroupGLorSLRespectingBilinearForm ],
{} -> RankFilter( IsHandledByNiceMonomorphism ), # override nice mon. method
function( mat, G )
local inv;
if not IsSubset( FieldOfMatrixGroup( G ), FieldOfMatrixList( [ mat ] ) )
or ( IsSubgroupSL( G ) and not IsOne( DeterminantMat( mat ) ) ) then
return false;
fi;
inv:= InvariantBilinearForm(G).matrix;
return mat * inv * TransposedMat( mat ) = inv;
end );

Here, FieldOfMatrixGroup is used to determine the "right" frobenius

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, OK -- I guess this would be fine for now given that the only two places which call SetInvariantSesquilinearForm also call SetFieldOfMatrixGroup.

On the long term it's not a great, because it means we can't use InvariantSesquilinearForm on subgroups.

But we are not there, and so we might as well use what works in the current system.

It does mean though that when conjugating, we have to check if the conjugating matrix is defined over FieldOfMatrixGroup(mat) (or a subfield of that), and only transfer the matrix if it is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that the field of the conjugating matrix g is relevant here. The important part is that G and G^g are defined over the same field, so that the "same" frobenius is involved.

I have some code for this now (not pushed yet), but when trying to write tests, I run into contradictions. In particular, consider the following:

gap> G:=SU(2,2);
SU(2,2)
gap> FieldOfMatrixGroup(G);
GF(2^2)
gap> GeneratorsOfGroup(G);
[ [ [ Z(2)^0, Z(2)^0 ], [ 0*Z(2), Z(2)^0 ] ], [ [ 0*Z(2), Z(2)^0 ], [ Z(2)^0, 0*Z(2) ] ] ]
gap> FieldOfMatrixList(GeneratorsOfGroup(G));
GF(2)

Obviously, a group that is generated by matrices over GF(2) should not state that the smallest field it is defineable over is GF(2^2).
So I have no idea on how to follow-up with the sesquilinear stuff (but we can from my POV also just move this to a future PR).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The observation about SU(2,2) is funny.

Indeed, for even q, the groups SL(2,q) and SU(2,q) are not only isomorphic (this is true for any prime power q) but they are equal, that is, the matrices in SL(2,q^2) that respect the given sesquilinear form live over GF(q).

This seems to show that

  • the code that constructs the SU groups sets wrong FieldOfMatrixGroup values and
  • the idea to define the IsFullSubgroup... filters relative to the FieldOfMatrixGroup value for the group does not work.

Apparently we have a conceptual problem (well, at least one) here.

@chseeger
Copy link

Thanks a lot for taking a look at this -- it matches exactly what I need, and the conjugation formulas for the preserved bilinear/quadratic forms look correct.

For sesquilinear forms, however, I'm unsure how to resolve the choice of Frobenius automorphism, given the ambiguity of the underlying field. This seems to be a more conceptual issue?

@lgoettgens lgoettgens changed the title Transfer invariant forms when conjugating matrix groups Transfer more properties when conjugating matrix groups Dec 22, 2025
@lgoettgens
Copy link
Member Author

The tests fail as they test the existence of some nice monomorphisms on the conjugated group. I think that my new dispatch has a higher priority as the one that handles nice monomorphisms. But that one is defined through some meta code at

GroupMethodByNiceMonomorphismCollElm( ConjugateGroup,
, where I don't really know how to hook into.

@fingolfin
Copy link
Member

That code was written (or at least recently rewritten) by @ThomasBreuer, maybe he can help:

basically the code in this PR is clashing with this:

GroupMethodByNiceMonomorphismCollElm( ConjugateGroup,
    [ IsGroup and HasParent, IsMultiplicativeElementWithInverse ] );

I think it is good that the code in this PR has a higher priority, but I wonder if there is something to be combined here.

In particular, GroupMethodByNiceMonomorphismCollElm tries to "transfer" any nice mono known for the original group $G$ to (in the case at hand) the conjugate group $G^x$. In the current implementation that is only possible if the element $x$ can be mapped under the nice mono.

Perhaps the code in here could be modified to also deal with situation: it does transport all kind of information, after all; so it would make some sense to also try to transport any nice mono. It could do so by imitating the code in GroupMethodByNiceMonomorphismCollElm.

Or it could also use a different technique: it could compose the nice mono with a ConjugatorIsomorphism -- only problem is that the current form of ConjugatorIsomorphism calls ConjugateGroup, so that'd be circular sigh. (This could be overcome, though, by adding an internal variant that takes the conjugated group as an additional input).

@fingolfin
Copy link
Member

Actually, I think in this case the test really should be changed... but I'll also add logic to transfer the nice mono. And I made PR #6194 -- but in the end don't want to use it here (e.g. it lacks the ginv optimization, and anyway the code I'll add is simpler)

But trying to do so, I keep finding additional issues...

@ThomasBreuer if I edit tst/testinstall/mapping.tst:494 to change ConjugateGroup to ClosureGroup then the test also fails, for the same reason (expects true, gets fail for HasIsHandledByNiceMonomorphism( g2 );). That's because it does not end up actually using the nice mono because it does not handle C. It "works" if further change ClosureGroup( g2, C ) to ClosureGroup( g2, B ) (which is what I have done now).

But before that I tried something else: namely, after creating g I called NiceMonomorphism(g) to force a nice mono for it, which then its subgroups could inherit. The idea was that then ClosureGroup( g2, C ) would be able to use the nice mono... but to my surprise it run into a strange error, see issue #6195.

@fingolfin
Copy link
Member

We could also transfer the nice mono if we think this is suitable:

diff --git a/lib/grpmat.gi b/lib/grpmat.gi
index 1f0940b39c..17f6747f3c 100644
--- a/lib/grpmat.gi
+++ b/lib/grpmat.gi
@@ -1274,7 +1274,7 @@ InstallMethod( InvariantBilinearForm,
 InstallMethod( ConjugateGroup, "<G>, <g>", IsCollsElms,
     [ IsMatrixGroup, IsMultiplicativeElementWithInverse ],
     function( G, g )
-    local   H, m, ginv;
+    local   H, m, ginv, nice, conj;
 
     H := GroupByGenerators( OnTuples( GeneratorsOfGroup( G ), g ), One(G) );
     UseIsomorphismRelation( G, H );
@@ -1314,5 +1314,16 @@ InstallMethod( ConjugateGroup, "<G>, <g>", IsCollsElms,
         SetIsFullSubgroupGLorSLRespectingQuadraticForm( H, true );
       fi;
     fi;
+    if HasNiceMonomorphism( G ) then
+        nice := NiceMonomorphism( G );
+        if not IsBound(ginv) then
+          ginv := g^-1;
+        fi;
+        conj := GroupHomomorphismByFunction( H, G, y -> g*y*ginv, x -> ginv*x*g );
+        SetNiceMonomorphism( H, conj * nice );
+        if HasNiceObject( G ) then
+          SetNiceObject( H, NiceObject( G ) );
+        fi;
+    fi;
     return H;
 end );

@ThomasBreuer
Copy link
Contributor

I think that using nice monomorphisms in ConjugateGroup methods is a bad idea:
When it works (that is, when the conjugating element can be mapped under the nice monomorphism of the group) then one first maps the group and the element under the nice monomorphism, then conjugates in the image, and then pulls back the result under the monomorphism. The group which one gets this way knows almost nothing except the nice monomorphism. And in general this will not work because the conjugating element will not fit.

Therefore I will make a pull request that removes ConjugateGroup from the operations for which nice monomorphisms are used.

@fingolfin fingolfin changed the title Transfer more properties when conjugating matrix groups Transfer more properties (such as IsNaturalSL, InvariantQuadraticForm etc.) when conjugating matrix groups Jan 16, 2026
@fingolfin fingolfin merged commit e019806 into gap-system:master Jan 16, 2026
32 checks passed
@lgoettgens lgoettgens deleted the lg/matgrp-conjugate branch January 16, 2026 13:13
hulpke pushed a commit to hulpke/gap that referenced this pull request Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes topic: library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Transfer more information when conjugating a matrix group

4 participants