[BACK]Return to subfield.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari-2.2 / src / modules

Diff for /OpenXM_contrib/pari-2.2/src/modules/Attic/subfield.c between version 1.1 and 1.2

version 1.1, 2001/10/02 11:17:12 version 1.2, 2002/09/11 07:27:06
Line 24  extern GEN matrixpow(long n, long m, GEN y, GEN P,GEN 
Line 24  extern GEN matrixpow(long n, long m, GEN y, GEN P,GEN 
 extern GEN Fp_factor_irred(GEN P,GEN l, GEN Q);  extern GEN Fp_factor_irred(GEN P,GEN l, GEN Q);
 extern GEN FpX_rand(long d1, long v, GEN p);  extern GEN FpX_rand(long d1, long v, GEN p);
 extern GEN hensel_lift_fact(GEN pol, GEN Q, GEN T, GEN p, GEN pe, long e);  extern GEN hensel_lift_fact(GEN pol, GEN Q, GEN T, GEN p, GEN pe, long e);
   extern GEN ZX_disc_all(GEN x, ulong bound);
   extern GEN indexpartial(GEN P, GEN DP);
   extern GEN initgaloisborne(GEN T, GEN dn, long prec, GEN *ptL, GEN *ptprep, GEN *ptdis);
   extern long ZX_get_prec(GEN x);
   
 static GEN print_block_system(long N,GEN Y,long d,GEN vbs,long maxl);  static GEN print_block_system(long N,GEN Y,long d,GEN vbs,long maxl);
   
Line 83  calc_block(long N,GEN Z,long d,GEN Y,GEN vbs,ulong max
Line 87  calc_block(long N,GEN Z,long d,GEN Y,GEN vbs,ulong max
       }        }
       if (dk == nn)        if (dk == nn)
       {        {
         long av=avma;          gpmem_t av=avma;
         int Z_equal_Zp = 1;          int Z_equal_Zp = 1;
   
         for (j=1; j<lnon; j++) non[j]=0;          for (j=1; j<lnon; j++) non[j]=0;
Line 108  calc_block(long N,GEN Z,long d,GEN Y,GEN vbs,ulong max
Line 112  calc_block(long N,GEN Z,long d,GEN Y,GEN vbs,ulong max
           setlg(Zpp, u);            setlg(Zpp, u);
           vbs = calc_block(N,Zpp,d,Yp,vbs,maxl);            vbs = calc_block(N,Zpp,d,Yp,vbs,maxl);
         }          }
         if (vbs && lg(vbs) > maxl) return vbs;          if (vbs && (ulong)lg(vbs) > maxl) return vbs;
         avma=av;          avma=av;
       }        }
     }      }
Line 119  calc_block(long N,GEN Z,long d,GEN Y,GEN vbs,ulong max
Line 123  calc_block(long N,GEN Z,long d,GEN Y,GEN vbs,ulong max
 static GEN  static GEN
 potential_block_systems(long N, long d, GEN n, ulong maxl)  potential_block_systems(long N, long d, GEN n, ulong maxl)
 {  {
   long av=avma,r,i,j,k;    long r, i, j, k;
     gpmem_t av=avma;
   GEN p1,vbs,Z;    GEN p1,vbs,Z;
   
   r=lg(n); Z=cgetg(r,t_VEC);    r=lg(n); Z=cgetg(r,t_VEC);
Line 134  potential_block_systems(long N, long d, GEN n, ulong m
Line 139  potential_block_systems(long N, long d, GEN n, ulong m
   
 /* product of permutations. Put the result in perm1. */  /* product of permutations. Put the result in perm1. */
 static void  static void
 perm_mul(GEN perm1,GEN perm2)  perm_mul_i(GEN perm1,GEN perm2)
 {  {
   long av = avma,i, N = lg(perm1);    long i, N = lg(perm1);
     gpmem_t av = avma;
   GEN perm=new_chunk(N);    GEN perm=new_chunk(N);
   for (i=1; i<N; i++) perm[i]=perm1[perm2[i]];    for (i=1; i<N; i++) perm[i]=perm1[perm2[i]];
   for (i=1; i<N; i++) perm1[i]=perm[i];    for (i=1; i<N; i++) perm1[i]=perm[i];
Line 153  cycle_power_to_perm(GEN perm,GEN cy,long l)
Line 159  cycle_power_to_perm(GEN perm,GEN cy,long l)
   for (i=1; i<N; i++) perm[i] = i;    for (i=1; i<N; i++) perm[i] = i;
   if (lp)    if (lp)
   {    {
     long av = avma;      gpmem_t av = avma;
     GEN p1 = new_chunk(N);      GEN p1 = new_chunk(N);
     b = cy[1];      b = cy[1];
     for (i=1; i<lcy; i++) b = (perm[b] = cy[i+1]);      for (i=1; i<lcy; i++) b = (perm[b] = cy[i+1]);
     perm[b] = cy[1];      perm[b] = cy[1];
     for (i=1; i<N; i++) p1[i] = perm[i];      for (i=1; i<N; i++) p1[i] = perm[i];
   
     for (j=2; j<=lp; j++) perm_mul(perm,p1);      for (j=2; j<=lp; j++) perm_mul_i(perm,p1);
     avma = av;      avma = av;
   }    }
   return perm;    return perm;
Line 221  append_vbs(GEN vbs, GEN D)
Line 227  append_vbs(GEN vbs, GEN D)
   l = lg(vbs); maxl = vbs[-1];    l = lg(vbs); maxl = vbs[-1];
   if (l == maxl)    if (l == maxl)
   {    {
     vbs = (GEN)gprealloc((void*)(vbs-1), (2 + (maxl<<1))*sizeof(GEN),      vbs = (GEN)gprealloc((void*)(vbs-1), (2 + (maxl<<1))*sizeof(GEN));
                                          (2 + maxl)*sizeof(GEN));  
     *vbs = maxl<<1; vbs++; setlg(vbs, 1);      *vbs = maxl<<1; vbs++; setlg(vbs, 1);
   }    }
   if (DEBUGLEVEL>5) fprintferr("appending D = %Z\n",D);    if (DEBUGLEVEL>5) fprintferr("appending D = %Z\n",D);
Line 256  print_block_system(long N,GEN Y,long d,GEN vbs,long ma
Line 261  print_block_system(long N,GEN Y,long d,GEN vbs,long ma
   if (DEBUGLEVEL>5) fprintferr("Y = %Z\n",Y);    if (DEBUGLEVEL>5) fprintferr("Y = %Z\n",Y);
   empty = cgetg(1,t_VEC);    empty = cgetg(1,t_VEC);
   n = new_chunk(N+1);    n = new_chunk(N+1);
   D = cgetg(N+1, t_VEC); setlg(D,1);    D = cget1(N+1, t_VEC);
   t=new_chunk(r+1); k=new_chunk(r+1); Z=cgetg(r+1,t_VEC);    t=new_chunk(r+1); k=new_chunk(r+1); Z=cgetg(r+1,t_VEC);
   for (ns=0,i=1; i<r; i++)    for (ns=0,i=1; i<r; i++)
   {    {
Line 299  print_block_system(long N,GEN Y,long d,GEN vbs,long ma
Line 304  print_block_system(long N,GEN Y,long d,GEN vbs,long ma
   perm = cgetg(N+1,t_VEC); i=ns;    perm = cgetg(N+1,t_VEC); i=ns;
   do    do
   {    {
     long av = avma;      gpmem_t av = avma;
     if (DEBUGLEVEL>5)      if (DEBUGLEVEL>5)
     {      {
       for (l=1; l<=ns; l++)        for (l=1; l<=ns; l++)
Line 313  print_block_system(long N,GEN Y,long d,GEN vbs,long ma
Line 318  print_block_system(long N,GEN Y,long d,GEN vbs,long ma
     for (u=1; u<=N; u++) perm[u]=u;      for (u=1; u<=N; u++) perm[u]=u;
     for (u=1; u<=ns; u++)      for (u=1; u<=ns; u++)
       for (v=1; v<=t[u]; v++)        for (v=1; v<=t[u]; v++)
         perm_mul(perm, cycle_power_to_perm(cyperm,gmael(Z,u,v),e[u][v]));          perm_mul_i(perm, cycle_power_to_perm(cyperm,gmael(Z,u,v),e[u][v]));
     vbs = append_vbs(vbs, im_block_by_perm(D,perm));      vbs = append_vbs(vbs, im_block_by_perm(D,perm));
     if (lg(vbs) > maxl) return vbs;      if (lg(vbs) > maxl) return vbs;
     avma = av;      avma = av;
Line 376  cand_for_subfields(GEN A,GEN DATA,GEN *ptlistdelta)
Line 381  cand_for_subfields(GEN A,GEN DATA,GEN *ptlistdelta)
 {  {
   long N,m,i,j,d,lf;    long N,m,i,j,d,lf;
   GEN M,T,pe,p,pol,fhk,g;    GEN M,T,pe,p,pol,fhk,g;
   GEN _d_1_term,delta,listdelta,whichdelta,firstroot;    GEN d_1_term,delta,listdelta,whichdelta,firstroot;
   
   pol=(GEN)DATA[1];    pol=(GEN)DATA[1];
   p = (GEN)DATA[2];    p = (GEN)DATA[2];
Line 390  cand_for_subfields(GEN A,GEN DATA,GEN *ptlistdelta)
Line 395  cand_for_subfields(GEN A,GEN DATA,GEN *ptlistdelta)
   lf = lg(firstroot);    lf = lg(firstroot);
   listdelta = cgetg(lf, t_VEC);    listdelta = cgetg(lf, t_VEC);
   whichdelta = cgetg(N+1, t_VECSMALL);    whichdelta = cgetg(N+1, t_VECSMALL);
   _d_1_term = gzero;    d_1_term = gzero;
   for (i=1; i<=m; i++)    for (i=1; i<=m; i++)
   {    {
     GEN Ai = (GEN)A[i], p1 = gun;      GEN Ai = (GEN)A[i], p1 = gun;
     for (j=1; j<=d; j++)      for (j=1; j<=d; j++)
       p1 = FpXQ_mul(p1, (GEN)fhk[Ai[j]], T,pe);        p1 = Fq_mul(p1, (GEN)fhk[Ai[j]], T,pe);
     delta[i] = (long)p1;      delta[i] = (long)p1;
     if (DEBUGLEVEL>2) fprintferr("delta[%ld] = %Z\n",i,p1);      if (DEBUGLEVEL>2) fprintferr("delta[%ld] = %Z\n",i,p1);
     /* g = prod (X - delta[i])      /* g = prod (X - delta[i])
Line 403  cand_for_subfields(GEN A,GEN DATA,GEN *ptlistdelta)
Line 408  cand_for_subfields(GEN A,GEN DATA,GEN *ptlistdelta)
     /* fk[k] belongs to block number whichdelta[k] */      /* fk[k] belongs to block number whichdelta[k] */
     for (j=1; j<=d; j++) whichdelta[Ai[j]] = i;      for (j=1; j<=d; j++) whichdelta[Ai[j]] = i;
     if (typ(p1) == t_POL) p1 = constant_term(p1);      if (typ(p1) == t_POL) p1 = constant_term(p1);
     _d_1_term = addii(_d_1_term, p1);      d_1_term = addii(d_1_term, p1);
   }    }
   _d_1_term = centermod(_d_1_term, pe); /* Tr(g) */    d_1_term = centermod(d_1_term, pe); /* Tr(g) */
   if (absi_cmp(_d_1_term, (GEN)M[3]) > 0) return gdeux; /* d-1 test */    if (absi_cmp(d_1_term, (GEN)M[3]) > 0) return gdeux; /* d-1 test */
   g = FqV_roots_to_pol(delta, T, pe, 0);    g = FqV_roots_to_pol(delta, T, pe, 0);
   g = centermod(polsimplify(g), pe); /* assume g in Z[X] */    g = centermod(polsimplify(g), pe); /* assume g in Z[X] */
   if (DEBUGLEVEL>2) fprintferr("pol. found = %Z\n",g);    if (DEBUGLEVEL>2) fprintferr("pol. found = %Z\n",g);
Line 497  chinese_retrieve_pol(GEN DATA, GEN listdelta)
Line 502  chinese_retrieve_pol(GEN DATA, GEN listdelta)
   return FpX_res(FpX_red(S, p), FpX_red((GEN)DATA[1],p), p);    return FpX_res(FpX_red(S, p), FpX_red((GEN)DATA[1],p), p);
 }  }
   
   /* return P(X + c) using destructive Horner */
   static GEN
   TR_pol(GEN P, GEN c)
   {
     GEN Q = dummycopy(P), *R;
     long i,k,n;
   
     if (!signe(P)) return Q;
     R = (GEN*)(Q+2); n = degpol(P);
     if (gcmp1(c))
     {
       for (i=1; i<=n; i++)
         for (k=n-i; k<n; k++)
           R[k] = gadd(R[k], R[k+1]);
     }
     else if (gcmp_1(c))
     {
       for (i=1; i<=n; i++)
         for (k=n-i; k<n; k++)
           R[k] = gsub(R[k], R[k+1]);
     }
     else
     {
       for (i=1; i<=n; i++)
         for (k=n-i; k<n; k++)
           R[k] = gadd(R[k], gmul(c, R[k+1]));
     }
     return Q;
   }
   
 /* g in Z[X] potentially defines a subfield of Q[X]/f. It is a subfield iff A  /* g in Z[X] potentially defines a subfield of Q[X]/f. It is a subfield iff A
  * (cf cand_for_subfields) was a block system; then there   * (cf cand_for_subfields) was a block system; then there
  * exists h in Q[X] such that f | g o h. listdelta determines h s.t f | g o h   * exists h in Q[X] such that f | g o h. listdelta determines h s.t f | g o h
Line 506  embedding_of_potential_subfields(GEN g,GEN DATA,GEN li
Line 541  embedding_of_potential_subfields(GEN g,GEN DATA,GEN li
 {  {
   GEN TR,w0_Q,w0,w1_Q,w1,wpow,h0,gp,T,q2,q,p,ind,maxp,a;    GEN TR,w0_Q,w0,w1_Q,w1,wpow,h0,gp,T,q2,q,p,ind,maxp,a;
   long rt;    long rt;
   ulong av;    gpmem_t av;
   
   T = (GEN)DATA[1]; rt = brent_kung_optpow(degpol(T), 2);    T = (GEN)DATA[1]; rt = brent_kung_optpow(degpol(T), 2);
   p = (GEN)DATA[2];    p = (GEN)DATA[2];
Line 535  embedding_of_potential_subfields(GEN g,GEN DATA,GEN li
Line 570  embedding_of_potential_subfields(GEN g,GEN DATA,GEN li
     w1_Q = centermod(gmul(w1, resii(ind,q)), q);      w1_Q = centermod(gmul(w1, resii(ind,q)), q);
     if (gegal(w1_Q, w0_Q) || cmpii(q,maxp) > 0)      if (gegal(w1_Q, w0_Q) || cmpii(q,maxp) > 0)
     {      {
       GEN G = gcmp1(ind)? g: ZX_rescale_pol(g,ind);        GEN G = gcmp1(ind)? g: rescale_pol(g,ind);
       if (gcmp0(poleval(G, gmodulcp(w1_Q,T)))) break;        if (gcmp0(poleval(G, gmodulcp(w1_Q,T)))) break;
     }      }
     if (cmpii(q, maxp) > 0)      if (cmpii(q, maxp) > 0)
Line 560  embedding_of_potential_subfields(GEN g,GEN DATA,GEN li
Line 595  embedding_of_potential_subfields(GEN g,GEN DATA,GEN li
     w0 = w1; w0_Q = w1_Q; p = q; q = q2;      w0 = w1; w0_Q = w1_Q; p = q; q = q2;
   }    }
   TR = (GEN)DATA[14];    TR = (GEN)DATA[14];
   if (!gcmp0(TR)) w1_Q = poleval(w1_Q, gadd(polx[0], TR));    if (!gcmp0(TR)) w1_Q = TR_pol(w1_Q, TR);
   return gdiv(w1_Q,ind);    return gdiv(w1_Q,ind);
 }  }
   
 static GEN  static GEN
 choose_prime(GEN pol,GEN dpol,long d,GEN *ptff,GEN *ptlistpotbl, long *ptlcm)  choose_prime(GEN pol,GEN dpol,long d,GEN *ptff,GEN *ptlistpotbl, long *ptlcm)
 {  {
   ulong av;    gpmem_t av;
   long j,k,oldllist,llist,r,lcm,oldlcm,N,pp;  
   GEN p,listpotbl,oldlistpotbl,ff,oldff,n,oldn;  
   byteptr di=diffptr;    byteptr di=diffptr;
     long j,k,oldllist,llist,r,lcm,oldlcm,pp,minp, N = degpol(pol), m = N/d;
   if (DEBUGLEVEL) timer2();    GEN p,listpotbl,oldlistpotbl,ff,oldff,n,oldn;
   di++; p = stoi(2); N = degpol(pol);  
   while (p[2]<=N) p[2] += *di++;    minp = N*(m-1)/2;
     if (DEBUGLEVEL) (void)timer2();
     di++; p = stoi(2);
     while (p[2]<=minp)
         NEXT_PRIME_VIADIFF(p[2], di);
   oldllist = 100000;    oldllist = 100000;
   oldlcm = 0;    oldlcm = 0;
   oldlistpotbl = oldff = oldn = NULL; pp = 0; /* gcc -Wall */    oldlistpotbl = oldff = oldn = NULL; pp = 0; /* gcc -Wall */
   av = avma;    av = avma;
   for(k=1; k<11 || !oldn; k++,p[2]+= *di++,avma = av)    for(k=1; k<11 || !oldn; k++,avma = av)
   {    {
     while (!smodis(dpol,p[2])) p[2] += *di++;      while (!smodis(dpol,p[2]))
         NEXT_PRIME_VIADIFF(p[2], di);
     if (k > 50) err(talker,"sorry, too many block systems in nfsubfields");      if (k > 50) err(talker,"sorry, too many block systems in nfsubfields");
     ff=(GEN)factmod(pol,p)[1]; r=lg(ff)-1;      ff=(GEN)factmod0(pol,p)[1]; r=lg(ff)-1;
     if (r == 1 || r == N) continue;      if (r == 1 || r == N) goto repeat;
   
     n = cgetg(r+1, t_VECSMALL);      n = cgetg(r+1, t_VECSMALL);
     lcm = n[1] = degpol(ff[1]);      lcm = n[1] = degpol(ff[1]);
     for (j=2; j<=r; j++) { n[j] = degpol(ff[j]); lcm = clcm(lcm,n[j]); }      for (j=2; j<=r; j++) { n[j] = degpol(ff[j]); lcm = clcm(lcm,n[j]); }
     if (lcm < oldlcm) continue; /* false when oldlcm = 0 */      if (lcm < oldlcm) goto repeat; /* false when oldlcm = 0 */
     if (r >= BIL) { err(warner,"subfields: overflow in calc_block"); continue; }      if (r >= BIL) { err(warner,"subfields: overflow in calc_block"); goto repeat; }
     if (DEBUGLEVEL) fprintferr("p = %ld,\tlcm = %ld,\torbits: %Z\n",p[2],lcm,n);      if (DEBUGLEVEL) fprintferr("p = %ld,\tlcm = %ld,\torbits: %Z\n",p[2],lcm,n);
     if (oldn && gegal(n,oldn)) continue;      if (oldn && gegal(n,oldn)) goto repeat;
   
     listpotbl = potential_block_systems(N,d,n, oldllist);      listpotbl = potential_block_systems(N,d,n, oldllist);
     if (!listpotbl) { oldlistpotbl = NULL; pp = p[2]; break; }      if (!listpotbl) { oldlistpotbl = NULL; pp = p[2]; break; }
Line 601  choose_prime(GEN pol,GEN dpol,long d,GEN *ptff,GEN *pt
Line 639  choose_prime(GEN pol,GEN dpol,long d,GEN *ptff,GEN *pt
     {      {
       if (DEBUGLEVEL) msgtimer("#pbs >= %ld [aborted]",oldllist);        if (DEBUGLEVEL) msgtimer("#pbs >= %ld [aborted]",oldllist);
       for (j=1; j<llist; j++) free((void*)listpotbl[j]);        for (j=1; j<llist; j++) free((void*)listpotbl[j]);
       free((void*)(listpotbl-1)); continue;        free((void*)(listpotbl-1)); goto repeat;
     }      }
     oldllist = llist; oldlistpotbl = listpotbl;      oldllist = llist; oldlistpotbl = listpotbl;
     pp = p[2]; oldff = ff; oldlcm = lcm; oldn = n;      pp = p[2]; oldff = ff; oldlcm = lcm; oldn = n;
     if (DEBUGLEVEL) msgtimer("#pbs = %ld",llist);      if (DEBUGLEVEL) msgtimer("#pbs = %ld",llist);
     av = avma;      av = avma;
      repeat:
       NEXT_PRIME_VIADIFF(p[2], di);
   }    }
   if (DEBUGLEVEL)    if (DEBUGLEVEL) fprintferr("Chosen prime: p = %ld\n",pp);
   {  
     fprintferr("Chosen prime: p = %ld\n",pp);  
     if (DEBUGLEVEL>2)  
       fprintferr("Potential block systems of size %ld: %Z\n", d,oldlistpotbl);  
     flusherr();  
   }  
   if (oldff) oldff = lift_intern(oldff);  
   *ptlistpotbl=oldlistpotbl; *ptff=oldff; *ptlcm=oldlcm; return stoi(pp);    *ptlistpotbl=oldlistpotbl; *ptff=oldff; *ptlcm=oldlcm; return stoi(pp);
 }  }
   
Line 625  bound_for_coeff(long m,GEN rr, GEN *maxroot)
Line 658  bound_for_coeff(long m,GEN rr, GEN *maxroot)
   long i,r1, lrr=lg(rr);    long i,r1, lrr=lg(rr);
   GEN p1,b1,b2,B,M, C = matpascal(m-1);    GEN p1,b1,b2,B,M, C = matpascal(m-1);
   
   for (r1=0; typ(rr[r1+1]) == t_REAL; r1++) /* empty */;    for (r1=1; r1 < lrr; r1++)
       if (typ(rr[r1]) != t_REAL) break;
     r1--;
   
   rr = gabs(rr,0); *maxroot = vecmax(rr);    rr = gabs(rr,0); *maxroot = vecmax(rr);
   for (i=1; i<lrr; i++)    for (i=1; i<lrr; i++)
Line 689  interpol(GEN H, GEN T, GEN p)
Line 724  interpol(GEN H, GEN T, GEN p)
   {    {
     d = constant_term(H[i]); /* -D[i] */      d = constant_term(H[i]); /* -D[i] */
     p1 = FpXQX_mul(p1,gadd(X,d), T,p);      p1 = FpXQX_mul(p1,gadd(X,d), T,p);
     p2 = FpXQ_mul(p2, gadd(a,d), T,p);      p2 = Fq_mul(p2, gadd(a,d), T,p);
   }    }
   p2 = FpXQ_inv(p2, T,p);    p2 = FpXQ_inv(p2, T,p);
   return FpXQX_FpXQ_mul(p1,p2, T,p);    return FpXQX_FpXQ_mul(p1,p2, T,p);
Line 732  struct poldata
Line 767  struct poldata
 static GEN  static GEN
 compute_data(GEN DATA, struct poldata PD, long d, GEN ff, GEN T,GEN p)  compute_data(GEN DATA, struct poldata PD, long d, GEN ff, GEN T,GEN p)
 {  {
   long i,j,l,e,N;    long i,j,l,e,N, lff = lg(ff);
   GEN den,roo,pe,p1,p2,fk,fhk,MM,maxroot,pol,interp,bezoutC;    GEN ffL,den,roo,pe,p1,p2,fk,fhk,MM,maxroot,pol,interp,bezoutC;
   
   if (DEBUGLEVEL>1) { fprintferr("Entering compute_data()\n\n"); flusherr(); }    if (DEBUGLEVEL>1) { fprintferr("Entering compute_data()\n\n"); flusherr(); }
   pol = PD.pol; N = degpol(pol);    pol = PD.pol; N = degpol(pol);
Line 743  compute_data(GEN DATA, struct poldata PD, long d, GEN 
Line 778  compute_data(GEN DATA, struct poldata PD, long d, GEN 
   {    {
     GEN Xm1 = gsub(polx[varn(pol)], gun);      GEN Xm1 = gsub(polx[varn(pol)], gun);
     GEN TR = addis((GEN)DATA[14],1);      GEN TR = addis((GEN)DATA[14],1);
       GEN mTR = negi(TR), mun = negi(gun);
     DATA[14] = (long)TR;      DATA[14] = (long)TR;
     pol = poleval(pol, gsub(polx[varn(pol)], TR));      pol = TR_pol(pol, mTR);
     p1 = dummycopy(roo); l = lg(p1);      p1 = dummycopy(roo); l = lg(p1);
     for (i=1; i<l; i++) p1[i] = ladd(TR, (GEN)p1[i]);      for (i=1; i<l; i++) p1[i] = ladd(TR, (GEN)p1[i]);
     roo = p1;      roo = p1;
Line 758  compute_data(GEN DATA, struct poldata PD, long d, GEN 
Line 794  compute_data(GEN DATA, struct poldata PD, long d, GEN 
     {      {
       if (degpol(interp[i]) > 0) /* do not turn polun[0] into gun */        if (degpol(interp[i]) > 0) /* do not turn polun[0] into gun */
       {        {
         p1 = poleval((GEN)interp[i], Xm1);          p1 = TR_pol((GEN)interp[i], mun);
         interp[i] = (long)FpXQX_red(p1, NULL,p);          interp[i] = (long)FpXQX_red(p1, NULL,p);
       }        }
       if (degpol(bezoutC[i]) > 0)        if (degpol(bezoutC[i]) > 0)
       {        {
         p1 = poleval((GEN)bezoutC[i], Xm1);          p1 = TR_pol((GEN)bezoutC[i], mun);
         bezoutC[i] = (long)FpXQX_red(p1, NULL,p);          bezoutC[i] = (long)FpXQX_red(p1, NULL,p);
       }        }
     }      }
       p1 = cgetg(lff, t_VEC);
       for (i=1; i<lff; i++)
         p1[i] = (long)FpX_red(TR_pol((GEN)ff[i], mTR), p);
       ff = p1;
   }    }
   else    else
   {    {
     GEN firstroot;      GEN firstroot = cgetg(lff, t_VECSMALL);
     long r = lg(ff);  
     DATA = cgetg(15,t_VEC);      DATA = cgetg(15,t_VEC);
     DATA[2] = (long)p;      DATA[2] = (long)p;
     DATA[4] = (long)T;      DATA[4] = (long)T;
     interp = cgetg(r, t_VEC);      interp = cgetg(lff, t_VEC);
     firstroot = cgetg(r, t_VECSMALL);  
     fk = cgetg(N+1,t_VEC);      fk = cgetg(N+1,t_VEC);
     for (l=1,j=1; j<r; j++)      for (l=1,j=1; j<lff; j++)
     { /* compute roots and fix ordering (Frobenius cycles) */      { /* compute roots and fix ordering (Frobenius cycles) */
       p1 = Fp_factor_irred((GEN)ff[j], p, (GEN)DATA[4]);        p1 = Fp_factor_irred((GEN)ff[j], p,T);
       interp[j] = (long)interpol(p1,T,p);        interp[j] = (long)interpol(p1,T,p);
       firstroot[j] = l;        firstroot[j] = l;
       for (i=1; i<lg(p1); i++,l++) fk[l] = p1[i];        for (i=1; i<lg(p1); i++,l++) fk[l] = p1[i];
Line 799  compute_data(GEN DATA, struct poldata PD, long d, GEN 
Line 837  compute_data(GEN DATA, struct poldata PD, long d, GEN 
   e = logint(shifti(vecmax(MM),20), p, &pe); /* overlift 2^20 [for d-1 test] */    e = logint(shifti(vecmax(MM),20), p, &pe); /* overlift 2^20 [for d-1 test] */
   DATA[3] = (long)pe;    DATA[3] = (long)pe;
   DATA[6] = (long)roots_from_deg1(fk);    DATA[6] = (long)roots_from_deg1(fk);
   
   #if 0
   fhk = hensel_lift_fact(pol,fk,(GEN)DATA[4],p,pe,e);    fhk = hensel_lift_fact(pol,fk,(GEN)DATA[4],p,pe,e);
   #else
     /* first lift in Zp to precision p^e */
     ffL = hensel_lift_fact(pol,ff, NULL,p,pe,e);
     fhk = NULL;
     for (l=i=1; i<lff; i++)
     { /* lift factorization of ff[i] in Qp[X] / T */
       GEN L = (GEN)ffL[i];
       long di = degpol(L);
       p2 = cgetg(di+1, t_VEC);
       for (j=1; j<=di; j++) p2[j] = fk[l++];
       p1 = hensel_lift_fact(L,p2,T,p,pe,e);
       fhk = fhk? concatsp(fhk, p1): p1;
     }
   #endif
   DATA[5] = (long)roots_from_deg1(fhk);    DATA[5] = (long)roots_from_deg1(fhk);
   
   p1 = gmul(stoi(N), gsqrt(gpuigs(stoi(N-1),N-1),DEFAULTPREC));    p1 = gmul(stoi(N), gsqrt(gpuigs(stoi(N-1),N-1),DEFAULTPREC));
Line 831  _subfield(GEN g, GEN h)
Line 885  _subfield(GEN g, GEN h)
 static GEN  static GEN
 subfields_of_given_degree(struct poldata PD,long d)  subfields_of_given_degree(struct poldata PD,long d)
 {  {
   ulong av,av2;    gpmem_t av, av2;
   long llist,i,nn;    long llist,i,nn,v;
   GEN listpotbl,ff,A,CSF,ESF,LSB,p,T,DATA,listdelta;    GEN listpotbl,ff,A,CSF,ESF,LSB,p,T,DATA,listdelta;
   GEN pol = PD.pol, dpol = PD.dis;    GEN pol = PD.pol, dpol = PD.dis;
   
Line 840  subfields_of_given_degree(struct poldata PD,long d)
Line 894  subfields_of_given_degree(struct poldata PD,long d)
   av = avma;    av = avma;
   p = choose_prime(pol,dpol,degpol(pol)/d,&ff,&listpotbl,&nn);    p = choose_prime(pol,dpol,degpol(pol)/d,&ff,&listpotbl,&nn);
   if (!listpotbl) { avma=av; return cgetg(1,t_VEC); }    if (!listpotbl) { avma=av; return cgetg(1,t_VEC); }
   T = lift_intern(ffinit(p,nn, fetch_var()));    v = fetch_var(); name_var(v,"y");
     T = lift_intern(ffinit(p,nn, v));
   DATA = NULL; LSB = cgetg(1,t_VEC);    DATA = NULL; LSB = cgetg(1,t_VEC);
   i = 1; llist = lg(listpotbl);    i = 1; llist = lg(listpotbl);
 CHANGE:  CHANGE:
Line 871  CHANGE: 
Line 926  CHANGE: 
       LSB = gerepileupto(av2, concat(LSB, _subfield(CSF,ESF)));        LSB = gerepileupto(av2, concat(LSB, _subfield(CSF,ESF)));
     }      }
   }    }
   delete_var();    (void)delete_var();
   for (i=1; i<llist; i++) free((void*)listpotbl[i]);    for (i=1; i<llist; i++) free((void*)listpotbl[i]);
   free((void*)(listpotbl-1));    free((void*)(listpotbl-1));
   if (DEBUGLEVEL) fprintferr("\nSubfields of degree %ld: %Z\n",d, LSB);    if (DEBUGLEVEL) fprintferr("\nSubfields of degree %ld: %Z\n",d, LSB);
Line 887  fix_var(GEN x, long v)
Line 942  fix_var(GEN x, long v)
   return x;    return x;
 }  }
   
 extern GEN get_nfpol(GEN x, GEN *nf);  
 extern GEN vandermondeinverseprep(GEN T, GEN L);  
 extern GEN ZX_disc_all(GEN x, ulong bound);  
 extern GEN indexpartial(GEN P, GEN DP);  
   
 void  void
 subfields_poldata(GEN T, struct poldata *PD)  subfields_poldata(GEN T, struct poldata *PD)
 {  {
   int     i, n;    GEN  nf,L,dis;
   GEN     L, z, prep, den;  
   long    prec;  
   
   GEN nf, dis;  
   T = get_nfpol(T, &nf);    T = get_nfpol(T, &nf);
   PD->pol = dummycopy(T); /* may change variable number later */    PD->pol = dummycopy(T); /* may change variable number later */
   if (nf)    if (nf)
   {    {
     PD->den = (GEN)nf[4];      PD->den = Q_denom((GEN)nf[7]);
     PD->roo = (GEN)nf[6];      PD->roo = (GEN)nf[6];
     PD->dis = mulii(absi((GEN)nf[3]), sqri((GEN)nf[4]));      PD->dis = mulii(absi((GEN)nf[3]), sqri((GEN)nf[4]));
     return;  
   }    }
     else
   /* copy-paste from galconj.c:galoisborne. Merge as soon as possible */  
   /* start of copy-paste */  
   n = degpol(T);  
   prec = 1;  
   for (i = 2; i < lgef(T); i++)  
     if (lg(T[i]) > prec)  
       prec = lg(T[i]);  
   /*prec++;*/  
   if (DEBUGLEVEL>=4) gentimer(3);  
   L = roots(T, prec);  
   if (DEBUGLEVEL>=4) genmsgtimer(3,"roots");  
   for (i = 1; i <= n; i++)  
   {    {
     z = (GEN) L[i];      PD->den = initgaloisborne(T,NULL,ZX_get_prec(T), &L,NULL,&dis);
     if (signe(z[2]))      PD->roo = L;
       break;      PD->dis = absi(dis);
     L[i] = z[1];  
   }    }
   if (DEBUGLEVEL>=4) gentimer(3);  
   prep=vandermondeinverseprep(T, L);  
   /* end of copy-paste */  
   {  
     GEN res = divide_conquer_prod(gabs(prep,prec), mpmul);  
     disable_dbg(0);  
     dis = ZX_disc_all(T, 1+logint(res,gdeux,NULL));  
     disable_dbg(-1);  
     den = indexpartial(T,dis);  
   }  
   
   PD->den = den;  
   PD->roo = L;  
   PD->dis = absi(dis);  
 }  }
   
 GEN  GEN
 subfields(GEN nf,GEN d)  subfields(GEN nf,GEN d)
 {  {
   ulong av = avma;    gpmem_t av = avma;
   long di,N,v0;    long di, N, v0;
   GEN LSB,pol;    GEN LSB, pol, G;
   struct poldata PD;    struct poldata PD;
   
   pol = get_nfpol(nf, &nf); /* in order to treat trivial cases */    pol = get_nfpol(nf, &nf); /* in order to treat trivial cases */
Line 958  subfields(GEN nf,GEN d)
Line 977  subfields(GEN nf,GEN d)
   if (di==1) return gerepilecopy(av, _subfield(polx[v0], pol));    if (di==1) return gerepilecopy(av, _subfield(polx[v0], pol));
   if (di < 1 || di > N || N % di) return cgetg(1,t_VEC);    if (di < 1 || di > N || N % di) return cgetg(1,t_VEC);
   
   subfields_poldata(nf, &PD);    /* much easier if nf is Galois (WSS) */
     G = galoisconj4(nf? nf: pol, NULL, 1, 0);
     if (typ(G) != t_INT)
     { /* Bingo */
       GEN L = galoissubgroups(G), F;
       long k,i, l = lg(L), o = N/di;
       F = cgetg(l, t_VEC);
       k = 1;
       for (i=1; i<l; i++)
       {
         GEN H = (GEN)L[i];
         if (group_order(H) == o)
           F[k++] = (long) lift_intern(galoisfixedfield(G, (GEN)H[1], 0, v0));
       }
       setlg(F, k);
       return gerepilecopy(av, F);
     }
   
     subfields_poldata(nf? nf:pol, &PD);
   pol = PD.pol;    pol = PD.pol;
   setvarn(pol, 0);    setvarn(pol, 0);
   LSB = subfields_of_given_degree(PD, di);    LSB = subfields_of_given_degree(PD, di);
Line 968  subfields(GEN nf,GEN d)
Line 1005  subfields(GEN nf,GEN d)
 static GEN  static GEN
 subfieldsall(GEN nf)  subfieldsall(GEN nf)
 {  {
   ulong av = avma;    gpmem_t av = avma;
   long N,ld,i,v0;    long N, ld, i, v0;
   GEN pol,dg,LSB,NLSB;    GEN G, pol, dg, LSB, NLSB;
   struct poldata PD;    struct poldata PD;
   
     /* much easier if nf is Galois (WSS) */
     G = galoisconj4(nf, NULL, 1, 0);
     if (typ(G) != t_INT)
     {
       pol = get_nfpol(nf, &nf);
       return gerepilecopy(av, lift_intern( galoissubfields(G, 0, varn(pol)) ));
     }
   
   subfields_poldata(nf, &PD);    subfields_poldata(nf, &PD);
   pol = PD.pol;    pol = PD.pol;
   
Line 986  subfieldsall(GEN nf)
Line 1031  subfieldsall(GEN nf)
     setvarn(pol, 0);      setvarn(pol, 0);
     for (i=2; i<ld; i++)      for (i=2; i<ld; i++)
     {      {
       ulong av1 = avma;        gpmem_t av1 = avma;
       NLSB = subfields_of_given_degree(PD, N / itos((GEN)dg[i]));        NLSB = subfields_of_given_degree(PD, N / itos((GEN)dg[i]));
       if (lg(NLSB) > 1) LSB = concatsp(LSB,NLSB); else avma = av1;        if (lg(NLSB) > 1) LSB = concatsp(LSB,NLSB); else avma = av1;
     }      }
Line 1002  subfields0(GEN nf,GEN d)
Line 1047  subfields0(GEN nf,GEN d)
   return d? subfields(nf,d): subfieldsall(nf);    return d? subfields(nf,d): subfieldsall(nf);
 }  }
   
 /* irreducible (unitary) polynomial of degree n over Fp[v] */  
 GEN  
 ffinit(GEN p,long n,long v)  
 {  
   long av = avma;  
   GEN pol;  
   
   if (n<=0) err(talker,"non positive degree in ffinit");  
   if (typ(p) != t_INT) err(typeer,"ffinit");  
   if (v<0) v = 0;  
   for(;; avma = av)  
   {  
     pol = gadd(gpowgs(polx[v],n), FpX_rand(n-1,v, p));  
     if (FpX_is_irred(pol, p)) break;  
   }  
   return gerepileupto(av, FpX(pol,p));  
 }  

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>