Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  classical.g   Sprache: unbekannt

 
########################################
# Classical Group Recognition in GAP4  #
#                                      #
########################################


#global record that will keep track of info
recognise := rec();


SetReturnNPFlags := function( grp, case )

   # first we check whether we found some evidence that the case was wrong
   if case = "symplectic"  and
       PositionProperty(recognise.E, x ->(x mod 2 <> 0)) <> false then
           #InfoRecog1("#I  The group does not preserve a symplectic form\n");
           recognise.type := "unknown";
           recognise.isGeneric := false;
           recognise.possibleOverLargerField := true;
           recognise.possibleNearlySimple := Set([]);
           return false;
   fi;
   if case = "unitary"  and
      PositionProperty(recognise.E, x ->(x mod 2 = 0)) <> false then
           #InfoRecog1("#I  The group does not preserve a unitary form\n");
           recognise.type := "unknown";
           recognise.isGeneric := false;
           recognise.possibleOverLargerField := true;
           recognise.possibleNearlySimple := Set([]);
           return false;
   fi;
  if case in ["orthogonalminus","orthogonalplus","orthogonalcircle"] and
        PositionProperty(recognise.E, x ->(x mod 2 <> 0)) <> false then
           #InfoRecog1("#I  The group does not preserve a quadratic form\n");
           recognise.type := "unknown";
           recognise.isGeneric := false;
           recognise.possibleOverLargerField := true;
           recognise.possibleNearlySimple := Set([]);
           return false;
   fi;

   #SetIsSymplecticGroupFlag( recognise, false );
   recognise.isSymplecticGroup := false;
   #SetIsOrthogonalGroupFlag( recognise, false );
   recognise.isOrthogonalGroup := false;
   #SetIsUnitaryGroupFlag( recognise, false );
   recognise.isUnitaryGroup := false;
   #SetIsSLContainedFlag( recognise, false );
   recognise.isSLContained := false;
   if case = "linear"  then
       #SetIsSLContainedFlag( recognise, true  );
       recognise.isSLContained := true;
   elif case = "symplectic"  then
       #SetIsSymplecticGroupFlag( recognise, true  );
       recognise.isSymplecticGroup := true;
   elif case = "unitary"  then
       #SetIsUnitaryGroupFlag( recognise, true  );
       recognise.isUnitaryGroup := true;
   elif case in ["orthogonalminus","orthogonalplus","orthogonalcircle"] then
       #SetIsOrthogonalGroupFlag( recognise, true  );
       recognise.isOrthogonalGroup := true;
   fi;
   #set the group type
   recognise.type := case;
   Unbind (recognise.dimsReducible);
   Unbind (recognise.possibleOverLargerField);
   Unbind (recognise.possibleNearlySimple);
   return true;

end;


#Initialise the record based on group  structure
InitRecog := function (grp,case)
   local f;

   f := FieldOfMatrixGroup(grp);

   recognise := rec( d := DegreeOfMatrixGroup(grp),
                     p := Characteristic(f),
                     a := DegreeOverPrimeField(f),
                     q := Characteristic(f)^DegreeOverPrimeField(f),
                     E := Set([]), LE := Set([]), basic := false,
                     n := 0,
                     isReducible := "unknown",
                     isGeneric := false,
                     type := case,
                     possibleOverLargerField := true,
                     possibleNearlySimple := Set([]),
                     dimsReducible := [],
                     orders := Set([]),
                     isSLContained := "unknown",
                     isSymplecticGroup := "unknown",
                     isOrthogonalGroup := "unknown",
                     isUnitaryGroup := "unknown",
                    );
 end;

# Compute the degrees of the irreducible factors of
# the characteristic polynomial <cpol>
IsReducible := function(grp,cpol)
  local deg, dims,g;

  #reducible groups still possible?
  if recognise.isReducible = false then
     return false;
  fi;

  #compute the degrees of the irreducible factors
  deg := List(Factors(cpol));

  #compute all possible dimensions
  dims := [0];
  for g in deg do
     UniteSet(dims,dims+g);
  od;

  #intersect it with recognise.dimsReducible
  if IsEmpty(recognise.dimsReducible) then
      recognise.dimsReducible := dims;
  else
      IntersectSet(recognise.dimsReducible,dims);
  fi;

  # G acts irreducibly if only 0 and d are possible
  if Length(recognise.dimsReducible = 2) then
      recognise.isReducible := false;
      #TODO: INFORECOG2?
     return false;
  fi;

  return true;
end;


#Test a random element Re: implementation paper. See GAP3 for better
#comment for now. TODO: Update comments to something reasonable
TestRandomElement := function (grp,g)
    local ppd, bppd, d, cpol;

    d := recognise.d;

    # Compute the characteristic polynomial
    cpol := CharacteristicPolynomial(g);
    IsReducible(grp,cpol);
    ppd := IsPpdElement (FieldOfMatrixGroup(grp), cpol, d, recognise.q, 1);
    if ppd = false then
        return false;
    fi;

    AddSet(recognise.E,ppd[1]);
    if ppd[2] = true then
        AddSet(recognise.LE,ppd[1]);
    fi;
    if recognise.basic = false then
        #We only need one basic ppd-element
        #Also, each basic ppd element is a ppd-element
        bppd := IsPpdElement (FieldOfMatrixGroup(grp), cpol, d, recognise.p, recognise.a);
        if bppd <> false then
            recognise.basic := bppd[1];
        fi;
    fi;

    return ppd[1];
end;

#Test to check whether the group contains both a large ppd element and a basic
#ppd element TODO: Better comments...
GenericParameters := function(grp,case)
    local fact,d,q;

    if not IsBound(recognise) then
        InitRecog(grp,case);
    fi;

    d := recognise.d;
    q := recognise.q;

    if case = "linear" and d <= 2 then
        return false;

    elif case = "linear" and d = 3 then
        #q = 2^s-1
        fact := Collected(Factors(q+1));
        if Length(fact) = 1 and fact[1][1] = 2 then
            return false;
        fi;
        return true;

    elif case = "symplectic" and
      (d < 6 or (d mod 2 <> 0) or
       [d,q] in [[6,2],[6,3],[8,2]]) then
        return false;

    elif case = "unitary" and
      (d < 5 or d = 6 or [d,q] = [5,4]) then
        return false;

    elif case = "orthogonalplus" and
      (d mod 2 <> 0 or d < 10
       or (d = 10 and q = 2)) then
        return false;

    elif case = "orthogonalminus" and
      (d mod 2 <> 0 or d < 6
       or [d,q] in [[6,2],[6,3],[8,2]]) then
        return false;

    elif case = "orthogonalcircle" then
        if d < 7 or [d,q] = [7,3] then
            return false;
        fi;
        if d mod 2 = 0 then
            return false;
        fi;
        if q mod 2 = 0 then
            #TODO: INFORECOG1 ... not irreducible
            #TODO: INFORECOG2 ... d odd --> q odd
            return false;
        fi;
    fi;

    return true;
end;


#Generate elements until we find the required ppd type elements...monte  yes
#TODO: Better comments

IsGeneric := function (grp, N_gen)
    local b, N, g;

    if not IsBound(recognise) then
        InitRecog(grp,"unknown");
    fi;

    if recognise.isGeneric then
        #TODO: INFORECOG2 ... group is generic
        return true;
    fi;

    b := recognise.d;

    for N in [1..N_gen] do
        g := PseudoRandom(grp);
        recognise.n := recognise.n + 1;
        TestRandomElement(grp,g);
        if Length(recognise.E) >= 2 and
           Length(recognise.LE) >= 1 and
           recognise.basic <> false then
            recognise.isGeneric := true;
            #TODO: INFORECOG2: group is geenric in n sections...
            return true;
        fi;
    od;

    return false;
end;


#enough info to rule out extension field groups...?
#TODO: comments...
RuledOutExtFieldParamaters := function (grp,case)

    local differmodfour, d, q, E;

    d := recognise.d;
    q := recognise.q;
    E := recognise.E;

    differmodfour := function(E)
        local e;
        for e in E do
            if E[1] mod 4 <> e mod 4 then
                return true;
            fi;
        od;
        return false;
    end;

    if case = "linear" then
        if not IsPrime(d)
           or E <> Set([d-1,d])
           or d-1 in recognise.LE then
            return true;
        fi;

    elif case = "unitary" then
        return true;

    elif case = "symplectic" then
        if d mod 4 = 2 and q mod 2 = 1 then
            return (PositionProperty(E, x -> (x mod 4 = 0)) <> false);
        elif  d mod 4 = 0 and q mod 2 = 0 then
            return (PositionProperty( E, x -> (x mod 4 = 2)) <> false);
        elif d mod 4 = 0 and q mod 2 = 1 then
            return differmodfour(E);
        elif d mod 4 = 2 and q mod 2 = 0 then
            return (Length(E) > 0);
        else
            Error("d cannot be odd in case Sp");
        fi;

    elif case = "orthogonalplus" then
        if d mod 4 = 2  then
            return (PositionProperty (E, x -> (x mod 4 = 0 )) <> false);
        elif d mod 4 = 0  then
            return differmodfour(E);
        else  Error("d cannot be odd in case O+");
     fi;

    elif case = "orthogonalminus" then
        if d mod 4 = 0  then
            return (PositionProperty ( E, x -> (x mod 4 = 2)) <> false);
        elif d mod 4 = 2  then
            return differmodfour(E);
        else  Error("d cannot be odd in case O-");
    fi;

    elif case = "orthogonalcircle" then
        return true;
    fi;

    return false;
end;


#rule out extension field...
#TODO: comments...
IsExtensionField := function (grp, case, N_ext)

    local b, bx, g, ppd, N, testext;

    if not IsBound(recognise) then
        InitRecog(grp,case);
    fi;

    if (recognise.isGeneric and
       (not recognise.possibleOverLargerField)) then
        return false;
    fi;

    b := recognise.d;

    if Length(recognise.E) > 0 then
        b := Gcd (UnionSet(recognise.E,[recognise.d]));
    fi;

    if case in ["linear","unitary","orthogonalcircle"] then
        bx := 1;
    else
        bx := 2;
    fi;

    if b = bx then
        if RuledOutExtFieldParamaters(grp,case) then
            #TODO: INFORECOG2 ... not an extension field group
            recognise.possibleOverLargerField := false;
        fi;
        return 0;
    fi;

    N := 1;

    while N <= N_ext do
        g := PseudoRandom(grp);
        recognise.n := recognise.n + 1;
        ppd := TestRandomElement(grp,g);
        N := N+1;
        if b > bx then
            b := Gcd(b,ppd);
        elif b < bx then
            return false;
        fi;

        if b = bx then
            testext := RuledOutExtFieldParamaters(grp,case);
            if testext then
                #TODO: INFORECOG2...not an extension field group...
                recognise.possibleOverLargerField := false;
                return N;
            fi;
        fi;
    od;

    #INFORECOG1 ... group could preserve an extension field...
    return true;
end;


# Functrions for rulng out nearly simple groups
# TODO: comments...
FindCounterExample := function (grp, prop, N)
    local i,g;

    g := One(grp);
    if prop(g) then
       return true;
    fi;

    for i in [1..N] do
       g := PseudoRandom(grp);
       recognise.n := recognise.n +1;
       TestRandomElement(grp,g);
       if prop(g) or Length (recognise.E) > 2 then
           return true;
       fi;
    od;

    return false;
end;


IsAlternating := function(grp,N)

    local V, P, i,g ,q;

    q := recognise.q;

    if recognise.d <> 4 or q <> recognise.p or (3 <= q and q < 23) then
       #TODO: INFORECOG2...G is not an alternating group
       return false;
    fi;

    if q = 2 then
       V := VectorSpace(IdentityMat(4,GF(2)),GF(2));
       P := Action(grp, Difference (Elements(V),Zero(V)));
       if Size(P) <> 3*4*5*6*7 then
           #TODO: INFORECOG2...G is not an alternating group...
           return false;
       else
           #TODO: INFORECOG2...G might be A_7...
           AddSet(recognise.possibleNearlySimple,"A7");
           return true;
       fi;
    fi;


    if q >= 23 then

       if FindCounterExample(grp,g->2 in recognise.LE,N ) <> false then
         #TODO: INFORECOG2...G is not an alternating group...
         return false;
       fi;

       AddSet (recognise.possibleNearlySimple, "2.A7");
       #TODO: INFORECOG2....G might be 2.A_7
       return true;
   fi;
end;



IsMatthieu := function( grp, N )

   local i, fn, g, d, q, E;

   d := recognise.d;
   q := recognise.q;
   E := recognise.E;

   if not [d, q]  in [ [5, 3], [6,3], [11, 2] ] then
       ##InfoRecog2( "#I  G' is not a Mathieu group;\n");
       return false;
   fi;

   if d  in [5, 6] then
       fn := function(g)
           local ord;
           ord := Order(g);
           return (ord mod 121=0 or (d=5 and ord=13) or (d=6 and ord=7));
       end;
   else
       fn := g -> ForAny([6,7,8,9],m-> m in E);
   fi;

   if FindCounterExample( grp, fn, N ) <> false then
       ##InfoRecog2("#I  G' is not a Mathieu group\n");
       return false;
   fi;

   if d = 5 then
       AddSet(recognise.possibleNearlySimple, "M_11" );
       ##InfoRecog2( "#I  G' might be M_11;\n");
   elif d = 6 then
       AddSet(recognise.possibleNearlySimple, "2M_12" );
       ##InfoRecog2( "#I  G' might be 2M_12;\n");
   else
       AddSet(recognise.possibleNearlySimple, "M_23" );
       AddSet(recognise.possibleNearlySimple, "M_24" );
       ##InfoRecog2( "#I  G' might be M_23 or M_24;\n");
   fi;

   return true;

end;


IsPSL := function ( grp, N )

   local i, E, LE, d, p, a, q,  str, fn;

   E := recognise.E;
   LE := recognise.LE;
   d := recognise.d;
   q := recognise.q;
   a := recognise.a;
   p := recognise.p;

   if d = 3 then
       str := "PSL(2,7)";
       i:= Factors(q+1);
       if i[Length(i)]=3 and (Length(i)=1 or i[Length(i)-1]=2)
           and not ((q^2-1) mod 9 = 0 or Maximum(Factors(q^2-1))>3) then
           # q = 3*2^s-1 and q^2-1 has no large ppd.
           fn := function(g)
               local ord;
               ord := Order(g);
               return (ord mod 8 <> 0 or (p^(2*a)-1) mod ord = 0);
           end;
       else
           if p = 3 or p = 7 then  fn := (g -> true);
           else  fn :=  (g -> 2 in LE);
           fi;
       fi;
   elif [d, q]  = [5,3] then
       str := "PSL(2,11)";
       fn := function(g)
           local ord;
           ord := Order(g);
           return (ord mod 11^2 = 0  or ord mod 20 = 0);
       end;
   elif d = 5  and p <> 5 and p <> 11 then
       str := "PSL(2,11)";
       fn := g -> (3 in LE or 4 in LE) ;
   elif [d, q]  = [6, 3] then
       str := "PSL(2,11)";
       fn :=  g-> (Order(g) mod 11^2=0 or 6 in E);
   elif d = 6 and p <> 5 and p <> 11 then
       str := "PSL(2,11)";
       fn :=  g -> (6 in E or 4 in LE);
   else
       str := "PSL(2,r)";
       fn :=  g->true;
   fi;

   i :=  FindCounterExample( grp, fn, N );
   if not i or E = [] then
       #InfoRecog2("#I  G' might be ", str, "\n");
       return true;
   fi;

   # test whether e_2 = e_1 + 1 and
   # e_1 + 1 and 2* e_2 + 1 are primes
   if i <> false or E[2]-1<>E[1] or
       not IsPrime(E[1]+1) or not IsPrime(2*E[2]+1) then
        #InfoRecog2("#I  G' is not ", str, "\n");
        return false;
   fi;

   str := Concatenation("PSL(2,",Int(2*E[2]+1));
   str := Concatenation(str, ")");
   #InfoRecog2("#I  G' might be ", str, "\n");
   AddSet( recognise.possibleNearlySimple, str );
   return true;
end;


IsGenericNearlySimple := function( grp, case, N )

   local   isal;

   if case <> "linear" then
       return false;
   fi;

   if N < 0 then
       return true;
   fi;

   if not IsBound(grp.recognise) then
       InitRecog(grp, case);
   fi;

   isal := IsAlternating(grp,N) or IsMatthieu(grp,N) or IsPSL(grp,N);

   if not isal then
       recognise.possibleNearlySimple := Set([]);
   fi;
   return isal;

end;

###################################################################
###################################################################
# OLD MAIN FUNCTIONS, PORTED FROM                                ##
# GAP3 CODE                                                      ##
###################################################################
###################################################################

######################################################################
##
#F  RecogniseClassicalNPCase(grp,case,N) . . . . . . .
#F                    . . . .  Does <grp>  contain a classical group?
##
##  Input:
##
##  - a group <grp>, which is a subgroup of  GL(d,q)
##  - a string <case>, one of "linear", "unitary", "symplectic",
##           "orthogonalplus", "orthogonalminus", or "orthogonalcircle"
##  - an optional integer N
##
##  Assumptions about the Input:
##
##  It is assumed that it is known that the only forms preserved by
##  <grp> are the forms of the corresponding case.
##
##  Output:
##
##  Either a boolean, i.e. either 'true' or 'false'
##  or the string "does not apply"
##
##
##  The  algorithm  is designed  to  test  whether <grp>  contains the
##  corresponding classical group Omega (see [1]).
##
##

RecogniseClassicalNPCase := function( arg )

    local   recog, d,  p,  a,  isext,  grp, N, case, n;

    if not Length(arg)  in [2,3] then
        Error("usage: RecogniseClassicalNPCase( <grp>, <case>[, N])" );
    fi;

    grp := arg[1];
    case := arg[2];
    if Length( arg ) = 3 then
        N := arg[3];
    else
        if case = "linear" then
             N := 15;
         else
             N := 25;
         fi;
     fi;

     if IsBound(recognise) then
         if case = "linear"  and recognise.isSLContained <> "unknown" then
             return recognise.isSLContained;
       elif case = "symplectic" and
         recognise.isSymplecticGroup <> "unknown" then
           return recognise.isSymplecticGroup;
       elif case = "unitary" and recognise.isUnitaryGroup <>"unknown" then
           return recognise.isUnitaryGroupFlag;
       elif case in ["orthogonalminus","orthogonalplus","orthogonalcircle"] and
         recognise.isOrthogonalGroup <> "unknown" then
           return recognise.isOrthogonalGroup;
       fi;
   fi;

   if not case in [ "linear", "unitary", "symplectic",
              "orthogonalplus", "orthogonalminus", "orthogonalcircle" ] then
       Error("unknown case\n");
   fi;

   if IsBound( recognise ) and IsBound(recognise.type) and
      recognise.type = "unknown" then
       recognise.type := case;
   fi;

   if not IsBound(recognise) then
       InitRecog( grp, case );
   elif (IsBound(recognise.type) and
         recognise.type <> case) then
       recognise.n := 0;
       recognise.type := case;
       recognise.possibleOverLargerField := true;
       recognise.possibleNearlySimple := Set([]);
   fi;

        # test whether the theory applies for this group and case
   if GenericParameters( grp, case ) = false then
       #InfoRecog1("#I  Either algorithm does not apply in this case\n");
       #InfoRecog1("#I  or the group is not of type ", case, ".\n");
       Unbind( recognise );
       return "does not apply";
   fi;

   n := recognise.n;
   # try to establish whether the group is generic
   if not IsGeneric( grp, N )  then
       #InfoRecog1 ("#I  The group is not generic\n");
       #InfoRecog1("#I  The group probably does not contain");
       #InfoRecog1(" a classical group\n");
       Unbind( recognise.type );
       return false;
   fi;

   isext := IsExtensionField( grp, case, N-recognise.n+n );
   if isext = true then
       return false;
   elif isext = false then
       #InfoRecog1( "#I  The group does not preserve a");
       if case = "symplectic" then
           #InfoRecog1(" symplectic form\n");
   else
       #InfoRecog1(" quadratic form\n");
   fi;
   Unbind(recognise.type);
   return false;
   fi;

   # Now we know that the group preserves no extension field structure on V;
   if  IsGenericNearlySimple( grp, case, N-recognise.n+n ) then
    #InfoRecog1( "#I  The group could be a nearly simple group.\n");
    Unbind(recognise.type);
    return false;
   fi;
   n := recognise.n - n;
   #InfoRecog2( "#I  The group is not nearly simple\n");

   # maybe the number of random elements selected was not sufficient
   # to prove that the group acts irreducibly. In this case we call
   # the meataxe.
   if recognise.isReducible = "unknown" then
       if IsIrreducible(
            GModuleByMats(GeneratorsOfGroup(grp),FieldOfMatrixGroup(grp)) ) then
           recognise.isReducible := false;
       else
           recognise.isReducible := true;
       fi;
   fi;
   # if the group acts reducibly then our algorithm does not apply
   if recognise.isReducible = true then
       # TODO: WHAT HERE? SetNotAbsIrredFlags (grp);
       #InfoRecog1("#I  The group acts reducibly\n");
       return "does not apply";
   fi;
   #InfoRecog2("#I  The group acts irreducibly\n");


   ##ALICE: returnNPFlags?
#   if SetReturnNPFlags( grp, case ) = true then
       #InfoRecog1("#I  Proved that the group contains a classical" );
       #InfoRecog1(" group of type ", case, "\n#I  in " );
       #InfoRecog1( StringInt(recognise.n)," random selections.\n");
       return true;
 #  else
 #      Unbind(recognise.type);
 #      return false;
 #  fi;

end;



######################################/
#
#  NonGenericLinear (grp, N) . . . . . . . . . . . . non-generic linear case
#
#  Recognise non-generic linear matrix groups over finite fields:
#  In order to prove that a group G <= GL( 3, 2^s-1) contains SL, we need to
#  find an element of order a multiple of 4 and a large and basic ppd(3,q;3)-
#  element
#
NonGenericLinear := function( grp, N )
    local order4, d,ord, g;

    if not IsBound(recognise) then
        InitRecog(grp,"linear");
    fi;

    if not IsBound(recognise.orders) then
        recognise.orders := Set([]);
    fi;


    order4 := false;
    d := recognise.d;
    while  N >= 0  do
        N := N - 1;
        g := Random(grp);
        recognise.n := recognise.n + 1;
        if order4 = false then
            ord := Order(g);
            if ord mod 4 = 0 then
                order4 := true;
            fi;
        fi;

        if Length(recognise.LE) = 0 then
            TestRandomElement( grp, g);
        fi;

        #ALICE: basic is a list in magma, boolean here?
        if Length(recognise.LE) >= 1 and 3 in recognise.LE and
           3 = recognise.basic and order4 = true  then
               return true;
        fi;
    od;


    return false;

end;



[ Dauer der Verarbeitung: 0.34 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge