=================================================================== RCS file: /home/cvs/OpenXM_contrib/pari-2.2/src/basemath/Attic/buch4.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -p -r1.1.1.1 -r1.2 --- OpenXM_contrib/pari-2.2/src/basemath/Attic/buch4.c 2001/10/02 11:17:03 1.1.1.1 +++ OpenXM_contrib/pari-2.2/src/basemath/Attic/buch4.c 2002/09/11 07:26:50 1.2 @@ -1,4 +1,4 @@ -/* $Id: buch4.c,v 1.1.1.1 2001/10/02 11:17:03 noro Exp $ +/* $Id: buch4.c,v 1.2 2002/09/11 07:26:50 noro Exp $ Copyright (C) 2000 The PARI group. @@ -22,6 +22,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, #include "pari.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 psquare(GEN a,GEN p) { @@ -44,7 +49,8 @@ psquare(GEN a,GEN p) static long 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; for (i=lgef(pol)-2,gx=(GEN) pol[i+1]; i>1; i--) @@ -65,7 +71,9 @@ lemma6(GEN pol,GEN p,long nu,GEN x) static long 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; for (i=lgef(pol)-2,gx=(GEN) pol[i+1]; i>1; i--) @@ -96,7 +104,8 @@ lemma7(GEN pol,long nu,GEN x) static long 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; result = (cmpis(p,2)) ? lemma6(pol,p,nu,x0) : lemma7(pol,nu,x0); @@ -137,7 +146,7 @@ qpsoluble(GEN pol,GEN p) static long psquarenf(GEN nf,GEN a,GEN pr) { - ulong av = avma; + gpmem_t av = avma; long v; GEN norm; @@ -169,7 +178,8 @@ check2(GEN nf, GEN a, GEN zinit) static long psquare2nf(GEN nf,GEN a,GEN pr,GEN zinit) { - long v, ltop = avma; + long v; + gpmem_t ltop = avma; if (gcmp0(a)) return 1; v = idealval(nf,a,pr); if (v&1) return 0; @@ -182,7 +192,8 @@ psquare2nf(GEN nf,GEN a,GEN pr,GEN zinit) static long 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)); v = check2(nf,a,zinit); avma = ltop; return v; @@ -191,7 +202,8 @@ psquare2qnf(GEN nf,GEN a,GEN p,long q) static long 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; for (i=lgef(pol)-2,gx=(GEN) pol[i+1]; i>1; i--) @@ -212,7 +224,8 @@ lemma6nf(GEN nf,GEN pol,GEN p,long nu,GEN x) static long 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; for (i=lgef(pol)-2, gx=(GEN) pol[i+1]; i>1; i--) @@ -237,7 +250,7 @@ lemma7nf(GEN nf,GEN pol,GEN p,long nu,GEN x,GEN zinit) q=(nu<<1)-lambda; res=0; } 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; avma=ltop; return res; } @@ -245,7 +258,8 @@ lemma7nf(GEN nf,GEN pol,GEN p,long nu,GEN x,GEN zinit) static long 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; nf=checknf(nf); @@ -297,7 +311,7 @@ long qpsolublenf(GEN nf,GEN pol,GEN pr) { GEN repr,zinit,p1; - long ltop=avma; + gpmem_t ltop=avma; if (gcmp0(pol)) return 1; if (typ(pol)!=t_POL) err(notpoler,"qpsolublenf"); @@ -333,7 +347,7 @@ long zpsolublenf(GEN nf,GEN pol,GEN p) { GEN repr,zinit; - long ltop=avma; + gpmem_t ltop=avma; if (gcmp0(pol)) return 1; if (typ(pol)!=t_POL) err(notpoler,"zpsolublenf"); @@ -359,9 +373,13 @@ zpsolublenf(GEN nf,GEN pol,GEN p) static long hilb2nf(GEN nf,GEN a,GEN b,GEN p) { - ulong av = avma; + gpmem_t av = avma; 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)]. * But it is only used as a placeholder, hence it is not a problem */ @@ -373,9 +391,9 @@ hilb2nf(GEN nf,GEN a,GEN b,GEN p) long 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; - ulong av = avma; + gpmem_t av = avma; if (gcmp0(a) || gcmp0(b)) err (talker,"0 argument in nfhilbertp"); checkprimeid(pr); nf = checknf(nf); @@ -394,9 +412,14 @@ nfhilbertp(GEN nf,GEN a,GEN b,GEN pr) /* quad. symbol is image of t by the quadratic character */ ord = subis( idealnorm(nf,pr), 1 ); /* |(O_K / pr)^*| */ ordp= subis( p, 1); /* |F_p^*| */ - prhall = nfmodprinit(nf, pr); - t = element_powmodpr(nf, t, divii(ord, ordp), prhall); /* in F_p^* */ - t = lift_intern((GEN)t[1]); + modpr = nf_to_ff_init(nf, &pr,&T,&p); + t = nf_to_ff(nf,t,modpr); + 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); avma = av; return rep; } @@ -409,7 +432,7 @@ nfhilbertp(GEN nf,GEN a,GEN b,GEN pr) long nfhilbert(GEN nf,GEN a,GEN b) { - ulong av = avma; + gpmem_t av = avma; long r1, i; GEN S, al, bl, ro; @@ -457,7 +480,8 @@ nfhilbert0(GEN nf,GEN a,GEN b,GEN p) extern GEN isprincipalfact(GEN bnf,GEN P, GEN e, GEN C, long flag); extern GEN vconcat(GEN Q1, GEN Q2); 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: * res[1] = generators of (S-units / units), as polynomials * res[2] = [perm, HB, den], for bnfissunit @@ -469,10 +493,10 @@ extern GEN factorback_i(GEN fa, GEN nf, int red); GEN bnfsunit(GEN bnf,GEN S,long prec) { - ulong ltop = avma; + gpmem_t ltop = avma; long i,j,ls; 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"); bnf = checkbnf(bnf); nf=(GEN)bnf[7]; @@ -504,23 +528,19 @@ bnfsunit(GEN bnf,GEN S,long prec) card = gun; if (lg(H) > 1) { /* 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]; - card = dethnf_i(p1); + D = smithall(H, &U, NULL); + for(i=1; i 0) xp = gmul(xp, gpuigs(p1, k)); - else xm = gmul(xm, gpuigs(p1,-k)); + if (k > 0) xp = gmul(xp, gpowgs(p1, k)); + else xm = gmul(xm, gpowgs(p1,-k)); } - if (xp != gun) x = gmul(x,xp); - if (xm != gun) x = gdiv(x,xm); - p1 = isunit(bnf,x); - if (lg(p1)==1) { avma = av; return cgetg(1,t_COL); } - tetpil=avma; return gerepile(av,tetpil,concat(p1,v)); + if (xp != gun) *px = gmul(*px,xp); + if (xm != gun) *px = gdiv(*px,xm); + return v; } -static void -vecconcat(GEN bnf,GEN relnf,GEN vec,GEN *prod,GEN *S1,GEN *S2) +/* cette fonction est l'equivalent de isunit, sauf qu'elle donne le resultat + * 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; i0 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. +static void +fa_pr_append(GEN nf,GEN rel,GEN N,GEN *prod,GEN *S1,GEN *S2) +{ + if (!is_pm1(N)) + { + GEN v = (GEN)factor(N)[1]; + long i, l = lg(v); + for (i=1; i 2) + { /* needs reltoabs */ + rnfeq = rnfequation2(bnf, relpol); + polabs = (GEN)rnfeq[1]; + k = (GEN)rnfeq[3]; + } + 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++) - if (isprime(stoi(i)) && signe(resis(prod,i))) - { - prod=mulis(prod,i); - S1=concatsp(S1,primedec(bnf,stoi(i))); - S2=concatsp(S2,primedec(relnf,stoi(i))); - } + GEN P = rnfeq? pol_up(rnfeq, relpol): relpol; + galois = nfisgalois(gsubst(nfrel, varn(P), polx[varn(T)]), P); } - 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 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); - A=lift(bnfissunit(bnf,suni,x)); - sunitrelnf=(GEN) bnfsunit(relnf,S2,PREC)[1]; - if (lg(sunitrelnf)>1) + * answer is a vector v = [a,b] such that + * x = N(a)*b and x is a norm iff b = 1 [assuming S large enough] */ +GEN +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)); - sunitrelnf=concatsp(tors,sunitrelnf); + res[1] = (long)x; + res[2] = un; return res; } - else sunitrelnf=tors; - aux=(GEN)relnf[8]; - if (lg(aux)>=6) aux=(GEN)aux[5]; - else + + /* build set T of ideals involved in the solutions */ + prod = (GEN)T[5]; + 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); - if(gcmp0((GEN)aux[2])) - err(precer,"bnfisnorm, please increase precision and try again"); - aux=(GEN)aux[1]; + byteptr d = diffptr; + long p = 0; + if (maxprime() < flag) err(primer1); + for(;;) + { + NEXT_PRIME_VIADIFF(p, d); + if (p > flag) break; + pr_append(nf,rel,stoi(p),&prod,&S1,&S2); + } } - if (lg(aux)>1) - sunitrelnf=concatsp(aux,sunitrelnf); - lgsunitrelnf=lg(sunitrelnf); - M=cgetg(lgsunitrelnf+1,t_MAT); - sunitnormnf=cgetg(lgsunitrelnf,t_VEC); - for (i=1; i 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