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


Quelle  matimpr.gi   Sprache: unbekannt

 
#############################################################################
##
##  This file is part of recog, a package for the GAP computer algebra system
##  which provides a collection of methods for the constructive recognition
##  of groups.
##
##  This files's authors include Max Neunhöffer, Alice Niemeyer, Ákos Seress.
##
##  Copyright of recog belongs to its developers whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-3.0-or-later
##
##
##  Find an imprimitive action of a matrix group.
##  This should better be (and is now) called "LowIndex".
##
#############################################################################

#############################################################################
##
#F  OrbitSubspaceWithLimit( <grp>, <U>, <max> ) . . . . . . orbit of subspace
##
##  Compute the orbit of a subspace but return fail if the orbit has
##  more than <max> elements.
##
# RECOG.OrbitSubspaceWithLimit := function( grp, U, max )

#     local   orb,  orbset, new,  pnt,  img,  gen, gens;

#     gens := GeneratorsOfGroup(grp);

#     # start with the singleton orbit
#     orb := [ U ];
#     orbset := [ U ];

#     # loop over all points found
#     for pnt  in orb  do

#         # apply all generators <gen>
#         for gen  in gens  do
#             img := OnSubspacesByCanonicalBasis( pnt, gen );

#             # add the image <img> to the orbit if it is new
#             # can perhaps be improved (is now)
#             if not img in orbset then
#                 Add( orb, img );
#                 AddSet( orbset, img );
#                 if Length(orb) > max then return fail; fi;
#             fi;

#         od;

#     od;
#     return orbset;
# end;

#
#  Test if the module hm already has a submodule with a
#  short enough orbit.
#  Note: We can tweak what ``short enough" means. I set it to 4d,
#  but if we make it smaller it will speed up the code.
#

RECOG.IndexMaxSub := function( hm, grp, d )
    # Call this function only with a reducible module hm!
    local dim,dimnew,f,i,lastorb,lastsub,orb,sp,spnew,sub,subdim;

    # Here is the invariant subspace
    sub := MTX.ProperSubmoduleBasis(hm);
    sub := MutableCopyMat( sub );  # make mutable copy
    # FIXME: this will be unnecessary:
    ConvertToMatrixRep(sub,hm.field);
    lastsub := fail;
    lastorb := fail;
    repeat
        TriangulizeMat(sub); # Find Hermite Normal Form
        #orb := RECOG.OrbitSubspaceWithLimit(grp, sub, 4 * d );
        orb := Orb(grp,sub,OnSubspacesByCanonicalBasis,
                   rec(storenumbers := true, hashlen := NextPrimeInt(8*d)));
        Enumerate(orb,4*d);
        if not IsClosed(orb) then
            Info(InfoRecog,2,"Did not find nice orbit.");
            if lastsub = fail then
                return fail;
            fi;
            return rec( orb := lastorb,
                        hom := OrbActionHomomorphism(grp,lastorb) );
        fi;
        Info(InfoRecog,2,"Found orbit of length ",Length(orb),
             " of subspaces of dimension ",Length(orb[1]),".");
        subdim := Length(orb[1]);
        if subdim * Length(orb) = d or    # have block system!
           subdim = 1 then                # no hope in this case
            return
                rec(orb := orb,
                    hom := OrbActionHomomorphism(grp,orb));
        fi;
        # we try intersecting the subspaces in the orbit:
        Info(InfoRecog,2,"Calculating intersections...");
        f := hm.field;
        sp := VectorSpace(f,orb[1]);
        dim := Dimension(sp);
        for i in [2..Length(orb)] do
            spnew := Intersection(sp,VectorSpace(f,orb[i]));
            dimnew := Dimension(spnew);
            if dimnew > 0 and dimnew < dim then
                sp := spnew;
                dim := dimnew;
            fi;
        od;
        Info(InfoRecog,2,"Got subspace of dimension ",Dimension(sp));
        if dim = Length(sub) then   # we got nothing new
            Info(InfoRecog,2,"That we already knew, giving up.");
            return
                rec(orb := orb,
                    hom := OrbActionHomomorphism(grp,orb));
        fi;
        lastsub := sub;
        lastorb := orb;
        sub := MutableCopyMat(AsList(Basis(sp)));
        # FIXME: This will vanish:
        ConvertToMatrixRep(sub,hm.field);
    until false;
end;

RECOG.SmallHomomorphicImageProjectiveGroup := function ( grp )

    local hm, findred, ans, fld, d, i, gens;

    fld := DefaultFieldOfMatrixGroup(grp);
    d := DimensionOfMatrixGroup(grp);

    findred := function( gens )
      local hm,i,j,res;
      i := Length(gens)+1;
      for j in [1..d] do
          gens[i] := PseudoRandom(grp);
          hm := GModuleByMats(gens,fld);
          if not MTX.IsIrreducible(hm) then
              res := RECOG.IndexMaxSub( hm, grp, d );
              if res <> fail then
                  return [res, gens];
              fi;
              if i < LogInt(d,2) then
                  res := findred(gens);
                  if res = false then
                      return false;
                  fi;
                  if res <> fail then
                      return res;
                  fi;
              fi;
          fi;
      od;
      return false;   # go out all the way without success
    end;

    Info(InfoRecog,2,"LowIndex: Trying 10 first elements...");
    for i in [1..10] do   # this is just heuristics!
        gens := [PseudoRandom(grp)];
        hm := GModuleByMats(gens,fld);
        if not MTX.IsIrreducible(hm) then
            ans := findred( gens );
            if ans <> fail and ans <> false then
                return ans;
            fi;
        fi;
        if InfoLevel(InfoRecog) >= 2 then Print(".\c"); fi;
    od;
    if InfoLevel(InfoRecog) >= 2 then Print("\n"); fi;

    return fail;
end;


#! @BeginChunk LowIndex
#! This method is designed for the handling of the Aschbacher class C2
#! (stabiliser of a decomposition of the underlying vector space), but may
#! succeed on other types of input as well. Given <A>G</A> <M> \le PGL(d,q)</M>,
#! the output is either the permutation action of <A>G</A> on a short
#! orbit of subspaces or <K>fail</K>. In the current setup, <Q>short orbit</Q>
#! is defined to have length at most <M>4d</M>.
#! @EndChunk
BindRecogMethod(FindHomMethodsProjective, "LowIndex",
"find an (imprimitive) action on subspaces",
function(ri,G)
  local res;
  RECOG.SetPseudoRandomStamp(G,"LowIndex");
  res := RECOG.SmallHomomorphicImageProjectiveGroup(G);
  if res = fail then
      return fail; # FIXME: fail = TemporaryFailure here really correct?
  else
      res := res[1];
      # Now distinguish between a block system and just an orbit:
      if Length(res.orb) * Length(res.orb[1]) <> ri!.dimension then
          Info(InfoRecog,2,"Found orbit of length ",Length(res.orb),
               " - not a block system.");
      else
          Info(InfoRecog,2,"Found block system with ",Length(res.orb),
               " blocks.");
          # A block system: We do a base change isomorphism:
          InitialDataForKernelRecogNode(ri).t := Concatenation(res.orb);
          InitialDataForKernelRecogNode(ri).blocksize := Length(res.orb[1]);
          AddMethod(InitialDataForKernelRecogNode(ri).hints, FindHomMethodsProjective.DoBaseChangeForBlocks, 2000);
          Setimmediateverification(ri,true);
          findgensNmeth(ri).args[1] := Length(res.orb)+3;
          findgensNmeth(ri).args[2] := 5;
      fi;

      # we are done, report the hom:
      SetHomom(ri,res.hom);
      Setmethodsforimage(ri,FindHomDbPerm);

      return Success;
  fi;
end);

#! @BeginChunk DoBaseChangeForBlocks
#! TODO
#! @EndChunk
BindRecogMethod(FindHomMethodsProjective, "DoBaseChangeForBlocks",
"Hint TODO",
function(ri,G)
  # Do the base change:
  local H,iso,newgens,ti;

  ti := ri!.t^-1;
  newgens := List(GeneratorsOfGroup(G),x->ri!.t*x*ti);
  H := GroupWithGenerators(newgens);
  iso := GroupHomByFuncWithData(G,H,RECOG.HomDoBaseChange,
                                rec(t := ri!.t,ti := ti));

  # Now report back:
  SetHomom(ri,iso);
  findgensNmeth(ri).method := FindKernelDoNothing;

  # Inform authorities that the image can be recognised easily:
  InitialDataForImageRecogNode(ri).blocksize := ri!.blocksize;
  AddMethod(InitialDataForImageRecogNode(ri).hints, FindHomMethodsProjective.Blocks, 2000);

  return Success;
end);

#! @BeginChunk Blocks
#! TODO
#! @EndChunk
BindRecogMethod(FindHomMethodsProjective, "Blocks",
"Hint TODO",
function(ri,G)
  # Here we use BlocksModScalars and then get a kernel of scalar blocks
  # altogether mod scalars.
  local blocks,d,hom,i;
  hom := IdentityMapping(G);
  SetHomom(ri,hom);
  blocks := [];
  d := ri!.dimension;
  for i in [1..d/ri!.blocksize] do
      Add(blocks,[(i-1)*ri!.blocksize+1..i*ri!.blocksize]);
  od;
  # For the image:
  InitialDataForImageRecogNode(ri).blocks := blocks;
  AddMethod(InitialDataForImageRecogNode(ri).hints, FindHomMethodsProjective.BlocksModScalars, 2000);
  # For the kernel:
  InitialDataForKernelRecogNode(ri).blocks := blocks;
  AddMethod(InitialDataForKernelRecogNode(ri).hints, FindHomMethodsProjective.BlocksBackToMats, 2000);
  return Success;
end);

RECOG.HomBackToMats := function(el)
  # We assume that el is block diagonal with the last block being scalar.
  # This just norms this last block to 1.
  local d;
  d := Length(el);
  return (el[d,d]^-1)*el;
end;

#! @BeginChunk BlocksBackToMats
#! TODO
#! @EndChunk
BindRecogMethod(FindHomMethodsProjective, "BlocksBackToMats",
"Hint TODO",
function(ri,G)
  # This is only called as hint from Blocks, so we know that we in fact
  # have scalar blocks along the diagonal and nothing else.
  local H,hom,newgens;
  newgens := List(GeneratorsOfGroup(G),RECOG.HomBackToMats);
  H := Group(newgens);
  hom := GroupHomomorphismByFunction(G,H,RECOG.HomBackToMats);
  SetHomom(ri,hom);

  # hints for the image:
  Setmethodsforimage(ri,FindHomDbMatrix);
  InitialDataForImageRecogNode(ri).blocks := ri!.blocks{[1..Length(ri!.blocks)-1]};
  AddMethod(InitialDataForImageRecogNode(ri).hints, FindHomMethodsMatrix.BlockScalar, 2000 );

  # This is an isomorphism:
  findgensNmeth(ri).method := FindKernelDoNothing;

  return Success;
end);

#FindHomMethodsProjective.BalTreeForBlocks := function(ri,G)
#  local H,cut,dim,hom,newgens,nrblocks,subdim,gen;
#  dim := ri!.dimension;
#  nrblocks := dim / ri!.blocksize;   # this we know from above
#  if nrblocks = 1 then     # this might happen during the descent into the tree
#      return false;
#  fi;
#  cut := QuoInt(nrblocks,2);  # this is now at least 1
#  subdim := cut * ri!.blocksize;
#
#  # Project onto image:
#  newgens := List(GeneratorsOfGroup(G),
#                  x->ExtractSubMatrix(x,[subdim+1..dim],[subdim+1..dim]));
#  for gen in newgens do
#      ConvertToMatrixRep(gen);
#  od;
#  H := GroupWithGenerators(newgens);
#  hom := GroupHomByFuncWithData(G,H,RECOG.HomInducedOnFactor,
#                                rec(subdim := subdim));
#  SetHomom(ri,hom);
#
#  # Create some more kernel generators:
#  findgensNmeth(ri).args[1] := 20 + nrblocks;
#
#  # Pass the block information on to the image:
#  InitialDataForImageRecogNode(ri).blocksize := ri!.blocksize;
#  AddMethod(InitialDataForImageRecogNode(ri).hints, FindHomMethodsProjective.BalTreeForBlocks, 2000);
#
#  # Inform authorities that the kernel can be recognised easily:
#  InitialDataForKernelRecogNode(ri).subdim := subdim;
#  InitialDataForKernelRecogNode(ri).blocksize := ri!.blocksize;
#  AddMethod(InitialDataForKernelRecogNode(ri).hints, FindHomMethodsProjective.BalTreeForBlocksProjKernel, 2000);
#
#  # Verify the kernel immediately after its recognition:
#  Setimmediateverification(ri,true);
#
#  return Success;
#end;
#
#RECOG.HomInducedOnSubspace := function(data,el)
#  local m;
#  m := ExtractSubMatrix(el,[1..data.subdim],[1..data.subdim]);
#  # FIXME: no longer necessary, as soon as the new interface is in place
#  ConvertToMatrixRep(m);
#  return m;
#end;

#FindHomMethodsMatrix.InducedOnSubspace := function(ri,G)
#  local H,dim,gens,hom,newgens,gen,data;
#  # Are we applicable?
#  if not IsBound(ri!.subdim) then
#      return NotEnoughInformation;
#  fi;
#
#  # Project onto subspace:
#  gens := GeneratorsOfGroup(G);
#  data := rec(subdim := ri!.subdim);
#  newgens := List(gens, x->RECOG.HomInducedOnSubspace(data,x));
#  H := Group(newgens);
#  hom := GroupHomByFuncWithData(G,H,RECOG.HomInducedOnSubspace,data);
#
#  # Now report back:
#  SetHomom(ri,hom);
#
#  # We know that the kernel is a GF(p) vectorspace and thus may need
#  # quite some generators. Therefore we generate them in a non-standard
#  # way such that we can be reasonably sure that we got enough:
#  findgensNmeth(ri).method := FindKernelLowerLeftPGroup;
#  findgensNmeth(ri).args := [];
#
#  # Inform authorities that the kernel can be recognised easily:
#  InitialDataForKernelRecogNode(ri).subdim := ri!.subdim;
#  AddMethod(InitialDataForKernelRecogNode(ri).hints, FindHomMethodsMatrix.LowerLeftPGroup, 2000);
#
#  return Success;
#end;

#FindHomMethodsProjective.BalTreeForBlocksProjKernel := function(ri,G)
#  # We just have to project onto the upper left corner, see
#  local H,gen,hom,newgens;
#
#  newgens := List(GeneratorsOfGroup(G),x->x{[1..ri!.subdim]}{[1..ri!.subdim]});
#  for gen in newgens do ConvertToMatrixRep(gen); od;
#  H := Group(newgens);
#  hom := GroupHomByFuncWithData(G,H,RECOG.HomInducedOnSubspace,
#                                rec(subdim := ri!.subdim));
#  SetHomom(ri,hom);
#
#  findgensNmeth(ri).method := FindKernelDoNothing;
#
#  # But pass on the information on blocks:
#  InitialDataForImageRecogNode(ri).blocksize := ri!.blocksize;
#  AddMethod(InitialDataForImageRecogNode(ri).hints, FindHomMethodsProjective.BalTreeForBlocks, 2000);
#
#  return Success;
#end;

[ Dauer der Verarbeitung: 0.22 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