Annotation of OpenXM_contrib/pari-2.2/src/basemath/base5.c, Revision 1.1.1.1
1.1 noro 1: /* $Id: base5.c,v 1.17 2001/10/01 12:11:29 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: /* BASIC NF OPERATIONS */
19: /* (continued 2) */
20: /* */
21: /*******************************************************************/
22: #include "pari.h"
23: GEN mat_to_vecpol(GEN x, long v);
24:
25: GEN
26: matbasistoalg(GEN nf,GEN x)
27: {
28: long i,j,lx,li;
29: GEN p1,z;
30:
31: if (typ(x)!=t_MAT)
32: err(talker,"argument must be a matrix in matbasistoalg");
33: lx=lg(x); z=cgetg(lx,t_MAT); if (lx==1) return z;
34:
35: li=lg(x[1]);
36: for (j=1; j<lx; j++)
37: {
38: p1=cgetg(li,t_COL); z[j]=(long)p1;
39: for (i=1; i<li; i++) p1[i]=(long)basistoalg(nf,gcoeff(x,i,j));
40: }
41: return z;
42: }
43:
44: GEN
45: matalgtobasis(GEN nf,GEN x)
46: {
47: long i,j,lx,li;
48: GEN p1,z;
49:
50: if (typ(x)!=t_MAT)
51: err(talker,"argument must be a matrix in matalgtobasis");
52: lx=lg(x); z=cgetg(lx,t_MAT); if (lx==1) return z;
53:
54: li=lg(x[1]);
55: for (j=1; j<lx; j++)
56: {
57: p1=cgetg(li,t_COL); z[j]=(long)p1;
58: for (i=1; i<li; i++) p1[i]=(long)algtobasis(nf,gcoeff(x,i,j));
59: }
60: return z;
61: }
62:
63: static GEN
64: rnfmakematrices(GEN rnf)
65: {
66: long i,j,k,n,r1,r2,ru,ruk,r1rel,r2rel;
67: GEN nf,pol,rac,base,base1,racnf,sig,vecmat,vecM,vecMC,vecT2,rack;
68: GEN M,p2,p3,MC,sigk,T2,T,p1,MD,TI,MDI;
69:
70: nf=(GEN)rnf[10]; racnf=(GEN)nf[6]; pol=(GEN)rnf[1];
71: n=degpol(pol);
72: base=(GEN)rnf[7]; base1=(GEN)base[1]; rac=(GEN)rnf[6]; sig=(GEN)rnf[2];
73: r1 = nf_get_r1(nf);
74: r2 = nf_get_r2(nf); ru = r1+r2;
75: vecmat=cgetg(8,t_VEC);
76: vecM=cgetg(ru+1,t_VEC); vecmat[1]=(long)vecM;
77: vecMC=cgetg(ru+1,t_VEC); vecmat[2]=(long)vecMC;
78: vecT2=cgetg(ru+1,t_VEC); vecmat[3]=(long)vecT2;
79: for (k=1; k<=ru; k++)
80: {
81: rack=(GEN)rac[k]; ruk=lg(rack)-1;
82: M=cgetg(n+1,t_MAT); vecM[k]=(long)M;
83: for (j=1; j<=n; j++)
84: {
85: p2=cgetg(ruk+1,t_COL); M[j]=(long)p2; p3=lift((GEN)base1[j]);
86: p3=gsubst(p3,varn(nf[1]),(GEN)racnf[k]);
87: for (i=1; i<=ruk; i++) p2[i]=lsubst(p3,varn(rnf[1]),(GEN)rack[i]);
88: }
89: MC=gconj(gtrans(M)); vecMC[k]=(long)MC;
90: if (k<=r1)
91: {
92: sigk=(GEN)sig[k]; r1rel=itos((GEN)sigk[1]); r2rel=itos((GEN)sigk[2]);
93: if (r1rel+r2rel != lg(MC)-1) err(talker,"bug in rnfmakematrices");
94: for (j=r1rel+1; j<=r1rel+r2rel; j++) MC[j]=lmul2n((GEN)MC[j],1);
95: }
96: T2=gmul(MC,M); vecT2[k]=(long)T2;
97: }
98: T=cgetg(n+1,t_MAT); vecmat[4]=(long)T;
99: for (j=1; j<=n; j++)
100: {
101: p1=cgetg(n+1,t_COL); T[j]=(long)p1;
102: for (i=1; i<=n; i++)
103: p1[i]=ltrace(gmodulcp(gmul((GEN)base1[i],(GEN)base1[j]),pol));
104: }
105: MD=cgetg(1,t_MAT); vecmat[5]=(long)MD; /* matrice de la differente */
106: TI=cgetg(1,t_MAT); vecmat[6]=(long)TI; /* matrice .... ? */
107: MDI=cgetg(1,t_MAT); vecmat[7]=(long)MDI; /* matrice .... ? */
108: return vecmat;
109: }
110:
111: GEN
112: rnfinitalg(GEN nf,GEN pol,long prec)
113: {
114: ulong av = avma;
115: long m,n,r1,r2,vnf,i,j,k,vpol,v1,r1j,r2j,lfac,degabs;
116: GEN RES,sig,rac,p1,p2,liftpol,delta,RAC,ro,p3,bas;
117: GEN f,f2,fac,fac1,fac2,id,p4,p5;
118:
119: if (typ(pol)!=t_POL) err(notpoler,"rnfinitalg");
120: nf=checknf(nf); n=degpol(pol); vpol=varn(pol);
121: vnf=0;
122: for (i=0; i<=n; i++)
123: {
124: long tp1;
125:
126: p1=(GEN)pol[i+2];
127: tp1=typ(p1);
128: if (! is_const_t(tp1))
129: {
130: if (tp1!=t_POLMOD) err(typeer,"rnfinitalg");
131: p1 = checknfelt_mod(nf, p1, "rnfinitalg");
132: if (! is_const_t(typ(p1)))
133: {
134: v1=varn(p1);
135: if (vnf && vnf!=v1) err(talker,"different variables in rnfinitalg");
136: if (!vnf) vnf=v1;
137: }
138: }
139: }
140: if (!vnf) vnf=varn(nf[1]);
141: if (vpol>=vnf)
142: err(talker,"main variable must be of higher priority in rnfinitalg");
143: RES=cgetg(12,t_VEC);
144: RES[1]=(long)pol;
145: m=degpol(nf[1]); degabs=n*m;
146: r1 = nf_get_r1(nf); r2 = (m-r1) >> 1;
147: sig=cgetg(r1+r2+1,t_VEC); RES[2]=(long)sig;
148: rac=(GEN)nf[6]; liftpol=lift(pol);
149: RAC=cgetg(r1+r2+1,t_VEC); RES[6]=(long)RAC;
150: for (j=1; j<=r1; j++)
151: {
152: p1=gsubst(liftpol,vnf,(GEN)rac[j]);
153: ro=roots(p1,prec);
154: r1j=0;
155: while (r1j<n && gcmp0(gimag((GEN)ro[r1j+1]))) r1j++;
156: p2=cgetg(3,t_VEC); p2[1]=lstoi(r1j); p2[2]=lstoi(r2j=((n-r1j)>>1));
157: sig[j]=(long)p2;
158: p3=cgetg(r1j+r2j+1,t_VEC);
159: for (i=1; i<=r1j; i++) p3[i]=lreal((GEN)ro[i]);
160: for (; i<=r1j+r2j; i++) p3[i]=(long)ro[(i<<1)-r1j];
161: RAC[j]=(long)p3;
162: }
163: for (; j<=r1+r2; j++)
164: {
165: p2=cgetg(3,t_VEC); p2[1]=zero; p2[2]=lstoi(n); sig[j]=(long)p2;
166: p1=gsubst(liftpol,vnf,(GEN)rac[j]);
167: RAC[j]=(long)roots(p1,prec);
168: }
169: p1 = rnfpseudobasis(nf,pol);
170:
171: delta = cgetg(3,t_VEC);
172: delta[1]=p1[3];
173: delta[2]=p1[4];
174: RES[3]=(long)delta;
175: p2 = matbasistoalg(nf,(GEN)p1[1]);
176: bas = cgetg(3,t_VEC);
177: bas[1]=(long)mat_to_vecpol(p2,vpol);
178: bas[2]=(long)p1[2];
179: RES[7]=(long)bas;
180: RES[8]=linvmat(p2);
181:
182: f2=idealdiv(nf,discsr(pol),(GEN)p1[3]);
183: fac=idealfactor(nf,f2);
184: fac1=(GEN)fac[1]; fac2=(GEN)fac[2]; lfac=lg(fac1)-1;
185: f=idmat(m);
186: for (i=1; i<=lfac; i++)
187: {
188: if (mpodd((GEN)fac2[i])) err(bugparier,"rnfinitalg (odd exponent)");
189: f=idealmul(nf,f,idealpow(nf,(GEN)fac1[i],gmul2n((GEN)fac2[i],-1)));
190: }
191: RES[4]=(long)f;
192: RES[10]=(long)nf;
193: RES[5]=(long)rnfmakematrices(RES);
194: if (DEBUGLEVEL>1) msgtimer("matrices");
195: RES[9]=lgetg(1,t_VEC); /* table de multiplication */
196: p2=cgetg(6,t_VEC); RES[11]=(long)p2;
197: p1=rnfequation2(nf,pol); for (i=1; i<=3; i++) p2[i]=p1[i];
198: p4=cgetg(degabs+1,t_MAT);
199: for (i=1; i<=n; i++)
200: { /* removing denominators speeds up multiplication */
201: GEN cop3,com, om = rnfelementreltoabs(RES,gmael(bas,1,i));
202:
203: if (DEBUGLEVEL>1) msgtimer("i = %ld",i);
204: com = content(om); om = gdiv(om,com);
205: id=gmael(bas,2,i);
206: for (j=1; j<=m; j++)
207: {
208: p5=cgetg(degabs+1,t_COL); p4[(i-1)*m+j]=(long)p5;
209: p1=gmul((GEN)nf[7],(GEN)id[j]);
210: p3 = gsubst(p1,varn(nf[1]), (GEN)p2[2]);
211: cop3 = content(p3); p3 = gdiv(p3,cop3);
212: p3 = gmul(gmul(com,cop3), lift_intern(gmul(om,p3)));
213:
214: for (k=1; k<lgef(p3)-1; k++) p5[k]=p3[k+1];
215: for ( ; k<=degabs; k++) p5[k]=zero;
216: }
217: }
218: if (DEBUGLEVEL>1) msgtimer("p4");
219: p3 = denom(p4);
220: p4 = hnfmodid(gmul(p3,p4), p3);
221: if (DEBUGLEVEL>1) msgtimer("hnfmod");
222: for (j=degabs-1; j>0; j--)
223: if (cmpis(gcoeff(p4,j,j),2) > 0)
224: {
225: p1=shifti(gcoeff(p4,j,j),-1);
226: for (k=j+1; k<=degabs; k++)
227: if (cmpii(gcoeff(p4,j,k),p1) > 0)
228: for (i=1; i<=j; i++)
229: coeff(p4,i,k)=lsubii(gcoeff(p4,i,k),gcoeff(p4,i,j));
230: }
231: p4 = gdiv(p4,p3);
232: p2[4]=(long)mat_to_vecpol(p4,vpol);
233: p2[5]=linvmat(p4);
234: return gerepilecopy(av,RES);
235: }
236:
237: GEN
238: rnfbasistoalg(GEN rnf,GEN x)
239: {
240: long tx=typ(x),lx=lg(x),av=avma,tetpil,i,n;
241: GEN p1,z,nf;
242:
243: checkrnf(rnf); nf=(GEN)rnf[10];
244: switch(tx)
245: {
246: case t_VEC:
247: x=gtrans(x); /* fall through */
248: case t_COL:
249: n=lg(x)-1; p1=cgetg(n+1,t_COL);
250: for (i=1; i<=n; i++)
251: {
252: if (typ(x[i])==t_COL) p1[i]=(long)basistoalg(nf,(GEN)x[i]);
253: else p1[i]=x[i];
254: }
255: p1=gmul(gmael(rnf,7,1),p1); tetpil=avma;
256: return gerepile(av,tetpil,gmodulcp(p1,(GEN)rnf[1]));
257:
258: case t_MAT:
259: z=cgetg(lx,tx);
260: for (i=1; i<lx; i++) z[i]=(long)rnfbasistoalg(rnf,(GEN)x[i]);
261: return z;
262:
263: case t_POLMOD:
264: return gcopy(x);
265:
266: default:
267: z=cgetg(3,t_POLMOD); z[1]=lcopy((GEN)rnf[1]);
268: z[2]=lmul(x,polun[varn(rnf[1])]); return z;
269: }
270: }
271:
272: extern long polegal_spec(GEN x, GEN y);
273:
274: /* assume x is a t_POLMOD */
275: GEN
276: lift_to_pol(GEN x)
277: {
278: GEN y = (GEN)x[2];
279: return (typ(y) != t_POL)? gtopoly(y,varn(x[1])): y;
280: }
281:
282: extern GEN mulmat_pol(GEN A, GEN x);
283:
284: GEN
285: rnfalgtobasis(GEN rnf,GEN x)
286: {
287: long av=avma,tx=typ(x), i,lx;
288: GEN z;
289:
290: checkrnf(rnf);
291: switch(tx)
292: {
293: case t_VEC: case t_COL: case t_MAT:
294: lx = lg(x); z = cgetg(lx,tx);
295: for (i=1; i<lx; i++) z[i]=(long)rnfalgtobasis(rnf,(GEN)x[i]);
296: return z;
297:
298: case t_POLMOD:
299: if (!polegal_spec((GEN)rnf[1],(GEN)x[1]))
300: err(talker,"not the same number field in rnfalgtobasis");
301: x = lift_to_pol(x); /* fall through */
302: case t_POL:
303: { /* cf algtobasis_intern */
304: GEN P = (GEN)rnf[1];
305: long N = degpol(P);
306: if (degpol(x) >= N) x = gres(x,P);
307: return gerepileupto(av, mulmat_pol((GEN)rnf[8], x));
308: }
309: }
310: return gscalcol(x, degpol(rnf[1]));
311: }
312:
313: /* x doit etre un polymod ou un polynome ou un vecteur de tels objets... */
314: GEN
315: rnfelementreltoabs(GEN rnf,GEN x)
316: {
317: long av=avma,tx,i,lx,va,tp3;
318: GEN z,p1,p2,p3,polabs,teta,alpha,s,k;
319:
320: checkrnf(rnf); tx=typ(x); lx=lg(x); va=varn((GEN)rnf[1]);
321: switch(tx)
322: {
323: case t_VEC: case t_COL: case t_MAT:
324: z=cgetg(lx,tx);
325: for (i=1; i<lx; i++) z[i]=(long)rnfelementreltoabs(rnf,(GEN)x[i]);
326: return z;
327:
328: case t_POLMOD:
329: x=lift_to_pol(x); /* fall through */
330: case t_POL:
331: if (gvar(x) > va) x = scalarpol(x,va);
332: p1=(GEN)rnf[11]; polabs=(GEN)p1[1]; alpha=(GEN)p1[2]; k=(GEN)p1[3];
333: if (typ(alpha) == t_INT)
334: teta=gmodulcp(gsub(polx[va],gmul(k,alpha)),polabs);
335: else
336: teta=gmodulcp(gsub(polx[va],gmul(k,(GEN)alpha[2])),polabs);
337: s=gzero;
338: for (i=lgef(x)-1; i>1; i--)
339: {
340: p3=(GEN)x[i]; tp3=typ(p3);
341: if (is_const_t(tp3)) p2 = p3;
342: else
343: switch(tp3)
344: {
345: case t_POLMOD:
346: p3 = (GEN)p3[2]; /* fall through */
347: case t_POL:
348: p2 = poleval(p3,alpha);
349: break;
350: default: err(talker, "incorrect data in rnfelementreltoabs");
351: return NULL; /* not reached */
352: }
353: s=gadd(p2,gmul(teta,s));
354: }
355: return gerepileupto(av,s);
356:
357: default: return gcopy(x);
358: }
359: }
360:
361: GEN
362: rnfelementabstorel(GEN rnf,GEN x)
363: {
364: long av=avma,tx,i,lx;
365: GEN z,p1,s,tetap,k,nf;
366:
367: checkrnf(rnf); tx=typ(x); lx=lg(x);
368: switch(tx)
369: {
370: case t_VEC: case t_COL: case t_MAT:
371: z=cgetg(lx,tx);
372: for (i=1; i<lx; i++) z[i]=(long)rnfelementabstorel(rnf,(GEN)x[i]);
373: return z;
374:
375: case t_POLMOD:
376: x=lift_to_pol(x); /* fall through */
377: case t_POL:
378: p1=(GEN)rnf[11]; k=(GEN)p1[3]; nf=(GEN)rnf[10];
379: tetap=gmodulcp(gadd(polx[varn(rnf[1])],
380: gmul(k,gmodulcp(polx[varn(nf[1])],(GEN)nf[1]))),(GEN)rnf[1]);
381: s=gzero;
382: for (i=lgef(x)-1; i>1; i--) s=gadd((GEN)x[i],gmul(tetap,s));
383: return gerepileupto(av,s);
384:
385: default: return gcopy(x);
386: }
387: }
388:
389: /* x doit etre un polymod ou un polynome ou un vecteur de tels objets... */
390: GEN
391: rnfelementup(GEN rnf,GEN x)
392: {
393: long i,lx,tx;
394: GEN z;
395:
396: checkrnf(rnf); tx=typ(x); lx=lg(x);
397: switch(tx)
398: {
399: case t_VEC: case t_COL: case t_MAT:
400: z=cgetg(lx,tx);
401: for (i=1; i<lx; i++) z[i]=(long)rnfelementup(rnf,(GEN)x[i]);
402: return z;
403:
404: case t_POLMOD:
405: x=(GEN)x[2]; /* fall through */
406: case t_POL:
407: return poleval(x,gmael(rnf,11,2));
408:
409: default: return gcopy(x);
410: }
411: }
412:
413: /* x doit etre un polymod ou un polynome ou un vecteur de tels objets..*/
414: GEN
415: rnfelementdown(GEN rnf,GEN x)
416: {
417: ulong av = avma;
418: long i,lx,tx;
419: GEN p1,z;
420:
421: checkrnf(rnf); tx=typ(x); lx=lg(x);
422: switch(tx)
423: {
424: case t_VEC: case t_COL: case t_MAT:
425: z=cgetg(lx,tx);
426: for (i=1; i<lx; i++) z[i]=(long)rnfelementdown(rnf,(GEN)x[i]);
427: return z;
428:
429: case t_POLMOD:
430: x=(GEN)x[2]; /* fall through */
431: case t_POL:
432: if (gcmp0(x)) return gzero;
433:
434: p1=rnfelementabstorel(rnf,x);
435: if (typ(p1)==t_POLMOD && varn(p1[1])==varn(rnf[1])) p1=(GEN)p1[2];
436: if (gvar(p1)>varn(rnf[1])) return gerepilecopy(av,p1);
437: if (lgef(p1)==3) return gerepilecopy(av,(GEN)p1[2]);
438: err(talker,"element is not in the base field in rnfelementdown");
439:
440: default: return gcopy(x);
441: }
442: }
443:
444: /* x est exprime sur la base relative */
445: static GEN
446: rnfprincipaltohermite(GEN rnf,GEN x)
447: {
448: long av=avma,tetpil;
449: GEN nf,bas,bas1,p1,z;
450:
451: x=rnfbasistoalg(rnf,x); nf=(GEN)rnf[10];
452: bas=(GEN)rnf[7]; bas1=(GEN)bas[1];
453: p1=rnfalgtobasis(rnf,gmul(x,gmodulcp(bas1,(GEN)rnf[1])));
454: z=cgetg(3,t_VEC); z[2]=bas[2];
455: settyp(p1,t_MAT); z[1]=(long)matalgtobasis(nf,p1);
456:
457: tetpil=avma;
458: return gerepile(av,tetpil,nfhermite(nf,z));
459: }
460:
461: GEN
462: rnfidealhermite(GEN rnf,GEN x)
463: {
464: long tx=typ(x),lx=lg(x),av=avma,tetpil,i,j,n,m;
465: GEN z,p1,p2,x1,x2,x1j,nf,bas,unnf,zeronf;
466:
467: checkrnf(rnf);
468: n=degpol(rnf[1]); nf=(GEN)rnf[10]; bas=(GEN)rnf[7];
469:
470: switch(tx)
471: {
472: case t_INT: case t_FRAC: case t_FRACN: z=cgetg(3,t_VEC);
473: m=degpol(nf[1]); zeronf=gscalcol_i(gzero,m); unnf=gscalcol_i(gun,m);
474: p1=cgetg(n+1,t_MAT); z[1]=(long)p1;
475: for (j=1; j<=n; j++)
476: {
477: p2=cgetg(n+1,t_COL); p1[j]=(long)p2;
478: for (i=1; i<=n; i++) p2[i]=(i==j)?(long)unnf:(long)zeronf;
479: }
480: z[2]=lmul(x,(GEN)bas[2]); return z;
481:
482: case t_POLMOD: case t_POL:
483: p1=rnfalgtobasis(rnf,x); tetpil=avma;
484: return gerepile(av,tetpil,rnfprincipaltohermite(rnf,p1));
485:
486: case t_VEC:
487: switch(lx)
488: {
489: case 3:
490: x1=(GEN)x[1];
491: if (typ(x1)!=t_MAT || lg(x1) < n+1 || lg(x1[1]) != n+1)
492: err(talker,"incorrect type in rnfidealhermite");
493: p1=cgetg(n+1,t_MAT);
494: for (j=1; j<=n; j++)
495: {
496: p2=cgetg(n+1,t_COL); p1[j]=(long)p2; x1j=(GEN)x1[j];
497: for (i=1; i<=n; i++)
498: {
499: tx = typ(x1j[i]);
500: if (is_const_t(tx)) p2[i] = x1j[i];
501: else
502: switch(tx)
503: {
504: case t_POLMOD: case t_POL:
505: p2[i]=(long)algtobasis(nf,(GEN)x1j[i]); break;
506: case t_COL:
507: p2[i]=x1j[i]; break;
508: default: err(talker,"incorrect type in rnfidealhermite");
509: }
510: }
511: }
512: x2=(GEN)x[2];
513: if (typ(x2)!=t_VEC || lg(x2)!=lg(x1))
514: err(talker,"incorrect type in rnfidealhermite");
515: tetpil=avma; z=cgetg(3,t_VEC); z[1]=lcopy(p1); z[2]=lcopy(x2);
516: z=gerepile(av,tetpil,nfhermite(nf,z));
517: if (lg(z[1]) != n+1)
518: err(talker,"not an ideal in rnfidealhermite");
519: return z;
520:
521: case 6:
522: err(impl,"rnfidealhermite for prime ideals");
523: default:
524: err(typeer,"rnfidealhermite");
525: }
526:
527: case t_COL:
528: if (lx!=(n+1)) err(typeer,"rnfidealhermite");
529: return rnfprincipaltohermite(rnf,x);
530:
531: case t_MAT:
532: return rnfidealabstorel(rnf,x);
533: }
534: err(typeer,"rnfidealhermite");
535: return NULL; /* not reached */
536: }
537:
538: GEN
539: rnfidealnormrel(GEN rnf,GEN id)
540: {
541: long av=avma,i,n;
542: GEN z,id2,nf;
543:
544: checkrnf(rnf);
545: id=rnfidealhermite(rnf,id); id2=(GEN)id[2];
546: n=degpol(rnf[1]); nf=(GEN)rnf[10];
547: if (n==1) { avma=av; return idmat(degpol(nf[1])); }
548: z=(GEN)id2[1]; for (i=2; i<=n; i++) z=idealmul(nf,z,(GEN)id2[i]);
549: return gerepileupto(av,z);
550: }
551:
552: GEN
553: rnfidealnormabs(GEN rnf,GEN id)
554: {
555: long av=avma,i,n;
556: GEN z,id2;
557:
558: checkrnf(rnf);
559: id=rnfidealhermite(rnf,id); id2=(GEN)id[2];
560: n=degpol(rnf[1]);
561: z=gun; for (i=1; i<=n; i++) z=gmul(z,dethnf((GEN)id2[i]));
562: return gerepileupto(av,z);
563: }
564:
565: GEN
566: rnfidealreltoabs(GEN rnf,GEN x)
567: {
568: long av=avma,i,j,k,n,m;
569: GEN nf,basinv,om,id,p1,p2,p3,p4,p5,c;
570:
571: checkrnf(rnf);
572: x = rnfidealhermite(rnf,x);
573: n=degpol(rnf[1]); nf=(GEN)rnf[10]; m=degpol(nf[1]);
574: basinv = gmael(rnf,11,5);
575: p3=cgetg(n*m+1,t_MAT); p2=gmael(rnf,11,2);
576: for (i=1; i<=n; i++)
577: {
578: om=rnfbasistoalg(rnf,gmael(x,1,i)); id=gmael(x,2,i);
579: om=rnfelementreltoabs(rnf,om);
580: for (j=1; j<=m; j++)
581: {
582: p1=gmul((GEN)nf[7],(GEN)id[j]);
583: p4=lift_intern(gmul(om,gsubst(p1,varn(nf[1]),p2)));
584: p5=cgetg(n*m+1,t_COL);
585: for (k=0; k<n*m; k++) p5[k+1]=(long)truecoeff(p4,k);
586: p3[(i-1)*m+j]=(long)p5;
587: }
588: }
589: p1 = gmul(basinv,p3); c = content(p1);
590: p2 = gmael(p1,1,1); /* x \cap Z */
591: if (is_pm1(c)) c = NULL; else { p1 = gdiv(p1, c); p2 = gdiv(p2, c); }
592: p1 = hnfmodid(p1, p2);
593: if (c) p1 = gmul(p1, c);
594: return gerepileupto(av, p1);
595: }
596:
597: GEN
598: rnfidealabstorel(GEN rnf,GEN x)
599: {
600: long av=avma,tetpil,n,m,j,k;
601: GEN nf,basabs,ma,xj,p1,p2,id;
602:
603: checkrnf(rnf); n=degpol(rnf[1]); nf=(GEN)rnf[10]; m=degpol(nf[1]);
604: if (typ(x)!=t_MAT || lg(x)!=(n*m+1) || lg(x[1])!=(n*m+1))
605: err(impl,"rnfidealabstorel for an ideal not in HNF");
606: basabs=gmael(rnf,11,4); ma=cgetg(n*m+1,t_MAT);
607: for (j=1; j<=n*m; j++)
608: {
609: p2=cgetg(n+1,t_COL); ma[j]=(long)p2;
610: xj=gmul(basabs,(GEN)x[j]);
611: xj=lift_intern(rnfelementabstorel(rnf,xj));
612: for (k=0; k<n; k++)
613: p2[k+1]=(long)truecoeff(xj,k);
614: }
615: ma=gmul((GEN)rnf[8],ma);
616: ma=matalgtobasis(nf,ma);
617: p1=cgetg(n*m+1,t_VEC); id=idmat(m);
618: for (j=1; j<=n*m; j++) p1[j]=(long)id;
619: p2=cgetg(3,t_VEC); p2[1]=(long)ma; p2[2]=(long)p1;
620: tetpil=avma; return gerepile(av,tetpil,nfhermite(nf,p2));
621: }
622:
623: GEN
624: rnfidealdown(GEN rnf,GEN x)
625: {
626: long av=avma;
627:
628: checkrnf(rnf); x=rnfidealhermite(rnf,x);
629: return gerepilecopy(av,gmael(x,2,1));
630: }
631:
632: /* lift ideal x to the relative extension, returns a Z-basis */
633: GEN
634: rnfidealup(GEN rnf,GEN x)
635: {
636: long av=avma,tetpil,i,n,m;
637: GEN nf,bas,bas2,p1,p2,zeronf,unnf;
638:
639: checkrnf(rnf);
640: bas=(GEN)rnf[7]; bas2=(GEN)bas[2];
641: n=lg(bas2)-1; nf=(GEN)rnf[10]; m=degpol((GEN)nf[1]);
642: zeronf=zerocol(m); unnf=gscalcol_i(gun,m);
643: p2=cgetg(3,t_VEC); p1=cgetg(n+1,t_VEC);
644: p2[1]=(long)idmat_intern(n,unnf,zeronf);
645: p2[2]=(long)p1;
646: for (i=1; i<=n; i++) p1[i]=(long)idealmul(nf,x,(GEN)bas2[i]);
647: tetpil=avma; return gerepile(av,tetpil,rnfidealreltoabs(rnf,p2));
648: }
649:
650: /* x a relative HNF ---> vector of 2 generators (relative polymods) */
651: GEN
652: rnfidealtwoelement(GEN rnf,GEN x)
653: {
654: long av=avma,tetpil,j;
655: GEN p1,p2,p3,res,polabs,nfabs,z;
656:
657: checkrnf(rnf);
658: res=(GEN)rnf[11]; polabs=(GEN)res[1];
659: nfabs=cgetg(10,t_VEC); nfabs[1]=(long)polabs;
660: for (j=2; j<=9; j++) nfabs[j]=zero;
661: nfabs[7]=(long)lift((GEN)res[4]); nfabs[8]=res[5];
662: p1=rnfidealreltoabs(rnf,x);
663: p2=ideal_two_elt(nfabs,p1);
664: p3=rnfelementabstorel(rnf,gmul((GEN)res[4],(GEN)p2[2]));
665: tetpil=avma; z=cgetg(3,t_VEC); z[1]=lcopy((GEN)p2[1]);
666: z[2]=(long)rnfalgtobasis(rnf,p3);
667: return gerepile(av,tetpil,z);
668: }
669:
670: GEN
671: rnfidealmul(GEN rnf,GEN x,GEN y) /* x et y sous HNF relative uniquement */
672: {
673: long av=avma,tetpil,i,j,n;
674: GEN z,nf,x1,x2,p1,p2,p3,p4,p5,res;
675:
676: z=rnfidealtwoelement(rnf,y);
677: nf=(GEN)rnf[10]; n=degpol(rnf[1]);
678: x=rnfidealhermite(rnf,x);
679: x1=gmodulcp(gmul(gmael(rnf,7,1),matbasistoalg(nf,(GEN)x[1])),(GEN) rnf[1]);
680: x2=(GEN)x[2]; p1=gmul((GEN)z[1],(GEN)x[1]);
681: p2=lift_intern(gmul(rnfbasistoalg(rnf,(GEN)z[2]),x1));
682: p3=cgetg(n+1,t_MAT);
683: for (j=1; j<=n; j++)
684: {
685: p4=cgetg(n+1,t_COL); p3[j]=(long)p4; p5=(GEN)p2[j];
686: for (i=1; i<=n; i++)
687: p4[i]=(long)algtobasis(nf,truecoeff((GEN)p5,i-1));
688: }
689: res=cgetg(3,t_VEC);
690: res[1]=(long)concatsp(p1,p3);
691: res[2]=(long)concatsp(x2,x2);
692: tetpil=avma; return gerepile(av,tetpil,nfhermite(nf,res));
693: }
694:
695: /*********************************************************************/
696: /** **/
697: /** LIBRARY FOR POLYNOMIALS WITH COEFFS. IN Z_K/P **/
698: /** An element in Z_K/P is a t_COL with degree(nf[1]) components. **/
699: /** These are integers modulo the prime p under prime ideal P **/
700: /** (only f(P/p) elements are non zero). These components are **/
701: /** given on the integer basis of K. **/
702: /** **/
703: /*********************************************************************/
704:
705: /* K.B: What follows is not meant to work (yet?) */
706:
707: GEN
708: polnfmulscal(GEN nf,GEN s,GEN x)
709: {
710: long i,lx=lgef(x);
711: GEN z;
712:
713: if (lx<3) return gcopy(x);
714: if (gcmp0(s))
715: {
716: z=cgetg(2,t_POL); z[1]=evallgef(2) | evalvarn(varn(x));
717: return z;
718: }
719: z=cgetg(lx,t_POL); z[1]=x[1];
720: for (i=2; i<lx; i++) z[i]=(long)element_mul(nf,s,(GEN)x[i]);
721: return z;
722: }
723:
724: GEN
725: polnfmul(GEN nf, GEN x, GEN y)
726: {
727: ulong av;
728: long m,i,d,imin,imax,lx,ly,lz;
729: GEN p1,z,zeronf;
730:
731: if (gcmp0(x) || gcmp0(y)) return zeropol(varn(x));
732: m=degpol(nf[1]); av=avma;
733: lx=degpol(x); ly=degpol(y); lz=lx+ly;
734: zeronf=gscalcol_i(gzero,m);
735: z=cgetg(lz+3,t_POL);
736: z[1] = evallgef(lz+3) | evalvarn(x) | evalsigne(1);
737: for (d=0; d<=lz; d++)
738: {
739: p1=zeronf; imin=max(0,d-ly); imax=min(d,lx);
740: for (i=imin; i<=imax; i++)
741: p1=gadd(p1,element_mul(nf,(GEN)x[i+2],(GEN)y[d-i+2]));
742: z[d+2]=(long)p1;
743: }
744: return gerepilecopy(av,z);
745: }
746:
747: /* division euclidienne */
748: GEN
749: polnfdeuc(GEN nf, GEN x, GEN y, GEN *ptr)
750: {
751: long av=avma,m,i,d,tx,lx,ly,lz,fl;
752: GEN z,unnf,lcy,r;
753: GEN *gptr[2];
754:
755: if (gcmp0(y)) err(talker,"division by zero in polnfdiv");
756: lx=lgef(x); ly=lgef(y); lz=lx-ly;
757: if (gcmp0(x) || lz<0) { *ptr=gcopy(x); return zeropol(varn(x)); }
758:
759: m=degpol(nf[1]); unnf=gscalcol_i(gun,m);
760: x=dummycopy(x); y=dummycopy(y);
761: for (i=2; i<lx; i++)
762: {
763: tx=typ(x[i]);
764: if (is_intreal_t(tx) || tx == t_INTMOD || is_frac_t(tx))
765: x[i]=lmul((GEN)x[i],unnf);
766: }
767: for (i=2; i<ly; i++)
768: {
769: tx=typ(y[i]);
770: if (is_intreal_t(tx) || tx == t_INTMOD || is_frac_t(tx))
771: y[i]=lmul((GEN)y[i],unnf);
772: }
773:
774: lz += 3;
775: z=cgetg(lz,t_POL); z[1]=evallgef(lz) | evalvarn(x) | evalsigne(1);
776: lcy=(GEN)y[ly-1];
777: if (gegal(lift(lcy),unnf)) fl=0;
778: else
779: {
780: fl=1; y=polnfmulscal(nf,element_inv(nf,lcy),y);
781: }
782: for (d=lz-1; d>=2; d--)
783: {
784: z[d]=x[d+ly-3];
785: for (i=d; i<d+ly-3; i++)
786: x[i]=lsub((GEN)x[i],element_mul(nf,(GEN)z[d],(GEN)y[i-d-2]));
787: }
788: if (fl) z=polnfmulscal(nf,lcy,z);
789:
790: for(;;)
791: {
792: if (!gcmp0((GEN)x[d]))
793: {
794: r=cgetg(d,t_POL);
795: r[1] = evallgef(d) | evalvarn(varn(x)) | evalsigne(1);
796: for (i=2; i<d; i++) r[i]=x[i];
797: break;
798: }
799: if (d==2) { r = zeropol(varn(x)); break; }
800: d--;
801: }
802: *ptr=r; gptr[0]=ptr; gptr[1]=&z;
803: gerepilemany(av,gptr,2); return z;
804: }
805:
806: GEN
807: polnfpow(GEN nf,GEN x,GEN k)
808: {
809: long s,av=avma,m;
810: GEN y,z;
811:
812: m=degpol(nf[1]);
813: if (typ(k)!=t_INT) err(talker,"not an integer exponent in nfpow");
814: s=signe(k); if (s<0) err(impl,"polnfpow for negative exponents");
815:
816: z=x; y=cgetg(3,t_POL);
817: y[1] = evallgef(3) | evalvarn(varn(x)) | evalsigne(1);
818: y[2] = (long)gscalcol_i(gun,m);
819: for(;;)
820: {
821: if (mpodd(k)) y=polnfmul(nf,z,y);
822: k=shifti(k,-1);
823: if (!signe(k)) { cgiv(k); return gerepileupto(av,y); }
824: z=polnfmul(nf,z,z);
825: }
826: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>