bridge/class-master/depend/pari/src/basemath/nffactor.c
/* return the factorization of the square-free polynomial pol. Not memory-clean
   The coeffs of pol are in Z_nf and its leading term is a rational integer.
   deg(pol) > 0, deg(nfpol) > 1
   fl is either FACTORS (return factors), or ROOTS / ROOTS_SPLIT (return roots):
     - ROOTS, return only the roots of x in nf
     - ROOTS_SPLIT, as ROOTS if pol splits, [] otherwise
   den is usually 1, otherwise nf.zk is doubtful, and den bounds the
   denominator of an arbitrary element of Z_nf on nf.zk */
return the factorization of the square-free polynomial pol. Not memory-clean
The coeffs of pol are in Z_nf and its leading term is a rational integer.
deg(pol) > 0, deg(nfpol) > 1
fl is either FACTORS (return factors), or ROOTS / ROOTS_SPLIT (return roots):
ROOTS, return only the roots of x in nf
ROOTS_SPLIT, as ROOTS if pol splits, [] otherwise
den is usually 1, otherwise nf.zk is doubtful, and den bounds the
denominator of an arbitrary element of Z_nf on nf.zk
return the factorization of the square - free polynomial pol . Not memory - clean The coeffs of pol are in Z_nf and its leading term is a rational integer . deg ( pol ) > 0 deg ( nfpol ) > 1 fl is either FACTORS ( return factors ) or ROOTS / ROOTS_SPLIT ( return roots ) : ROOTS return only the roots of x in nf ROOTS_SPLIT as ROOTS if pol splits [] otherwise den is usually 1 otherwise nf . zk is doubtful and den bounds the denominator of an arbitrary element of Z_nf on nf . zk
static GEN
nfsqff(GEN nf, GEN pol, long fl, GEN den)
{
  long n, nbf, dpol = degpol(pol);
  GEN C0, polbase;
  GEN N2, res, polred, lt, nfpol = typ(nf)==t_POL?nf:nf_get_pol(nf);
  ulong pp;
  nfcmbf_t T;
  nflift_t L;
  pari_timer ti, ti_tot;
  if (DEBUGLEVEL>2) { timer_start(&ti); timer_start(&ti_tot); }
  n = degpol(nfpol);
  if (dpol == 1) {
    if (fl == FACTORS) return mkvec(QXQX_normalize(pol, nfpol));
    return mkvec(gneg(gdiv(gel(pol,2),gel(pol,3))));
  }
  if (typ(nf)==t_POL || nfsqff_use_Trager(n,dpol))
  {
    GEN z;
    if (DEBUGLEVEL>2) err_printf("Using Trager's method\n");
    if (typ(nf) != t_POL) den =  mulii(den, nf_get_index(nf));
    z = nfsqff_trager(Q_primpart(pol), nfpol, den);
    if (fl != FACTORS) {
      long i, l = lg(z);
      for (i = 1; i < l; i++)
      {
        GEN LT, t = gel(z,i); if (degpol(t) > 1) break;
        LT = gel(t,3);
        if (typ(LT) == t_POL) LT = gel(LT,2); 
        gel(z,i) = gdiv(gel(t,2), negi(LT));
      }
      setlg(z, i);
      if (fl == ROOTS_SPLIT && i != l) return cgetg(1,t_VEC);
    }
    return z;
  }
  polbase = RgX_to_nfX(nf, pol);
  nbf = nf_pick_prime(nf, pol, fl, &lt, &L.Tp, &pp);
  if (L.Tp)
  {
    L.Tp = Flx_to_ZX(L.Tp);
    L.p = utoi(pp);
  }
  if (fl == ROOTS_SPLIT && nbf < dpol) return cgetg(1,t_VEC);
  if (nbf <= 1)
  {
    if (fl == FACTORS) return mkvec(QXQX_normalize(pol, nfpol)); 
    if (!nbf) return cgetg(1,t_VEC); 
  }
  if (DEBUGLEVEL>2) {
    timer_printf(&ti, "choice of a prime ideal");
    err_printf("Prime ideal chosen: (%lu,x^%ld+...)\n", pp, degpol(L.Tp));
  }
  L.tozk = nf_get_invzk(nf);
  L.topow= nf_get_zkprimpart(nf);
  L.topowden = nf_get_zkden(nf);
  if (is_pm1(den)) den = NULL;
  L.dn = den;
  T.ZC = L2_bound(nf, den);
  T.Br = nf_root_bounds(nf, pol); if (lt) T.Br = gmul(T.Br, lt);
  if (fl != FACTORS) C0 = normTp(T.Br, 2, n);
  else               C0 = nf_factor_bound(nf, polbase);
  T.bound = mulrr(T.ZC, C0); 
  N2 = mulur(dpol*dpol, normTp(T.Br, 4, n)); 
  T.BS_2 = mulrr(T.ZC, N2); 
  if (DEBUGLEVEL>2) {
    timer_printf(&ti, "bound computation");
    err_printf("  1) T_2 bound for %s: %Ps\n",
               fl == FACTORS?"factor": "root", C0);
    err_printf("  2) Conversion from T_2 --> | |^2 bound : %Ps\n", T.ZC);
    err_printf("  3) Final bound: %Ps\n", T.bound);
  }
  bestlift_init(0, nf, T.bound, &L);
  if (DEBUGLEVEL>2) timer_start(&ti);
  polred = ZqX_normalize(polbase, lt, &L); 
  if (fl != FACTORS) {
    GEN z = nf_DDF_roots(pol, polred, nfpol, fl, &L);
    if (lg(z) == 1) return cgetg(1, t_VEC);
    return z;
  }
  T.fact = gel(FqX_factor(polred, L.Tp, L.p), 1);
  if (DEBUGLEVEL>2)
    timer_printf(&ti, "splitting mod %Ps^%ld", L.p, degpol(L.Tp));
  T.L  = &L;
  T.polbase = polbase;
  T.pol   = pol;
  T.nf    = nf;
  res = nf_combine_factors(&T, polred, dpol-1);
  if (DEBUGLEVEL>2)
    err_printf("Total Time: %ld\n===========\n", timer_delay(&ti_tot));
  return res;
}
static GEN nfsqff ( GEN nf , GEN pol , long fl , GEN den ) { long n , nbf , dpol = degpol ( pol ) ; GEN C0 , polbase ; GEN N2 , res , polred , lt , nfpol = typ ( nf ) == t_POL ? nf : nf_get_pol ( nf ) ; ulong pp ; nfcmbf_t T ; nflift_t L ; pari_timer ti , ti_tot ; if ( DEBUGLEVEL > 2 ) { timer_start ( & ti ) ; timer_start ( & ti_tot ) ; } n = degpol ( nfpol ) ; if ( dpol == 1 ) { if ( fl == FACTORS ) return mkvec ( QXQX_normalize ( pol , nfpol ) ) ; return mkvec ( gneg ( gdiv ( gel ( pol , 2 ) , gel ( pol , 3 ) ) ) ) ; } if ( typ ( nf ) == t_POL || nfsqff_use_Trager ( n , dpol ) ) { GEN z ; if ( DEBUGLEVEL > 2 ) err_printf ( " \n " ) ; if ( typ ( nf ) != t_POL ) den = mulii ( den , nf_get_index ( nf ) ) ; z = nfsqff_trager ( Q_primpart ( pol ) , nfpol , den ) ; if ( fl != FACTORS ) { long i , l = lg ( z ) ; for ( i = 1 ; i < l ; i ++ ) { GEN LT , t = gel ( z , i ) ; if ( degpol ( t ) > 1 ) break ; LT = gel ( t , 3 ) ; if ( typ ( LT ) == t_POL ) LT = gel ( LT , 2 ) ; gel ( z , i ) = gdiv ( gel ( t , 2 ) , negi ( LT ) ) ; } setlg ( z , i ) ; if ( fl == ROOTS_SPLIT && i != l ) return cgetg ( 1 , t_VEC ) ; } return z ; } polbase = RgX_to_nfX ( nf , pol ) ; nbf = nf_pick_prime ( nf , pol , fl , & lt , & L . Tp , & pp ) ; if ( L . Tp ) { L . Tp = Flx_to_ZX ( L . Tp ) ; L . p = utoi ( pp ) ; } if ( fl == ROOTS_SPLIT && nbf < dpol ) return cgetg ( 1 , t_VEC ) ; if ( nbf <= 1 ) { if ( fl == FACTORS ) return mkvec ( QXQX_normalize ( pol , nfpol ) ) ; if ( ! nbf ) return cgetg ( 1 , t_VEC ) ; } if ( DEBUGLEVEL > 2 ) { timer_printf ( & ti , " " ) ; err_printf ( " \n " , pp , degpol ( L . Tp ) ) ; } L . tozk = nf_get_invzk ( nf ) ; L . topow = nf_get_zkprimpart ( nf ) ; L . topowden = nf_get_zkden ( nf ) ; if ( is_pm1 ( den ) ) den = NULL ; L . dn = den ; T . ZC = L2_bound ( nf , den ) ; T . Br = nf_root_bounds ( nf , pol ) ; if ( lt ) T . Br = gmul ( T . Br , lt ) ; if ( fl != FACTORS ) C0 = normTp ( T . Br , 2 , n ) ; else C0 = nf_factor_bound ( nf , polbase ) ; T . bound = mulrr ( T . ZC , C0 ) ; N2 = mulur ( dpol * dpol , normTp ( T . Br , 4 , n ) ) ; T . BS_2 = mulrr ( T . ZC , N2 ) ; if ( DEBUGLEVEL > 2 ) { timer_printf ( & ti , " " ) ; err_printf ( " \n " , fl == FACTORS ? " " : " " , C0 ) ; err_printf ( " \n " , T . ZC ) ; err_printf ( " \n " , T . bound ) ; } bestlift_init ( 0 , nf , T . bound , & L ) ; if ( DEBUGLEVEL > 2 ) timer_start ( & ti ) ; polred = ZqX_normalize ( polbase , lt , & L ) ; if ( fl != FACTORS ) { GEN z = nf_DDF_roots ( pol , polred , nfpol , fl , & L ) ; if ( lg ( z ) == 1 ) return cgetg ( 1 , t_VEC ) ; return z ; } T . fact = gel ( FqX_factor ( polred , L . Tp , L . p ) , 1 ) ; if ( DEBUGLEVEL > 2 ) timer_printf ( & ti , " " , L . p , degpol ( L . Tp ) ) ; T . L = & L ; T . polbase = polbase ; T . pol = pol ; T . nf = nf ; res = nf_combine_factors ( & T , polred , dpol - 1 ) ; if ( DEBUGLEVEL > 2 ) err_printf ( " \n \n " , timer_delay ( & ti_tot ) ) ; return res ; }
return the factorization of the square-free polynomial pol.
return the factorization of the square - free polynomial pol .
/* deg = 1 => irreducible */ /* constant */ /* irred. */ /* no root */ /* C0 = bound for T_2(Q_i), Q | P */ /* bound for |Q_i|^2 in Z^n on chosen Z-basis */ /* bound for T_2(lt * S_2) */ /* bound for |S_2|^2 on chosen Z-basis */ /* monic */