gap-packages / forms

Forms -- sesquilinear and quadratic, a package for GAP
https://gap-packages.github.io/forms
2 stars 3 forks source link

Definition of canonical form unclear #27

Open fingolfin opened 2 years ago

fingolfin commented 2 years ago

Consider this example:

gap> gram:=DiagonalMat([2,1,1,1,1,1]*Z(5)^0);;
gap> form := BilinearFormByMatrix( gram, GF(5) );
< bilinear form >
gap> Display(form);
Bilinear form
Gram Matrix:
 2 . . . . .
 . 1 . . . .
 . . 1 . . .
 . . . 1 . .
 . . . . 1 .
 . . . . . 1
gap> Display(IsometricCanonicalForm(form));
Elliptic bilinear form
Gram Matrix:
 1 . . . . .
 . 2 . . . .
 . . . 3 . .
 . . 3 . . .
 . . . . . 3
 . . . . 3 .
Witt Index: 2

I don't understand how this form fits with the description of "canonical forms" in chapter 5 of the forms manual. Based on that, I would have expected this Gram matrix

 2 . . . . .
 . 1 . . . .
 . . . 1 . .
 . . 1 . . .
 . . . . . 1
 . . . . 1 .

Granted, these two forms are similar, but I thought we really get the canonical form?

What am I missing?

fingolfin commented 12 months ago

Case in point: the manual includes examples/include/basechangehom.include as an example. There we see this example:

gl:=GL(3,3);
go:=GO(3,3);
form := PreservedSesquilinearForms(go)[1]; 
gram := GramMatrix( form );  
b := BaseChangeToCanonical(form);;
hom := BaseChangeHomomorphism(b, GF(3));
newgo := Image(hom, go); 
gens := GeneratorsOfGroup(newgo);;
canonical := b * gram * TransposedMat(b);

In the pre-generated .include file and hence in the manual, it claims this is the output:

 1 . .
 . . 2
 . 2 .

But when actually running the code, we get

 2 . .
 . . 1
 . 1 .

Well, actually... running the code multiple times, I sometimes get the one and sometimes the other... so much for "canonical"...

fingolfin commented 12 months ago

@johnbamberg @jdebeule if you next look at forms, perhaps you could also briefly consider this issue...

fingolfin commented 8 months ago

So what I described here so far is only about a scalar multiple. We can't kill scalars in BaseChangeToCanonical, which only can work up to similarity.

Alas for IsometricCanonicalForm I would expect it to produce "the" canonical form?

But beyond that, after the (false) issue #65 I now believe that the description of canonical forms in section 5.1-3 is wrong: in the case where $U$ has dimension 2, the value of $\mu$ should not always be a non-square. Instead I think it should be a non-square for $n\equiv 1 \mod 4$ and a square (so e.g. $1$) when $n\equiv 3\mod 4$.

@johnbamberg @jdebeule can you confirm?

jdebeule commented 1 month ago

Hmm... I thought at first sight this was going to be easy. At the documentation has to be made more precise. But I do not see immediately why multiple calls can produce different output. Once again it makes clear that we did this particular part of the code (24 years ago) from the viewpoint of projective geometry: we don't care up to scalar... We will find the problem!

fingolfin commented 1 month ago

Of course one can explain some of this by "up to scalar", but then indeed this needs to be clarified in the manual.

And in some situation, whether the question is "up to scalar", or not, requires two different answers. Both of which may be useful (and e.g. the request #43 to adding constructors for "conformal groups" is one of these: if we go "up to scalar" then instead of orthogonal groups we should consider conformal groups).

In my example where the output changes, it all, depends on which preserved form is produced by PreservedSesquilinearForms. Sometimes I see this:

gap> gl:=GL(3,3);
GL(3,3)
gap> go:=GO(3,3);
GO(0,3,3)
gap> form := PreservedSesquilinearForms(go)[1];
< bilinear form >
gap> gram := GramMatrix( form );
[ [ 0*Z(3), Z(3), 0*Z(3) ], [ Z(3), 0*Z(3), 0*Z(3) ], [ 0*Z(3), 0*Z(3), Z(3)^0 ] ]
gap> Display(gram);
 . 2 .
 2 . .
 . . 1
gap> b := BaseChangeToCanonical(form);;
gap> hom := BaseChangeHomomorphism(b, GF(3));
^[ [ 0*Z(3), Z(3)^0, 0*Z(3) ], [ Z(3), Z(3), Z(3)^0 ], [ Z(3)^0, Z(3), 0*Z(3) ] ]
gap> newgo := Image(hom, go);
Group([ [ [ Z(3)^0, Z(3)^0, 0*Z(3) ], [ 0*Z(3), Z(3), 0*Z(3) ], [ Z(3), Z(3)^0, Z(3) ] ],
  [ [ Z(3)^0, Z(3), 0*Z(3) ], [ Z(3), Z(3), Z(3)^0 ], [ 0*Z(3), Z(3)^0, 0*Z(3) ] ] ])
gap> gens := GeneratorsOfGroup(newgo);;
gap> canonical := b * gram * TransposedMat(b);
[ [ Z(3)^0, 0*Z(3), 0*Z(3) ], [ 0*Z(3), 0*Z(3), Z(3) ], [ 0*Z(3), Z(3), 0*Z(3) ] ]
gap> Display(canonical);
 1 . .
 . . 2
 . 2 .

and sometimes I get this:

gap> gl:=GL(3,3);
GL(3,3)
gap> go:=GO(3,3);
GO(0,3,3)
gap> form := PreservedSesquilinearForms(go)[1];
< bilinear form >
gap> gram := GramMatrix( form );
[ [ 0*Z(3), Z(3)^0, 0*Z(3) ], [ Z(3)^0, 0*Z(3), 0*Z(3) ], [ 0*Z(3), 0*Z(3), Z(3) ] ]
gap> Display(gram);
 . 1 .
 1 . .
 . . 2
gap> b := BaseChangeToCanonical(form);;
gap> hom := BaseChangeHomomorphism(b, GF(3));
^[ [ 0*Z(3), 0*Z(3), Z(3) ], [ Z(3), Z(3), Z(3)^0 ], [ Z(3), 0*Z(3), Z(3) ] ]
gap> newgo := Image(hom, go);
Group([ [ [ Z(3)^0, 0*Z(3), Z(3) ], [ Z(3)^0, Z(3), Z(3)^0 ], [ 0*Z(3), 0*Z(3), Z(3) ] ],
  [ [ Z(3), Z(3)^0, 0*Z(3) ], [ 0*Z(3), Z(3), 0*Z(3) ], [ Z(3)^0, Z(3)^0, Z(3) ] ] ])
gap> gens := GeneratorsOfGroup(newgo);;
gap> canonical := b * gram * TransposedMat(b);
[ [ Z(3), 0*Z(3), 0*Z(3) ], [ 0*Z(3), 0*Z(3), Z(3)^0 ], [ 0*Z(3), Z(3)^0, 0*Z(3) ] ]
gap> Display(canonical);
 2 . .
 . . 1
 . 1 .

So yeah, the base change cannot get rid of the scalar at the end. To make it stable, PreservedSesquilinearForms would have to take care of that and e.g. force the first non-zero entry of the first row to be 1. Then I think the output will become stable.

Then the documentation for BaseChangeToCanonical could be augmented to explain that the final form can only be canonical up to a scalar for mathematical reasons.