Annotation of OpenXM_contrib/pari-2.2/src/basemath/base1.c, Revision 1.1.1.1
1.1 noro 1: /* $Id: base1.c,v 1.41 2001/10/01 12:11:28 karim Exp $
2:
3: Copyright (C) 2000 The PARI group.
4:
5: This file is part of the PARI/GP package.
6:
7: PARI/GP is free software; you can redistribute it and/or modify it under the
8: terms of the GNU General Public License as published by the Free Software
9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
10: ANY WARRANTY WHATSOEVER.
11:
12: Check the License for details. You should have received a copy of it, along
13: with the package; see the file 'COPYING'. If not, write to the Free Software
14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15:
16: /**************************************************************/
17: /* */
18: /* NUMBER FIELDS */
19: /* */
20: /**************************************************************/
21: #include "pari.h"
22: #include "parinf.h"
23: GEN idealhermite_aux(GEN nf, GEN x);
24:
25: void
26: checkrnf(GEN rnf)
27: {
28: if (typ(rnf)!=t_VEC) err(idealer1);
29: if (lg(rnf)!=12) err(idealer1);
30: }
31:
32: GEN
33: checkbnf(GEN bnf)
34: {
35: if (typ(bnf)!=t_VEC) err(idealer1);
36: switch (lg(bnf))
37: {
38: case 11: return bnf;
39: case 10:
40: if (typ(bnf[1])==t_POL)
41: err(talker,"please apply bnfinit first");
42: break;
43: case 7:
44: return checkbnf((GEN)bnf[1]);
45:
46: case 3:
47: if (typ(bnf[2])==t_POLMOD)
48: return checkbnf((GEN)bnf[1]);
49: }
50: err(idealer1);
51: return NULL; /* not reached */
52: }
53:
54: GEN
55: checkbnf_discard(GEN bnf)
56: {
57: GEN x = checkbnf(bnf);
58: if (x != bnf && lg(bnf) == 3)
59: err(warner,"non-monic polynomial. Change of variables discarded");
60: return x;
61: }
62:
63: GEN
64: checknf(GEN nf)
65: {
66: if (typ(nf)==t_POL) err(talker,"please apply nfinit first");
67: if (typ(nf)!=t_VEC) err(idealer1);
68: switch(lg(nf))
69: {
70: case 10: return nf;
71: case 11: return checknf((GEN)nf[7]);
72: case 7: return checknf((GEN)nf[1]);
73: case 3: if (typ(nf[2]) == t_POLMOD) return checknf((GEN)nf[1]);
74: }
75: err(idealer1);
76: return NULL; /* not reached */
77: }
78:
79: void
80: checkbnr(GEN bnr)
81: {
82: if (typ(bnr)!=t_VEC || lg(bnr)!=7)
83: err(talker,"incorrect bigray field");
84: (void)checkbnf((GEN)bnr[1]);
85: }
86:
87: void
88: checkbnrgen(GEN bnr)
89: {
90: checkbnr(bnr);
91: if (lg(bnr[5])<=3)
92: err(talker,"please apply bnrinit(,,1) and not bnrinit(,)");
93: }
94:
95: GEN
96: check_units(GEN bnf, char *f)
97: {
98: GEN nf, x;
99: bnf = checkbnf(bnf); nf = checknf(bnf);
100: x = (GEN)bnf[8];
101: if (lg(x) < 7 || (lg(x[5]) == 1 && lg(nf[6]) > 2))
102: err(talker,"missing units in %s", f);
103: return (GEN)x[5];
104: }
105:
106: void
107: checkid(GEN x, long N)
108: {
109: if (typ(x)!=t_MAT) err(idealer2);
110: if (lg(x) == 1 || lg(x[1]) != N+1)
111: err(talker,"incorrect matrix for ideal");
112: }
113:
114: void
115: checkbid(GEN bid)
116: {
117: if (typ(bid)!=t_VEC || lg(bid)!=6 || lg(bid[1])!=3)
118: err(talker,"incorrect bigideal");
119: }
120:
121: void
122: checkprimeid(GEN id)
123: {
124: if (typ(id) != t_VEC || lg(id) != 6)
125: err(talker,"incorrect prime ideal");
126: }
127:
128: void
129: checkprhall(GEN prhall)
130: {
131: if (typ(prhall) != t_VEC || lg(prhall) != 3 || typ(prhall[1]) != t_MAT)
132: err(talker,"incorrect prhall format");
133: }
134:
135: void
136: check_pol_int(GEN x, char *s)
137: {
138: long k = lgef(x)-1;
139: for ( ; k>1; k--)
140: if (typ(x[k])!=t_INT) err(talker,"polynomial not in Z[X] in %s",s);
141: }
142:
143: GEN
144: checknfelt_mod(GEN nf, GEN x, char *s)
145: {
146: if (!gegal((GEN)x[1],(GEN)nf[1]))
147: err(talker,"incompatible modulus in %s:\n mod = %Z,\n nf = %Z",
148: s, x[1], nf[1]);
149: return (GEN)x[2];
150: }
151:
152: GEN
153: get_primeid(GEN x)
154: {
155: if (typ(x) != t_VEC) return NULL;
156: if (lg(x) == 3) x = (GEN)x[1];
157: if (lg(x) != 6 || typ(x[3]) != t_INT) return NULL;
158: return x;
159: }
160:
161: GEN
162: get_bnf(GEN x, int *t)
163: {
164: switch(typ(x))
165: {
166: case t_POL: *t = typ_POL; return NULL;
167: case t_QUAD: *t = typ_Q ; return NULL;
168: case t_VEC:
169: switch(lg(x))
170: {
171: case 3:
172: if (typ(x[2]) != t_POLMOD) break;
173: return get_bnf((GEN)x[1],t);
174: case 6 : *t = typ_QUA; return NULL;
175: case 10: *t = typ_NF; return NULL;
176: case 11: *t = typ_BNF; return x;
177: case 7 : *t = typ_BNR;
178: x = (GEN)x[1]; if (typ(x)!=t_VEC || lg(x)!=11) break;
179: return x;
180: }
181: case t_MAT:
182: if (lg(x)==2)
183: switch(lg(x[1]))
184: {
185: case 8: case 11:
186: *t = typ_CLA; return NULL;
187: }
188: }
189: *t = typ_NULL; return NULL;
190: }
191:
192: GEN
193: get_nf(GEN x, int *t)
194: {
195: switch(typ(x))
196: {
197: case t_POL : *t = typ_POL; return NULL;
198: case t_QUAD: *t = typ_Q ; return NULL;
199: case t_VEC:
200: switch(lg(x))
201: {
202: case 3:
203: if (typ(x[2]) != t_POLMOD) break;
204: return get_nf((GEN)x[1],t);
205: case 10: *t = typ_NF; return x;
206: case 11: *t = typ_BNF;
207: x = (GEN)x[7]; if (typ(x)!=t_VEC || lg(x)!=10) break;
208: return x;
209: case 7 : *t = typ_BNR;
210: x = (GEN)x[1]; if (typ(x)!=t_VEC || lg(x)!=11) break;
211: x = (GEN)x[7]; if (typ(x)!=t_VEC || lg(x)!=10) break;
212: return x;
213: case 9 :
214: x = (GEN)x[2];
215: if (typ(x) == t_VEC && lg(x) == 4) *t = typ_GAL;
216: return NULL;
217: case 14: case 20:
218: *t = typ_ELL; return NULL;
219: }break;
220: case t_MAT:
221: if (lg(x)==2)
222: switch(lg(x[1]))
223: {
224: case 8: case 11:
225: *t = typ_CLA; return NULL;
226: }
227: }
228: *t = typ_NULL; return NULL;
229: }
230:
231: /*************************************************************************/
232: /** **/
233: /** GALOIS GROUP **/
234: /** **/
235: /*************************************************************************/
236:
237: /* exchange elements i and j in vector x */
238: static GEN
239: transroot(GEN x, int i, int j)
240: {
241: long k;
242: x = dummycopy(x);
243: k=x[i]; x[i]=x[j]; x[j]=k; return x;
244: }
245:
246: #define randshift (BITS_IN_RANDOM - 3)
247:
248: GEN
249: tschirnhaus(GEN x)
250: {
251: long a, v = varn(x), av = avma;
252: GEN u, p1 = cgetg(5,t_POL);
253:
254: if (typ(x)!=t_POL) err(notpoler,"tschirnhaus");
255: if (lgef(x) < 4) err(constpoler,"tschirnhaus");
256: if (v) { u=dummycopy(x); setvarn(u,0); x=u; }
257: p1[1] = evalsigne(1)|evalvarn(0)|evallgef(5);
258: do
259: {
260: a = mymyrand() >> randshift; if (a==0) a =1; p1[4]=lstoi(a);
261: a = mymyrand() >> (randshift-1); if (a>=4) a-=8; p1[3]=lstoi(a);
262: a = mymyrand() >> (randshift-1); if (a>=4) a-=8; p1[2]=lstoi(a);
263: u = caract2(x,p1,v); a=avma;
264: }
265: while (lgef(srgcd(u,derivpol(u))) > 3); /* while u not separable */
266: if (DEBUGLEVEL>1)
267: fprintferr("Tschirnhaus transform. New pol: %Z",u);
268: avma=a; return gerepileupto(av,u);
269: }
270: #undef randshift
271:
272: int
273: gpolcomp(GEN p1, GEN p2)
274: {
275: int s,j = lgef(p1)-2;
276:
277: if (lgef(p2)-2 != j)
278: err(bugparier,"gpolcomp (different degrees)");
279: for (; j>=2; j--)
280: {
281: s = absi_cmp((GEN)p1[j], (GEN)p2[j]);
282: if (s) return s;
283: }
284: return 0;
285: }
286:
287: /* assume pol in Z[X] */
288: GEN
289: primitive_pol_to_monic(GEN pol, GEN *ptlead)
290: {
291: long i,j,n = degpol(pol);
292: GEN lead,fa,e,a, POL = dummycopy(pol);
293:
294: a = POL + 2; lead = (GEN)a[n];
295: if (signe(lead) < 0) { POL = gneg_i(POL); a = POL+2; lead = negi(lead); }
296: if (is_pm1(lead)) { if (ptlead) *ptlead = NULL; return POL; }
297: fa = auxdecomp(lead,0); lead = gun;
298: e = (GEN)fa[2]; fa = (GEN)fa[1];
299: for (i=lg(e)-1; i>0;i--) e[i] = itos((GEN)e[i]);
300: for (i=lg(fa)-1; i>0; i--)
301: {
302: GEN p = (GEN)fa[i], p1,pk,pku;
303: long k = (long)ceil((double)e[i] / n);
304: long d = k * n - e[i], v, j0;
305: /* find d, k such that p^d pol(x / p^k) monic */
306: for (j=n-1; j>0; j--)
307: {
308: if (!signe(a[j])) continue;
309: v = pvaluation((GEN)a[j], p, &p1);
310: while (v + d < k * j) { k++; d += n; }
311: }
312: pk = gpowgs(p,k); j0 = d/k;
313: pku = gpowgs(p,d - k*j0);
314: /* a[j] *= p^(d - kj) */
315: for (j=j0; j>=0; j--)
316: {
317: if (j < j0) pku = mulii(pku, pk);
318: a[j] = lmulii((GEN)a[j], pku);
319: }
320: j0++;
321: pku = gpowgs(p,k*j0 - d);
322: /* a[j] /= p^(kj - d) */
323: for (j=j0; j<=n; j++)
324: {
325: if (j > j0) pku = mulii(pku, pk);
326: a[j] = ldivii((GEN)a[j], pku);
327: }
328: lead = mulii(lead, pk);
329: }
330: if (ptlead) *ptlead = lead; return POL;
331: }
332:
333: /* compute x1*x2^2 + x2*x3^2 + x3*x4^2 + x4*x1^2 */
334: static GEN
335: get_F4(GEN x)
336: {
337: GEN p1=gzero;
338: long i;
339:
340: for (i=1; i<=4; i++)
341: p1 = gadd(p1, gmul((GEN)x[i], gsqr((GEN)x[(i&3)+1])));
342: return p1;
343: }
344:
345: GEN galoisbig(GEN x, long prec);
346: GEN roots_to_pol(GEN a, long v);
347:
348: GEN
349: galois(GEN x, long prec)
350: {
351: long av=avma,av1,i,j,k,n,f,l,l2,e,e1,pr,ind;
352: GEN x1,p1,p2,p3,p4,p5,p6,w,y,z,ee;
353: static int ind5[20]={2,5,3,4, 1,3,4,5, 1,5,2,4, 1,2,3,5, 1,4,2,3};
354: static int ind6[60]={3,5,4,6, 2,6,4,5, 2,3,5,6, 2,4,3,6, 2,5,3,4,
355: 1,4,5,6, 1,5,3,6, 1,6,3,4, 1,3,4,5, 1,6,2,5,
356: 1,2,4,6, 1,5,2,4, 1,3,2,6, 1,2,3,5, 1,4,2,3};
357: if (typ(x)!=t_POL) err(notpoler,"galois");
358: n=degpol(x); if (n<=0) err(constpoler,"galois");
359: if (n>11) err(impl,"galois of degree higher than 11");
360: x = gdiv(x,content(x));
361: check_pol_int(x, "galois");
362: if (gisirreducible(x) != gun)
363: err(impl,"galois of reducible polynomial");
364:
365: if (n<4)
366: {
367: if (n<3)
368: {
369: avma=av; y=cgetg(4,t_VEC);
370: y[1] = (n==1)? un: deux;
371: y[2]=lnegi(gun);
372: }
373: else /* n=3 */
374: {
375: f=carreparfait(discsr(x));
376: avma=av; y=cgetg(4,t_VEC);
377: if (f) { y[1]=lstoi(3); y[2]=un; }
378: else { y[1]=lstoi(6); y[2]=lnegi(gun); }
379: }
380: y[3]=un; return y;
381: }
382: x1 = x = primitive_pol_to_monic(x,NULL); av1=avma;
383: if (n>7) return galoisbig(x,prec);
384: for(;;)
385: {
386: switch(n)
387: {
388: case 4: z = cgetg(7,t_VEC);
389: for(;;)
390: {
391: p1=roots(x,prec);
392: z[1] = (long)get_F4(p1);
393: z[2] = (long)get_F4(transroot(p1,1,2));
394: z[3] = (long)get_F4(transroot(p1,1,3));
395: z[4] = (long)get_F4(transroot(p1,1,4));
396: z[5] = (long)get_F4(transroot(p1,2,3));
397: z[6] = (long)get_F4(transroot(p1,3,4));
398: p4 = roots_to_pol(z,0);
399: p5=grndtoi(greal(p4),&e);
400: e1=gexpo(gimag(p4)); if (e1>e) e=e1;
401: if (e <= -10) break;
402: prec = (prec<<1)-2;
403: }
404: p6 = modulargcd(p5, derivpol(p5));
405: if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
406: p2 = (GEN)factor(p5)[1];
407: switch(lg(p2)-1)
408: {
409: case 1: f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC);
410: y[3]=un;
411: if (f) { y[2]=un; y[1]=lstoi(12); return y; }
412: y[2]=lnegi(gun); y[1]=lstoi(24); return y;
413:
414: case 2: avma=av; y=cgetg(4,t_VEC);
415: y[3]=un; y[2]=lnegi(gun); y[1]=lstoi(8); return y;
416:
417: case 3: avma=av; y=cgetg(4,t_VEC);
418: y[1]=lstoi(4); y[3]=un;
419: y[2] = (lgef(p2[1])==5)? un: lnegi(gun);
420: return y;
421:
422: default: err(bugparier,"galois (bug1)");
423: }
424:
425: case 5: z = cgetg(7,t_VEC);
426: ee = new_chunk(7); w = new_chunk(7);
427: for(;;)
428: {
429: for(;;)
430: {
431: p1=roots(x,prec);
432: for (l=1; l<=6; l++)
433: {
434: p2=(l==1)?p1: ((l<6)?transroot(p1,1,l): transroot(p1,2,5));
435: p3=gzero;
436: for (k=0,i=1; i<=5; i++,k+=4)
437: {
438: p5 = gadd(gmul((GEN)p2[ind5[k]],(GEN)p2[ind5[k+1]]),
439: gmul((GEN)p2[ind5[k+2]],(GEN)p2[ind5[k+3]]));
440: p3 = gadd(p3, gmul(gsqr((GEN)p2[i]),p5));
441: }
442: w[l]=lrndtoi(greal(p3),&e);
443: e1 = gexpo(gimag(p3)); if (e1>e) e=e1;
444: ee[l]=e; z[l] = (long)p3;
445: }
446: p4 = roots_to_pol(z,0);
447: p5=grndtoi(greal(p4),&e);
448: e1 = gexpo(gimag(p4)); if (e1>e) e=e1;
449: if (e <= -10) break;
450: prec = (prec<<1)-2;
451: }
452: p6 = modulargcd(p5,derivpol(p5));
453: if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
454: p3=(GEN)factor(p5)[1];
455: f=carreparfait(discsr(x));
456: if (lg(p3)-1==1)
457: {
458: avma=av; y=cgetg(4,t_VEC); y[3]=un;
459: if (f) { y[2]=un; y[1]=lstoi(60); return y; }
460: else { y[2]=lneg(gun); y[1]=lstoi(120); return y; }
461: }
462: if (!f)
463: {
464: avma=av; y=cgetg(4,t_VEC);
465: y[3]=un; y[2]=lneg(gun); y[1]=lstoi(20); return y;
466: }
467: pr = - (bit_accuracy(prec) >> 1);
468: for (l=1; l<=6; l++)
469: if (ee[l] <= pr && gcmp0(poleval(p5,(GEN)w[l]))) break;
470: if (l>6) err(bugparier,"galois (bug4)");
471: p2=(l==6)? transroot(p1,2,5):transroot(p1,1,l);
472: p3=gzero;
473: for (i=1; i<=5; i++)
474: {
475: j=(i%5)+1;
476: p3=gadd(p3,gmul(gmul((GEN)p2[i],(GEN)p2[j]),
477: gsub((GEN)p2[j],(GEN)p2[i])));
478: }
479: p5=gsqr(p3); p4=grndtoi(greal(p5),&e);
480: e1 = gexpo(gimag(p5)); if (e1>e) e=e1;
481: if (e <= -10)
482: {
483: if (gcmp0(p4)) goto tchi;
484: f=carreparfait(p4); avma=av; y=cgetg(4,t_VEC);
485: y[3]=y[2]=un; y[1]=lstoi(f?5:10);
486: return y;
487: }
488: prec=(prec<<1)-2;
489: }
490:
491: case 6: z = cgetg(7, t_VEC);
492: for(;;)
493: {
494: for(;;)
495: {
496: p1=roots(x,prec);
497: for (l=1; l<=6; l++)
498: {
499: p2=(l==1)?p1:transroot(p1,1,l);
500: p3=gzero; k=0;
501: for (i=1; i<=5; i++) for (j=i+1; j<=6; j++)
502: {
503: p5=gadd(gmul((GEN)p2[ind6[k]],(GEN)p2[ind6[k+1]]),
504: gmul((GEN)p2[ind6[k+2]],(GEN)p2[ind6[k+3]]));
505: p3=gadd(p3,gmul(gsqr(gmul((GEN)p2[i],(GEN)p2[j])),p5)); k+=4;
506: }
507: z[l] = (long)p3;
508: }
509: p4=roots_to_pol(z,0);
510: p5=grndtoi(greal(p4),&e);
511: e1 = gexpo(gimag(p4)); if (e1>e) e=e1;
512: if (e <= -10) break;
513: prec=(prec<<1)-2;
514: }
515: p6 = modulargcd(p5,derivpol(p5));
516: if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
517: p2=(GEN)factor(p5)[1];
518: switch(lg(p2)-1)
519: {
520: case 1:
521: z = cgetg(11,t_VEC); ind=0;
522: p3=gadd(gmul(gmul((GEN)p1[1],(GEN)p1[2]),(GEN)p1[3]),
523: gmul(gmul((GEN)p1[4],(GEN)p1[5]),(GEN)p1[6]));
524: z[++ind] = (long)p3;
525: for (i=1; i<=3; i++)
526: for (j=4; j<=6; j++)
527: {
528: p2=transroot(p1,i,j);
529: p3=gadd(gmul(gmul((GEN)p2[1],(GEN)p2[2]),(GEN)p2[3]),
530: gmul(gmul((GEN)p2[4],(GEN)p2[5]),(GEN)p2[6]));
531: z[++ind] = (long)p3;
532: }
533: p4 = roots_to_pol(z,0);
534: p5=grndtoi(greal(p4),&e);
535: e1 = gexpo(gimag(p4)); if (e1>e) e=e1;
536: if (e <= -10)
537: {
538: p6 = modulargcd(p5,derivpol(p5));
539: if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
540: p2=(GEN)factor(p5)[1];
541: f=carreparfait(discsr(x));
542: avma=av; y=cgetg(4,t_VEC); y[3]=un;
543: if (lg(p2)-1==1)
544: {
545: if (f) { y[2]=un; y[1]=lstoi(360); }
546: else { y[2]=lnegi(gun); y[1]=lstoi(720); }
547: }
548: else
549: {
550: if (f) { y[2]=un; y[1]=lstoi(36); }
551: else { y[2]=lnegi(gun); y[1]=lstoi(72); }
552: }
553: return y;
554: }
555: prec=(prec<<1)-2; break;
556:
557: case 2: l2=degpol(p2[1]); if (l2>3) l2=6-l2;
558: switch(l2)
559: {
560: case 1: f=carreparfait(discsr(x));
561: avma=av; y=cgetg(4,t_VEC); y[3]=un;
562: if (f) { y[2]=un; y[1]=lstoi(60); }
563: else { y[2]=lneg(gun); y[1]=lstoi(120); }
564: return y;
565: case 2: f=carreparfait(discsr(x));
566: if (f)
567: {
568: avma=av; y=cgetg(4,t_VEC);
569: y[3]=y[2]=un; y[1]=lstoi(24);
570: }
571: else
572: {
573: p3=(lgef(p2[1])==5) ? (GEN)p2[2]:(GEN)p2[1];
574: f=carreparfait(discsr(p3));
575: avma=av; y=cgetg(4,t_VEC); y[2]=lneg(gun);
576: if (f) { y[1]=lstoi(24); y[3]=deux; }
577: else { y[1]=lstoi(48); y[3]=un; }
578: }
579: return y;
580: case 3: f=carreparfait(discsr((GEN)p2[1]))
581: || carreparfait(discsr((GEN)p2[2]));
582: avma=av; y=cgetg(4,t_VEC);
583: y[3]=un; y[2]=lneg(gun); y[1]=lstoi(f? 18: 36);
584: return y;
585: }
586: case 3:
587: for (l2=1; l2<=3; l2++)
588: if (lgef(p2[l2])>=6) p3=(GEN)p2[l2];
589: if (lgef(p3)==6)
590: {
591: f=carreparfait(discsr(p3)); avma=av; y=cgetg(4,t_VEC);
592: y[2]=lneg(gun); y[1]=lstoi(f? 6: 12);
593: }
594: else
595: {
596: f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC);
597: if (f) { y[2]=un; y[1]=lstoi(12); }
598: else { y[2]=lneg(gun); y[1]=lstoi(24); }
599: }
600: y[3]=un; return y;
601: case 4: avma=av; y=cgetg(4,t_VEC);
602: y[1]=lstoi(6); y[2]=lneg(gun); y[3]=deux; return y;
603: default: err(bugparier,"galois (bug3)");
604: }
605: }
606:
607: case 7: z = cgetg(36,t_VEC);
608: for(;;)
609: {
610: ind = 0; p1=roots(x,prec); p4=gun;
611: for (i=1; i<=5; i++)
612: for (j=i+1; j<=6; j++)
613: {
614: p6 = gadd((GEN)p1[i],(GEN)p1[j]);
615: for (k=j+1; k<=7; k++)
616: z[++ind] = (long) gadd(p6,(GEN)p1[k]);
617: }
618: p4 = roots_to_pol(z,0);
619: p5 = grndtoi(greal(p4),&e);
620: e1 = gexpo(gimag(p4)); if (e1>e) e=e1;
621: if (e <= -10) break;
622: prec = (prec<<1)-2;
623: }
624: p6 = modulargcd(p5,derivpol(p5));
625: if (typ(p6)==t_POL && lgef(p6)>3) goto tchi;
626: p2=(GEN)factor(p5)[1];
627: switch(lg(p2)-1)
628: {
629: case 1: f=carreparfait(discsr(x)); avma=av; y=cgetg(4,t_VEC); y[3]=un;
630: if (f) { y[2]=un; y[1]=lstoi(2520); }
631: else { y[2]=lneg(gun); y[1]=lstoi(5040); }
632: return y;
633: case 2: f=degpol(p2[1]); avma=av; y=cgetg(4,t_VEC); y[3]=un;
634: if (f==7 || f==28) { y[2]=un; y[1]=lstoi(168); }
635: else { y[2]=lneg(gun); y[1]=lstoi(42); }
636: return y;
637: case 3: avma=av; y=cgetg(4,t_VEC);
638: y[3]=y[2]=un; y[1]=lstoi(21); return y;
639: case 4: avma=av; y=cgetg(4,t_VEC);
640: y[3]=un; y[2]=lneg(gun); y[1]=lstoi(14); return y;
641: case 5: avma=av; y=cgetg(4,t_VEC);
642: y[3]=y[2]=un; y[1]=lstoi(7); return y;
643: default: err(talker,"galois (bug2)");
644: }
645: }
646: tchi: avma=av1; x=tschirnhaus(x1);
647: }
648: }
649:
650: GEN
651: galoisapply(GEN nf, GEN aut, GEN x)
652: {
653: long av=avma,tetpil,lx,j,N;
654: GEN p,p1,y,pol;
655:
656: nf=checknf(nf); pol=(GEN)nf[1];
657: if (typ(aut)==t_POL) aut = gmodulcp(aut,pol);
658: else
659: {
660: if (typ(aut)!=t_POLMOD || !gegal((GEN)aut[1],pol))
661: err(talker,"incorrect galois automorphism in galoisapply");
662: }
663: switch(typ(x))
664: {
665: case t_INT: case t_INTMOD: case t_FRAC: case t_FRACN: case t_PADIC:
666: avma=av; return gcopy(x);
667:
668: case t_POLMOD: x = (GEN) x[2]; /* fall through */
669: case t_POL:
670: p1 = gsubst(x,varn(pol),aut);
671: if (typ(p1)!=t_POLMOD || !gegal((GEN)p1[1],pol)) p1 = gmodulcp(p1,pol);
672: return gerepileupto(av,p1);
673:
674: case t_VEC:
675: if (lg(x)==3)
676: {
677: y=cgetg(3,t_VEC);
678: y[1]=(long)galoisapply(nf,aut,(GEN)x[1]);
679: y[2]=lcopy((GEN)x[2]); return gerepileupto(av, y);
680: }
681: if (lg(x)!=6) err(typeer,"galoisapply");
682: y=cgetg(6,t_VEC); y[1]=x[1]; y[3]=x[3]; y[4]=x[4];
683: p = (GEN)x[1];
684: p1=centermod(galoisapply(nf,aut,(GEN)x[2]), p);
685: if (is_pm1(x[3]))
686: if (ggval(subres(gmul((GEN)nf[7],p1),pol), p) > itos((GEN)x[4]))
687: p1[1] = (signe(p1[1]) > 0)? lsub((GEN)p1[1], p)
688: : ladd((GEN)p1[1], p);
689: y[2]=(long)p1;
690: y[5]=(long)centermod(galoisapply(nf,aut,(GEN)x[5]), p);
691: return gerepilecopy(av,y);
692:
693: case t_COL:
694: N=degpol(pol);
695: if (lg(x)!=N+1) err(typeer,"galoisapply");
696: p1=galoisapply(nf,aut,gmul((GEN)nf[7],x)); tetpil=avma;
697: return gerepile(av,tetpil,algtobasis(nf,p1));
698:
699: case t_MAT:
700: lx=lg(x); if (lx==1) return cgetg(1,t_MAT);
701: N=degpol(pol);
702: if (lg(x[1])!=N+1) err(typeer,"galoisapply");
703: p1=cgetg(lx,t_MAT);
704: for (j=1; j<lx; j++) p1[j]=(long)galoisapply(nf,aut,(GEN)x[j]);
705: if (lx==N+1) p1 = idealhermite(nf,p1);
706: return gerepileupto(av,p1);
707: }
708: err(typeer,"galoisapply");
709: return NULL; /* not reached */
710: }
711:
712: GEN pol_to_monic(GEN pol, GEN *lead);
713: int cmp_pol(GEN x, GEN y);
714:
715: GEN
716: get_nfpol(GEN x, GEN *nf)
717: {
718: if (typ(x) == t_POL) { *nf = NULL; return x; }
719: *nf = checknf(x); return (GEN)(*nf)[1];
720: }
721:
722: /* if fliso test for isomorphism, for inclusion otherwise. */
723: static GEN
724: nfiso0(GEN a, GEN b, long fliso)
725: {
726: ulong av = avma;
727: long n,m,i,vb,lx;
728: GEN nfa,nfb,p1,y,la,lb;
729:
730: a = get_nfpol(a, &nfa);
731: b = get_nfpol(b, &nfb);
732: if (fliso && nfa && !nfb) { p1=a; a=b; b=p1; p1=nfa; nfa=nfb; nfb=p1; }
733: m=degpol(a);
734: n=degpol(b); if (m<=0 || n<=0) err(constpoler,"nfiso or nfincl");
735: if (fliso)
736: { if (n!=m) return gzero; }
737: else
738: { if (n%m) return gzero; }
739:
740: if (nfb) lb = NULL; else b = pol_to_monic(b,&lb);
741: if (nfa) la = NULL; else a = pol_to_monic(a,&la);
742: if (nfa && nfb)
743: {
744: if (fliso)
745: {
746: if (!gegal((GEN)nfa[2],(GEN)nfb[2])
747: || !gegal((GEN)nfa[3],(GEN)nfb[3])) return gzero;
748: }
749: else
750: if (!divise((GEN)nfb[3], gpowgs((GEN)nfa[3],n/m))) return gzero;
751: }
752: else
753: {
754: GEN da = nfa? (GEN)nfa[3]: discsr(a);
755: GEN db = nfb? (GEN)nfb[3]: discsr(b);
756: if (fliso)
757: {
758: p1=gdiv(da,db);
759: if (typ(p1)==t_FRAC) p1=mulii((GEN)p1[1],(GEN)p1[2]);
760: if (!gcarreparfait(p1)) { avma=av; return gzero; }
761: }
762: else
763: {
764: long q=n/m;
765: GEN fa=factor(da), ex=(GEN)fa[2];
766: fa=(GEN)fa[1]; lx=lg(fa);
767: for (i=1; i<lx; i++)
768: if (mod2((GEN)ex[i]) && !divise(db,gpowgs((GEN)fa[i],q)))
769: { avma=av; return gzero; }
770: }
771: }
772: a = dummycopy(a); setvarn(a,0);
773: b = dummycopy(b); vb=varn(b);
774: if (nfb)
775: {
776: if (vb == 0) nfb = gsubst(nfb, 0, polx[MAXVARN]);
777: y = lift_intern(nfroots(nfb,a));
778: }
779: else
780: {
781: if (vb == 0) setvarn(b, fetch_var());
782: y = (GEN)polfnf(a,b)[1]; lx = lg(y);
783: for (i=1; i<lx; i++)
784: {
785: if (lgef(y[i]) != 4) { setlg(y,i); break; }
786: y[i] = (long)gneg_i(lift_intern(gmael(y,i,2)));
787: }
788: y = gen_sort(y, 0, cmp_pol);
789: settyp(y, t_VEC);
790: if (vb == 0) delete_var();
791: }
792: lx = lg(y); if (lx==1) { avma=av; return gzero; }
793: for (i=1; i<lx; i++)
794: {
795: p1 = (GEN)y[i];
796: if (typ(p1) == t_POL) setvarn(p1, vb); else p1 = scalarpol(p1, vb);
797: if (lb) p1 = poleval(p1, gmul(polx[vb],lb));
798: y[i] = la? ldiv(p1,la): (long)p1;
799: }
800: return gerepilecopy(av,y);
801: }
802:
803: GEN
804: nfisisom(GEN a, GEN b)
805: {
806: return nfiso0(a,b,1);
807: }
808:
809: GEN
810: nfisincl(GEN a, GEN b)
811: {
812: return nfiso0(a,b,0);
813: }
814:
815: /*************************************************************************/
816: /** **/
817: /** INITALG **/
818: /** **/
819: /*************************************************************************/
820: extern GEN LLL_nfbasis(GEN *x, GEN polr, GEN base, long prec);
821: extern GEN eleval(GEN f,GEN h,GEN a);
822: extern int canon_pol(GEN z);
823: extern GEN mat_to_vecpol(GEN x, long v);
824: extern GEN vecpol_to_mat(GEN v, long n);
825:
826: /* For internal use. compute trace(x mod pol), sym=polsym(pol,deg(pol)-1) */
827: GEN
828: quicktrace(GEN x, GEN sym)
829: {
830: GEN p1 = gzero;
831: long i;
832:
833: if (signe(x))
834: {
835: sym--;
836: for (i=lgef(x)-1; i>1; i--)
837: p1 = gadd(p1, gmul((GEN)x[i],(GEN)sym[i]));
838: }
839: return p1;
840: }
841:
842: /* T = trace(w[i]), x = sum x[i] w[i], x[i] integer */
843: static GEN
844: trace_col(GEN x, GEN T)
845: {
846: ulong av = avma;
847: GEN t = gzero;
848: long i, l = lg(x);
849:
850: t = mulii((GEN)x[1],(GEN)T[1]);
851: for (i=2; i<l; i++)
852: if (signe(x[i])) t = addii(t, mulii((GEN)x[i],(GEN)T[i]));
853: return gerepileuptoint(av, t);
854: }
855:
856: /* Seek a new, simpler, polynomial pol defining the same number field as
857: * x (assumed to be monic at this point).
858: * *ptx receives pol
859: * *ptdx receives disc(pol)
860: * *ptrev expresses the new root in terms of the old one.
861: * base updated in place.
862: * prec = 0 <==> field is totally real
863: */
864: static void
865: nfinit_reduce(long flag, GEN *px, GEN *pdx, GEN *prev, GEN *pbase, long prec)
866: {
867: GEN chbas,a,phimax,dxn,s,sn,p1,p2,p3,polmax,rev,polr;
868: GEN x = *px, dx = *pdx, base = *pbase;
869: long i,j,nmax,numb,flc,v=varn(x), n=lg(base)-1;
870:
871: if (n == 1)
872: {
873: *px = gsub(polx[v],gun); *pdx = gun;
874: *prev = polymodrecip(gmodulcp(gun, x)); return;
875: }
876: polr = prec? roots(x, prec): NULL;
877: if (polr)
878: for (s=gzero,i=1; i<=n; i++) s = gadd(s,gnorm((GEN)polr[i]));
879: else
880: s = subii(sqri((GEN)x[n+1]), shifti((GEN)x[n],1));
881:
882: chbas = LLL_nfbasis(&x,polr,base,prec);
883: if (DEBUGLEVEL) msgtimer("LLL basis");
884:
885: phimax=polx[v]; polmax=dummycopy(x);
886: nmax=(flag & nf_PARTIAL)?min(n,3):n;
887:
888: for (numb=0,i=2; i<=nmax || (!numb && i<=n); i++)
889: { /* cf pols_for_polred */
890: if (DEBUGLEVEL>2) { fprintferr("i = %ld\n",i); flusherr(); }
891: p1 = a = gmul(base,(GEN)chbas[i]); p3=content(p1);
892: if (gcmp1(p3)) p3 = NULL; else p1 = gdiv(p1,p3);
893: p1 = caract2(x,p1,v);
894: if (p3)
895: for (p2=gun, j=lgef(p1)-2; j>=2; j--)
896: {
897: p2 = gmul(p2,p3); p1[j] = lmul((GEN)p1[j], p2);
898: }
899: p2 = modulargcd(derivpol(p1),p1);
900: if (lgef(p2) > 3) continue;
901:
902: if (DEBUGLEVEL>3) outerr(p1);
903: dxn=discsr(p1); flc=absi_cmp(dxn,dx); numb++;
904: if (flc>0) continue;
905:
906: if (polr)
907: for (sn=gzero,j=1; j<=n; j++)
908: sn = gadd(sn,gnorm(poleval(a,(GEN)polr[j])));
909: else
910: sn = subii(sqri((GEN)p1[n+1]), shifti((GEN)p1[n],1));
911: if (flc>=0)
912: {
913: flc=gcmp(sn,s);
914: if (flc>0 || (!flc && gpolcomp(p1,polmax) >= 0)) continue;
915: }
916: dx=dxn; s=sn; polmax=p1; phimax=a;
917: }
918: if (!numb)
919: {
920: if (gisirreducible(x)!=gun) err(redpoler,"nfinit_reduce");
921: err(talker,"you have found a counter-example to a conjecture, "
922: "please send us\nthe polynomial as soon as possible");
923: }
924: if (phimax == polx[v]) /* no improvement */
925: rev = gmodulcp(phimax,x);
926: else
927: {
928: if (canon_pol(polmax) < 0) phimax = gneg_i(phimax);
929: if (DEBUGLEVEL>1) fprintferr("polmax = %Z\n",polmax);
930: p2 = gmodulcp(phimax,x); rev = polymodrecip(p2);
931: a = base; base = cgetg(n+1,t_VEC);
932: p1 = (GEN)rev[2];
933: for (i=1; i<=n; i++)
934: base[i] = (long)eleval(polmax, (GEN)a[i], p1);
935: p1 = vecpol_to_mat(base,n); p2=denom(p1); p1=gmul(p2,p1);
936: p1 = gdiv(hnfmodid(p1,p2), p2);
937: base = mat_to_vecpol(p1,v);
938: }
939: *px=polmax; *pdx=dx; *prev=rev; *pbase = base;
940: }
941:
942: /* pol belonging to Z[x], return a monic polynomial generating the same field
943: * as pol (x-> ax+b)) set lead = NULL if pol was monic (after dividing
944: * by the content), and to to leading coeff otherwise.
945: * No garbage collecting done.
946: */
947: GEN
948: pol_to_monic(GEN pol, GEN *lead)
949: {
950: long n = lgef(pol)-1;
951: GEN p1;
952:
953: if (n==1 || gcmp1((GEN)pol[n])) { *lead = NULL; return pol; }
954:
955: p1=content(pol); if (!gcmp1(p1)) pol = gdiv(pol,p1);
956: return primitive_pol_to_monic(pol,lead);
957: }
958:
959: /* NB: TI integral, det(TI) = d_K, ideal/dideal = codifferent */
960: GEN
961: make_MDI(GEN nf, GEN TI, GEN *ideal, GEN *dideal)
962: {
963: GEN c = content(TI);
964: GEN p1;
965:
966: *dideal = divii((GEN)nf[3], c);
967: *ideal = p1 = hnfmodid(gdiv(TI,c), *dideal);
968: return gmul(c, ideal_two_elt(nf, p1));
969: }
970:
971: /* [bas[i]/den[i]]= integer basis. roo = real part of the roots */
972: GEN
973: make_M(GEN basden,GEN roo)
974: {
975: GEN p1,d,M, bas=(GEN)basden[1], den=(GEN)basden[2];
976: long i,j, ru = lg(roo), n = lg(bas);
977: M = cgetg(n,t_MAT);
978: for (j=1; j<n; j++)
979: {
980: p1=cgetg(ru,t_COL); M[j]=(long)p1;
981: for (i=1; i<ru; i++)
982: p1[i]=(long)poleval((GEN)bas[j],(GEN)roo[i]);
983: }
984: if (den)
985: {
986: long prec = precision((GEN)roo[1]);
987: GEN invd,rd = cgetr(prec+1);
988: for (j=1; j<n; j++)
989: {
990: d = (GEN)den[j]; if (!d) continue;
991: p1 = (GEN)M[j]; affir(d,rd); invd = ginv(rd);
992: for (i=1; i<ru; i++) p1[i] = lmul((GEN)p1[i], invd);
993: }
994: }
995: if (DEBUGLEVEL>4) msgtimer("matrix M");
996: return M;
997: }
998:
999: GEN
1000: make_MC(long r1,GEN M)
1001: {
1002: long i,j,av,tetpil, n = lg(M), ru = lg(M[1]);
1003: GEN p1,p2,MC=cgetg(ru,t_MAT);
1004:
1005: for (j=1; j<ru; j++)
1006: {
1007: p1=cgetg(n,t_COL); MC[j]=(long)p1;
1008: for (i=1; i<n; i++)
1009: {
1010: av=avma; p2=gconj(gcoeff(M,j,i)); tetpil=avma;
1011: p1[i] = (j<=r1)? (long)p2: lpile(av,tetpil,gmul2n(p2,1));
1012: }
1013: }
1014: if (DEBUGLEVEL>4) msgtimer("matrix MC");
1015: return MC;
1016: }
1017:
1018: GEN
1019: get_roots(GEN x,long r1,long ru,long prec)
1020: {
1021: GEN roo = (typ(x)==t_VEC)? dummycopy(x): roots(x,prec);
1022: long i;
1023:
1024: for (i=1; i<=r1; i++) roo[i]=lreal((GEN)roo[i]);
1025: for ( ; i<=ru; i++) roo[i]=roo[(i<<1)-r1];
1026: roo[0]=evaltyp(t_VEC)|evallg(ru+1); return roo;
1027: }
1028:
1029: /* assume lg(nf) > 3 && typ(nf) = container [hopefully a genuine nf] */
1030: long
1031: nf_get_r1(GEN nf)
1032: {
1033: GEN x = (GEN)nf[2];
1034: if (typ(x) != t_VEC || lg(x) != 3 || typ(x[1]) != t_INT)
1035: err(talker,"false nf in nf_get_r1");
1036: return itos((GEN)x[1]);
1037: }
1038: long
1039: nf_get_r2(GEN nf)
1040: {
1041: GEN x = (GEN)nf[2];
1042: if (typ(x) != t_VEC || lg(x) != 3 || typ(x[2]) != t_INT)
1043: err(talker,"false nf in nf_get_r2");
1044: return itos((GEN)x[2]);
1045: }
1046:
1047: extern GEN mulmat_pol(GEN A, GEN x);
1048:
1049: static GEN
1050: get_T(GEN mul, GEN x, GEN bas, GEN den)
1051: {
1052: long i,j,n = lg(bas)-1;
1053: GEN tr,T,T1,sym;
1054: T = cgetg(n+1,t_MAT);
1055: T1 = cgetg(n+1,t_COL);
1056: sym = polsym(x, n-1);
1057:
1058: T1[1]=lstoi(n);
1059: for (i=2; i<=n; i++)
1060: {
1061: tr = quicktrace((GEN)bas[i], sym);
1062: if (den && den[i]) tr = diviiexact(tr,(GEN)den[i]);
1063: T1[i] = (long)tr; /* tr(w[i]) */
1064: }
1065: T[1] = (long)T1;
1066: for (i=2; i<=n; i++)
1067: {
1068: T[i] = lgetg(n+1,t_COL); coeff(T,1,i) = T1[i];
1069: for (j=2; j<=i; j++)
1070: coeff(T,i,j) = coeff(T,j,i) = (long)trace_col((GEN)mul[j+(i-1)*n], T1);
1071: }
1072: return T;
1073: }
1074:
1075: /* return [bas[i]*denom(bas[i]), denom(bas[i])], denom 1 is given as NULL */
1076: GEN
1077: get_bas_den(GEN bas)
1078: {
1079: GEN z,d,den, dbas = dummycopy(bas);
1080: long i, c = 0, l = lg(bas);
1081: den = cgetg(l,t_VEC);
1082: for (i=1; i<l; i++)
1083: {
1084: d = denom(content((GEN)dbas[i]));
1085: if (is_pm1(d)) d = NULL; else { dbas[i] = lmul((GEN)dbas[i],d); c++; }
1086: den[i] = (long)d;
1087: }
1088: if (!c) den = NULL; /* power basis */
1089: z = cgetg(3,t_VEC);
1090: z[1] = (long)dbas;
1091: z[2] = (long)den; return z;
1092: }
1093:
1094: /* allow x or y = NULL (act as 1) */
1095: static GEN
1096: _mulii(GEN x, GEN y)
1097: {
1098: if (!x) return y;
1099: if (!y) return x;
1100: return mulii(x,y);
1101: }
1102:
1103: GEN
1104: get_mul_table(GEN x,GEN basden,GEN invbas,GEN *T)
1105: {
1106: long i,j, n = degpol(x);
1107: GEN z,d, mul = cgetg(n*n+1,t_MAT), bas=(GEN)basden[1], den=(GEN)basden[2];
1108:
1109: for (j=1; j<=n*n; j++) mul[j]=lgetg(n+1,t_COL);
1110: for (i=1; i<=n; i++)
1111: for (j=i; j<=n; j++)
1112: {
1113: ulong av = avma;
1114: z = gres(gmul((GEN)bas[j],(GEN)bas[i]), x);
1115: z = mulmat_pol(invbas, z); /* integral column */
1116: if (den)
1117: {
1118: d = _mulii((GEN)den[i], (GEN)den[j]);
1119: if (d) z = gdivexact(z, d);
1120: }
1121: mul[j+(i-1)*n] = mul[i+(j-1)*n] = lpileupto(av,z);
1122: }
1123: if (T) *T = get_T(mul,x,bas,den);
1124: return mul;
1125: }
1126:
1127: /* fill mat = nf[5], as well as nf[8] and nf[9]
1128: * If (small) only compute a subset (use dummy 0s for the rest) */
1129: void
1130: get_nf_matrices(GEN nf, long small)
1131: {
1132: GEN x=(GEN)nf[1],dK=(GEN)nf[3],index=(GEN)nf[4],ro=(GEN)nf[6],bas=(GEN)nf[7];
1133: GEN basden,mul,invbas,M,MC,T,MDI,D,TI,A,dA,mat;
1134: long r1 = nf_get_r1(nf), n = lg(bas)-1;
1135:
1136: mat = cgetg(small? 4: 8,t_VEC); nf[5] = (long)mat;
1137: basden = get_bas_den(bas);
1138: M = make_M(basden,ro);
1139: MC = make_MC(r1,M);
1140: mat[1]=(long)M;
1141: mat[3]=(long)mulmat_real(MC,M);
1142: if (small) { nf[8]=nf[9]=mat[2]=zero; return; }
1143:
1144: invbas = QM_inv(vecpol_to_mat(bas,n), gun);
1145: mul = get_mul_table(x,basden,invbas,&T);
1146: if (DEBUGLEVEL) msgtimer("mult. table");
1147:
1148: nf[8]=(long)invbas;
1149: nf[9]=(long)mul;
1150:
1151: TI = ZM_inv(T, dK); /* dK T^-1 */
1152: MDI = make_MDI(nf,TI, &A, &dA);
1153: mat[6]=(long)TI;
1154: mat[7]=(long)MDI; /* needed in idealinv below */
1155: if (is_pm1(index))
1156: D = idealhermite_aux(nf, derivpol(x));
1157: else
1158: D = gmul(dA, idealinv(nf, A));
1159: mat[2]=(long)MC;
1160: mat[4]=(long)T;
1161: mat[5]=(long)D;
1162: if (DEBUGLEVEL) msgtimer("matrices");
1163: }
1164:
1165: /* Initialize the number field defined by the polynomial x (in variable v)
1166: * flag & nf_REGULAR
1167: * regular behaviour.
1168: * flag & nf_SMALL
1169: * compute only nf[1] (pol), nf[2] (signature), nf[5][3] (T2) and
1170: * nf[7] (integer basis), the other components are filled with gzero.
1171: * flag & nf_REDUCE
1172: * try a polred first.
1173: * flag & nf_PARTIAL
1174: * do a partial polred, not a polredabs
1175: * flag & nf_ORIG
1176: * do a polred and return [nfinit(x),Mod(a,red)], where
1177: * Mod(a,red)=Mod(v,x) (i.e return the base change).
1178: */
1179:
1180: /* here x can be a polynomial, an nf or a bnf */
1181: GEN
1182: initalgall0(GEN x, long flag, long prec)
1183: {
1184: GEN lead = NULL,nf,ro,bas,mat,rev,dK,dx,index,res;
1185: long av=avma,n,i,r1,r2,ru,PRECREG;
1186:
1187: if (DEBUGLEVEL) timer2();
1188: if (typ(x)==t_POL)
1189: {
1190: n=degpol(x); if (n<=0) err(constpoler,"initalgall0");
1191: check_pol_int(x,"initalg");
1192: if (gisirreducible(x) == gzero) err(redpoler,"nfinit");
1193: if (!gcmp1((GEN)x[n+2]))
1194: {
1195: x = pol_to_monic(x,&lead);
1196: if (!(flag & nf_SMALL))
1197: {
1198: if (!(flag & nf_REDUCE))
1199: err(warner,"non-monic polynomial. Result of the form [nf,c]");
1200: flag = flag | nf_REDUCE | nf_ORIG;
1201: }
1202: }
1203: bas = allbase4(x,0,&dK,NULL);
1204: if (DEBUGLEVEL) msgtimer("round4");
1205: dx = discsr(x); r1 = sturm(x);
1206: }
1207: else
1208: {
1209: i = lg(x);
1210: if (typ(x) == t_VEC && i<=4 && i>=3 && typ(x[1])==t_POL)
1211: { /* polynomial + integer basis */
1212: bas=(GEN)x[2]; x=(GEN)x[1]; n=degpol(x);
1213: if (typ(bas) == t_MAT) { mat = bas; bas = mat_to_vecpol(mat,varn(x)); }
1214: else mat = vecpol_to_mat(bas,n);
1215: dx = discsr(x); r1 = sturm(x);
1216: dK = gmul(dx, gsqr(det2(mat)));
1217: }
1218: else
1219: {
1220: nf=checknf(x);
1221: bas=(GEN)nf[7]; x=(GEN)nf[1]; n=degpol(x);
1222: dK=(GEN)nf[3]; dx=mulii(dK, sqri((GEN)nf[4]));
1223: r1 = nf_get_r1(nf);
1224: }
1225: bas[1]=lpolun[varn(x)]; /* it may be gun => SEGV later */
1226: }
1227: r2=(n-r1)>>1; ru=r1+r2;
1228: PRECREG = prec + (expi(dK)>>(TWOPOTBITS_IN_LONG+1))
1229: + (long)((sqrt((double)n)+3) / sizeof(long) * 4);
1230: rev = NULL;
1231: if (flag & nf_REDUCE)
1232: {
1233: nfinit_reduce(flag, &x, &dx, &rev, &bas, r1==n? 0: prec);
1234: if (DEBUGLEVEL) msgtimer("polred");
1235: }
1236: if (!carrecomplet(divii(dx,dK),&index))
1237: err(bugparier,"nfinit (incorrect discriminant)");
1238:
1239: ro=get_roots(x,r1,ru,PRECREG);
1240: if (DEBUGLEVEL) msgtimer("roots");
1241:
1242: nf=cgetg(10,t_VEC);
1243: nf[1]=(long)x;
1244: nf[2]=lgetg(3,t_VEC);
1245: mael(nf,2,1)=lstoi(r1);
1246: mael(nf,2,2)=lstoi(r2);
1247: nf[3]=(long)dK;
1248: nf[4]=(long)index;
1249: nf[6]=(long)ro;
1250: nf[7]=(long)bas;
1251: get_nf_matrices(nf, flag & nf_SMALL);
1252:
1253: if (flag & nf_ORIG)
1254: {
1255: if (!rev) err(talker,"bad flag in initalgall0");
1256: res = cgetg(3,t_VEC);
1257: res[1]=(long)nf; nf = res;
1258: res[2]=lead? ldiv(rev,lead): (long)rev;
1259: }
1260: return gerepilecopy(av, nf);
1261: }
1262:
1263: GEN
1264: initalgred(GEN x, long prec)
1265: {
1266: return initalgall0(x,nf_REDUCE,prec);
1267: }
1268:
1269: GEN
1270: initalgred2(GEN x, long prec)
1271: {
1272: return initalgall0(x,nf_REDUCE|nf_ORIG,prec);
1273: }
1274:
1275: GEN
1276: nfinit0(GEN x, long flag,long prec)
1277: {
1278: switch(flag)
1279: {
1280: case 0:
1281: case 1: return initalgall0(x,nf_REGULAR,prec);
1282: case 2: return initalgall0(x,nf_REDUCE,prec);
1283: case 3: return initalgall0(x,nf_REDUCE|nf_ORIG,prec);
1284: case 4: return initalgall0(x,nf_REDUCE|nf_PARTIAL,prec);
1285: case 5: return initalgall0(x,nf_REDUCE|nf_ORIG|nf_PARTIAL,prec);
1286: case 6: return initalgall0(x,nf_SMALL,prec);
1287: default: err(flagerr,"nfinit");
1288: }
1289: return NULL; /* not reached */
1290: }
1291:
1292: GEN
1293: initalg(GEN x, long prec)
1294: {
1295: return initalgall0(x,nf_REGULAR,prec);
1296: }
1297:
1298: /* assume x a bnr/bnf/nf */
1299: long
1300: nfgetprec(GEN x)
1301: {
1302: GEN nf = checknf(x), ro = (GEN)nf[6];
1303: return (typ(ro)==t_VEC)?precision((GEN)ro[1]): DEFAULTPREC;
1304: }
1305:
1306: GEN
1307: nfnewprec(GEN nf, long prec)
1308: {
1309: long av=avma,r1,r2,ru,n;
1310: GEN y,pol,ro,basden,MC,mat,M;
1311:
1312: if (typ(nf) != t_VEC) err(talker,"incorrect nf in nfnewprec");
1313: if (lg(nf) == 11) return bnfnewprec(nf,prec);
1314: if (lg(nf) == 7) return bnrnewprec(nf,prec);
1315: (void)checknf(nf);
1316: y = dummycopy(nf);
1317: pol=(GEN)nf[1]; n=degpol(pol);
1318: r1 = nf_get_r1(nf);
1319: r2 = (n - r1) >> 1; ru = r1+r2;
1320: mat=dummycopy((GEN)nf[5]);
1321: ro=get_roots(pol,r1,ru,prec);
1322: y[5]=(long)mat;
1323: y[6]=(long)ro;
1324: basden = get_bas_den((GEN)nf[7]);
1325: M = make_M(basden,ro);
1326: MC = make_MC(r1,M);
1327: mat[1]=(long)M;
1328: if (typ(nf[8]) != t_INT) mat[2]=(long)MC; /* not a small nf */
1329: mat[3]=(long)mulmat_real(MC,M);
1330: return gerepilecopy(av, y);
1331: }
1332:
1333: static long
1334: nf_pm1(GEN y)
1335: {
1336: long i,l;
1337:
1338: if (!is_pm1(y[1])) return 0;
1339: l = lg(y);
1340: for (i=2; i<l; i++)
1341: if (signe(y[i])) return 0;
1342: return signe(y[1]);
1343:
1344: }
1345:
1346: static GEN
1347: is_primitive_root(GEN nf, GEN fa, GEN x, long w)
1348: {
1349: GEN y, exp = stoi(2), pp = (GEN)fa[1];
1350: long i,p, l = lg(pp);
1351:
1352: for (i=1; i<l; i++)
1353: {
1354: p = itos((GEN)pp[i]);
1355: exp[2] = w / p; y = element_pow(nf,x,exp);
1356: if (nf_pm1(y) > 0) /* y = 1 */
1357: {
1358: if (p!=2 || !gcmp1(gcoeff(fa,i,2))) return NULL;
1359: x = gneg_i(x);
1360: }
1361: }
1362: return x;
1363: }
1364:
1365: GEN
1366: rootsof1(GEN nf)
1367: {
1368: ulong av;
1369: long N,k,i,ws,prec;
1370: GEN algun,p1,y,R1,d,list,w;
1371:
1372: y=cgetg(3,t_VEC); av=avma; nf=checknf(nf);
1373: R1=gmael(nf,2,1); algun=gmael(nf,8,1);
1374: if (signe(R1))
1375: {
1376: y[1]=deux;
1377: y[2]=lneg(algun); return y;
1378: }
1379: N=degpol(nf[1]); prec=gprecision((GEN)nf[6]);
1380: #ifdef LONG_IS_32BIT
1381: if (prec < 10) prec = 10;
1382: #else
1383: if (prec < 6) prec = 6;
1384: #endif
1385: for (i=1; ; i++)
1386: {
1387: p1 = fincke_pohst(nf,stoi(N),1000,1,prec,NULL);
1388: if (p1) break;
1389: if (i == MAXITERPOL) err(accurer,"rootsof1");
1390: prec=(prec<<1)-2;
1391: if (DEBUGLEVEL) err(warnprec,"rootsof1",prec);
1392: nf=nfnewprec(nf,prec);
1393: }
1394: if (itos(ground((GEN)p1[2])) != N) err(bugparier,"rootsof1 (bug1)");
1395: w=(GEN)p1[1]; ws = itos(w);
1396: if (ws == 2)
1397: {
1398: y[1]=deux; avma=av;
1399: y[2]=lneg(algun); return y;
1400: }
1401:
1402: d = decomp(w); list = (GEN)p1[3]; k = lg(list);
1403: for (i=1; i<k; i++)
1404: {
1405: p1 = (GEN)list[i];
1406: p1 = is_primitive_root(nf,d,p1,ws);
1407: if (p1)
1408: {
1409: y[2]=lpilecopy(av,p1);
1410: y[1]=lstoi(ws); return y;
1411: }
1412: }
1413: err(bugparier,"rootsof1");
1414: return NULL; /* not reached */
1415: }
1416:
1417: /*******************************************************************/
1418: /* */
1419: /* DEDEKIND ZETA FUNCTION */
1420: /* */
1421: /*******************************************************************/
1422:
1423: ulong smulss(ulong x, ulong y, ulong *rem);
1424:
1425: static GEN
1426: dirzetak0(GEN nf, long N0)
1427: {
1428: GEN vect,p1,pol,disc,c,c2;
1429: long av=avma,i,j,k,limk,lx;
1430: ulong q,p,rem;
1431: byteptr d=diffptr;
1432: long court[] = {evaltyp(t_INT)|m_evallg(3), evalsigne(1)|evallgefint(3),0};
1433:
1434: pol=(GEN)nf[1]; disc=(GEN)nf[4];
1435: c = (GEN) gpmalloc((N0+1)*sizeof(long));
1436: c2 = (GEN) gpmalloc((N0+1)*sizeof(long));
1437: c2[0]=c[0]=evaltyp(t_VEC) | evallg(N0+1);
1438: c2[1]=c[1]=1; for (i=2; i<=N0; i++) c[i]=0;
1439: court[2] = 0;
1440:
1441: while (court[2]<=N0)
1442: {
1443: court[2] += *d++; if (! *d) err(primer1);
1444: if (smodis(disc,court[2])) /* court does not divide index */
1445: { vect = (GEN) simplefactmod(pol,court)[1]; lx=lg(vect); }
1446: else
1447: {
1448: p1=primedec(nf,court); lx=lg(p1); vect=cgetg(lx,t_COL);
1449: for (i=1; i<lx; i++) vect[i]=mael(p1,i,4);
1450: }
1451: for (j=1; j<lx; j++)
1452: {
1453: p1=powgi(court, (GEN)vect[j]); /* p1 = court^f */
1454: if (cmpis(p1,N0) <= 0)
1455: {
1456: q=p=p1[2]; limk=N0/q;
1457: for (k=2; k<=N0; k++) c2[k]=c[k];
1458: while (q<=(ulong)N0)
1459: {
1460: for (k=1; k<=limk; k++) c2[k*q] += c[k];
1461: q = smulss(q,p,&rem);
1462: if (rem) break;
1463: limk /= p;
1464: }
1465: p1=c; c=c2; c2=p1;
1466: }
1467: }
1468: avma=av;
1469: if (DEBUGLEVEL>6) fprintferr(" %ld",court[2]);
1470: }
1471: if (DEBUGLEVEL>6) { fprintferr("\n"); flusherr(); }
1472: free(c2); return c;
1473: }
1474:
1475: GEN
1476: dirzetak(GEN nf, GEN b)
1477: {
1478: GEN z,c;
1479: long i;
1480:
1481: if (typ(b)!=t_INT) err(talker,"not an integer type in dirzetak");
1482: if (signe(b)<=0) return cgetg(1,t_VEC);
1483: nf = checknf(nf);
1484: if (is_bigint(b)) err(talker,"too many terms in dirzetak");
1485: c = dirzetak0(nf,itos(b));
1486: i = lg(c); z=cgetg(i,t_VEC);
1487: for (i-- ; i; i--) z[i]=lstoi(c[i]);
1488: free(c); return z;
1489: }
1490:
1491: GEN
1492: initzeta(GEN pol, long prec)
1493: {
1494: GEN nfz,nf,alpha,beta,mu,gr1,gr2,gru,p1,p2,cst,A0,c0,c1,c2,eps,coef;
1495: GEN limx,bnf,resi,zet,C,coeflog,racpi,aij,tabj,colzero, *tabcstn, *tabcstni;
1496: GEN c_even,ck_even,c_odd,ck_odd,serie_even,serie_odd,serie_exp,Pi;
1497: long N0,imin,imax,r1,r2,ru,R,N,i,j,k,n, av,av2,tetpil;
1498: long court[] = {evaltyp(t_INT)|m_evallg(3), evalsigne(1)|evallgefint(3),0};
1499: stackzone *zone, *zone0, *zone1;
1500:
1501: /*************** Calcul du residu et des constantes ***************/
1502: eps=gmul2n(gun,-bit_accuracy(prec)-6); p1=dbltor(0.5);
1503: nfz=cgetg(10,t_VEC);
1504: bnf=buchinit(pol,p1,p1,prec+1); prec=(prec<<1)-1;
1505: bnf = checkbnf_discard(bnf);
1506: Pi = mppi(prec); racpi=gsqrt(Pi,prec);
1507:
1508: /* Nb de classes et regulateur */
1509: nf=(GEN)bnf[7]; N=degpol(nf[1]);
1510: r1 = nf_get_r1(nf); r2 = (N-r1)>>1;
1511: gr1=gmael(nf,2,1); gr2=gmael(nf,2,2);
1512: ru=r1+r2; R=ru+2;
1513: av=avma; p1=(GEN)bnf[8]; p2 = gmul(gmul2n(gmael(p1,1,1),r1), (GEN)p1[2]);
1514: tetpil = avma; resi=gerepile(av,tetpil,gdiv(p2, gmael(p1,4,1)));
1515:
1516: /* Calcul de N0 */
1517: cst = cgetr(prec); av = avma;
1518: mu = gadd(gmul2n(gr1,-1),gr2);
1519: alpha = gmul2n(stoi(ru+1),-1);
1520: beta = gpui(gdeux,gmul2n(gr1,-1),DEFAULTPREC);
1521: A0 = gmul2n(gpowgs(mu,R),r1);
1522: A0 = gmul(A0,gpowgs(gmul2n(Pi,1),1-ru));
1523: A0 = gsqrt(A0,DEFAULTPREC);
1524:
1525: c1 = gmul(mu,gpui(beta,ginv(mu),DEFAULTPREC));
1526: c0 = gdiv(gmul(A0,gpowgs(gmul2n(Pi,1),ru-1)),mu);
1527: c0 = gmul(c0,gpui(c1,gneg_i(alpha),DEFAULTPREC));
1528: c2 = gdiv(alpha,mu);
1529:
1530: p1 = glog(gdiv(c0,eps),DEFAULTPREC);
1531: limx = gdiv(gsub(glog(p1,DEFAULTPREC),glog(c1,DEFAULTPREC)),
1532: gadd(c2,gdiv(p1,mu)));
1533: limx = gmul(gpui(gdiv(c1,p1),mu,DEFAULTPREC),
1534: gadd(gun,gmul(alpha,limx)));
1535: p1 = gsqrt(absi((GEN)nf[3]),prec);
1536: p2 = gmul2n(gpowgs(racpi,N),r2);
1537: gaffect(gdiv(p1,p2), cst);
1538:
1539: av = avma; p1 = gfloor(gdiv(cst,limx)); N0 = p1[2];
1540: if (is_bigint(p1) || N0 > 10000000)
1541: err(talker,"discriminant too large for initzeta, sorry");
1542: if (DEBUGLEVEL>=2)
1543: { fprintferr("\ninitzeta:\nN0 = %ld\n",N0); flusherr(); timer2(); }
1544:
1545: /* Calcul de imax */
1546:
1547: imin=1; imax=1400;
1548: p1 = gmul(gpowgs(gmul2n(racpi,1),r2),gpowgs(stoi(5),r1));
1549: p1 = gdiv(p1,gmul(gmul(gsqrt(limx,DEFAULTPREC),gmul2n(eps,4)),
1550: gpowgs(racpi,3)));
1551: while (imax-imin >= 4)
1552: {
1553: long itest = (imax+imin)>>1;
1554: p2 = gmul(gpowgs(mpfactr(itest,DEFAULTPREC),r2),gpowgs(limx,itest));
1555: p2 = gmul(p2,gpowgs(mpfactr(itest/2,DEFAULTPREC),r1));
1556: if (gcmp(p2,p1) >= 0) imax=itest; else imin=itest;
1557: }
1558: imax -= (imax & 1); avma = av;
1559: if (DEBUGLEVEL>=2) { fprintferr("imax = %ld\n",imax); flusherr(); }
1560: /* Tableau des i/cst (i=1 a N0) */
1561:
1562: i = prec*N0;
1563: zone = switch_stack(NULL,i + 2*(N0+1) + 6*prec);
1564: zone1 = switch_stack(NULL,2*i);
1565: zone0 = switch_stack(NULL,2*i);
1566: switch_stack(zone,1);
1567: tabcstn = (GEN*) cgetg(N0+1,t_VEC);
1568: tabcstni = (GEN*) cgetg(N0+1,t_VEC);
1569: p1 = ginv(cst);
1570: for (i=1; i<=N0; i++) { tabcstni[i] = gun; tabcstn[i] = mulsr(i,p1); }
1571: switch_stack(zone,0);
1572:
1573: /********** Calcul des coefficients a(i,j) independants de s **********/
1574:
1575: zet=cgetg(R,t_VEC); zet[1] = lmpeuler(prec);
1576: for (i=2; i<R; i++) zet[i] = (long)gzeta(stoi(i),prec);
1577:
1578: aij=cgetg(imax+1,t_VEC);
1579: for (i=1; i<=imax; i++) aij[i] = lgetg(R,t_VEC);
1580:
1581: c_even = realun(prec);
1582: c_even = gmul2n(c_even,r1);
1583: c_odd = gmul(c_even,gpowgs(racpi,r1));
1584: if (ru&1) c_odd=gneg_i(c_odd);
1585: ck_even=cgetg(R,t_VEC); ck_odd=cgetg(r2+2,t_VEC);
1586: for (k=1; k<R; k++)
1587: {
1588: ck_even[k]=lmul((GEN)zet[k],gadd(gr2,gmul2n(gr1,-k)));
1589: if (k&1) ck_even[k]=lneg((GEN)ck_even[k]);
1590: }
1591: gru=stoi(ru);
1592: for (k=1; k<=r2+1; k++)
1593: {
1594: ck_odd[k]=lmul((GEN)zet[k], gsub(gru, gmul2n(gr1,-k)));
1595: if (k&1) ck_odd[k]=lneg((GEN)ck_odd[k]);
1596: ck_odd[k]=ladd(gru,(GEN)ck_odd[k]);
1597: }
1598: ck_odd[1]=lsub((GEN)ck_odd[1],gmul(gr1,glog(gdeux,prec)));
1599: serie_even =cgetg(ru+3,t_SER); serie_odd=cgetg(r2+3,t_SER);
1600: serie_even[1] = serie_odd[1] = evalsigne(1)+evalvalp(1);
1601: i=0;
1602:
1603: while (i<imax/2)
1604: {
1605: for (k=1; k<R; k++)
1606: serie_even[k+1]=ldivgs((GEN)ck_even[k],k);
1607: serie_exp=gmul(c_even,gexp(serie_even,0));
1608: p1=(GEN)aij[2*i+1];
1609: for (j=1; j<R; j++) p1[j]=serie_exp[ru+3-j];
1610:
1611: for (k=1; k<=r2+1; k++)
1612: serie_odd[k+1]=ldivgs((GEN)ck_odd[k],k);
1613: serie_exp=gmul(c_odd,gexp(serie_odd,0));
1614: p1=(GEN)aij[2*i+2];
1615: for (j=1; j<=r2+1; j++) p1[j]=serie_exp[r2+3-j];
1616: for ( ; j<R; j++) p1[j]=zero;
1617: i++;
1618:
1619: c_even = gdiv(c_even,gmul(gpowgs(stoi(i),ru),gpowgs(stoi(2*i-1),r2)));
1620: c_odd = gdiv(c_odd, gmul(gpowgs(stoi(i),r2),gpowgs(stoi(2*i+1),ru)));
1621: c_even = gmul2n(c_even,-r2);
1622: c_odd = gmul2n(c_odd,r1-r2);
1623: if (r1&1) { c_even=gneg_i(c_even); c_odd=gneg_i(c_odd); }
1624: p1 = gr2; p2 = gru;
1625: for (k=1; k<R; k++)
1626: {
1627: p1=gdivgs(p1,2*i-1); p2=gdivgs(p2,2*i);
1628: ck_even[k] = ladd((GEN)ck_even[k], gadd(p1,p2));
1629: }
1630: p1 = gru; p2 = gr2;
1631: for (k=1; k<=r2+1; k++)
1632: {
1633: p1=gdivgs(p1,2*i+1); p2=gdivgs(p2,2*i);
1634: ck_odd[k] = ladd((GEN)ck_odd[k], gadd(p1,p2));
1635: }
1636: }
1637: aij=gerepilecopy(av,aij);
1638: if (DEBUGLEVEL>=2) msgtimer("a(i,j)");
1639: p1=cgetg(5,t_VEC);
1640: p1[1]=lstoi(r1); p1[2]=lstoi(r2); p1[3]=lstoi(imax); p1[4]=(long)bnf;
1641: nfz[1]=(long)p1;
1642: nfz[2]=(long)resi;
1643: nfz[5]=(long)cst;
1644: nfz[6]=llog(cst,prec);
1645: nfz[7]=(long)aij;
1646:
1647: /************* Calcul du nombre d'ideaux de norme donnee *************/
1648: coef = dirzetak0(nf,N0); tabj = cgetg(N0+1,t_MAT);
1649: if (DEBUGLEVEL>=2) msgtimer("coef");
1650: colzero=cgetg(ru+2,t_COL); for (j=1; j<=ru+1; j++) colzero[j]=zero;
1651: for (i=1; i<=N0; i++)
1652: if (coef[i])
1653: {
1654: GEN t = cgetg(ru+2,t_COL);
1655: p1 = glog((GEN)tabcstn[i],prec); setsigne(p1, -signe(p1));
1656: t[1] = lstoi(coef[i]); t[2] = lmul((GEN)t[1],p1);
1657: for (j=2; j<=ru; j++)
1658: {
1659: long av2 = avma; p2 = gmul((GEN)t[j],p1);
1660: t[j+1] = (long)gerepileuptoleaf(av2, divrs(p2,j));
1661: }
1662: /* tabj[n,j]=coef(n)*ln(c/n)^(j-1)/(j-1)! */
1663: tabj[i] = (long)t;
1664: }
1665: else tabj[i]=(long)colzero;
1666: if (DEBUGLEVEL>=2) msgtimer("a(n)");
1667:
1668: coeflog=cgetg(N0+1,t_VEC); coeflog[1]=zero;
1669: for (i=2; i<=N0; i++)
1670: if (coef[i])
1671: {
1672: court[2]=i; p1=glog(court,prec);
1673: setsigne(p1,-1); coeflog[i]=(long)p1;
1674: }
1675: else coeflog[i] = zero;
1676: if (DEBUGLEVEL>=2) msgtimer("log(n)");
1677:
1678: nfz[3]=(long)tabj;
1679: p1 = cgetg(N0+1,t_VECSMALL);
1680: for (i=1; i<=N0; i++) p1[i] = coef[i];
1681: nfz[8]=(long)p1;
1682: nfz[9]=(long)coeflog;
1683:
1684: /******************** Calcul des coefficients Cik ********************/
1685:
1686: C = cgetg(ru+1,t_MAT);
1687: for (k=1; k<=ru; k++) C[k] = lgetg(imax+1,t_COL);
1688: av2 = avma;
1689: for (i=1; i<=imax; i++)
1690: {
1691: stackzone *z;
1692: for (k=1; k<=ru; k++)
1693: {
1694: p1 = NULL;
1695: for (n=1; n<=N0; n++)
1696: if (coef[n])
1697: for (j=1; j<=ru-k+1; j++)
1698: {
1699: p2 = gmul(tabcstni[n],
1700: gmul(gmael(aij,i,j+k), gmael(tabj,n,j)));
1701: p1 = p1? gadd(p1,p2): p2;
1702: }
1703: coeff(C,i,k) = p1? (long)gerepileupto(av2,p1): zero;
1704: av2 = avma;
1705: }
1706: /* use a parallel stack */
1707: z = i&1? zone1: zone0;
1708: switch_stack(z, 1);
1709: for (n=1; n<=N0; n++)
1710: if (coef[n]) tabcstni[n] = mpmul(tabcstni[n],tabcstn[n]);
1711: /* come back */
1712: switch_stack(z, 0);
1713: }
1714: nfz[4] = (long) C;
1715: if (DEBUGLEVEL>=2) msgtimer("Cik");
1716: gunclone(aij);
1717: free((void*)zone); free((void*)zone1); free((void*)zone0);
1718: free((void*)coef); return nfz;
1719: }
1720:
1721: GEN
1722: gzetakall(GEN nfz, GEN s, long flag, long prec2)
1723: {
1724: GEN resi,C,cst,cstlog,coeflog,cs,coef;
1725: GEN lambd,gammas,gammaunmoins,gammas2,gammaunmoins2,var1,var2;
1726: GEN p1,unmoins,gexpro,gar,val,valm,valk,valkm;
1727: long ts = typ(s), r1,r2,ru,imax,i,j,k,N0,sl,prec,bigprec, av = avma;
1728:
1729: if (typ(nfz)!=t_VEC || lg(nfz)!=10 || typ(nfz[1]) != t_VEC)
1730: err(talker,"not a zeta number field in zetakall");
1731: if (! is_intreal_t(ts) && ts != t_COMPLEX && ! is_frac_t(ts))
1732: err(typeer,"gzetakall");
1733: resi=(GEN)nfz[2]; C=(GEN)nfz[4]; cst=(GEN)nfz[5];
1734: cstlog=(GEN)nfz[6]; coef=(GEN)nfz[8]; coeflog=(GEN)nfz[9];
1735: r1 = itos(gmael(nfz,1,1));
1736: r2 = itos(gmael(nfz,1,2)); ru = r1+r2;
1737: imax = itos(gmael(nfz,1,3)); N0 = lg(coef)-1;
1738: bigprec = precision(cst); prec = prec2+1;
1739:
1740: if (ts==t_COMPLEX && gcmp0(gimag(s))) { s=greal(s); ts = typ(s); }
1741: if (ts==t_REAL && !signe(gfrac(s))) { s=mptrunc(s); ts = t_INT; }
1742: if (ts==t_INT)
1743: {
1744: sl=itos(s);
1745: if (sl==1) err(talker,"s = 1 is a pole (gzetakall)");
1746: if (sl==0)
1747: {
1748: avma = av;
1749: if (flag) err(talker,"s = 0 is a pole (gzetakall)");
1750: if (ru == 1) return gneg(r1? ghalf: resi);
1751: return gzero;
1752: }
1753: if (sl<0 && (r2 || !odd(sl)))
1754: {
1755: if (!flag) return gzero;
1756: s = subsi(1,s); sl = 1-sl;
1757: }
1758: unmoins=subsi(1,s);
1759: lambd = gdiv(resi, mulis(s,sl-1));
1760: gammas2=ggamma(gmul2n(s,-1),prec);
1761: gar=gpowgs(gammas2,r1);
1762: cs=gexp(gmul(cstlog,s),prec);
1763: val=s; valm=unmoins;
1764: if (sl < 0) /* r2 = 0 && odd(sl) */
1765: {
1766: gammaunmoins2=ggamma(gmul2n(unmoins,-1),prec);
1767: var1=var2=gun;
1768: for (i=2; i<=N0; i++)
1769: if (coef[i])
1770: {
1771: gexpro=gexp(gmul((GEN)coeflog[i],s),bigprec);
1772: var1 = gadd(var1,gmulsg(coef[i],gexpro));
1773: var2 = gadd(var2,gdivsg(coef[i],gmulsg(i,gexpro)));
1774: }
1775: lambd=gadd(lambd,gmul(gmul(var1,cs),gar));
1776: lambd=gadd(lambd,gmul(gmul(var2,gdiv(cst,cs)),
1777: gpowgs(gammaunmoins2,r1)));
1778: for (i=1; i<=imax; i+=2)
1779: {
1780: valk = val;
1781: valkm = valm;
1782: for (k=1; k<=ru; k++)
1783: {
1784: p1 = gcoeff(C,i,k);
1785: lambd = gsub(lambd,gdiv(p1,valk )); valk = mulii(val,valk);
1786: lambd = gsub(lambd,gdiv(p1,valkm)); valkm = mulii(valm,valkm);
1787: }
1788: val = addis(val, 2);
1789: valm = addis(valm,2);
1790: }
1791: }
1792: else
1793: {
1794: GEN tabj=(GEN)nfz[3], aij=(GEN)nfz[7];
1795:
1796: gar = gmul(gar,gpowgs(ggamma(s,prec),r2));
1797: var1=var2=gzero;
1798: for (i=1; i<=N0; i++)
1799: if (coef[i])
1800: {
1801: gexpro=gexp(gmul((GEN)coeflog[i],s),bigprec);
1802: var1 = gadd(var1,gmulsg(coef[i],gexpro));
1803: if (sl <= imax)
1804: {
1805: p1=gzero;
1806: for (j=1; j<=ru+1; j++)
1807: p1 = gadd(p1, gmul(gmael(aij,sl,j), gmael(tabj,i,j)));
1808: var2=gadd(var2,gdiv(p1,gmulsg(i,gexpro)));
1809: }
1810: }
1811: lambd=gadd(lambd,gmul(gmul(var1,cs),gar));
1812: lambd=gadd(lambd,gmul(var2,gdiv(cst,cs)));
1813: for (i=1; i<=imax; i++)
1814: {
1815: valk = val;
1816: valkm = valm;
1817: if (i == sl)
1818: for (k=1; k<=ru; k++)
1819: {
1820: p1 = gcoeff(C,i,k);
1821: lambd = gsub(lambd,gdiv(p1,valk)); valk = mulii(val,valk);
1822: }
1823: else
1824: for (k=1; k<=ru; k++)
1825: {
1826: p1 = gcoeff(C,i,k);
1827: lambd = gsub(lambd,gdiv(p1,valk )); valk = mulii(val,valk);
1828: lambd = gsub(lambd,gdiv(p1,valkm)); valkm = mulii(valm,valkm);
1829: }
1830: val = addis(val,1);
1831: valm = addis(valm,1);
1832: }
1833: }
1834: }
1835: else
1836: {
1837: GEN Pi = mppi(prec);
1838: if (is_frac_t(ts))
1839: s = gmul(s, realun(bigprec));
1840: else
1841: s = gprec_w(s, bigprec);
1842:
1843: unmoins = gsub(gun,s);
1844: lambd = gdiv(resi,gmul(s,gsub(s,gun)));
1845: gammas = ggamma(s,prec);
1846: gammas2= ggamma(gmul2n(s,-1),prec);
1847: gar = gmul(gpowgs(gammas,r2),gpowgs(gammas2,r1));
1848: cs = gexp(gmul(cstlog,s),prec);
1849: var1 = gmul(Pi,s);
1850: gammaunmoins = gdiv(Pi,gmul(gsin(var1,prec),gammas));
1851: gammaunmoins2= gdiv(gmul(gmul(gsqrt(Pi,prec),gpui(gdeux,gsub(s,gun),prec)),
1852: gammas2),
1853: gmul(gcos(gmul2n(var1,-1),prec),gammas));
1854: var1 = var2 = gun;
1855: for (i=2; i<=N0; i++)
1856: if (coef[i])
1857: {
1858: gexpro = gexp(gmul((GEN)coeflog[i],s),bigprec);
1859: var1 = gadd(var1,gmulsg(coef[i], gexpro));
1860: var2 = gadd(var2,gdivsg(coef[i], gmulsg(i,gexpro)));
1861: }
1862: lambd = gadd(lambd,gmul(gmul(var1,cs),gar));
1863: lambd = gadd(lambd,gmul(gmul(gmul(var2,gdiv(cst,cs)),
1864: gpowgs(gammaunmoins,r2)),
1865: gpowgs(gammaunmoins2,r1)));
1866: val = s;
1867: valm = unmoins;
1868: for (i=1; i<=imax; i++)
1869: {
1870: valk = val;
1871: valkm = valm;
1872: for (k=1; k<=ru; k++)
1873: {
1874: p1 = gcoeff(C,i,k);
1875: lambd = gsub(lambd,gdiv(p1,valk )); valk = gmul(val, valk);
1876: lambd = gsub(lambd,gdiv(p1,valkm)); valkm = gmul(valm,valkm);
1877: }
1878: if (r2)
1879: {
1880: val = gadd(val, gun);
1881: valm = gadd(valm,gun);
1882: }
1883: else
1884: {
1885: val = gadd(val, gdeux);
1886: valm = gadd(valm,gdeux); i++;
1887: }
1888: }
1889: }
1890: if (!flag) lambd = gdiv(lambd,gmul(gar,cs)); /* zetak */
1891: return gerepileupto(av, gprec_w(lambd, prec2));
1892: }
1893:
1894: GEN
1895: gzetak(GEN nfz, GEN s, long prec)
1896: {
1897: return gzetakall(nfz,s,0,prec);
1898: }
1899:
1900: GEN
1901: glambdak(GEN nfz, GEN s, long prec)
1902: {
1903: return gzetakall(nfz,s,1,prec);
1904: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>