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

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

version 1.1, 2001/10/02 11:17:03 version 1.2, 2002/09/11 07:26:50
Line 22  Foundation, Inc., 59 Temple Place - Suite 330, Boston,
Line 22  Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 #include "pari.h"  #include "pari.h"
 #include "parinf.h"  #include "parinf.h"
   
   extern GEN to_polmod(GEN x, GEN mod);
   extern GEN hnfall0(GEN A, long remove);
   extern GEN get_theta_abstorel(GEN T, GEN pol, GEN k);
   extern GEN _rnfequation(GEN A, GEN B, long *pk, GEN *pLPRS);
   
 static long  static long
 psquare(GEN a,GEN p)  psquare(GEN a,GEN p)
 {  {
Line 44  psquare(GEN a,GEN p)
Line 49  psquare(GEN a,GEN p)
 static long  static long
 lemma6(GEN pol,GEN p,long nu,GEN x)  lemma6(GEN pol,GEN p,long nu,GEN x)
 {  {
   long i,lambda,mu,ltop=avma;    long i, lambda, mu;
     gpmem_t ltop=avma;
   GEN gx,gpx;    GEN gx,gpx;
   
   for (i=lgef(pol)-2,gx=(GEN) pol[i+1]; i>1; i--)    for (i=lgef(pol)-2,gx=(GEN) pol[i+1]; i>1; i--)
Line 65  lemma6(GEN pol,GEN p,long nu,GEN x)
Line 71  lemma6(GEN pol,GEN p,long nu,GEN x)
   
 static long  static long
 lemma7(GEN pol,long nu,GEN x)  lemma7(GEN pol,long nu,GEN x)
 { long i,odd4,lambda,mu,mnl,ltop=avma;  {
     long i,odd4,lambda,mu,mnl;
     gpmem_t ltop=avma;
   GEN gx,gpx,oddgx;    GEN gx,gpx,oddgx;
   
   for (i=lgef(pol)-2,gx=(GEN) pol[i+1]; i>1; i--)    for (i=lgef(pol)-2,gx=(GEN) pol[i+1]; i>1; i--)
Line 96  lemma7(GEN pol,long nu,GEN x)
Line 104  lemma7(GEN pol,long nu,GEN x)
 static long  static long
 zpsol(GEN pol,GEN p,long nu,GEN pnu,GEN x0)  zpsol(GEN pol,GEN p,long nu,GEN pnu,GEN x0)
 {  {
   long i,result,ltop=avma;    long i, result;
     gpmem_t ltop=avma;
   GEN x,pnup;    GEN x,pnup;
   
   result = (cmpis(p,2)) ? lemma6(pol,p,nu,x0) : lemma7(pol,nu,x0);    result = (cmpis(p,2)) ? lemma6(pol,p,nu,x0) : lemma7(pol,nu,x0);
Line 137  qpsoluble(GEN pol,GEN p)
Line 146  qpsoluble(GEN pol,GEN p)
 static long  static long
 psquarenf(GEN nf,GEN a,GEN pr)  psquarenf(GEN nf,GEN a,GEN pr)
 {  {
   ulong av = avma;    gpmem_t av = avma;
   long v;    long v;
   GEN norm;    GEN norm;
   
Line 169  check2(GEN nf, GEN a, GEN zinit)
Line 178  check2(GEN nf, GEN a, GEN zinit)
 static long  static long
 psquare2nf(GEN nf,GEN a,GEN pr,GEN zinit)  psquare2nf(GEN nf,GEN a,GEN pr,GEN zinit)
 {  {
   long v, ltop = avma;    long v;
     gpmem_t ltop = avma;
   
   if (gcmp0(a)) return 1;    if (gcmp0(a)) return 1;
   v = idealval(nf,a,pr); if (v&1) return 0;    v = idealval(nf,a,pr); if (v&1) return 0;
Line 182  psquare2nf(GEN nf,GEN a,GEN pr,GEN zinit)
Line 192  psquare2nf(GEN nf,GEN a,GEN pr,GEN zinit)
 static long  static long
 psquare2qnf(GEN nf,GEN a,GEN p,long q)  psquare2qnf(GEN nf,GEN a,GEN p,long q)
 {  {
   long v, ltop=avma;    long v;
     gpmem_t ltop=avma;
   GEN zinit = zidealstarinit(nf,idealpows(nf,p,q));    GEN zinit = zidealstarinit(nf,idealpows(nf,p,q));
   
   v = check2(nf,a,zinit); avma = ltop; return v;    v = check2(nf,a,zinit); avma = ltop; return v;
Line 191  psquare2qnf(GEN nf,GEN a,GEN p,long q)
Line 202  psquare2qnf(GEN nf,GEN a,GEN p,long q)
 static long  static long
 lemma6nf(GEN nf,GEN pol,GEN p,long nu,GEN x)  lemma6nf(GEN nf,GEN pol,GEN p,long nu,GEN x)
 {  {
   long i,lambda,mu,ltop=avma;    long i, lambda, mu;
     gpmem_t ltop=avma;
   GEN gx,gpx;    GEN gx,gpx;
   
   for (i=lgef(pol)-2,gx=(GEN) pol[i+1]; i>1; i--)    for (i=lgef(pol)-2,gx=(GEN) pol[i+1]; i>1; i--)
Line 212  lemma6nf(GEN nf,GEN pol,GEN p,long nu,GEN x)
Line 224  lemma6nf(GEN nf,GEN pol,GEN p,long nu,GEN x)
 static long  static long
 lemma7nf(GEN nf,GEN pol,GEN p,long nu,GEN x,GEN zinit)  lemma7nf(GEN nf,GEN pol,GEN p,long nu,GEN x,GEN zinit)
 {  {
   long res,i,lambda,mu,q,ltop=avma;    long res, i, lambda, mu, q;
     gpmem_t ltop=avma;
   GEN gx,gpx,p1;    GEN gx,gpx,p1;
   
   for (i=lgef(pol)-2, gx=(GEN) pol[i+1]; i>1; i--)    for (i=lgef(pol)-2, gx=(GEN) pol[i+1]; i>1; i--)
Line 237  lemma7nf(GEN nf,GEN pol,GEN p,long nu,GEN x,GEN zinit)
Line 250  lemma7nf(GEN nf,GEN pol,GEN p,long nu,GEN x,GEN zinit)
     q=(nu<<1)-lambda; res=0;      q=(nu<<1)-lambda; res=0;
   }    }
   if (q > itos((GEN) p[3])<<1) { avma=ltop; return -1; }    if (q > itos((GEN) p[3])<<1) { avma=ltop; return -1; }
   p1 = gmodulcp(gpuigs(gmul((GEN)nf[7],(GEN)p[2]), lambda), (GEN)nf[1]);    p1 = gmodulcp(gpowgs(gmul((GEN)nf[7],(GEN)p[2]), lambda), (GEN)nf[1]);
   if (!psquare2qnf(nf,gdiv(gx,p1), p,q)) res = -1;    if (!psquare2qnf(nf,gdiv(gx,p1), p,q)) res = -1;
   avma=ltop; return res;    avma=ltop; return res;
 }  }
Line 245  lemma7nf(GEN nf,GEN pol,GEN p,long nu,GEN x,GEN zinit)
Line 258  lemma7nf(GEN nf,GEN pol,GEN p,long nu,GEN x,GEN zinit)
 static long  static long
 zpsolnf(GEN nf,GEN pol,GEN p,long nu,GEN pnu,GEN x0,GEN repr,GEN zinit)  zpsolnf(GEN nf,GEN pol,GEN p,long nu,GEN pnu,GEN x0,GEN repr,GEN zinit)
 {  {
   long i,result,ltop=avma;    long i, result;
     gpmem_t ltop=avma;
   GEN pnup;    GEN pnup;
   
   nf=checknf(nf);    nf=checknf(nf);
Line 297  long
Line 311  long
 qpsolublenf(GEN nf,GEN pol,GEN pr)  qpsolublenf(GEN nf,GEN pol,GEN pr)
 {  {
   GEN repr,zinit,p1;    GEN repr,zinit,p1;
   long ltop=avma;    gpmem_t ltop=avma;
   
   if (gcmp0(pol)) return 1;    if (gcmp0(pol)) return 1;
   if (typ(pol)!=t_POL) err(notpoler,"qpsolublenf");    if (typ(pol)!=t_POL) err(notpoler,"qpsolublenf");
Line 333  long
Line 347  long
 zpsolublenf(GEN nf,GEN pol,GEN p)  zpsolublenf(GEN nf,GEN pol,GEN p)
 {  {
   GEN repr,zinit;    GEN repr,zinit;
   long ltop=avma;    gpmem_t ltop=avma;
   
   if (gcmp0(pol)) return 1;    if (gcmp0(pol)) return 1;
   if (typ(pol)!=t_POL) err(notpoler,"zpsolublenf");    if (typ(pol)!=t_POL) err(notpoler,"zpsolublenf");
Line 359  zpsolublenf(GEN nf,GEN pol,GEN p)
Line 373  zpsolublenf(GEN nf,GEN pol,GEN p)
 static long  static long
 hilb2nf(GEN nf,GEN a,GEN b,GEN p)  hilb2nf(GEN nf,GEN a,GEN b,GEN p)
 {  {
   ulong av = avma;    gpmem_t av = avma;
   long rep;    long rep;
   GEN pol = coefs_to_pol(3, lift(a), zero, lift(b));    GEN pol;
   
     if (typ(a) != t_POLMOD) a = basistoalg(nf, a);
     if (typ(b) != t_POLMOD) b = basistoalg(nf, b);
     pol = coefs_to_pol(3, lift(a), zero, lift(b));
   /* varn(nf.pol) = 0, pol is not a valid GEN  [as in Pol([x,x], x)].    /* varn(nf.pol) = 0, pol is not a valid GEN  [as in Pol([x,x], x)].
    * But it is only used as a placeholder, hence it is not a problem */     * But it is only used as a placeholder, hence it is not a problem */
   
Line 373  hilb2nf(GEN nf,GEN a,GEN b,GEN p)
Line 391  hilb2nf(GEN nf,GEN a,GEN b,GEN p)
 long  long
 nfhilbertp(GEN nf,GEN a,GEN b,GEN pr)  nfhilbertp(GEN nf,GEN a,GEN b,GEN pr)
 {  {
   GEN ord, ordp, p, prhall,t;    GEN ord, ordp, T,p, modpr,t;
   long va, vb, rep;    long va, vb, rep;
   ulong av = avma;    gpmem_t av = avma;
   
   if (gcmp0(a) || gcmp0(b)) err (talker,"0 argument in nfhilbertp");    if (gcmp0(a) || gcmp0(b)) err (talker,"0 argument in nfhilbertp");
   checkprimeid(pr); nf = checknf(nf);    checkprimeid(pr); nf = checknf(nf);
Line 394  nfhilbertp(GEN nf,GEN a,GEN b,GEN pr)
Line 412  nfhilbertp(GEN nf,GEN a,GEN b,GEN pr)
   /* quad. symbol is image of t by the quadratic character  */    /* quad. symbol is image of t by the quadratic character  */
   ord = subis( idealnorm(nf,pr), 1 ); /* |(O_K / pr)^*| */    ord = subis( idealnorm(nf,pr), 1 ); /* |(O_K / pr)^*| */
   ordp= subis( p, 1);                 /* |F_p^*|        */    ordp= subis( p, 1);                 /* |F_p^*|        */
   prhall = nfmodprinit(nf, pr);    modpr = nf_to_ff_init(nf, &pr,&T,&p);
   t = element_powmodpr(nf, t, divii(ord, ordp), prhall); /* in F_p^* */    t = nf_to_ff(nf,t,modpr);
   t = lift_intern((GEN)t[1]);    t = FpXQ_pow(t, diviiexact(ord, ordp), T,p); /* in F_p^* */
     if (typ(t) == t_POL)
     {
       if (degpol(t)) err(bugparier,"nfhilbertp");
       t = constant_term(t);
     }
   rep = kronecker(t, p);    rep = kronecker(t, p);
   avma = av; return rep;    avma = av; return rep;
 }  }
Line 409  nfhilbertp(GEN nf,GEN a,GEN b,GEN pr)
Line 432  nfhilbertp(GEN nf,GEN a,GEN b,GEN pr)
 long  long
 nfhilbert(GEN nf,GEN a,GEN b)  nfhilbert(GEN nf,GEN a,GEN b)
 {  {
   ulong av = avma;    gpmem_t av = avma;
   long r1, i;    long r1, i;
   GEN S, al, bl, ro;    GEN S, al, bl, ro;
   
Line 457  nfhilbert0(GEN nf,GEN a,GEN b,GEN p)
Line 480  nfhilbert0(GEN nf,GEN a,GEN b,GEN p)
 extern GEN isprincipalfact(GEN bnf,GEN P, GEN e, GEN C, long flag);  extern GEN isprincipalfact(GEN bnf,GEN P, GEN e, GEN C, long flag);
 extern GEN vconcat(GEN Q1, GEN Q2);  extern GEN vconcat(GEN Q1, GEN Q2);
 extern GEN mathnfspec(GEN x, GEN *ptperm, GEN *ptdep, GEN *ptB, GEN *ptC);  extern GEN mathnfspec(GEN x, GEN *ptperm, GEN *ptdep, GEN *ptB, GEN *ptC);
 extern GEN factorback_i(GEN fa, GEN nf, int red);  extern GEN factorback_i(GEN fa, GEN e, GEN nf, int red);
   extern GEN detcyc(GEN cyc);
 /* S a list of prime ideal in primedec format. Return res:  /* S a list of prime ideal in primedec format. Return res:
  * res[1] = generators of (S-units / units), as polynomials   * res[1] = generators of (S-units / units), as polynomials
  * res[2] = [perm, HB, den], for bnfissunit   * res[2] = [perm, HB, den], for bnfissunit
Line 469  extern GEN factorback_i(GEN fa, GEN nf, int red);
Line 493  extern GEN factorback_i(GEN fa, GEN nf, int red);
 GEN  GEN
 bnfsunit(GEN bnf,GEN S,long prec)  bnfsunit(GEN bnf,GEN S,long prec)
 {  {
   ulong ltop = avma;    gpmem_t ltop = avma;
   long i,j,ls;    long i,j,ls;
   GEN p1,nf,classgp,gen,M,U,H;    GEN p1,nf,classgp,gen,M,U,H;
   GEN sunit,card,sreg,res,pow,fa = cgetg(3, t_MAT);    GEN sunit,card,sreg,res,pow;
   
   if (typ(S) != t_VEC) err(typeer,"bnfsunit");    if (typ(S) != t_VEC) err(typeer,"bnfsunit");
   bnf = checkbnf(bnf); nf=(GEN)bnf[7];    bnf = checkbnf(bnf); nf=(GEN)bnf[7];
Line 504  bnfsunit(GEN bnf,GEN S,long prec)
Line 528  bnfsunit(GEN bnf,GEN S,long prec)
   card = gun;    card = gun;
   if (lg(H) > 1)    if (lg(H) > 1)
   { /* non trivial (rare!) */    { /* non trivial (rare!) */
     GEN SNF, ClS = cgetg(4,t_VEC);      GEN D,U, ClS = cgetg(4,t_VEC);
   
     SNF = smith2(H); p1 = (GEN)SNF[3];      D = smithall(H, &U, NULL);
     card = dethnf_i(p1);      for(i=1; i<lg(D); i++)
         if (gcmp1((GEN)D[i])) break;
       setlg(D,i); D = mattodiagonal_i(D); /* cf smithrel */
       card = detcyc(D);
     ClS[1] = (long)card; /* h */      ClS[1] = (long)card; /* h */
     for(i=1; i<lg(p1); i++)      ClS[2] = (long)D; /* cyc */
       if (gcmp1((GEN)p1[i])) break;  
     setlg(p1,i);  
     ClS[2]=(long)p1; /* cyc */  
   
     p1=cgetg(i,t_VEC); pow=ZM_inv((GEN)SNF[1],gun);      p1=cgetg(i,t_VEC); pow=ZM_inv(U,gun);
     fa[1] = (long)gen;  
     for(i--; i; i--)      for(i--; i; i--)
     {        p1[i] = (long)factorback_i(gen, (GEN)pow[i], nf, 1);
       fa[2] = pow[i];  
       p1[i] = (long)factorback_i(fa, nf, 1);  
     }  
     ClS[3]=(long)p1; /* gen */      ClS[3]=(long)p1; /* gen */
     res[5]=(long) ClS;      res[5]=(long) ClS;
   }    }
Line 546  bnfsunit(GEN bnf,GEN S,long prec)
Line 566  bnfsunit(GEN bnf,GEN S,long prec)
     Sperm = cgetg(ls, t_VEC); sunit = cgetg(ls, t_VEC);      Sperm = cgetg(ls, t_VEC); sunit = cgetg(ls, t_VEC);
     for (i=1; i<ls; i++) Sperm[i] = S[perm[i]]; /* S o perm */      for (i=1; i<ls; i++) Sperm[i] = S[perm[i]]; /* S o perm */
   
     setlg(Sperm, lH); fa[1] = (long)Sperm;      setlg(Sperm, lH);
     for (i=1; i<lH; i++)      for (i=1; i<lH; i++)
       sunit[i] = isprincipalfact(bnf,Sperm,(GEN)H[i],NULL,fl)[2];        sunit[i] = isprincipalfact(bnf,Sperm,(GEN)H[i],NULL,fl)[2];
     for (j=1; j<lB; j++,i++)      for (j=1; j<lB; j++,i++)
Line 574  bnfsunit(GEN bnf,GEN S,long prec)
Line 594  bnfsunit(GEN bnf,GEN S,long prec)
   return gerepilecopy(ltop,res);    return gerepilecopy(ltop,res);
 }  }
   
 /* cette fonction est l'equivalent de isunit, sauf qu'elle donne le resultat  static GEN
  * avec des s-unites: si x n'est pas une s-unite alors issunit=[]~;  make_unit(GEN bnf, GEN suni, GEN *px)
  * si x est une s-unite alors  
  * x=\prod_{i=0}^r {e_i^issunit[i]}*prod{i=r+1}^{r+s} {s_i^issunit[i]}  
  * ou les e_i sont les unites du corps (comme dans isunit)  
  * et les s_i sont les s-unites calculees par sunit (dans le meme ordre).  
  */  
 GEN  
 bnfissunit(GEN bnf,GEN suni,GEN x)  
 {  {
   long lB,cH,i,k,ls,tetpil, av = avma;    long lB, cH, i, k, ls;
   GEN den,gen,S,v,p1,xp,xm,xb,N,HB,perm;    GEN den,gen,S,v,p1,xp,xm,xb,N,HB,perm;
   
   bnf = checkbnf(bnf);    if (gcmp0(*px)) return NULL;
   if (typ(suni)!=t_VEC || lg(suni)!=7) err(typeer,"bnfissunit");  
   switch (typ(x))  
   {  
     case t_INT: case t_FRAC: case t_FRACN:  
     case t_POL: case t_COL:  
       x = basistoalg(bnf,x); break;  
     case t_POLMOD: break;  
     default: err(typeer,"bnfissunit");  
   }  
   if (gcmp0(x)) return cgetg(1,t_COL);  
   
   S = (GEN) suni[6]; ls=lg(S);    S = (GEN) suni[6]; ls=lg(S);
   if (ls==1) return isunit(bnf,x);    if (ls==1) return cgetg(1, t_COL);
   
     xb = algtobasis(bnf,*px); p1 = Q_denom(xb);
     N = mulii(gnorm(gmul(*px,p1)), p1); /* relevant primes divide N */
     if (is_pm1(N)) return zerocol(ls -1);
   
   p1 = (GEN)suni[2];    p1 = (GEN)suni[2];
   perm = (GEN)p1[1];    perm = (GEN)p1[1];
   HB = (GEN)p1[2]; den = (GEN)p1[3];    HB = (GEN)p1[2];
     den = (GEN)p1[3];
   cH = lg(HB[1]) - 1;    cH = lg(HB[1]) - 1;
   lB = lg(HB) - cH;    lB = lg(HB) - cH;
   xb = algtobasis(bnf,x); p1 = denom(content(xb));  
   N = mulii(gnorm(gmul(x,p1)), p1); /* relevant primes divide N */  
   v = cgetg(ls, t_VECSMALL);    v = cgetg(ls, t_VECSMALL);
   for (i=1; i<ls; i++)    for (i=1; i<ls; i++)
   {    {
Line 622  bnfissunit(GEN bnf,GEN suni,GEN x)
Line 627  bnfissunit(GEN bnf,GEN suni,GEN x)
   for (i=1; i<=cH; i++)    for (i=1; i<=cH; i++)
   {    {
     GEN w = gdiv((GEN)v[i], den);      GEN w = gdiv((GEN)v[i], den);
     if (typ(w) != t_INT) { avma = av; return cgetg(1,t_COL); }      if (typ(w) != t_INT) return NULL;
     v[i] = (long)w;      v[i] = (long)w;
   }    }
   p1 += cH;    p1 += cH;
Line 634  bnfissunit(GEN bnf,GEN suni,GEN x)
Line 639  bnfissunit(GEN bnf,GEN suni,GEN x)
   {    {
     k = -itos((GEN)v[i]); if (!k) continue;      k = -itos((GEN)v[i]); if (!k) continue;
     p1 = basistoalg(bnf, (GEN)gen[i]);      p1 = basistoalg(bnf, (GEN)gen[i]);
     if (k > 0) xp = gmul(xp, gpuigs(p1, k));      if (k > 0) xp = gmul(xp, gpowgs(p1, k));
     else       xm = gmul(xm, gpuigs(p1,-k));      else       xm = gmul(xm, gpowgs(p1,-k));
   }    }
   if (xp != gun) x = gmul(x,xp);    if (xp != gun) *px = gmul(*px,xp);
   if (xm != gun) x = gdiv(x,xm);    if (xm != gun) *px = gdiv(*px,xm);
   p1 = isunit(bnf,x);    return v;
   if (lg(p1)==1) { avma = av; return cgetg(1,t_COL); }  
   tetpil=avma; return gerepile(av,tetpil,concat(p1,v));  
 }  }
   
 static void  /* cette fonction est l'equivalent de isunit, sauf qu'elle donne le resultat
 vecconcat(GEN bnf,GEN relnf,GEN vec,GEN *prod,GEN *S1,GEN *S2)   * avec des s-unites: si x n'est pas une s-unite alors issunit=[]~;
    * si x est une s-unite alors
    * x=\prod_{i=0}^r {e_i^issunit[i]}*prod{i=r+1}^{r+s} {s_i^issunit[i]}
    * ou les e_i sont les unites du corps (comme dans isunit)
    * et les s_i sont les s-unites calculees par sunit (dans le meme ordre).
    */
   GEN
   bnfissunit(GEN bnf,GEN suni,GEN x)
 {  {
   long i;    gpmem_t av = avma;
     GEN v, w;
   
   for (i=1; i<lg(vec); i++)    bnf = checkbnf(bnf);
     if (signe(resii(*prod,(GEN)vec[i])))    if (typ(suni)!=t_VEC || lg(suni)!=7) err(typeer,"bnfissunit");
     {    switch (typ(x))
        *prod=mulii(*prod,(GEN)vec[i]);    {
        *S1=concatsp(*S1,primedec(bnf,(GEN)vec[i]));      case t_INT: case t_FRAC: case t_FRACN:
        *S2=concatsp(*S2,primedec(relnf,(GEN)vec[i]));      case t_POL: case t_COL:
     }        x = basistoalg(bnf,x); break;
       case t_POLMOD: break;
       default: err(typeer,"bnfissunit");
     }
     v = NULL;
     if ( (w = make_unit(bnf, suni, &x)) ) v = isunit(bnf, x);
     if (!v || lg(v) == 1) { avma = av; return cgetg(1,t_COL); }
     return gerepileupto(av, concat(v, w));
 }  }
   
 /* bnf est le corps de base (buchinitfu).  static void
  * ext definit l'extension relative:  pr_append(GEN nf, GEN rel, GEN p, GEN *prod, GEN *S1, GEN *S2)
  * ext[1] est une equation relative du corps,  {
  * telle qu'une de ses racines engendre le corps sur Q.    if (divise(*prod, p)) return;
  * ext[2] exprime le generateur (y) du corps de base,    *prod = mulii(*prod, p);
  * en fonction de la racine (x) de ext[1],    *S1 = concatsp(*S1, primedec(nf,p));
  * ext[3] est le buchinitfu (sur Q) de l'extension.    *S2 = concatsp(*S2, primedec(rel,p));
   }
   
  * si flag=0 c'est qu'on sait a l'avance que l'extension est galoisienne,  static void
  * et dans ce cas la reponse est exacte.  fa_pr_append(GEN nf,GEN rel,GEN N,GEN *prod,GEN *S1,GEN *S2)
  * si flag>0 alors on ajoue dans S tous les ideaux qui divisent p<=flag.  {
  * si flag<0 alors on ajoute dans S tous les ideaux qui divisent -flag.    if (!is_pm1(N))
     {
       GEN v = (GEN)factor(N)[1];
       long i, l = lg(v);
       for (i=1; i<l; i++) pr_append(nf,rel,(GEN)v[i],prod,S1,S2);
     }
   }
   
  * la reponse est un vecteur v a 2 composantes telles que  static GEN
  * x=N(v[1])*v[2].  pol_up(GEN rnfeq, GEN x)
  * x est une norme ssi v[2]=1.  {
  */    long i, l = lgef(x);
     GEN y = cgetg(l, t_POL); y[1] = x[1];
     for (i=1; i<l; i++) y[i] = (long)rnfelementreltoabs(rnfeq, (GEN)x[i]);
     return y;
   }
   
 GEN  GEN
 rnfisnorm(GEN bnf,GEN ext,GEN x,long flag,long PREC)  rnfisnorminit(GEN T, GEN relpol, int galois)
 {  {
   long lgsunitrelnf,i;    gpmem_t av = avma;
   ulong ltop = avma;    long i, l, drel;
   GEN relnf,aux,vec,tors,xnf,H,Y,M,A,suni,sunitrelnf,sunitnormnf,prod;    GEN prod, S1, S2, gen, cyc, bnf, nf, nfrel, rnfeq, rel, res, k, polabs;
   GEN res = cgetg(3,t_VEC), S1,S2;    GEN y = cgetg(9, t_VEC);
   
   if (typ(ext)!=t_VEC || lg(ext)!=4) err (typeer,"bnfisnorm");    T = get_bnfpol(T, &bnf, &nf);
   if (typ(x)!=t_POL) x = basistoalg(bnf,x);    if (!bnf) bnf = bnfinit0(nf? nf: T, 1, NULL, DEFAULTPREC);
   bnf = checkbnf(bnf); relnf = (GEN)ext[3];    if (!nf) nf = checknf(bnf);
   if (gcmp0(x) || gcmp1(x) || (gcmp_1(x) && (degpol(ext[1])&1)))  
   {  
     avma = (long)res; res[1]=lcopy(x); res[2]=un; return res;  
   }  
   
 /* construction de l'ensemble S des ideaux    relpol = get_bnfpol(relpol, &rel, &nfrel);
    qui interviennent dans les solutions */    drel = degpol(relpol);
   
   prod=gun; S1=S2=cgetg(1,t_VEC);    rnfeq = NULL; /* no reltoabs needed */
   if (!gcmp1(gmael3(relnf,8,1,1)))    if (degpol(nf[1]) == 1)
     { /* over Q */
       polabs = lift(relpol);
       k = gzero;
     }
     else
   {    {
     GEN genclass=gmael3(relnf,8,1,3);      if (galois == 2 && drel > 2)
     vec=cgetg(1,t_VEC);      { /* needs reltoabs */
     for(i=1;i<lg(genclass);i++)        rnfeq = rnfequation2(bnf, relpol);
       if (!gcmp1(ggcd(gmael4(relnf,8,1,2,i), stoi(degpol(ext[1])))))        polabs = (GEN)rnfeq[1];
         vec=concatsp(vec,(GEN)factor(gmael3(genclass,i,1,1))[1]);        k =      (GEN)rnfeq[3];
     vecconcat(bnf,relnf,vec,&prod,&S1,&S2);      }
       else
       {
         long sk;
         polabs = _rnfequation(bnf, relpol, &sk, NULL);
         k = stoi(sk);
       }
   }    }
     if (!rel || !gcmp0(k)) rel = bnfinit0(polabs, 1, NULL, nfgetprec(nf));
     if (!nfrel) nfrel = checknf(rel);
   
   if (flag>1)    if (galois < 0 || galois > 2) err(flagerr, "rnfisnorminit");
     if (galois == 2)
   {    {
     for (i=2; i<=flag; i++)      GEN P = rnfeq? pol_up(rnfeq, relpol): relpol;
       if (isprime(stoi(i)) && signe(resis(prod,i)))      galois = nfisgalois(gsubst(nfrel, varn(P), polx[varn(T)]), P);
       {  
         prod=mulis(prod,i);  
         S1=concatsp(S1,primedec(bnf,stoi(i)));  
         S2=concatsp(S2,primedec(relnf,stoi(i)));  
       }  
   }    }
   else if (flag<0)  
     vecconcat(bnf,relnf,(GEN)factor(stoi(-flag))[1],&prod,&S1,&S2);  
   
   if (flag)    prod = gun; S1 = S2 = cgetg(1, t_VEC);
     res = gmael(rel,8,1);
     cyc = (GEN)res[2];
     gen = (GEN)res[3]; l = lg(cyc);
     for(i=1; i<l; i++)
   {    {
     GEN normdiscrel=divii(gmael(relnf,7,3),      if (cgcd(smodis((GEN)cyc[i], drel), drel) == 1) break;
                           gpuigs(gmael(bnf,7,3),lg(ext[1])-3));      fa_pr_append(nf,rel,gmael3(gen,i,1,1),&prod,&S1,&S2);
     vecconcat(bnf,relnf,(GEN) factor(absi(normdiscrel))[1],  
               &prod,&S1,&S2);  
   }    }
   vec=(GEN) idealfactor(bnf,x)[1]; aux=cgetg(2,t_VEC);    if (!galois)
   for (i=1; i<lg(vec); i++)    {
     if (signe(resii(prod,gmael(vec,i,1))))      GEN Ndiscrel = diviiexact((GEN)nfrel[3], gpowgs((GEN)nf[3], drel));
     {      fa_pr_append(nf,rel,absi(Ndiscrel), &prod,&S1,&S2);
       aux[1]=vec[i]; S1=concatsp(S1,aux);    }
     }  
   xnf=lift(x);  
   xnf=gsubst(xnf,varn(xnf),(GEN)ext[2]);  
   vec=(GEN) idealfactor(relnf,xnf)[1];  
   for (i=1; i<lg(vec); i++)  
     if (signe(resii(prod,gmael(vec,i,1))))  
     {  
       aux[1]=vec[i]; S2=concatsp(S2,aux);  
     }  
   
   res[1]=un; res[2]=(long)x;    y[1] = (long)bnf;
   tors=cgetg(2,t_VEC); tors[1]=mael3(relnf,8,4,2);    y[2] = (long)rel;
     y[3] = (long)relpol;
     y[4] = (long)get_theta_abstorel(T, relpol, k);
     y[5] = (long)prod;
     y[6] = (long)S1;
     y[7] = (long)S2;
     y[8] = lstoi(galois); return gerepilecopy(av, y);
   }
   
   /* calcul sur les S-unites */  /* T as output by rnfisnorminit
    * if flag=0 assume extension is Galois (==> answer is unconditional)
    * if flag>0 add to S all primes dividing p <= flag
    * if flag<0 add to S all primes dividing abs(flag)
   
   suni=bnfsunit(bnf,S1,PREC);   * answer is a vector v = [a,b] such that
   A=lift(bnfissunit(bnf,suni,x));   * x = N(a)*b and x is a norm iff b = 1  [assuming S large enough] */
   sunitrelnf=(GEN) bnfsunit(relnf,S2,PREC)[1];  GEN
   if (lg(sunitrelnf)>1)  rnfisnorm(GEN T, GEN x, long flag)
   {
     gpmem_t av = avma;
     GEN bnf = (GEN)T[1], rel = (GEN)T[2], relpol = (GEN)T[3], theta = (GEN)T[4];
     GEN nf, aux, H, Y, M, A, suni, sunitrel, futu, tu, w;
     GEN prod, S1, S2;
     GEN res = cgetg(3,t_VEC);
     long L, i, drel, itu;
   
     if (typ(T) != t_VEC || lg(T) != 9)
       err(talker,"please apply rnfisnorminit first");
     bnf = checkbnf(bnf);
     rel = checkbnf(rel);
     nf = checknf(bnf);
     x = basistoalg(nf,x);
     if (typ(x) != t_POLMOD) err(typeer, "rnfisnorm");
     drel = degpol(relpol);
     if (gcmp0(x) || gcmp1(x) || (gcmp_1(x) && odd(drel)))
   {    {
     sunitrelnf=lift(basistoalg(relnf,sunitrelnf));      res[1] = (long)x;
     sunitrelnf=concatsp(tors,sunitrelnf);      res[2] = un; return res;
   }    }
   else sunitrelnf=tors;  
   aux=(GEN)relnf[8];    /* build set T of ideals involved in the solutions */
   if (lg(aux)>=6) aux=(GEN)aux[5];    prod = (GEN)T[5];
   else    S1   = (GEN)T[6];
     S2   = (GEN)T[7];
     if (flag && !gcmp0((GEN)T[8]))
       err(warner,"useless flag in rnfisnorm: the extension is Galois");
     if (flag > 0)
   {    {
     aux=buchfu(relnf);      byteptr d = diffptr;
     if(gcmp0((GEN)aux[2]))      long p = 0;
       err(precer,"bnfisnorm, please increase precision and try again");      if (maxprime() < flag) err(primer1);
     aux=(GEN)aux[1];      for(;;)
       {
         NEXT_PRIME_VIADIFF(p, d);
         if (p > flag) break;
         pr_append(nf,rel,stoi(p),&prod,&S1,&S2);
       }
   }    }
   if (lg(aux)>1)    else if (flag < 0)
     sunitrelnf=concatsp(aux,sunitrelnf);      fa_pr_append(nf,rel,stoi(-flag),&prod,&S1,&S2);
   lgsunitrelnf=lg(sunitrelnf);    /* overkill: prime ideals dividing x would be enough */
   M=cgetg(lgsunitrelnf+1,t_MAT);    fa_pr_append(nf,rel,idealnorm(nf,x), &prod,&S1,&S2);
   sunitnormnf=cgetg(lgsunitrelnf,t_VEC);  
   for (i=1; i<lgsunitrelnf; i++)    /* computation on T-units */
     w  = gmael3(rel,8,4,1);
     tu = gmael3(rel,8,4,2);
     futu = concatsp(check_units(rel,"rnfisnorm"), tu);
     suni = bnfsunit(bnf,S1,3);
     sunitrel = (GEN)bnfsunit(rel,S2,3)[1];
     if (lg(sunitrel) > 1) sunitrel = lift_intern(basistoalg(rel,sunitrel));
     sunitrel = concatsp(futu, sunitrel);
   
     A = lift(bnfissunit(bnf,suni,x));
     L = lg(sunitrel);
     itu = lg(nf[6])-1; /* index of torsion unit in bnfsunit(nf) output */
     M = cgetg(L+1,t_MAT);
     for (i=1; i<L; i++)
   {    {
     sunitnormnf[i]=lnorm(gmodulcp((GEN) sunitrelnf[i],(GEN)ext[1]));      GEN u = poleval((GEN)sunitrel[i], theta); /* abstorel */
     M[i]=llift(bnfissunit(bnf,suni,(GEN) sunitnormnf[i]));      if (typ(u) != t_POLMOD) u = to_polmod(u, (GEN)theta[1]);
       sunitrel[i] = (long)u;
       u = bnfissunit(bnf,suni, gnorm(u));
       if (lg(u) == 1) err(bugparier,"rnfisnorm");
       u[itu] = llift((GEN)u[itu]); /* lift root of 1 part */
       M[i] = (long)u;
   }    }
   M[lgsunitrelnf]=lgetg(lg(A),t_COL);    aux = zerocol(lg(A)-1); aux[itu] = (long)w;
   for (i=1; i<lg(A); i++) mael(M,lgsunitrelnf,i)=zero;    M[L] = (long)aux;
   mael(M,lgsunitrelnf,lg(mael(bnf,7,6))-1)=mael3(bnf,8,4,1);    H = hnfall0(M, 0);
   H=hnfall(M); Y=inverseimage(gmul(M,(GEN) H[2]),A);    Y = gmul((GEN)H[2], inverseimage((GEN)H[1],A));
   Y=gmul((GEN) H[2],Y);    /* Y: sols of MY = A over Q */
   for (aux=(GEN)res[1],i=1; i<lgsunitrelnf; i++)    setlg(Y, L);
     aux=gmul(aux,gpuigs(gmodulcp((GEN) sunitrelnf[i],(GEN)ext[1]),    aux = factorback(sunitrel, gfloor(Y));
                         itos(gfloor((GEN)Y[i]))));    x = gdiv(x, gnorm(gmodulcp(lift_intern(aux), relpol)));
   x = gdiv(x,gnorm(gmodulcp(lift(aux),(GEN)ext[1])));    if (typ(x) == t_POLMOD && (typ(x[2]) != t_POL || !degpol(x[2])))
   if (typ(x) == t_POLMOD && (typ(x[2]) != t_POL || lgef(x[2]) == 3))  
   {    {
     x = (GEN)x[2]; /* rational number */      x = (GEN)x[2]; /* rational number */
     if (typ(x) == t_POL) x = (GEN)x[2];      if (typ(x) == t_POL) x = (GEN)x[2];
   }    }
   res[1]=(long)aux;    if (typ(aux) == t_POLMOD && degpol(nf[1]) == 1)
   res[2]=(long)x;      aux[2] = (long)lift_intern((GEN)aux[2]);
   return gerepilecopy(ltop,res);    res[1] = (long)aux;
     res[2] = (long)x;
     return gerepilecopy(av, res);
 }  }
   
 GEN  GEN
 bnfisnorm(GEN bnf,GEN x,long flag,long PREC)  bnfisnorm(GEN bnf,GEN x,long flag,long PREC)
 {  {
   long ltop = avma, lbot;    gpmem_t av = avma;
   GEN ext = cgetg(4,t_VEC);    GEN T = rnfisnorminit(polx[MAXVARN], bnf, flag == 0? 1: 2);
     return gerepileupto(av, rnfisnorm(T, x, flag));
   bnf = checkbnf(bnf);  
   ext[1] = mael(bnf,7,1);  
   ext[2] = zero;  
   ext[3] = (long) bnf;  
   bnf = buchinitfu(polx[MAXVARN],NULL,NULL,0); lbot = avma;  
   return gerepile(ltop,lbot,rnfisnorm(bnf,ext,x,flag,PREC));  
 }  }

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

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