/********************************************************************/ /** **/ /** BIBLIOTHEQUE MATHEMATIQUE **/ /** (deuxieme partie) **/ /** **/ /********************************************************************/ /* $Id: bibli2.c,v 1.1.1.1 1999/09/16 13:47:24 karim Exp $ */ #include "pari.h" /********************************************************************/ /** **/ /** DEVELOPPEMENTS LIMITES **/ /** **/ /********************************************************************/ GEN tayl(GEN x, long v, long precdl) { long tetpil,i,vx = gvar9(x), av=avma; GEN p1,y; if (v <= vx) { long p1[] = { evaltyp(t_SER)|m_evallg(2), 0 }; p1[1] = evalvalp(precdl) | evalvarn(v); return gadd(p1,x); } p1=cgetg(v+2,t_VEC); for (i=0; i1) err(warnmem,"tchebi"); gerepilemanysp(av,tetpil,gptr,2); } } q = addshiftw(gmul2n(p1,1), z, 1); tetpil=avma; setvarn(q,v); return gerepile(av,tetpil,gadd(q,p0)); } /* Legendre polynomial */ /* L0=1; L1=X; (n+1)*L(n+1)=(2*n+1)*X*L(n)-n*L(n-1) */ GEN legendre(long n, long v) { long av,tetpil,m,lim; GEN p0,p1,p2; if (v<0) v = 0; if (n==0) return polun[v]; if (n==1) return polx[v]; p0=polun[v]; av=avma; lim=stack_lim(av,2); p1=gmul2n(polx[v],1); for (m=1; m1) err(warnmem,"legendre"); p0=gcopy(p0); gptr[0]=&p0; gptr[1]=&p1; gerepilemanysp(av,tetpil,gptr,2); } } tetpil=avma; return gerepile(av,tetpil,gmul2n(p1,-n)); } /* cyclotomic polynomial */ GEN cyclo(long n, long v) { long av=avma,tetpil,d,q,m; GEN yn,yd; if (n<=0) err(arither2); if (v<0) v = 0; yn = yd = polun[0]; for (d=1; d*d<=n; d++) { if (n%d) continue; q=n/d; m = mu(stoi(q)); if (m) { /* y *= (x^d - 1) */ if (m>0) yn = addshiftw(yn, gneg(yn), d); else yd = addshiftw(yd, gneg(yd), d); } if (q==d) break; m = mu(stoi(d)); if (m) { /* y *= (x^q - 1) */ if (m>0) yn = addshiftw(yn, gneg(yn), q); else yd = addshiftw(yd, gneg(yd), q); } } tetpil=avma; yn = gerepile(av,tetpil,gdeuc(yn,yd)); setvarn(yn,v); return yn; } /* compute prod (L*x ± a[i]) */ GEN roots_to_pol_intern(GEN L, GEN a, long v, int plus) { long i,k,lx = lg(a), code; GEN p1,p2; if (lx == 1) return polun[v]; p1 = cgetg(lx, t_VEC); code = evalsigne(1)|evalvarn(v)|evallgef(5); for (k=1,i=1; i>= 1; if (n == 1) err(talker,"degree does not divide phi(n) in subcyclo"); fa = factor(stoi(n)); p = itos(gmael(fa,1,1)); al= itos(gmael(fa,2,1)); if (lg((GEN)fa[1]) > 2 || (p==2 && al>2)) err(impl,"subcyclo in non-cyclic case"); if (d < n) { k = 1 + svaluation(d,p,&i); if (k>TWOPOTBITS_IN_LONG); if (prec>1; for (i=2; i 1) { qpow = (GEN*)new_chunk(I+1); qpow[2]=q; } for (j=3; j<=I; j++) qpow[j] = gmul(q, qpow[j-1]); } for (i=1; i<=n; i++) { I = (i+1)/2; coeff(m,i,1)=un; if (q) { for (j=2; j<=I; j++) coeff(m,i,j) = ladd(gmul(qpow[j],gcoeff(m,i-1,j)), gcoeff(m,i-1,j-1)); } else { for (j=2; j<=I; j++) coeff(m,i,j) = laddii(gcoeff(m,i-1,j), gcoeff(m,i-1,j-1)); } for ( ; j<=i; j++) coeff(m,i,j) = coeff(m,i,i+1-j); for ( ; j<=n; j++) coeff(m,i,j) = zero; } return gerepileupto(av, gcopy(m)); } /********************************************************************/ /** **/ /** LAPLACE TRANSFORM (OF A SERIES) **/ /** **/ /********************************************************************/ GEN laplace(GEN x) { long i,l,ec,av,tetpil; GEN y,p1; if (typ(x)!=t_SER) err(talker,"not a series in laplace"); if (gcmp0(x)) return gcopy(x); av=avma; ec=valp(x); if (ec<0) err(talker,"negative valuation in laplace"); l=lg(x); y=cgetg(l,t_SER); p1=mpfact(ec); y[1]=x[1]; for (i=2; iv) v=ey; l=ex+lx; i=ey+ly; if (i=lx) for ( ; i>=lx; i--) y[i]=zero; for ( ; i>=2; i--) y[i]=lcopy((GEN)x[i]); break; case t_POL: lx=lgef(x); y=cgetg(lx,tx); y[1]=x[1]; for (i=2; i 0) { GEN z = subis(n,k); if (cmpis(z,k) < 0) k = itos(z); avma = av; if (k <= 1) { if (k < 0) return gzero; if (k == 0) return gun; return gcopy(n); } } for (i=2; i<=k; i++) y = gdivgs(gmul(y,addis(n,i-1-k)), i); } else { for (i=2; i<=k; i++) y = gdivgs(gmul(y,gaddgs(n,i-1-k)), i); } return gerepileupto(av, y); } /********************************************************************/ /** **/ /** POLYNOMIAL INTERPOLATION **/ /** **/ /********************************************************************/ GEN polint_i(GEN xa, GEN ya, GEN x, long n, GEN *ptdy) { long av = avma,tetpil,i,m, ns=0, tx=typ(x); GEN den,ho,hp,w,y,c,d,dy; if (is_scalar_t(tx) && tx != t_INTMOD && tx != t_PADIC && tx != t_POLMOD) { GEN dif = NULL, dift; for (i=0; i=li) { j = (ri+li)>>1; fl = gcmp((GEN)x[j],y); if (!fl) { avma=av; return flag? 0: j; } if (fl<0) li=j+1; else ri=j-1; } avma=av; if (!flag) return 0; return (fl<0)? j+1: j; } GEN setunion(GEN x, GEN y) { long av=avma,tetpil; GEN z; if (typ(x) != t_VEC || typ(y) != t_VEC) err(talker,"not a set in setunion"); z=concatsp(x,y); tetpil=avma; return gerepile(av,tetpil,gtoset(z)); } GEN setintersect(GEN x, GEN y) { long av=avma,tetpil,i,lx,c; GEN z; if (!setisset(x) || !setisset(y)) err(talker,"not a set in setintersect"); lx=lg(x); z=cgetg(lx,t_VEC); c=1; for (i=1; i>12)&LOWMASK, (mymyrand()>>12)&LOWMASK); #else #define GLUE4(hi1,hi2, lo1,lo2) GLUE2(((hi1)<<16)|(hi2), ((lo1)<<16)|(lo2)) # define LOWMASK2 0xffffUL return GLUE4((mymyrand()>>12)&LOWMASK2, (mymyrand()>>12)&LOWMASK2, (mymyrand()>>12)&LOWMASK2, (mymyrand()>>12)&LOWMASK2); #endif } GEN genrand(GEN N) { long lx,i; GEN x; if (!N) return stoi(mymyrand()); if (typ(N)!=t_INT || signe(N)<=0) err(talker,"invalid bound in random"); lx = lgefint(N); x = new_chunk(lx); for (i=2; i2) | evallgefint(lx); x[0] = evaltyp(t_INT) | evallg(lx); avma = (long)x; return x; } long setrand(long seed) { return (pari_randseed = seed); } long getrand() { return pari_randseed; } long getstack() { return top-avma; } long gettime() { return timer2(); } /***********************************************************************/ /** **/ /** PERMUTATIONS **/ /** **/ /***********************************************************************/ GEN permute(long n, GEN x) { long av=avma,i,a,r; GEN v,w,y; v=(GEN)gpmalloc((n+1)*sizeof(long)); v[1]=1; for (r=2; r<=n; r++) { x=dvmdis(x,r,&w); a=itos(w); for (i=r; i>=a+2; i--) v[i]=v[i-1]; v[i]=r; } avma=av; y=cgetg(n+1,t_VEC); for (i=1; i<=n; i++) y[i]=lstoi(v[i]); free(v); return y; } GEN permuteInv(GEN x) { long av=avma,tetpil, len=lg(x)-1, ini=len, last, ind; GEN ary,res; if (typ(x)!=t_VEC && typ(x)!=t_COL) err(talker,"not a vector in permuteInv"); res=gzero; ary=cgetg(len+1,t_VEC); for (ind=1; ind<=len; ind++) ary[ind]=*++x; ary++; for (last=len; last>0; last--) { len--; ind=len; while (ind>0 && itos((GEN)ary[ind])!=last) ind--; res=mulis(res,last); tetpil=avma; res=addis(res,ind); while (ind++ (long)y)? 1: ((x == y)? 0: -1); } /* Sort x = vector of elts, using cmp to compare them. * flag & cmp_IND: indirect sort: return permutation that would sort x * For private use: * flag & cmp_C : as cmp_IND, but return permutation as vector of C-longs */ GEN gen_sort(GEN x, int flag, int (*cmp)(GEN,GEN)) { long i,j,indxt,ir,l,tx=typ(x),lx=lg(x); GEN q,y,indx; if (!is_matvec_t(tx) && tx != t_VECSMALL) err(typeer,"gen_sort"); if (flag & cmp_C) tx = t_VECSMALL; else if (flag & cmp_IND) tx = t_VEC; y = cgetg(lx, tx); if (lx==1) return y; if (lx==2) { if (flag & cmp_C) y[1] = 1; else if (flag & cmp_IND) y[1] = un; else y[1] = lcopy((GEN)x[1]); return y; } if (!cmp) cmp = &longcmp; indx = (GEN) gpmalloc(lx*sizeof(long)); for (j=1; j>1)+1; for(;;) { if (l>1) { l--; indxt = indx[l]; } else { indxt = indx[ir]; indx[ir]=indx[1]; ir--; if (ir == 1) { indx[1] = indxt; if (flag & cmp_C) for (i=1; i= 0) break; indx[i]=indx[j]; i=j; } indx[i]=indxt; } } #define sort_fun(flag) ((flag & cmp_LEX)? &lexcmp: &gcmp) GEN gen_vecsort(GEN x, GEN k, long flag) { long i,j,l,t, lx = lg(x), tmp[2]; if (lx<=2) return gen_sort(x,flag,sort_fun(flag)); t = typ(k); vcmp_cmp = sort_fun(flag); if (t==t_INT) { tmp[1] = (long)k; k = tmp; vcmp_lk = 2; } else { if (! is_vec_t(t)) err(talker,"incorrect lextype in vecsort"); vcmp_lk = lg(k); } l = 0; vcmp_k = (GEN)gpmalloc(vcmp_lk * sizeof(long)); for (i=1; il) l=j; } t = typ(x); if (! is_matvec_t(t)) err(typeer,"vecsort"); for (j=1; j= cmp_C) err(flagerr,"vecsort"); return k? gen_vecsort(x,k,flag): gen_sort(x,flag, sort_fun(flag)); } GEN vecsort(GEN x, GEN k) { return gen_vecsort(x,k, 0); } GEN sindexsort(GEN x) { return gen_sort(x, cmp_IND | cmp_C, gcmp); } GEN sindexlexsort(GEN x) { return gen_sort(x, cmp_IND | cmp_C, lexcmp); } GEN indexsort(GEN x) { return gen_sort(x, cmp_IND, gcmp); } GEN indexlexsort(GEN x) { return gen_sort(x, cmp_IND, lexcmp); } GEN sort(GEN x) { return gen_sort(x, 0, gcmp); } GEN lexsort(GEN x) { return gen_sort(x, 0, lexcmp); } /* index of x in table T, 0 otherwise */ long tablesearch(GEN T, GEN x, int (*cmp)(GEN,GEN)) { long l=1,u=lg(T)-1,i,s; while (u>=l) { i = (l+u)>>1; s = cmp(x,(GEN)T[i]); if (!s) return i; if (s<0) u=i-1; else l=i+1; } return 0; } /* assume lg(x) = lg(y), x,y in Z^n */ int cmp_vecint(GEN x, GEN y) { long fl,i, lx = lg(x); for (i=1; i 0)? 1: -1) : cmp_vecint((GEN)x[2], (GEN)y[2]); } int cmp_prime_ideal(GEN x, GEN y) { int k = cmpii((GEN)x[1], (GEN)y[1]); return k? k: cmp_prime_over_p(x,y); }