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"; } }
//===================================================== 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 }