Ejemplo n.º 1
0
void SFBerlekamp(vec_ZZ_pX& factors, const ZZ_pX& ff, long verbose)
{
   ZZ_pX f = ff;

   if (!IsOne(LeadCoeff(f)))
      Error("SFBerlekamp: bad args");

   if (deg(f) == 0) {
      factors.SetLength(0);
      return;
   }

   if (deg(f) == 1) {
      factors.SetLength(1);
      factors[0] = f;
      return;
   }

   double t;

   const ZZ& p = ZZ_p::modulus();

   long n = deg(f);

   ZZ_pXModulus F;

   build(F, f);

   ZZ_pX g, h;

   if (verbose) { cerr << "computing X^p..."; t = GetTime(); }
   PowerXMod(g, p, F);
   if (verbose) { cerr << (GetTime()-t) << "\n"; }

   vec_long D;
   long r;

   vec_ZZVec M;

   if (verbose) { cerr << "building matrix..."; t = GetTime(); }
   BuildMatrix(M, n, g, F, verbose);
   if (verbose) { cerr << (GetTime()-t) << "\n"; }

   if (verbose) { cerr << "diagonalizing..."; t = GetTime(); }
   NullSpace(r, D, M, verbose);
   if (verbose) { cerr << (GetTime()-t) << "\n"; }


   if (verbose) cerr << "number of factors = " << r << "\n";

   if (r == 1) {
      factors.SetLength(1);
      factors[0] = f;
      return;
   }

   if (verbose) { cerr << "factor extraction..."; t = GetTime(); }

   vec_ZZ_p roots;

   RandomBasisElt(g, D, M);
   MinPolyMod(h, g, F, r);
   if (deg(h) == r) M.kill();
   FindRoots(roots, h);
   FindFactors(factors, f, g, roots);

   ZZ_pX g1;
   vec_ZZ_pX S, S1;
   long i;

   while (factors.length() < r) {
      if (verbose) cerr << "+";
      RandomBasisElt(g, D, M);
      S.kill();
      for (i = 0; i < factors.length(); i++) {
         const ZZ_pX& f = factors[i];
         if (deg(f) == 1) {
            append(S, f);
            continue;
         }
         build(F, f);
         rem(g1, g, F);
         if (deg(g1) <= 0) {
            append(S, f);
            continue;
         }
         MinPolyMod(h, g1, F, min(deg(f), r-factors.length()+1));
         FindRoots(roots, h);
         S1.kill();
         FindFactors(S1, f, g1, roots);
         append(S, S1);
      }
      swap(factors, S);
   }

   if (verbose) { cerr << (GetTime()-t) << "\n"; }

   if (verbose) {
      cerr << "degrees:";
      long i;
      for (i = 0; i < factors.length(); i++)
         cerr << " " << deg(factors[i]);
      cerr << "\n";
   }
}
Ejemplo n.º 2
0
//=====================================================
BerlekampFactorization::BerlekampFactorization(
    PolyOvrPrimeField *orig_poly )
{

    int k, r, s;
    int poly_idx;
    int deg = orig_poly->MaxDegree();
    int prime_char = orig_poly->PrimeBase();
    matrix_pf *v;
    PolyOvrPrimeField **polys;

    int num_facs = 1;
    int num_polys;

    Factors = new PolyOvrPrimeField*[1];
    Factors[0] = orig_poly;

    for(int iter=0; iter<1; iter++)
    {
        num_polys = num_facs;
        polys = new PolyOvrPrimeField*[num_polys];

        for( poly_idx=0; poly_idx<num_polys; poly_idx++)
        {
            polys[poly_idx] = Factors[poly_idx];
            int yydeg = (polys[poly_idx])->MaxDegree();
            // delete (Factors[poly_idx]);
        } // end of loop over poly_idx
        delete[] Factors;
        num_facs = 0;
        Factors = new PolyOvrPrimeField*[20];

        for( poly_idx=0; poly_idx<num_polys; poly_idx++)
        {
//int xxdeg = (polys[poly_idx])->MaxDegree();
//if(xxdeg == 7) continue;
            B_Mtx = new BerlekampMatrix( polys[poly_idx] );
            //  Row k corresponds to the term x**(k*p) where p is the
            //  characteristic of the prime field over which the polynomial
            //  is to be factored.

            //-----------------------------------------------------
            //  Compute null space of B matrix

            v = NullSpace(B_Mtx, &r);

            //----------------------------------------------------
            // Find factors

            //DebugFile << "rrr = " << r << endl;
            R = r;
            //
            //  The original polynomial should factor into r irreducible
            //  polynomials.  However each iteration of the Berlekamp
            //  factorization will only factor the original polynomial
            //  into p polynomials (which, in general, may be reducible)
            //  where p is the prime characteristic of the field from
            //  which the coefficients are drawn.  Additional iterations
            //  can be performed until all r irreducible factors are found.

            // Factors = new PolyOvrPrimeField*[r];

            //PolyOvrPrimeField factor_poly;
            //Factors[0] = new PolyOvrPrimeField;
            for(k=1; k<2; k++)
            {
                //--------------------------------------------------------------
                //  Use the row 1 elements of v as coefficients for a polynomial

                PolyOvrPrimeField *work_poly = new PolyOvrPrimeField( prime_char,
                        &((*v)[k]));
                //DebugFile << "work_poly:" << endl;
                //work_poly->DumpToStream(&DebugFile);
                //DebugFile << "poly:" << endl;
                //polys[poly_idx]->DumpToStream(&DebugFile);

                for(s=0; s<prime_char; s++)
                {
                    Factors[num_facs] = &(EuclideanAlgorithm( polys[poly_idx], work_poly ) );
                    //DebugFile << "factor_poly (for k=" << k <<", s=" << s << "):" << endl;
                    //(Factors[num_facs])->DumpToStream(&DebugFile);
                    (*work_poly) -= PrimeFieldElem( prime_char, 1 );
                    num_facs++;
                }
                delete work_poly;
                delete B_Mtx;
                delete v;

            } // end of loop over k
        } // end of loop over poly_idx
    } // end of loop over iter
}