Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/factint/lib/   (GAP Algebra Version 4.15.1©)  Datei vom 15.10.2019 mit Größe 6 kB image not shown  

Quelle  pplus1.gi   Sprache: Shell

 

#############################################################################
##
#W  pplus1.gi               GAP4 Package `FactInt'                Stefan Kohl
##
##  This file contains functions for factorization using a variant of
##  Williams' p+1.
##
##  Arguments of FactorsPplus1:
##
##  <n>         the integer to be factored
##  <Residues>  the number of residues that should be examined
##              (the probability of hitting a usable one is
##              approx. 1 - 1/2^<Residues>)
##  <Limit1>    the limit for the first stage
##  <Limit2>    the limit for the second stage
##
##  The result is returned as a list of two lists. The first list
##  contains the prime factors found, and the second list contains
##  remaining unfactored parts of <n>, if there are any.
##
#############################################################################

BindGlobal("Pplus1Product", function (a,b,n)

  local  c,c12,a12b12;

  a12b12 := a[1][2] * b[1][2];
  c12    := (a[1][1] * b[1][2] + a[1][2] * b[2][2]) mod n;
  c      := [[(a[1][1] * b[1][1] + a12b12) mod n, c12],
             [c12, (a12b12 + a[2][2] * b[2][2]) mod n]];
  return c;
end);

BindGlobal("Pplus1Square", function (a,n)

  local  c,c12,a12a12;

  a12a12 := a[1][2] * a[1][2];
  c12    := a[1][2] * (a[1][1] + a[2][2]) mod n;
  c      := [[(a[1][1]^2 + a12a12) mod n, c12],
             [c12, (a12a12 + a[2][2]^2) mod n]];
  return c;
end);

BindGlobal("Pplus1Power", function (Base,exp,n)

  local  Power,BinExp,i;

  BinExp := CoefficientsQadic(exp,2);
  Power  := Base;

  for i in [Length(BinExp),Length(BinExp)-1..2] do
    Power := Pplus1Square(Power,n);
    if BinExp[i-1] = 1 then
      Power := Pplus1Product(Power,Base,n);
    fi;
  od;

  return Power;
end);

BindGlobal("Pplus1Split", function (n,Residues,Limit1,Limit2)

  local  Residue,ResNo,a,
         PowerOfa,PowerAfterFirstStage,p,pExponent,
         DiffPowers,DiffPos,DiffSum,NextDiff,DiffsLng,BufProd,
         FactorFoundAndReady,FactorsFound;

  FactorFoundAndReady := function (PowerProd)
    
    local  Result,i,j,k;

    Result := Gcd(PowerProd,n);
    if not Result in [1,n] then
      Info(IntegerFactorizationInfo,1,LogInt(Result,10) + 1,
           "-digit factor ",Result," was found");
      Add(FactorsFound,Result); n := n/Result;
      if IsProbablyPrimeInt(n) then Add(FactorsFound,n); return true; fi;
      if IsBound(DiffPowers) then 
        for i in [1..Length(DiffPowers)] do 
          if IsBound(DiffPowers[i]) then 
            for j in [1,2] do for k in [1,2] do
              DiffPowers[i][j][k] := DiffPowers[i][j][k] mod n;
            od; od; 
          fi;
        od;
      fi;
    fi;
    return false;
  end;

  if IsProbablyPrimeInt(n) then return [n]; fi;
  FactorsFound := [];

  Info(IntegerFactorizationInfo,2,
       "p+1 for n = ",n,"\nResidues : ",Residues,
       ", Limit1 : ",Limit1,", Limit2 : ",Limit2);

  Residue := 1;
  for ResNo in [1..Residues] do
    Info(IntegerFactorizationInfo,2,"Residue no. ",ResNo);
    a := [[Residue,1],[1,0]];

    Info(IntegerFactorizationInfo,3,"First stage");
    p := 2; PowerOfa := a;
    while p <= Limit1 do
      pExponent := LogInt(Limit1,p);
      PowerOfa  := Pplus1Power(PowerOfa,p^pExponent,n);
      if   FactorFoundAndReady(PowerOfa[1][2]) 
      then return FactorsFound; fi;
      p := NextPrimeInt(p);
    od;

    Info(IntegerFactorizationInfo,3,"Second stage");
    PowerAfterFirstStage := PowerOfa; PowerOfa := [[1,0],[0,1]];
    DiffPowers := []; DiffPos := 1; DiffSum := 0;
    DiffsLng := Length(PrimeDiffs); BufProd := 1;
    while (DiffSum <= Limit2) and (DiffPos <= DiffsLng) do
      NextDiff := PrimeDiffs[DiffPos];
      DiffSum := DiffSum + NextDiff;
      if not IsBound(DiffPowers[NextDiff]) 
      then DiffPowers[NextDiff] := 
           Pplus1Power(PowerAfterFirstStage,NextDiff,n); fi;
      PowerOfa := Pplus1Product(PowerOfa,DiffPowers[NextDiff],n);
      BufProd  := BufProd * PowerOfa[1][2] mod n;
      if DiffPos mod 50 = 0 then
        if   FactorFoundAndReady(BufProd)
        then return FactorsFound; fi;
      fi; 
      DiffPos := DiffPos + 1;
    od;
    Residue := NextPrimeInt(Residue);
  od;

  Add(FactorsFound,n); return FactorsFound;
end);

#############################################################################
##
#F  FactorsPplus1( <n>, [ [ <Residues> ], <Limit1>, [ <Limit2> ] ] )
##
InstallGlobalFunction( FactorsPplus1,

function ( arg )

  local  n, Residues, Limit1, Limit2, GetArg, ArgCorrect,
         FactorsList, m, Split, q;

  GetArg := function (ArgPos,ArgName,ArgDefault)
    if IsBound(arg[ArgPos]) then 
      if arg[ArgPos] <> fail then return arg[ArgPos];
                             else return ArgDefault; fi; 
    fi;
    if ValueOption(ArgName) <> fail then return ValueOption(ArgName); fi;
    return ArgDefault;
  end;

  ArgCorrect := Length(arg) in [1..4];
  if ArgCorrect then
    n := arg[1];
    if Length(arg) = 4 
    then
      Residues := arg[2];
      Limit1   := GetArg(3,"Pplus1Limit1",Int(PrimeDiffLimit/40));
      Limit2   := GetArg(4,"Pplus1Limit2",40 * Limit1);
    else
      Residues := GetArg(5,"Pplus1Residues",2);
      Limit1   := GetArg(2,"Pplus1Limit1",Int(PrimeDiffLimit/40));
      Limit2   := GetArg(3,"Pplus1Limit2",40 * Limit1);
    fi; 
    if not (IsInt(n) and n >= 1 and IsInt(Residues) and Residues >= 1
            and IsPosInt(Limit1) and IsPosInt(Limit2)) 
    then ArgCorrect := false; fi; 
  fi;
  if not ArgCorrect
  then Error("Usage : FactorsPplus1( <n>, [ [ <Residues> ], <Limit1>, ",
             "[ <Limit2> ] ] ), where <n>, <Residues>, ",
             "<Limit1> and <Limit2> have to be positive integers");
  fi;

  if IsProbablyPrimeInt(n) then return [[n],[]]; fi;

  InitPrimeDiffs(Limit2); 

  FactorsList := FactorsTD(n);
  if FactorsList[2] <> [] then
    m := FactorsList[2][1];
    if   SmallestRootInt(m) < m
    then ApplyFactoringMethod(FactorsPowerCheck,
                              [FactorsPplus1,"FactorsPplus1"],
                              FactorsList,infinity);
    else
      Split := Pplus1Split(m,Residues,Limit1,Limit2);
      FactorsList[2] := [];
      for q in Split do if   IsProbablyPrimeInt(q) 
                        then Add(FactorsList[1],q);
                        else Add(FactorsList[2],q); fi; od;
    fi;
  fi;

  Sort(FactorsList[1]); Sort(FactorsList[2]);
  FactorizationCheck(n,FactorsList);
  return FactorsList;
end);

#############################################################################
##
#E  pplus1.gi  . . . . . . . . . . . . . . . . . . . . . . . . . .  ends here

Messung V0.5 in Prozent
C=87 H=84 G=85

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-10-12) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.