522522# # nicegens:=List(l[1],a->ResultOfStraightLineProgram(a,GeneratorsOfGroup(G)));
523523# # List(last, a->a^l[2]);
524524# #
525+
526+ # # Note does not work for q = 2,3,5
525527RecogNaturalSL2 := function (G, q )
526528 local GM, one, zero, qm1fac, c, m, gens, xm, x, pol, v, z, exp, a,
527529 mat, tm, ym, y, ymat, tr, d, cm, r1, r2, r, log, i, trupm,
@@ -707,74 +709,75 @@ end;
707709# # G must be SL(2,q) generated by 2x2 matrices over GF(q).
708710# # Note: does not work for q = 2, 3, 5.
709711ConRecogNaturalSL2 := function (G, f )
710- local q, res, nicegens, diag, u1, u2, umat, lmat, k, j, i, el, result, bas, true_diag, true_u1, true_u2, basi, p, basis, coeffs, m, c, l;
711- q := Size(f);
712- p := Characteristic(f);
713- j := DegreeOverPrimeField(GF(q));
714- # # standard generators of SL(2,q) in the natural representation
715- true_diag := [[ Z(q)^ (- 1 ),0 * Z(q)] ,[ 0 * Z(q),Z(q)]] ;
716- true_u1 := [[ Z(q)^ 0 ,0 * Z(q)] ,[ Z(q)^ 0 ,Z(q)^ 0 ]] ;
717- true_u2 := [[ Z(q)^ 0 ,Z(q)^ 0 ] ,[ 0 * Z(q),Z(q)^ 0 ]] ;
718- # # retry until RecogNaturalSL2 returns generators matching the standard form
719- for i in [ 1 .. 100 ] do
720- res := RecogNaturalSL2(G,q);
721- nicegens := List(res[ 1 ] ,a-> ResultOfStraightLineProgram(a,GeneratorsOfGroup(G)));
722- diag := nicegens[ 1 ] ;
723- u1 := nicegens[ 2 ] ;
724- u2 := nicegens[ 3 ] ;
725- # # check if we found the correct generators
726- if diag^ res[ 2 ] = true_diag and u1^ res[ 2 ] = true_u1 and u2^ res[ 2 ] = true_u2 then
727- break ;
728- fi ;
729- od ;
730-
731- if IsEvenInt(q) then
732- # # even characteristic: conjugation by diag generates all of GF(q)* directly
733- lmat := [] ;
734- for k in [ 0 .. j- 1 ] do
735- i := (q- 1 - k)* Int(2 )^- 1 mod (q- 1 );
736- el := u1^ (diag^ i);
737- Add(lmat,el);
738- od ;
739- umat := [] ;
740- for k in [ 0 .. j- 1 ] do
741- i := k * Int(2 )^- 1 mod (q- 1 );
742- el := u2^ (diag^ i);
743- Add(umat, el);
744- od ;
745- else
746- # # odd characteristic: conjugation only yields squares, so express z^l
747- # # in the Fp-basis {z^0, z^2, ..., z^(2(j-1))} and multiply conjugates
748- basis := List([ 0 .. j- 1 ] , i -> Z(q)^ (2 * i));
749- lmat := [] ;
750- for l in [ 0 .. j- 1 ] do
751- coeffs := Coefficients(Basis(GF(q), basis), Z(q)^ l);
752- m := u1^ 0 ;
753- for i in [ 0 .. j- 1 ] do
754- c := IntFFE(coeffs[ i+ 1 ] );
755- m := m * (diag^ i * u1 * diag^ (- i))^ c;
756- od ;
757- Add(lmat, m);
758- od ;
759- umat := [] ;
760- for l in [ 0 .. j- 1 ] do
761- coeffs := Coefficients(Basis(GF(q), basis), Z(q)^ l);
762- m := u2^ 0 ;
763- for i in [ 0 .. j- 1 ] do
764- c := IntFFE(coeffs[ i+ 1 ] );
765- m := m * (diag^ (- i) * u2 * diag^ i)^ c;
766- od ;
767- Add(umat, m);
768- od ;
769- fi ;
770- basi := res[ 2 ] ;
771- bas := basi^ (- 1 );
772- result := rec ( g := G, t := lmat, s := umat, bas := bas, basi := basi,
773- one := One(f), a := umat[ 1 ] * lmat[ 1 ] * umat[ 1 ] , b := One(umat[ 1 ] ),
774- One := One(umat[ 1 ] ), f := f, q := q, p := Characteristic(f), ext := j,
775- d := 2 );
776- result.all := Concatenation(result.s,result.t,[ result.a] ,[ result.b] );
777- return result;
712+ local q, res, nicegens, diag, u1, u2, umat, lmat, k, j, i, el, result, bas, true_diag, true_u1, true_u2, basi, p, basis, coeffs, m, c, l;
713+ q := Size(f);
714+ p := Characteristic(f);
715+ j := DegreeOverPrimeField(GF(q));
716+ # # standard generators of SL(2,q) in the natural representation
717+ true_diag := [[ Z(q)^ (- 1 ),0 * Z(q)] ,[ 0 * Z(q),Z(q)]] ;
718+ true_u1 := [[ Z(q)^ 0 ,0 * Z(q)] ,[ Z(q)^ 0 ,Z(q)^ 0 ]] ;
719+ true_u2 := [[ Z(q)^ 0 ,Z(q)^ 0 ] ,[ 0 * Z(q),Z(q)^ 0 ]] ;
720+ # # retry until RecogNaturalSL2 returns generators matching the standard form
721+ for i in [ 1 .. 100 ] do
722+ res := RecogNaturalSL2(G,q);
723+ nicegens := List(res[ 1 ] ,a-> ResultOfStraightLineProgram(a,GeneratorsOfGroup(G)));
724+ diag := nicegens[ 1 ] ;
725+ u1 := nicegens[ 2 ] ;
726+ u2 := nicegens[ 3 ] ;
727+ # # check if we found the correct generators
728+ if diag^ res[ 2 ] = true_diag and u1^ res[ 2 ] = true_u1 and u2^ res[ 2 ] = true_u2 then
729+ break ;
730+ fi ;
731+ od ;
732+
733+ if IsEvenInt(q) then
734+ # # even characteristic: conjugation by diag generates all of GF(q)* directly
735+ lmat := [] ;
736+ for k in [ 0 .. j- 1 ] do
737+ i := (q- 1 - k)* Int(2 )^- 1 mod (q- 1 );
738+ el := u1^ (diag^ i);
739+ Add(lmat,el);
740+ od ;
741+ umat := [] ;
742+ for k in [ 0 .. j- 1 ] do
743+ i := k * Int(2 )^- 1 mod (q- 1 );
744+ el := u2^ (diag^ i);
745+ Add(umat, el);
746+ od ;
747+ else
748+ # # odd characteristic: conjugation only yields squares, so express z^l
749+ # # in the Fp-basis {z^0, z^2, ..., z^(2(j-1))} and multiply conjugates
750+ basis := List([ 0 .. j- 1 ] , i -> Z(q)^ (2 * i));
751+ lmat := [] ;
752+ for l in [ 0 .. j- 1 ] do
753+ coeffs := Coefficients(Basis(GF(q), basis), Z(q)^ l);
754+ m := u1^ 0 ;
755+ for i in [ 0 .. j- 1 ] do
756+ c := IntFFE(coeffs[ i+ 1 ] );
757+ m := m * (diag^ i * u1 * diag^ (- i))^ c;
758+ od ;
759+ Add(lmat, m);
760+ od ;
761+ umat := [] ;
762+ for l in [ 0 .. j- 1 ] do
763+ coeffs := Coefficients(Basis(GF(q), basis), Z(q)^ l);
764+ m := u2^ 0 ;
765+ for i in [ 0 .. j- 1 ] do
766+ c := IntFFE(coeffs[ i+ 1 ] );
767+ m := m * (diag^ (- i) * u2 * diag^ i)^ c;
768+ od ;
769+ Add(umat, m);
770+ od ;
771+ fi ;
772+ basi := res[ 2 ] ;
773+ bas := basi^ (- 1 );
774+ a := umat[ 1 ] ^ (- 1 )* lmat[ 1 ] * umat[ 1 ] ^ (- 1 );
775+ b := One(umat[ 1 ] );
776+ result := rec ( g := G, t := lmat, s := umat, bas := bas, basi := basi,
777+ one := One(f), a := a, b := b,
778+ all := Concatenation(umat,lmat,[ a] ,[ b] ), One := One(umat[ 1 ] ), f := f,
779+ q := q, p := Characteristic(f), ext := j, d := 2 );
780+ return result;
778781end ;
779782
780783
@@ -783,43 +786,44 @@ end;
783786# # Input: either a list of prime powers or the empty list
784787# # (then a preset list of prime powers is tested).
785788test_ConRecogNaturalSL2 := function (input )
786- local i, G, list, qlist, res_old, res, f, q, valid;
787- if input = [] then
789+ local i, G, list, qlist, res_old, res, f, q, valid;
790+ if input = [] then
788791 qlist := [ 2 ^ 3 , 2 ^ 5 , 3 ^ 4 , 25 , 17 ^ 3 , 9967 ] ;
789- elif Size(input)> 0 then
792+ elif Size(input)> 0 then
790793 qlist := [] ;
791- for q in input do
792- if IsPrimePowerInt(q) then
793- Add(qlist, q);
794- fi ;
795- od ;
796- fi ;
797- valid := true ;
798- for q in qlist do
799- Print(" testing q = " , q, " \n " );
794+ for q in input do
795+ if IsPrimePowerInt(q) then
796+ Add(qlist, q);
797+ fi ;
798+ od ;
799+ fi ;
800+
801+ valid := true ;
802+ for q in qlist do
803+ Print(" testing q = " , q, " \n " );
800804 f := GF(q);
801805 list := [] ;
802- for i in [ 1 .. 5 ] do
803- Add(list, Random(SL(2 ,q)));
804- od ;
806+ for i in [ 1 .. 5 ] do
807+ Add(list, Random(SL(2 ,q)));
808+ od ;
805809 G := GroupWithGenerators(list);
806- if IsEvenInt(q) then
807- res_old := RECOG.RecogniseSL2NaturalEvenChar(G,f,false );
808- else
809- res_old := RECOG.RecogniseSL2NaturalOddCharUsingBSGS(G,f);
810- fi ;
810+ if IsEvenInt(q) then
811+ res_old := RECOG.RecogniseSL2NaturalEvenChar(G,f,false );
812+ else
813+ res_old := RECOG.RecogniseSL2NaturalOddCharUsingBSGS(G,f);
814+ fi ;
811815 res := ConRecogNaturalSL2(G,f);
812- # # compare all generators after change of basis
813- for i in [ 1 .. Length(res.all)] do
814- if res.all[ i] ^ res.basi <> res_old.all[ i] ^ res_old.basi then
815- Print(" Test failed for q = " , q, " , index i = " , i, " \n " );
816+ # # compare all generators after change of basis
817+ for i in [ 1 .. Length(res.all)] do
818+ if res.all[ i] ^ res.basi <> res_old.all[ i] ^ res_old.basi then
819+ Print(" Test failed for q = " , q, " , index i = " , i, " in the list \" all \" failed \n " );
816820 valid := false ;
817- fi ;
818- od ;
819- od ;
820- if valid then
821- Print(" All tests passed.\n " );
822- fi ;
821+ fi ;
822+ od ;
823+ od ;
824+ if valid then
825+ Print(" All tests passed.\n " );
826+ fi ;
823827end ;
824828
825829
0 commit comments