Testing latest pari + WASM + node.js... and it works?! Wow.
License: GPL3
ubuntu2004
/* Copyright (C) 2000-2010 The PARI group.12This file is part of the PARI/GP package.34PARI/GP is free software; you can redistribute it and/or modify it under the5terms of the GNU General Public License as published by the Free Software6Foundation; either version 2 of the License, or (at your option) any later7version. It is distributed in the hope that it will be useful, but WITHOUT8ANY WARRANTY WHATSOEVER.910Check the License for details. You should have received a copy of it, along11with the package; see the file 'COPYING'. If not, write to the Free Software12Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */1314/*********************************************************************/15/* MALLOC/FREE WRAPPERS */16/*********************************************************************/17#define BLOCK_SIGALRM_START \18{ \19int block=PARI_SIGINT_block; \20PARI_SIGINT_block = 2; \21MT_SIGINT_BLOCK(block);2223#define BLOCK_SIGINT_START \24{ \25int block=PARI_SIGINT_block; \26PARI_SIGINT_block = 1; \27MT_SIGINT_BLOCK(block);2829#define BLOCK_SIGINT_END \30PARI_SIGINT_block = block; \31MT_SIGINT_UNBLOCK(block); \32if (!block && PARI_SIGINT_pending) \33{ \34int sig = PARI_SIGINT_pending; \35PARI_SIGINT_pending = 0; \36raise(sig); \37} \38}3940/*******************************************************************/41/* */42/* CONSTRUCTORS */43/* */44/*******************************************************************/45#define retmkfrac(x,y)\46do { GEN _v = cgetg(3, t_FRAC);\47gel(_v,1) = (x);\48gel(_v,2) = (y); return _v; } while(0)49#define retmkrfrac(x,y)\50do { GEN _v = cgetg(3, t_RFRAC);\51gel(_v,1) = (x);\52gel(_v,2) = (y); return _v; } while(0)53#define retmkintmod(x,y)\54do { GEN _v = cgetg(3, t_INTMOD);\55gel(_v,1) = (y);\56gel(_v,2) = (x); return _v; } while(0)57#define retmkcomplex(x,y)\58do { GEN _v = cgetg(3, t_COMPLEX);\59gel(_v,1) = (x);\60gel(_v,2) = (y); return _v; } while(0)61#define retmkpolmod(x,y)\62do { GEN _v = cgetg(3, t_POLMOD);\63gel(_v,1) = (y);\64gel(_v,2) = (x); return _v; } while(0)65#define retmkvec(x)\66do { GEN _v = cgetg(2, t_VEC);\67gel(_v,1) = (x); return _v; } while(0)68#define retmkvec2(x,y)\69do { GEN _v = cgetg(3, t_VEC);\70gel(_v,1) = (x);\71gel(_v,2) = (y); return _v; } while(0)72#define retmkvec3(x,y,z)\73do { GEN _v = cgetg(4, t_VEC);\74gel(_v,1) = (x);\75gel(_v,2) = (y);\76gel(_v,3) = (z); return _v; } while(0)77#define retmkqfb(x,y,z,d)\78do { GEN _v = cgetg(5, t_QFB);\79gel(_v,1) = (x);\80gel(_v,2) = (y);\81gel(_v,3) = (z);\82gel(_v,4) = (d); return _v; } while(0)83#define retmkquad(x,y,z)\84do { GEN _v = cgetg(4, t_QUAD);\85gel(_v,1) = (x);\86gel(_v,2) = (y);\87gel(_v,3) = (z); return _v; } while(0)88#define retmkvec4(x,y,z,t)\89do { GEN _v = cgetg(5, t_VEC);\90gel(_v,1) = (x);\91gel(_v,2) = (y);\92gel(_v,3) = (z);\93gel(_v,4) = (t); return _v; } while(0)94#define retmkvec5(x,y,z,t,u)\95do { GEN _v = cgetg(6, t_VEC);\96gel(_v,1) = (x);\97gel(_v,2) = (y);\98gel(_v,3) = (z);\99gel(_v,4) = (t);\100gel(_v,5) = (u); return _v; } while(0)101#define retmkcol(x)\102do { GEN _v = cgetg(2, t_COL);\103gel(_v,1) = (x); return _v; } while(0)104#define retmkcol2(x,y)\105do { GEN _v = cgetg(3, t_COL);\106gel(_v,1) = (x);\107gel(_v,2) = (y); return _v; } while(0)108#define retmkcol3(x,y,z)\109do { GEN _v = cgetg(4, t_COL);\110gel(_v,1) = (x);\111gel(_v,2) = (y);\112gel(_v,3) = (z); return _v; } while(0)113#define retmkcol4(x,y,z,t)\114do { GEN _v = cgetg(5, t_COL);\115gel(_v,1) = (x);\116gel(_v,2) = (y);\117gel(_v,3) = (z);\118gel(_v,4) = (t); return _v; } while(0)119#define retmkcol5(x,y,z,t,u)\120do { GEN _v = cgetg(6, t_COL);\121gel(_v,1) = (x);\122gel(_v,2) = (y);\123gel(_v,3) = (z);\124gel(_v,4) = (t);\125gel(_v,5) = (u); return _v; } while(0)126#define retmkcol6(x,y,z,t,u,v)\127do { GEN _v = cgetg(7, t_COL);\128gel(_v,1) = (x);\129gel(_v,2) = (y);\130gel(_v,3) = (z);\131gel(_v,4) = (t);\132gel(_v,5) = (u);\133gel(_v,6) = (v); return _v; } while(0)134#define retmkmat(x)\135do { GEN _v = cgetg(2, t_MAT);\136gel(_v,1) = (x); return _v; } while(0)137#define retmkmat2(x,y)\138do { GEN _v = cgetg(3, t_MAT);\139gel(_v,1) = (x);\140gel(_v,2) = (y); return _v; } while(0)141#define retmkmat3(x,y,z)\142do { GEN _v = cgetg(4, t_MAT);\143gel(_v,1) = (x);\144gel(_v,2) = (y);\145gel(_v,3) = (z); return _v; } while(0)146#define retmkmat4(x,y,z,t)\147do { GEN _v = cgetg(5, t_MAT);\148gel(_v,1) = (x);\149gel(_v,2) = (y);\150gel(_v,3) = (z);\151gel(_v,4) = (t); return _v; } while(0)152#define retmkmat5(x,y,z,t,u)\153do { GEN _v = cgetg(6, t_MAT);\154gel(_v,1) = (x);\155gel(_v,2) = (y);\156gel(_v,3) = (z);\157gel(_v,4) = (t);\158gel(_v,5) = (u); return _v; } while(0)159160INLINE GEN161mkintmod(GEN x, GEN y) { retmkintmod(x,y); }162INLINE GEN163mkintmodu(ulong x, ulong y) {164GEN v = cgetg(3,t_INTMOD);165gel(v,1) = utoipos(y);166gel(v,2) = utoi(x); return v;167}168INLINE GEN169mkpolmod(GEN x, GEN y) { retmkpolmod(x,y); }170INLINE GEN171mkfrac(GEN x, GEN y) { retmkfrac(x,y); }172INLINE GEN173mkfracss(long x, long y) { retmkfrac(stoi(x),utoipos(y)); }174/* q = n/d a t_FRAC or t_INT; recover (n,d) */175INLINE void176Qtoss(GEN q, long *n, long *d)177{178if (typ(q) == t_INT) { *n = itos(q); *d = 1; }179else { *n = itos(gel(q,1)); *d = itou(gel(q,2)); }180}181INLINE GEN182sstoQ(long n, long d)183{184ulong r;185long g, q;186if (!n)187{188if (!d) pari_err_INV("sstoQ",gen_0);189return gen_0;190}191if (d < 0) { d = -d; n = -n; }192if (d == 1) return stoi(n);193q = udivuu_rem(labs(n),d,&r);194if (!r) return n > 0? utoipos(q): utoineg(q);195g = ugcd(d,r); /* gcd(n,d) */196if (g != 1) { n /= g; d /= g; }197retmkfrac(stoi(n), utoi(d));198}199200INLINE GEN201mkfraccopy(GEN x, GEN y) { retmkfrac(icopy(x), icopy(y)); }202INLINE GEN203mkrfrac(GEN x, GEN y) { GEN v = cgetg(3, t_RFRAC);204gel(v,1) = x; gel(v,2) = y; return v; }205INLINE GEN206mkrfraccopy(GEN x, GEN y) { GEN v = cgetg(3, t_RFRAC);207gel(v,1) = gcopy(x); gel(v,2) = gcopy(y); return v; }208INLINE GEN209mkcomplex(GEN x, GEN y) { retmkcomplex(x,y); }210INLINE GEN211gen_I(void) { return mkcomplex(gen_0, gen_1); }212INLINE GEN213cgetc(long l) { retmkcomplex(cgetr(l), cgetr(l)); }214INLINE GEN215mkquad(GEN n, GEN x, GEN y) { GEN v = cgetg(4, t_QUAD);216gel(v,1) = n; gel(v,2) = x; gel(v,3) = y; return v; }217/* vecsmall */218INLINE GEN219mkvecsmall(long x) { GEN v = cgetg(2, t_VECSMALL); v[1] = x; return v; }220INLINE GEN221mkvecsmall2(long x,long y) { GEN v = cgetg(3, t_VECSMALL);222v[1]=x; v[2]=y; return v; }223INLINE GEN224mkvecsmall3(long x,long y,long z) { GEN v = cgetg(4, t_VECSMALL);225v[1]=x; v[2]=y; v[3]=z; return v; }226INLINE GEN227mkvecsmall4(long x,long y,long z,long t) { GEN v = cgetg(5, t_VECSMALL);228v[1]=x; v[2]=y; v[3]=z; v[4]=t; return v; }229INLINE GEN230mkvecsmall5(long x,long y,long z,long t,long u) { GEN v = cgetg(6, t_VECSMALL);231v[1]=x; v[2]=y; v[3]=z; v[4]=t; v[5]=u; return v; }232233INLINE GEN234mkqfb(GEN x, GEN y, GEN z, GEN d) { retmkqfb(x,y,z,d); }235/* vec */236INLINE GEN237mkvec(GEN x) { retmkvec(x); }238INLINE GEN239mkvec2(GEN x, GEN y) { retmkvec2(x,y); }240INLINE GEN241mkvec3(GEN x, GEN y, GEN z) { retmkvec3(x,y,z); }242INLINE GEN243mkvec4(GEN x, GEN y, GEN z, GEN t) { retmkvec4(x,y,z,t); }244INLINE GEN245mkvec5(GEN x, GEN y, GEN z, GEN t, GEN u) { retmkvec5(x,y,z,t,u); }246INLINE GEN247mkvecs(long x) { retmkvec(stoi(x)); }248INLINE GEN249mkvec2s(long x, long y) { retmkvec2(stoi(x),stoi(y)); }250INLINE GEN251mkvec3s(long x, long y, long z) { retmkvec3(stoi(x),stoi(y),stoi(z)); }252INLINE GEN253mkvec4s(long x, long y, long z, long t) { retmkvec4(stoi(x),stoi(y),stoi(z),stoi(t)); }254INLINE GEN255mkveccopy(GEN x) { GEN v = cgetg(2, t_VEC); gel(v,1) = gcopy(x); return v; }256INLINE GEN257mkvec2copy(GEN x, GEN y) {258GEN v = cgetg(3,t_VEC); gel(v,1) = gcopy(x); gel(v,2) = gcopy(y); return v; }259/* col */260INLINE GEN261mkcol(GEN x) { retmkcol(x); }262INLINE GEN263mkcol2(GEN x, GEN y) { retmkcol2(x,y); }264INLINE GEN265mkcol3(GEN x, GEN y, GEN z) { retmkcol3(x,y,z); }266INLINE GEN267mkcol4(GEN x, GEN y, GEN z, GEN t) { retmkcol4(x,y,z,t); }268INLINE GEN269mkcol5(GEN x, GEN y, GEN z, GEN t, GEN u) { retmkcol5(x,y,z,t,u); }270INLINE GEN271mkcol6(GEN x, GEN y, GEN z, GEN t, GEN u, GEN v) { retmkcol6(x,y,z,t,u,v); }272INLINE GEN273mkcols(long x) { retmkcol(stoi(x)); }274INLINE GEN275mkcol2s(long x, long y) { retmkcol2(stoi(x),stoi(y)); }276INLINE GEN277mkcol3s(long x, long y, long z) { retmkcol3(stoi(x),stoi(y),stoi(z)); }278INLINE GEN279mkcol4s(long x, long y, long z, long t) { retmkcol4(stoi(x),stoi(y),stoi(z),stoi(t)); }280INLINE GEN281mkcolcopy(GEN x) { GEN v = cgetg(2, t_COL); gel(v,1) = gcopy(x); return v; }282/* mat */283INLINE GEN284mkmat(GEN x) { retmkmat(x); }285INLINE GEN286mkmat2(GEN x, GEN y) { retmkmat2(x,y); }287INLINE GEN288mkmat3(GEN x, GEN y, GEN z) { retmkmat3(x,y,z); }289INLINE GEN290mkmat4(GEN x, GEN y, GEN z, GEN t) { retmkmat4(x,y,z,t); }291INLINE GEN292mkmat5(GEN x, GEN y, GEN z, GEN t, GEN u) { retmkmat5(x,y,z,t,u); }293INLINE GEN294mkmatcopy(GEN x) { GEN v = cgetg(2, t_MAT); gel(v,1) = gcopy(x); return v; }295INLINE GEN296mkerr(long x) { GEN v = cgetg(2, t_ERROR); v[1] = x; return v; }297INLINE GEN298mkoo(void) { GEN v = cgetg(2, t_INFINITY); gel(v,1) = gen_1; return v; }299INLINE GEN300mkmoo(void) { GEN v = cgetg(2, t_INFINITY); gel(v,1) = gen_m1; return v; }301INLINE long302inf_get_sign(GEN x) { return signe(gel(x,1)); }303INLINE GEN304mkmat22s(long a, long b, long c, long d) {retmkmat2(mkcol2s(a,c),mkcol2s(b,d));}305INLINE GEN306mkmat22(GEN a, GEN b, GEN c, GEN d) { retmkmat2(mkcol2(a,c),mkcol2(b,d)); }307308/* pol */309INLINE GEN310pol_x(long v) {311GEN p = cgetg(4, t_POL);312p[1] = evalsigne(1)|evalvarn(v);313gel(p,2) = gen_0;314gel(p,3) = gen_1; return p;315}316/* x^n, assume n >= 0 */317INLINE GEN318pol_xn(long n, long v) {319long i, a = n+2;320GEN p = cgetg(a+1, t_POL);321p[1] = evalsigne(1)|evalvarn(v);322for (i = 2; i < a; i++) gel(p,i) = gen_0;323gel(p,a) = gen_1; return p;324}325/* x^n, no assumption on n */326INLINE GEN327pol_xnall(long n, long v)328{329if (n < 0) retmkrfrac(gen_1, pol_xn(-n,v));330return pol_xn(n, v);331}332/* x^n, assume n >= 0 */333INLINE GEN334polxn_Flx(long n, long sv) {335long i, a = n+2;336GEN p = cgetg(a+1, t_VECSMALL);337p[1] = sv;338for (i = 2; i < a; i++) p[i] = 0;339p[a] = 1; return p;340}341INLINE GEN342pol_1(long v) {343GEN p = cgetg(3, t_POL);344p[1] = evalsigne(1)|evalvarn(v);345gel(p,2) = gen_1; return p;346}347INLINE GEN348pol_0(long v)349{350GEN x = cgetg(2,t_POL);351x[1] = evalvarn(v); return x;352}353#define retconst_vec(n,x)\354do { long _i, _n = (n);\355GEN _v = cgetg(_n+1, t_VEC), _x = (x);\356for (_i = 1; _i <= _n; _i++) gel(_v,_i) = _x;\357return _v; } while(0)358INLINE GEN359const_vec(long n, GEN x) { retconst_vec(n, x); }360#define retconst_col(n,x)\361do { long _i, _n = (n);\362GEN _v = cgetg(_n+1, t_COL), _x = (x);\363for (_i = 1; _i <= _n; _i++) gel(_v,_i) = _x;\364return _v; } while(0)365INLINE GEN366const_col(long n, GEN x) { retconst_col(n, x); }367INLINE GEN368const_vecsmall(long n, long c)369{370long i;371GEN V = cgetg(n+1,t_VECSMALL);372for(i=1;i<=n;i++) V[i] = c;373return V;374}375376/*** ZERO ***/377/* O(p^e) */378INLINE GEN379zeropadic(GEN p, long e)380{381GEN y = cgetg(5,t_PADIC);382gel(y,4) = gen_0;383gel(y,3) = gen_1;384gel(y,2) = icopy(p);385y[1] = evalvalp(e) | _evalprecp(0);386return y;387}388INLINE GEN389zeropadic_shallow(GEN p, long e)390{391GEN y = cgetg(5,t_PADIC);392gel(y,4) = gen_0;393gel(y,3) = gen_1;394gel(y,2) = p;395y[1] = evalvalp(e) | _evalprecp(0);396return y;397}398/* O(pol_x(v)^e) */399INLINE GEN400zeroser(long v, long e)401{402GEN x = cgetg(2, t_SER);403x[1] = evalvalp(e) | evalvarn(v); return x;404}405INLINE int406ser_isexactzero(GEN x)407{408if (!signe(x)) switch(lg(x))409{410case 2: return 1;411case 3: return isexactzero(gel(x,2));412}413return 0;414}415/* 0 * pol_x(v) */416INLINE GEN417zeropol(long v) { return pol_0(v); }418/* vector(n) */419INLINE GEN420zerocol(long n)421{422GEN y = cgetg(n+1,t_COL);423long i; for (i=1; i<=n; i++) gel(y,i) = gen_0;424return y;425}426/* vectorv(n) */427INLINE GEN428zerovec(long n)429{430GEN y = cgetg(n+1,t_VEC);431long i; for (i=1; i<=n; i++) gel(y,i) = gen_0;432return y;433}434/* matrix(m, n) */435INLINE GEN436zeromat(long m, long n)437{438GEN y = cgetg(n+1,t_MAT);439GEN v = zerocol(m);440long i; for (i=1; i<=n; i++) gel(y,i) = v;441return y;442}443/* = zero_zx, sv is a evalvarn()*/444INLINE GEN445zero_Flx(long sv) { return pol0_Flx(sv); }446INLINE GEN447zero_Flv(long n)448{449GEN y = cgetg(n+1,t_VECSMALL);450long i; for (i=1; i<=n; i++) y[i] = 0;451return y;452}453/* matrix(m, n) */454INLINE GEN455zero_Flm(long m, long n)456{457GEN y = cgetg(n+1,t_MAT);458GEN v = zero_Flv(m);459long i; for (i=1; i<=n; i++) gel(y,i) = v;460return y;461}462/* matrix(m, n) */463INLINE GEN464zero_Flm_copy(long m, long n)465{466GEN y = cgetg(n+1,t_MAT);467long i; for (i=1; i<=n; i++) gel(y,i) = zero_Flv(m);468return y;469}470471INLINE GEN472zero_F2v(long m)473{474long l = nbits2nlong(m);475GEN v = zero_Flv(l+1);476v[1] = m;477return v;478}479480INLINE GEN481zero_F2m(long m, long n)482{483long i;484GEN M = cgetg(n+1, t_MAT);485GEN v = zero_F2v(m);486for (i = 1; i <= n; i++)487gel(M,i) = v;488return M;489}490491492INLINE GEN493zero_F2m_copy(long m, long n)494{495long i;496GEN M = cgetg(n+1, t_MAT);497for (i = 1; i <= n; i++)498gel(M,i)= zero_F2v(m);499return M;500}501502/* matrix(m, n) */503INLINE GEN504zeromatcopy(long m, long n)505{506GEN y = cgetg(n+1,t_MAT);507long i; for (i=1; i<=n; i++) gel(y,i) = zerocol(m);508return y;509}510511INLINE GEN512zerovec_block(long len)513{514long i;515GEN blk = cgetg_block(len + 1, t_VEC);516for (i = 1; i <= len; ++i)517gel(blk, i) = gen_0;518return blk;519}520521/* i-th vector in the standard basis */522INLINE GEN523col_ei(long n, long i) { GEN e = zerocol(n); gel(e,i) = gen_1; return e; }524INLINE GEN525vec_ei(long n, long i) { GEN e = zerovec(n); gel(e,i) = gen_1; return e; }526INLINE GEN527F2v_ei(long n, long i) { GEN e = zero_F2v(n); F2v_set(e,i); return e; }528INLINE GEN529vecsmall_ei(long n, long i) { GEN e = zero_zv(n); e[i] = 1; return e; }530INLINE GEN531Rg_col_ei(GEN x, long n, long i) { GEN e = zerocol(n); gel(e,i) = x; return e; }532533INLINE GEN534shallowcopy(GEN x)535{ return typ(x) == t_MAT ? RgM_shallowcopy(x): leafcopy(x); }536537/* routines for naive growarrays */538INLINE GEN539vectrunc_init(long l)540{541GEN z = new_chunk(l);542z[0] = evaltyp(t_VEC) | _evallg(1); return z;543}544INLINE GEN545coltrunc_init(long l)546{547GEN z = new_chunk(l);548z[0] = evaltyp(t_COL) | _evallg(1); return z;549}550INLINE void551lg_increase(GEN x) { x[0]++; }552INLINE void553vectrunc_append(GEN x, GEN t) { gel(x, lg(x)) = t; lg_increase(x); }554INLINE void555vectrunc_append_batch(GEN x, GEN y)556{557long i, l = lg(x), ly = lg(y);558GEN z = x + l-1;559for (i = 1; i < ly; i++) gel(z,i) = gel(y,i);560setlg(x, l+ly-1);561}562INLINE GEN563vecsmalltrunc_init(long l)564{565GEN z = new_chunk(l);566z[0] = evaltyp(t_VECSMALL) | _evallg(1); return z;567}568INLINE void569vecsmalltrunc_append(GEN x, long t) { x[ lg(x) ] = t; lg_increase(x); }570571/*******************************************************************/572/* */573/* STRING HASH FUNCTIONS */574/* */575/*******************************************************************/576INLINE ulong577hash_str(const char *str)578{579ulong hash = 5381UL, c;580while ( (c = (ulong)*str++) )581hash = ((hash << 5) + hash) + c; /* hash * 33 + c */582return hash;583}584INLINE ulong585hash_str_len(const char *str, long len)586{587ulong hash = 5381UL;588long i;589for (i = 0; i < len; i++)590{591ulong c = (ulong)*str++;592hash = ((hash << 5) + hash) + c; /* hash * 33 + c */593}594return hash;595}596597/*******************************************************************/598/* */599/* VEC / COL / VECSMALL */600/* */601/*******************************************************************/602/* shallow*/603INLINE GEN604vec_shorten(GEN v, long n)605{606long i;607GEN V = cgetg(n+1,t_VEC);608for(i=1;i<=n;i++) gel(V,i) = gel(v,i);609return V;610}611/* shallow*/612INLINE GEN613vec_lengthen(GEN v, long n)614{615long i;616long l=lg(v);617GEN V = cgetg(n+1,t_VEC);618for(i=1;i<l;i++) gel(V,i) = gel(v,i);619return V;620}621/* shallow*/622INLINE GEN623vec_append(GEN V, GEN s)624{625long i, l2 = lg(V);626GEN res = cgetg(l2+1, typ(V));627for (i = 1; i < l2; ++i) gel(res, i) = gel(V,i);628gel(res,l2) = s; return res;629}630/* shallow*/631INLINE GEN632vec_prepend(GEN v, GEN s)633{634long i, l = lg(v);635GEN w = cgetg(l+1, typ(v));636gel(w,1) = s;637for (i = 2; i <= l; ++i) gel(w,i) = gel(v,i-1);638return w;639}640/* shallow*/641INLINE GEN642vec_setconst(GEN v, GEN x)643{644long i, l = lg(v);645for (i = 1; i < l; i++) gel(v,i) = x;646return v;647}648INLINE GEN649vecsmall_shorten(GEN v, long n)650{651long i;652GEN V = cgetg(n+1,t_VECSMALL);653for(i=1;i<=n;i++) V[i] = v[i];654return V;655}656INLINE GEN657vecsmall_lengthen(GEN v, long n)658{659long i, l = lg(v);660GEN V = cgetg(n+1,t_VECSMALL);661for(i=1;i<l;i++) V[i] = v[i];662return V;663}664665INLINE GEN666vec_to_vecsmall(GEN x)667{ pari_APPLY_long(itos(gel(x,i))) }668INLINE GEN669vecsmall_to_vec(GEN x)670{ pari_APPLY_type(t_VEC, stoi(x[i])) }671INLINE GEN672vecsmall_to_vec_inplace(GEN z)673{674long i, l = lg(z);675for (i=1; i<l; i++) gel(z,i) = stoi(z[i]);676settyp(z, t_VEC); return z;677}678INLINE GEN679vecsmall_to_col(GEN x)680{ pari_APPLY_type(t_COL, stoi(x[i])) }681682INLINE int683vecsmall_lexcmp(GEN x, GEN y)684{685long lx,ly,l,i;686lx = lg(x);687ly = lg(y); l = minss(lx,ly);688for (i=1; i<l; i++)689if (x[i] != y[i]) return x[i]<y[i]? -1: 1;690if (lx == ly) return 0;691return (lx < ly)? -1 : 1;692}693694INLINE int695vecsmall_prefixcmp(GEN x, GEN y)696{697long i, lx = lg(x), ly = lg(y), l = minss(lx,ly);698for (i=1; i<l; i++)699if (x[i] != y[i]) return x[i]<y[i]? -1: 1;700return 0;701}702703/*Can be used on t_VEC, but coeffs not gcopy-ed*/704INLINE GEN705vecsmall_prepend(GEN V, long s)706{707long i, l2 = lg(V);708GEN res = cgetg(l2+1, typ(V));709res[1] = s;710for (i = 2; i <= l2; ++i) res[i] = V[i - 1];711return res;712}713714INLINE GEN715vecsmall_append(GEN V, long s)716{717long i, l2 = lg(V);718GEN res = cgetg(l2+1, t_VECSMALL);719for (i = 1; i < l2; ++i) res[i] = V[i];720res[l2] = s; return res;721}722723INLINE GEN724vecsmall_concat(GEN u, GEN v)725{726long i, l1 = lg(u)-1, l2 = lg(v)-1;727GEN res = cgetg(l1+l2+1, t_VECSMALL);728for (i = 1; i <= l1; ++i) res[i] = u[i];729for (i = 1; i <= l2; ++i) res[i+l1] = v[i];730return res;731}732733/* return the number of indices where u and v are equal */734INLINE long735vecsmall_coincidence(GEN u, GEN v)736{737long i, s = 0, l = minss(lg(u),lg(v));738for(i=1; i<l; i++)739if(u[i] == v[i]) s++;740return s;741}742743/* returns the first index i<=n such that x=v[i] if it exists, 0 otherwise */744INLINE long745vecsmall_isin(GEN v, long x)746{747long i, l = lg(v);748for (i = 1; i < l; i++)749if (v[i] == x) return i;750return 0;751}752753INLINE long754vecsmall_pack(GEN V, long base, long mod)755{756long i, s = 0;757for(i=1; i<lg(V); i++) s = (base*s + V[i]) % mod;758return s;759}760761INLINE long762vecsmall_indexmax(GEN x)763{764long i, i0 = 1, t = x[1], lx = lg(x);765for (i=2; i<lx; i++)766if (x[i] > t) t = x[i0=i];767return i0;768}769770INLINE long771vecsmall_max(GEN x)772{773long i, t = x[1], lx = lg(x);774for (i=2; i<lx; i++)775if (x[i] > t) t = x[i];776return t;777}778779INLINE long780vecsmall_indexmin(GEN x)781{782long i, i0 = 1, t = x[1], lx =lg(x);783for (i=2; i<lx; i++)784if (x[i] < t) t = x[i0=i];785return i0;786}787788INLINE long789vecsmall_min(GEN x)790{791long i, t = x[1], lx =lg(x);792for (i=2; i<lx; i++)793if (x[i] < t) t = x[i];794return t;795}796797INLINE int798ZV_isscalar(GEN x)799{800long l = lg(x);801while (--l > 1)802if (signe(gel(x, l))) return 0;803return 1;804}805INLINE int806QV_isscalar(GEN x)807{808long lx = lg(x),i;809for (i=2; i<lx; i++)810if (!isintzero(gel(x, i))) return 0;811return 1;812}813INLINE int814RgV_isscalar(GEN x)815{816long lx = lg(x),i;817for (i=2; i<lx; i++)818if (!gequal0(gel(x, i))) return 0;819return 1;820}821INLINE int822RgX_isscalar(GEN x)823{824long i;825for (i=lg(x)-1; i>2; i--)826if (!gequal0(gel(x, i))) return 0;827return 1;828}829INLINE long830RgX_equal_var(GEN x, GEN y) { return varn(x) == varn(y) && RgX_equal(x,y); }831INLINE GEN832RgX_to_RgV(GEN x, long N) { x = RgX_to_RgC(x, N); settyp(x, t_VEC); return x; }833834INLINE int835RgX_is_rational(GEN x)836{837long i;838for (i = lg(x)-1; i > 1; i--)839if (!is_rational_t(typ(gel(x,i)))) return 0;840return 1;841}842INLINE int843RgX_is_ZX(GEN x)844{845long i;846for (i = lg(x)-1; i > 1; i--)847if (typ(gel(x,i)) != t_INT) return 0;848return 1;849}850INLINE int851RgX_is_QX(GEN x)852{853long k = lg(x)-1;854for ( ; k>1; k--)855if (!is_rational_t(typ(gel(x,k)))) return 0;856return 1;857}858INLINE int859RgX_is_monomial(GEN x)860{861long i;862if (!signe(x)) return 0;863for (i=lg(x)-2; i>1; i--)864if (!isexactzero(gel(x,i))) return 0;865return 1;866}867INLINE int868RgV_is_ZV(GEN x)869{870long i;871for (i = lg(x)-1; i > 0; i--)872if (typ(gel(x,i)) != t_INT) return 0;873return 1;874}875INLINE int876RgV_is_QV(GEN x)877{878long i;879for (i = lg(x)-1; i > 0; i--)880if (!is_rational_t(typ(gel(x,i)))) return 0;881return 1;882}883INLINE long884RgV_isin_i(GEN v, GEN x, long n)885{886long i;887for (i = 1; i <= n; i++)888if (gequal(gel(v,i), x)) return i;889return 0;890}891INLINE long892RgV_isin(GEN v, GEN x) { return RgV_isin_i(v, x, lg(v)-1); }893894/********************************************************************/895/** **/896/** Dynamic arrays implementation **/897/** **/898/********************************************************************/899INLINE void **900pari_stack_base(pari_stack *s) { return s->data; }901902INLINE void903pari_stack_init(pari_stack *s, size_t size, void **data)904{905s->data = data;906*data = NULL;907s->n = 0;908s->alloc = 0;909s->size = size;910}911912INLINE void913pari_stack_alloc(pari_stack *s, long nb)914{915void **sdat = pari_stack_base(s);916long alloc = s->alloc;917if (s->n+nb <= alloc) return;918if (!alloc)919alloc = nb;920else921{922while (s->n+nb > alloc) alloc <<= 1;923}924pari_realloc_ip(sdat,alloc*s->size);925s->alloc = alloc;926}927928INLINE long929pari_stack_new(pari_stack *s) { pari_stack_alloc(s, 1); return s->n++; }930931INLINE void932pari_stack_delete(pari_stack *s)933{934void **sdat = pari_stack_base(s);935if (*sdat) pari_free(*sdat);936}937938INLINE void939pari_stack_pushp(pari_stack *s, void *u)940{941long n = pari_stack_new(s);942void **sdat =(void**) *pari_stack_base(s);943sdat[n] = u;944}945946/*******************************************************************/947/* */948/* EXTRACT */949/* */950/*******************************************************************/951INLINE GEN952vecslice(GEN A, long y1, long y2)953{954long i,lB = y2 - y1 + 2;955GEN B = cgetg(lB, typ(A));956for (i=1; i<lB; i++) B[i] = A[y1-1+i];957return B;958}959INLINE GEN960vecslicepermute(GEN A, GEN p, long y1, long y2)961{962long i,lB = y2 - y1 + 2;963GEN B = cgetg(lB, typ(A));964for (i=1; i<lB; i++) B[i] = A[p[y1-1+i]];965return B;966}967/* rowslice(rowpermute(A,p), x1, x2) */968INLINE GEN969rowslicepermute(GEN x, GEN p, long j1, long j2)970{ pari_APPLY_same(vecslicepermute(gel(x,i),p,j1,j2)) }971972INLINE GEN973rowslice(GEN x, long j1, long j2)974{ pari_APPLY_same(vecslice(gel(x,i), j1, j2)) }975976INLINE GEN977matslice(GEN A, long x1, long x2, long y1, long y2)978{ return rowslice(vecslice(A, y1, y2), x1, x2); }979980/* shallow, remove coeff of index j */981INLINE GEN982rowsplice(GEN x, long j)983{ pari_APPLY_same(vecsplice(gel(x,i), j)) }984985/* shallow, remove coeff of index j */986INLINE GEN987vecsplice(GEN a, long j)988{989long i, k, l = lg(a);990GEN b;991if (l == 1) pari_err(e_MISC, "incorrect component in vecsplice");992b = cgetg(l-1, typ(a));993for (i = k = 1; i < l; i++)994if (i != j) gel(b, k++) = gel(a,i);995return b;996}997/* shallow */998INLINE GEN999RgM_minor(GEN a, long i, long j)1000{1001GEN b = vecsplice(a, j);1002long k, l = lg(b);1003for (k = 1; k < l; k++) gel(b,k) = vecsplice(gel(b,k), i);1004return b;1005}10061007/* A[x0,] */1008INLINE GEN1009row(GEN x, long j)1010{ pari_APPLY_type(t_VEC, gcoeff(x, j, i)) }1011INLINE GEN1012Flm_row(GEN x, long j)1013{ pari_APPLY_ulong((ulong)coeff(x, j, i)) }1014/* A[x0,] */1015INLINE GEN1016rowcopy(GEN x, long j)1017{ pari_APPLY_type(t_VEC, gcopy(gcoeff(x, j, i))) }1018/* A[x0, x1..x2] */1019INLINE GEN1020row_i(GEN A, long x0, long x1, long x2)1021{1022long i, lB = x2 - x1 + 2;1023GEN B = cgetg(lB, t_VEC);1024for (i=x1; i<=x2; i++) gel(B, i) = gcoeff(A, x0, i);1025return B;1026}10271028INLINE GEN1029vecreverse(GEN A)1030{1031long i, l;1032GEN B = cgetg_copy(A, &l);1033for (i=1; i<l; i++) gel(B, i) = gel(A, l-i);1034return B;1035}10361037INLINE GEN1038vecsmall_reverse(GEN A)1039{1040long i, l;1041GEN B = cgetg_copy(A, &l);1042for (i=1; i<l; i++) B[i] = A[l-i];1043return B;1044}10451046INLINE void1047vecreverse_inplace(GEN y)1048{1049long l = lg(y), lim = l>>1, i;1050for (i = 1; i <= lim; i++)1051{1052GEN z = gel(y,i);1053gel(y,i) = gel(y,l-i);1054gel(y,l-i) = z;1055}1056}10571058INLINE GEN1059vecsmallpermute(GEN A, GEN p) { return perm_mul(A, p); }10601061INLINE GEN1062vecpermute(GEN A, GEN x)1063{ pari_APPLY_type(typ(A), gel(A, x[i])) }10641065INLINE GEN1066rowpermute(GEN x, GEN p)1067{ pari_APPLY_same(typ(gel(x,i)) == t_VECSMALL ? vecsmallpermute(gel(x, i), p)1068: vecpermute(gel(x, i), p))1069}1070/*******************************************************************/1071/* */1072/* PERMUTATIONS */1073/* */1074/*******************************************************************/1075INLINE GEN1076identity_zv(long n)1077{1078GEN v = cgetg(n+1, t_VECSMALL);1079long i;1080for (i = 1; i <= n; i++) v[i] = i;1081return v;1082}1083INLINE GEN1084identity_ZV(long n)1085{1086GEN v = cgetg(n+1, t_VEC);1087long i;1088for (i = 1; i <= n; i++) gel(v,i) = utoipos(i);1089return v;1090}1091/* identity permutation */1092INLINE GEN1093identity_perm(long n) { return identity_zv(n); }10941095/* assume d <= n */1096INLINE GEN1097cyclic_perm(long n, long d)1098{1099GEN perm = cgetg(n+1, t_VECSMALL);1100long i;1101for (i = 1; i <= n-d; i++) perm[i] = i+d;1102for ( ; i <= n; i++) perm[i] = i-n+d;1103return perm;1104}11051106/* Multiply (compose) two permutations */1107INLINE GEN1108perm_mul(GEN s, GEN x)1109{ pari_APPLY_long(s[x[i]]) }11101111INLINE GEN1112perm_sqr(GEN x)1113{ pari_APPLY_long(x[x[i]]) }11141115/* Compute the inverse (reciprocal) of a permutation. */1116INLINE GEN1117perm_inv(GEN x)1118{1119long i, lx;1120GEN y = cgetg_copy(x, &lx);1121for (i=1; i<lx; i++) y[ x[i] ] = i;1122return y;1123}1124/* Return s*t*s^-1 */1125INLINE GEN1126perm_conj(GEN s, GEN t)1127{1128long i, l;1129GEN v = cgetg_copy(s, &l);1130for (i = 1; i < l; i++) v[ s[i] ] = s[ t[i] ];1131return v;1132}11331134INLINE void1135pari_free(void *pointer)1136{1137BLOCK_SIGINT_START;1138free(pointer);1139BLOCK_SIGINT_END;1140}1141INLINE void*1142pari_malloc(size_t size)1143{1144if (size)1145{1146char *tmp;1147BLOCK_SIGINT_START;1148tmp = (char*)malloc(size);1149BLOCK_SIGINT_END;1150if (!tmp) pari_err(e_MEM);1151return tmp;1152}1153return NULL;1154}1155INLINE void*1156pari_realloc(void *pointer, size_t size)1157{1158char *tmp;11591160BLOCK_SIGINT_START;1161if (!pointer) tmp = (char *) malloc(size);1162else tmp = (char *) realloc(pointer,size);1163BLOCK_SIGINT_END;1164if (!tmp) pari_err(e_MEM);1165return tmp;1166}1167INLINE void1168pari_realloc_ip(void **pointer, size_t size)1169{1170char *tmp;1171BLOCK_SIGINT_START;1172if (!*pointer) tmp = (char *) malloc(size);1173else tmp = (char *) realloc(*pointer,size);1174if (!tmp) pari_err(e_MEM);1175*pointer = tmp;1176BLOCK_SIGINT_END;1177}11781179INLINE void*1180pari_calloc(size_t size)1181{1182void *t = pari_malloc(size);1183memset(t, 0, size); return t;1184}1185INLINE GEN1186cgetalloc(long t, size_t l)1187{ /* evallg may raise e_OVERFLOW, which would leak x */1188ulong x0 = evaltyp(t) | evallg(l);1189GEN x = (GEN)pari_malloc(l * sizeof(long));1190x[0] = x0; return x;1191}11921193/*******************************************************************/1194/* */1195/* GARBAGE COLLECTION */1196/* */1197/*******************************************************************/1198/* copy integer x as if we had set_avma(av) */1199INLINE GEN1200icopy_avma(GEN x, pari_sp av)1201{1202long i = lgefint(x), lx = i;1203GEN y = ((GEN)av) - i;1204while (--i > 0) y[i] = x[i];1205y[0] = evaltyp(t_INT)|evallg(lx);1206return y;1207}1208/* copy leaf x as if we had set_avma(av) */1209INLINE GEN1210leafcopy_avma(GEN x, pari_sp av)1211{1212long i = lg(x);1213GEN y = ((GEN)av) - i;1214while (--i > 0) y[i] = x[i];1215y[0] = x[0] & (~CLONEBIT);1216return y;1217}1218INLINE GEN1219gerepileuptoleaf(pari_sp av, GEN x)1220{1221long lx;1222GEN q;12231224if (!isonstack(x) || (GEN)av<=x) return gc_const(av,x);1225lx = lg(x);1226q = ((GEN)av) - lx;1227set_avma((pari_sp)q);1228while (--lx >= 0) q[lx] = x[lx];1229return q;1230}1231INLINE GEN1232gerepileuptoint(pari_sp av, GEN x)1233{1234if (!isonstack(x) || (GEN)av<=x) return gc_const(av,x);1235set_avma((pari_sp)icopy_avma(x, av));1236return (GEN)avma;1237}1238INLINE GEN1239gerepileupto(pari_sp av, GEN x)1240{1241if (!isonstack(x) || (GEN)av<=x) return gc_const(av,x);1242switch(typ(x))1243{ /* non-default = !is_recursive_t(tq) */1244case t_INT: return gerepileuptoint(av, x);1245case t_REAL:1246case t_STR:1247case t_VECSMALL: return gerepileuptoleaf(av,x);1248default:1249/* NB: x+i --> ((long)x) + i*sizeof(long) */1250return gerepile(av, (pari_sp) (x+lg(x)), x);1251}1252}12531254/* gerepileupto(av, gcopy(x)) */1255INLINE GEN1256gerepilecopy(pari_sp av, GEN x)1257{1258if (is_recursive_t(typ(x)))1259{1260GENbin *p = copy_bin(x);1261set_avma(av); return bin_copy(p);1262}1263else1264{1265set_avma(av);1266if (x < (GEN)av) {1267if (x < (GEN)pari_mainstack->bot) new_chunk(lg(x));1268x = leafcopy_avma(x, av);1269set_avma((pari_sp)x);1270} else1271x = leafcopy(x);1272return x;1273}1274}12751276INLINE void1277guncloneNULL(GEN x) { if (x) gunclone(x); }1278INLINE void1279guncloneNULL_deep(GEN x) { if (x) gunclone_deep(x); }12801281/* Takes an array of pointers to GENs, of length n. Copies all1282* objects to contiguous locations and cleans up the stack between1283* av and avma. */1284INLINE void1285gerepilemany(pari_sp av, GEN* gptr[], int n)1286{1287int i;1288for (i=0; i<n; i++) *gptr[i] = (GEN)copy_bin(*gptr[i]);1289set_avma(av);1290for (i=0; i<n; i++) *gptr[i] = bin_copy((GENbin*)*gptr[i]);1291}12921293INLINE void1294gerepileall(pari_sp av, int n, ...)1295{1296int i;1297va_list a; va_start(a, n);1298if (n < 10)1299{1300GEN *gptr[10];1301for (i=0; i<n; i++)1302{ gptr[i] = va_arg(a,GEN*); *gptr[i] = (GEN)copy_bin(*gptr[i]); }1303set_avma(av);1304for (--i; i>=0; i--) *gptr[i] = bin_copy((GENbin*)*gptr[i]);13051306}1307else1308{1309GEN **gptr = (GEN**) pari_malloc(n*sizeof(GEN*));1310for (i=0; i<n; i++)1311{ gptr[i] = va_arg(a,GEN*); *gptr[i] = (GEN)copy_bin(*gptr[i]); }1312set_avma(av);1313for (--i; i>=0; i--) *gptr[i] = bin_copy((GENbin*)*gptr[i]);1314pari_free(gptr);1315}1316va_end(a);1317}13181319INLINE void1320gerepilecoeffs(pari_sp av, GEN x, int n)1321{1322int i;1323for (i=0; i<n; i++) gel(x,i) = (GEN)copy_bin(gel(x,i));1324set_avma(av);1325for (i=0; i<n; i++) gel(x,i) = bin_copy((GENbin*)x[i]);1326}13271328/* p from copy_bin. Copy p->x back to stack, then destroy p */1329INLINE GEN1330bin_copy(GENbin *p)1331{1332GEN x, y, base;1333long dx, len;13341335x = p->x; if (!x) { pari_free(p); return gen_0; }1336len = p->len;1337base= p->base; dx = x - base;1338y = (GEN)memcpy((void*)new_chunk(len), (void*)GENbinbase(p), len*sizeof(long));1339y += dx;1340p->rebase(y, ((ulong)y-(ulong)x));1341pari_free(p); return y;1342}13431344INLINE GEN1345GENbinbase(GENbin *p) { return (GEN)(p + 1); }13461347INLINE void1348cgiv(GEN x)1349{1350pari_sp av = (pari_sp)(x+lg(x));1351if (isonstack((GEN)av)) set_avma(av);1352}13531354INLINE void1355killblock(GEN x) { gunclone(x); }13561357INLINE int1358is_universal_constant(GEN x) { return (x >= gen_0 && x <= ghalf); }13591360/*******************************************************************/1361/* */1362/* CONVERSION / ASSIGNMENT */1363/* */1364/*******************************************************************/1365/* z is a type which may be a t_COMPLEX component (not a t_QUAD) */1366INLINE GEN1367cxcompotor(GEN z, long prec)1368{1369switch(typ(z))1370{1371case t_INT: return itor(z, prec);1372case t_FRAC: return fractor(z, prec);1373case t_REAL: return rtor(z, prec);1374default: pari_err_TYPE("cxcompotor",z);1375return NULL; /* LCOV_EXCL_LINE */1376}1377}1378INLINE GEN1379cxtofp(GEN x, long prec)1380{ retmkcomplex(cxcompotor(gel(x,1),prec), cxcompotor(gel(x,2),prec)); }13811382INLINE GEN1383cxtoreal(GEN q)1384{ return (typ(q) == t_COMPLEX && gequal0(gel(q,2)))? gel(q,1): q; }13851386INLINE double1387gtodouble(GEN x)1388{1389if (typ(x)!=t_REAL) {1390pari_sp av = avma;1391x = gtofp(x, DEFAULTPREC);1392if (typ(x)!=t_REAL) pari_err_TYPE("gtodouble [t_REAL expected]", x);1393set_avma(av);1394}1395return rtodbl(x);1396}13971398INLINE int1399gisdouble(GEN x, double *g)1400{1401if (typ(x)!=t_REAL) {1402pari_sp av = avma;1403x = gtofp(x, DEFAULTPREC);1404if (typ(x)!=t_REAL) pari_err_TYPE("gisdouble [t_REAL expected]", x);1405set_avma(av);1406}1407if (expo(x) >= 0x3ff) return 0;1408*g = rtodbl(x); return 1;1409}14101411INLINE long1412gtos(GEN x) {1413if (typ(x) != t_INT) pari_err_TYPE("gtos [integer expected]",x);1414return itos(x);1415}14161417INLINE ulong1418gtou(GEN x) {1419if (typ(x) != t_INT || signe(x)<0)1420pari_err_TYPE("gtou [integer >=0 expected]",x);1421return itou(x);1422}14231424INLINE GEN1425absfrac(GEN x)1426{1427GEN y = cgetg(3, t_FRAC);1428gel(y,1) = absi(gel(x,1));1429gel(y,2) = icopy(gel(x,2)); return y;1430}1431INLINE GEN1432absfrac_shallow(GEN x)1433{ return signe(gel(x,1))>0? x: mkfrac(negi(gel(x,1)), gel(x,2)); }1434INLINE GEN1435Q_abs(GEN x) { return (typ(x) == t_INT)? absi(x): absfrac(x); }1436INLINE GEN1437Q_abs_shallow(GEN x)1438{ return (typ(x) == t_INT)? absi_shallow(x): absfrac_shallow(x); }1439INLINE GEN1440R_abs_shallow(GEN x)1441{ return (typ(x) == t_FRAC)? absfrac_shallow(x): mpabs_shallow(x); }1442INLINE GEN1443R_abs(GEN x)1444{ return (typ(x) == t_FRAC)? absfrac(x): mpabs(x); }14451446/* Force z to be of type real/complex with floating point components */1447INLINE GEN1448gtofp(GEN z, long prec)1449{1450switch(typ(z))1451{1452case t_INT: return itor(z, prec);1453case t_FRAC: return fractor(z, prec);1454case t_REAL: return rtor(z, prec);1455case t_COMPLEX: {1456GEN a = gel(z,1), b = gel(z,2);1457if (isintzero(b)) return cxcompotor(a, prec);1458if (isintzero(a)) {1459GEN y = cgetg(3, t_COMPLEX);1460b = cxcompotor(b, prec);1461gel(y,1) = real_0_bit(expo(b) - prec2nbits(prec));1462gel(y,2) = b; return y;1463}1464return cxtofp(z, prec);1465}1466case t_QUAD: return quadtofp(z, prec);1467default: pari_err_TYPE("gtofp",z);1468return NULL; /* LCOV_EXCL_LINE */1469}1470}1471/* Force z to be of type real / int */1472INLINE GEN1473gtomp(GEN z, long prec)1474{1475switch(typ(z))1476{1477case t_INT: return z;1478case t_FRAC: return fractor(z, prec);1479case t_REAL: return rtor(z, prec);1480case t_QUAD: z = quadtofp(z, prec);1481if (typ(z) == t_REAL) return z;1482default: pari_err_TYPE("gtomp",z);1483return NULL; /* LCOV_EXCL_LINE */1484}1485}14861487INLINE GEN1488RgX_gtofp(GEN x, long prec)1489{1490long l;1491GEN y = cgetg_copy(x, &l);1492while (--l > 1) gel(y,l) = gtofp(gel(x,l), prec);1493y[1] = x[1]; return y;1494}1495INLINE GEN1496RgC_gtofp(GEN x, long prec)1497{ pari_APPLY_type(t_COL, gtofp(gel(x,i), prec)) }14981499INLINE GEN1500RgV_gtofp(GEN x, long prec)1501{ pari_APPLY_type(t_VEC, gtofp(gel(x,i), prec)) }15021503INLINE GEN1504RgM_gtofp(GEN x, long prec)1505{ pari_APPLY_same(RgC_gtofp(gel(x,i), prec)) }15061507INLINE GEN1508RgC_gtomp(GEN x, long prec)1509{ pari_APPLY_type(t_COL, gtomp(gel(x,i), prec)) }15101511INLINE GEN1512RgM_gtomp(GEN x, long prec)1513{ pari_APPLY_same(RgC_gtomp(gel(x,i), prec)) }15141515INLINE GEN1516RgX_fpnorml2(GEN x, long prec)1517{1518pari_sp av = avma;1519return gerepileupto(av, gnorml2(RgX_gtofp(x, prec)));1520}1521INLINE GEN1522RgC_fpnorml2(GEN x, long prec)1523{1524pari_sp av = avma;1525return gerepileupto(av, gnorml2(RgC_gtofp(x, prec)));1526}1527INLINE GEN1528RgM_fpnorml2(GEN x, long prec)1529{1530pari_sp av = avma;1531return gerepileupto(av, gnorml2(RgM_gtofp(x, prec)));1532}15331534/* y a t_REAL */1535INLINE void1536affgr(GEN x, GEN y)1537{1538pari_sp av;1539switch(typ(x)) {1540case t_INT: affir(x,y); break;1541case t_REAL: affrr(x,y); break;1542case t_FRAC: rdiviiz(gel(x,1),gel(x,2), y); break;1543case t_QUAD: av = avma; affgr(quadtofp(x,realprec(y)), y); set_avma(av); break;1544default: pari_err_TYPE2("=",x,y);1545}1546}15471548INLINE GEN1549affc_fixlg(GEN x, GEN res)1550{1551if (typ(x) == t_COMPLEX)1552{1553affrr_fixlg(gel(x,1), gel(res,1));1554affrr_fixlg(gel(x,2), gel(res,2));1555}1556else1557{1558set_avma((pari_sp)(res+3));1559res = cgetr(realprec(gel(res,1)));1560affrr_fixlg(x, res);1561}1562return res;1563}15641565INLINE GEN1566trunc_safe(GEN x) { long e; return gcvtoi(x,&e); }15671568/*******************************************************************/1569/* */1570/* LENGTH CONVERSIONS */1571/* */1572/*******************************************************************/1573INLINE long1574ndec2nlong(long x) { return 1 + (long)((x)*(LOG2_10/BITS_IN_LONG)); }1575INLINE long1576ndec2prec(long x) { return 2 + ndec2nlong(x); }1577INLINE long1578ndec2nbits(long x) { return ndec2nlong(x) << TWOPOTBITS_IN_LONG; }1579/* Fast implementation of ceil(x / (8*sizeof(long))); typecast to (ulong)1580* to avoid overflow. Faster than 1 + ((x-1)>>TWOPOTBITS_IN_LONG)) :1581* addl, shrl instead of subl, sarl, addl */1582INLINE long1583nbits2nlong(long x) {1584return (long)(((ulong)x+BITS_IN_LONG-1) >> TWOPOTBITS_IN_LONG);1585}15861587INLINE long1588nbits2extraprec(long x) {1589return (long)(((ulong)x+BITS_IN_LONG-1) >> TWOPOTBITS_IN_LONG);1590}15911592/* Fast implementation of 2 + nbits2nlong(x) */1593INLINE long1594nbits2prec(long x) {1595return (long)(((ulong)x+3*BITS_IN_LONG-1) >> TWOPOTBITS_IN_LONG);1596}1597INLINE long1598nbits2lg(long x) {1599return (long)(((ulong)x+3*BITS_IN_LONG-1) >> TWOPOTBITS_IN_LONG);1600}1601/* ceil(x / sizeof(long)) */1602INLINE long1603nchar2nlong(long x) {1604return (long)(((ulong)x+sizeof(long)-1) >> (TWOPOTBITS_IN_LONG-3L));1605}1606INLINE long1607prec2nbits(long x) { return (x-2) * BITS_IN_LONG; }1608INLINE double1609bit_accuracy_mul(long x, double y) { return (x-2) * (BITS_IN_LONG*y); }1610INLINE double1611prec2nbits_mul(long x, double y) { return (x-2) * (BITS_IN_LONG*y); }1612INLINE long1613bit_prec(GEN x) { return prec2nbits(realprec(x)); }1614INLINE long1615bit_accuracy(long x) { return prec2nbits(x); }1616INLINE long1617prec2ndec(long x) { return (long)prec2nbits_mul(x, LOG10_2); }1618INLINE long1619nbits2ndec(long x) { return (long)(x * LOG10_2); }1620INLINE long1621precdbl(long x) {return (x - 1) << 1;}1622INLINE long1623divsBIL(long n) { return n >> TWOPOTBITS_IN_LONG; }1624INLINE long1625remsBIL(long n) { return n & (BITS_IN_LONG-1); }16261627/*********************************************************************/1628/** **/1629/** OPERATIONS MODULO m **/1630/** **/1631/*********************************************************************/1632/* Assume m > 0, more efficient if 0 <= a, b < m */16331634INLINE GEN1635Fp_red(GEN a, GEN m) { return modii(a, m); }1636INLINE GEN1637Fp_add(GEN a, GEN b, GEN m)1638{1639pari_sp av=avma;1640GEN p = addii(a,b);1641long s = signe(p);1642if (!s) return p; /* = gen_0 */1643if (s > 0) /* general case */1644{1645GEN t = subii(p, m);1646s = signe(t);1647if (!s) return gc_const(av, gen_0);1648if (s < 0) return gc_const((pari_sp)p, p);1649if (cmpii(t, m) < 0) return gerepileuptoint(av, t); /* general case ! */1650p = remii(t, m);1651}1652else1653p = modii(p, m);1654return gerepileuptoint(av, p);1655}1656INLINE GEN1657Fp_sub(GEN a, GEN b, GEN m)1658{1659pari_sp av=avma;1660GEN p = subii(a,b);1661long s = signe(p);1662if (!s) return p; /* = gen_0 */1663if (s > 0)1664{1665if (cmpii(p, m) < 0) return p; /* general case ! */1666p = remii(p, m);1667}1668else1669{1670GEN t = addii(p, m);1671if (!s) return gc_const(av, gen_0);1672if (s > 0) return gerepileuptoint(av, t); /* general case ! */1673p = modii(t, m);1674}1675return gerepileuptoint(av, p);1676}1677INLINE GEN1678Fp_neg(GEN b, GEN m)1679{1680pari_sp av = avma;1681long s = signe(b);1682GEN p;1683if (!s) return gen_0;1684if (s > 0)1685{1686p = subii(m, b);1687if (signe(p) >= 0) return p; /* general case ! */1688p = modii(p, m);1689} else1690p = remii(negi(b), m);1691return gerepileuptoint(av, p);1692}16931694INLINE GEN1695Fp_halve(GEN a, GEN p)1696{1697if (mpodd(a)) a = addii(a,p);1698return shifti(a,-1);1699}17001701/* assume 0 <= u < p and ps2 = p>>1 */1702INLINE GEN1703Fp_center(GEN u, GEN p, GEN ps2)1704{ return abscmpii(u,ps2)<=0? icopy(u): subii(u,p); }1705/* same without copy */1706INLINE GEN1707Fp_center_i(GEN u, GEN p, GEN ps2)1708{ return abscmpii(u,ps2)<=0? u: subii(u,p); }17091710/* x + y*z mod p */1711INLINE GEN1712Fp_addmul(GEN x, GEN y, GEN z, GEN p)1713{1714pari_sp av;1715if (!signe(y) || !signe(z)) return Fp_red(x, p);1716if (!signe(x)) return Fp_mul(z,y, p);1717av = avma;1718return gerepileuptoint(av, modii(addii(x, mulii(y,z)), p));1719}17201721INLINE GEN1722Fp_mul(GEN a, GEN b, GEN m)1723{1724pari_sp av=avma;1725GEN p; /*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/1726(void)new_chunk(lg(a)+lg(b)+(lg(m)<<1));1727p = mulii(a,b);1728set_avma(av); return modii(p,m);1729}1730INLINE GEN1731Fp_sqr(GEN a, GEN m)1732{1733pari_sp av=avma;1734GEN p; /*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/1735(void)new_chunk((lg(a)+lg(m))<<1);1736p = sqri(a);1737set_avma(av); return remii(p,m); /*Use remii: p >= 0 */1738}1739INLINE GEN1740Fp_mulu(GEN a, ulong b, GEN m)1741{1742long l = lgefint(m);1743if (l == 3)1744{1745ulong mm = m[2];1746return utoi( Fl_mul(umodiu(a, mm), b, mm) );1747} else {1748pari_sp av = avma;1749GEN p; /*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/1750(void)new_chunk(lg(a)+1+(l<<1));1751p = muliu(a,b);1752set_avma(av); return modii(p,m);1753}1754}1755INLINE GEN1756Fp_muls(GEN a, long b, GEN m)1757{1758long l = lgefint(m);1759if (l == 3)1760{1761ulong mm = m[2];1762if (b < 0)1763{1764ulong t = Fl_mul(umodiu(a, mm), -b, mm);1765return t? utoipos(mm - t): gen_0;1766}1767else1768return utoi( Fl_mul(umodiu(a, mm), b, mm) );1769} else {1770pari_sp av = avma;1771GEN p; /*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/1772(void)new_chunk(lg(a)+1+(l<<1));1773p = mulis(a,b);1774set_avma(av); return modii(p,m);1775}1776}17771778INLINE GEN1779Fp_inv(GEN a, GEN m)1780{1781GEN res;1782if (! invmod(a,m,&res)) pari_err_INV("Fp_inv", mkintmod(res,m));1783return res;1784}1785INLINE GEN1786Fp_invsafe(GEN a, GEN m)1787{1788GEN res;1789if (! invmod(a,m,&res)) return NULL;1790return res;1791}1792INLINE GEN1793Fp_div(GEN a, GEN b, GEN m)1794{1795pari_sp av = avma;1796GEN p;1797if (lgefint(b) == 3)1798{1799a = Fp_divu(a, b[2], m);1800if (signe(b) < 0) a = Fp_neg(a, m);1801return a;1802}1803/*HACK: assume modii use <=lg(p)+(lg(m)<<1) space*/1804(void)new_chunk(lg(a)+(lg(m)<<1));1805p = mulii(a, Fp_inv(b,m));1806set_avma(av); return modii(p,m);1807}1808INLINE GEN1809Fp_divu(GEN x, ulong a, GEN p)1810{1811pari_sp av = avma;1812ulong b;1813if (lgefint(p) == 3)1814{1815ulong pp = p[2], xp = umodiu(x, pp);1816return xp? utoipos(Fl_div(xp, a % pp, pp)): gen_0;1817}1818x = Fp_red(x, p);1819b = Fl_neg(Fl_div(umodiu(x,a), umodiu(p,a), a), a); /* x + pb = 0 (mod a) */1820return gerepileuptoint(av, diviuexact(addmuliu(x, p, b), a));1821}18221823INLINE GEN1824Flx_mulu(GEN x, ulong a, ulong p) { return Flx_Fl_mul(x,a%p,p); }18251826INLINE GEN1827get_F2x_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }18281829INLINE long1830get_F2x_var(GEN T) { return typ(T)==t_VEC? mael(T,2,1): T[1]; }18311832INLINE long1833get_F2x_degree(GEN T) { return typ(T)==t_VEC? F2x_degree(gel(T,2)): F2x_degree(T); }18341835INLINE GEN1836get_F2xqX_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }18371838INLINE long1839get_F2xqX_var(GEN T) { return typ(T)==t_VEC? varn(gel(T,2)): varn(T); }18401841INLINE long1842get_F2xqX_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }18431844INLINE GEN1845get_Flx_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }18461847INLINE long1848get_Flx_var(GEN T) { return typ(T)==t_VEC? mael(T,2,1): T[1]; }18491850INLINE long1851get_Flx_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }18521853INLINE GEN1854get_FlxqX_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }18551856INLINE long1857get_FlxqX_var(GEN T) { return typ(T)==t_VEC? varn(gel(T,2)): varn(T); }18581859INLINE long1860get_FlxqX_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }18611862INLINE GEN1863get_FpX_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }18641865INLINE long1866get_FpX_var(GEN T) { return typ(T)==t_VEC? varn(gel(T,2)): varn(T); }18671868INLINE long1869get_FpX_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }18701871INLINE GEN1872get_FpXQX_mod(GEN T) { return typ(T)==t_VEC? gel(T,2): T; }18731874INLINE long1875get_FpXQX_var(GEN T) { return typ(T)==t_VEC? varn(gel(T,2)): varn(T); }18761877INLINE long1878get_FpXQX_degree(GEN T) { return typ(T)==t_VEC? degpol(gel(T,2)): degpol(T); }18791880/*******************************************************************/1881/* */1882/* ADDMULII / SUBMULII */1883/* */1884/*******************************************************************/1885/* x - y*z */1886INLINE GEN1887submulii(GEN x, GEN y, GEN z)1888{1889long lx = lgefint(x), ly, lz;1890pari_sp av;1891GEN t;1892if (lx == 2) { t = mulii(z,y); togglesign(t); return t; }1893ly = lgefint(y);1894if (ly == 2) return icopy(x);1895lz = lgefint(z);1896av = avma; (void)new_chunk(lx+ly+lz); /* HACK */1897t = mulii(z, y);1898set_avma(av); return subii(x,t);1899}1900/* y*z - x */1901INLINE GEN1902mulsubii(GEN y, GEN z, GEN x)1903{1904long lx = lgefint(x), ly, lz;1905pari_sp av;1906GEN t;1907if (lx == 2) return mulii(z,y);1908ly = lgefint(y);1909if (ly == 2) return negi(x);1910lz = lgefint(z);1911av = avma; (void)new_chunk(lx+ly+lz); /* HACK */1912t = mulii(z, y);1913set_avma(av); return subii(t,x);1914}19151916/* x - u*y */1917INLINE GEN1918submuliu(GEN x, GEN y, ulong u)1919{1920pari_sp av;1921long ly = lgefint(y);1922if (ly == 2) return icopy(x);1923av = avma;1924(void)new_chunk(3+ly+lgefint(x)); /* HACK */1925y = mului(u,y);1926set_avma(av); return subii(x, y);1927}1928/* x + u*y */1929INLINE GEN1930addmuliu(GEN x, GEN y, ulong u)1931{1932pari_sp av;1933long ly = lgefint(y);1934if (ly == 2) return icopy(x);1935av = avma;1936(void)new_chunk(3+ly+lgefint(x)); /* HACK */1937y = mului(u,y);1938set_avma(av); return addii(x, y);1939}1940/* x - u*y */1941INLINE GEN1942submuliu_inplace(GEN x, GEN y, ulong u)1943{1944pari_sp av;1945long ly = lgefint(y);1946if (ly == 2) return x;1947av = avma;1948(void)new_chunk(3+ly+lgefint(x)); /* HACK */1949y = mului(u,y);1950set_avma(av); return subii(x, y);1951}1952/* x + u*y */1953INLINE GEN1954addmuliu_inplace(GEN x, GEN y, ulong u)1955{1956pari_sp av;1957long ly = lgefint(y);1958if (ly == 2) return x;1959av = avma;1960(void)new_chunk(3+ly+lgefint(x)); /* HACK */1961y = mului(u,y);1962set_avma(av); return addii(x, y);1963}1964/* ux + vy */1965INLINE GEN1966lincombii(GEN u, GEN v, GEN x, GEN y)1967{1968long lx = lgefint(x), ly;1969GEN p1, p2;1970pari_sp av;1971if (lx == 2) return mulii(v,y);1972ly = lgefint(y);1973if (ly == 2) return mulii(u,x);1974av = avma; (void)new_chunk(lx+ly+lgefint(u)+lgefint(v)); /* HACK */1975p1 = mulii(u,x);1976p2 = mulii(v,y);1977set_avma(av); return addii(p1,p2);1978}19791980/*******************************************************************/1981/* */1982/* GEN SUBTYPES */1983/* */1984/*******************************************************************/19851986INLINE int1987is_const_t(long t) { return (t < t_POLMOD); }1988INLINE int1989is_extscalar_t(long t) { return (t <= t_POL); }1990INLINE int1991is_intreal_t(long t) { return (t <= t_REAL); }1992INLINE int1993is_matvec_t(long t) { return (t >= t_VEC && t <= t_MAT); }1994INLINE int1995is_noncalc_t(long tx) { return (tx) >= t_LIST; }1996INLINE int1997is_qfb_t(long t) { return (t == t_QFB); }1998INLINE int1999is_rational_t(long t) { return (t == t_INT || t == t_FRAC); }2000INLINE int2001is_real_t(long t) { return (t == t_INT || t == t_REAL || t == t_FRAC); }2002INLINE int2003is_recursive_t(long t) { return lontyp[t]; }2004INLINE int2005is_scalar_t(long t) { return (t < t_POL); }2006INLINE int2007is_vec_t(long t) { return (t == t_VEC || t == t_COL); }20082009INLINE int2010qfb_is_qfi(GEN q) { return signe(gel(q,4)) < 0; }20112012/*******************************************************************/2013/* */2014/* TRANSCENDENTAL */2015/* */2016/*******************************************************************/2017INLINE GEN2018sqrtr(GEN x) {2019long s = signe(x);2020if (s == 0) return real_0_bit(expo(x) >> 1);2021if (s >= 0) return sqrtr_abs(x);2022retmkcomplex(gen_0, sqrtr_abs(x));2023}2024INLINE GEN2025cbrtr_abs(GEN x) { return sqrtnr_abs(x, 3); }2026INLINE GEN2027cbrtr(GEN x) {2028long s = signe(x);2029GEN r;2030if (s == 0) return real_0_bit(expo(x) / 3);2031r = cbrtr_abs(x);2032if (s < 0) togglesign(r);2033return r;2034}2035INLINE GEN2036sqrtnr(GEN x, long n) {2037long s = signe(x);2038GEN r;2039if (s == 0) return real_0_bit(expo(x) / n);2040r = sqrtnr_abs(x, n);2041if (s < 0) pari_err_IMPL("sqrtnr for x < 0");2042return r;2043}2044INLINE long2045logint(GEN B, GEN y) { return logintall(B,y,NULL); }2046INLINE ulong2047ulogint(ulong B, ulong y)2048{2049ulong r;2050long e;2051if (y == 2) return expu(B);2052r = y;2053for (e=1;; e++)2054{ /* here, r = y^e, r2 = y^(e-1) */2055if (r >= B) return r == B? e: e-1;2056r = umuluu_or_0(y, r);2057if (!r) return e;2058}2059}20602061/*******************************************************************/2062/* */2063/* MISCELLANEOUS */2064/* */2065/*******************************************************************/2066INLINE int ismpzero(GEN x) { return is_intreal_t(typ(x)) && !signe(x); }2067INLINE int isintzero(GEN x) { return typ(x) == t_INT && !signe(x); }2068INLINE int isint1(GEN x) { return typ(x)==t_INT && equali1(x); }2069INLINE int isintm1(GEN x){ return typ(x)==t_INT && equalim1(x);}2070INLINE int equali1(GEN n)2071{ return (ulong) n[1] == (evallgefint(3UL) | evalsigne(1)) && n[2] == 1; }2072INLINE int equalim1(GEN n)2073{ return (ulong) n[1] == (evallgefint(3UL) | evalsigne(-1)) && n[2] == 1; }2074/* works only for POSITIVE integers */2075INLINE int is_pm1(GEN n)2076{ return lgefint(n) == 3 && n[2] == 1; }2077INLINE int is_bigint(GEN n)2078{ long l = lgefint(n); return l > 3 || (l == 3 && (n[2] & HIGHBIT)); }20792080INLINE int odd(long x) { return x & 1; }2081INLINE int both_odd(long x, long y) { return x & y & 1; }20822083INLINE int2084isonstack(GEN x)2085{ return ((pari_sp)x >= pari_mainstack->bot2086&& (pari_sp)x < pari_mainstack->top); }20872088/* assume x != 0 and x t_REAL, return an approximation to log2(|x|) */2089INLINE double2090dbllog2r(GEN x)2091{ return log2((double)(ulong)x[2]) + (double)(expo(x) - (BITS_IN_LONG-1)); }20922093INLINE GEN2094mul_content(GEN cx, GEN cy)2095{2096if (!cx) return cy;2097if (!cy) return cx;2098return gmul(cx,cy);2099}2100INLINE GEN2101inv_content(GEN c) { return c? ginv(c): NULL; }2102INLINE GEN2103div_content(GEN cx, GEN cy)2104{2105if (!cy) return cx;2106if (!cx) return ginv(cy);2107return gdiv(cx,cy);2108}2109INLINE GEN2110mul_denom(GEN dx, GEN dy)2111{2112if (!dx) return dy;2113if (!dy) return dx;2114return mulii(dx,dy);2115}21162117/* POLYNOMIALS */2118INLINE GEN2119constant_coeff(GEN x) { return signe(x)? gel(x,2): gen_0; }2120INLINE GEN2121leading_coeff(GEN x) { return lg(x) == 2? gen_0: gel(x,lg(x)-1); }2122INLINE ulong2123Flx_lead(GEN x) { return lg(x) == 2? 0: x[lg(x)-1]; }2124INLINE ulong2125Flx_constant(GEN x) { return lg(x) == 2? 0: x[2]; }2126INLINE long2127degpol(GEN x) { return lg(x)-3; }2128INLINE long2129lgpol(GEN x) { return lg(x)-2; }2130INLINE long2131lgcols(GEN x) { return lg(gel(x,1)); }2132INLINE long2133nbrows(GEN x) { return lg(gel(x,1))-1; }2134INLINE GEN2135truecoef(GEN x, long n) { return polcoef(x,n,-1); }21362137INLINE GEN2138ZXQ_mul(GEN y, GEN x, GEN T) { return ZX_rem(ZX_mul(y, x), T); }2139INLINE GEN2140ZXQ_sqr(GEN x, GEN T) { return ZX_rem(ZX_sqr(x), T); }21412142INLINE GEN2143RgX_copy(GEN x)2144{2145long lx, i;2146GEN y = cgetg_copy(x, &lx); y[1] = x[1];2147for (i = 2; i<lx; i++) gel(y,i) = gcopy(gel(x,i));2148return y;2149}2150/* have to use ulong to avoid silly warnings from gcc "assuming signed2151* overflow does not occur" */2152INLINE GEN2153RgX_coeff(GEN x, long n)2154{2155ulong l = lg(x);2156return (n < 0 || ((ulong)n+3) > l)? gen_0: gel(x,n+2);2157}2158INLINE GEN2159RgX_renormalize(GEN x) { return RgX_renormalize_lg(x, lg(x)); }2160INLINE GEN2161RgX_div(GEN x, GEN y) { return RgX_divrem(x,y,NULL); }2162INLINE GEN2163RgXQX_div(GEN x, GEN y, GEN T) { return RgXQX_divrem(x,y,T,NULL); }2164INLINE GEN2165RgXQX_rem(GEN x, GEN y, GEN T) { return RgXQX_divrem(x,y,T,ONLY_REM); }2166INLINE GEN2167FpX_div(GEN x, GEN y, GEN p) { return FpX_divrem(x,y,p, NULL); }2168INLINE GEN2169Flx_div(GEN x, GEN y, ulong p) { return Flx_divrem(x,y,p, NULL); }2170INLINE GEN2171F2x_div(GEN x, GEN y) { return F2x_divrem(x,y, NULL); }2172INLINE GEN2173FpV_FpC_mul(GEN x, GEN y, GEN p) { return FpV_dotproduct(x,y,p); }2174INLINE GEN2175pol0_Flx(long sv) { return mkvecsmall(sv); }2176INLINE GEN2177pol1_Flx(long sv) { return mkvecsmall2(sv, 1); }2178INLINE GEN2179polx_Flx(long sv) { return mkvecsmall3(sv, 0, 1); }2180INLINE GEN2181zero_zx(long sv) { return zero_Flx(sv); }2182INLINE GEN2183polx_zx(long sv) { return polx_Flx(sv); }2184INLINE GEN2185zx_shift(GEN x, long n) { return Flx_shift(x,n); }2186INLINE GEN2187zx_renormalize(GEN x, long l) { return Flx_renormalize(x,l); }2188INLINE GEN2189zero_F2x(long sv) { return zero_Flx(sv); }2190INLINE GEN2191pol0_F2x(long sv) { return pol0_Flx(sv); }2192INLINE GEN2193pol1_F2x(long sv) { return pol1_Flx(sv); }2194INLINE GEN2195polx_F2x(long sv) { return mkvecsmall2(sv, 2); }2196INLINE int2197F2x_equal1(GEN x) { return Flx_equal1(x); }2198INLINE int2199F2x_equal(GEN V, GEN W) { return Flx_equal(V,W); }2200INLINE GEN2201F2x_copy(GEN x) { return leafcopy(x); }2202INLINE GEN2203F2v_copy(GEN x) { return leafcopy(x); }2204INLINE GEN2205Flv_copy(GEN x) { return leafcopy(x); }2206INLINE GEN2207Flx_copy(GEN x) { return leafcopy(x); }2208INLINE GEN2209vecsmall_copy(GEN x) { return leafcopy(x); }2210INLINE int2211Flx_equal1(GEN x) { return degpol(x)==0 && x[2] == 1; }2212INLINE int2213ZX_equal1(GEN x) { return degpol(x)==0 && equali1(gel(x,2)); }2214INLINE int2215ZX_is_monic(GEN x) { return equali1(leading_coeff(x)); }22162217INLINE GEN2218ZX_renormalize(GEN x, long lx) { return ZXX_renormalize(x,lx); }2219INLINE GEN2220FpX_renormalize(GEN x, long lx) { return ZXX_renormalize(x,lx); }2221INLINE GEN2222FpXX_renormalize(GEN x, long lx) { return ZXX_renormalize(x,lx); }2223INLINE GEN2224FpXQX_renormalize(GEN x, long lx) { return ZXX_renormalize(x,lx); }2225INLINE GEN2226F2x_renormalize(GEN x, long lx) { return Flx_renormalize(x,lx); }2227INLINE GEN2228F2v_to_F2x(GEN x, long sv) {2229GEN y = leafcopy(x);2230y[1] = sv; F2x_renormalize(y, lg(y)); return y;2231}22322233INLINE long2234sturm(GEN x) { return sturmpart(x, NULL, NULL); }22352236INLINE long2237gval(GEN x, long v)2238{ pari_sp av = avma; return gc_long(av, gvaluation(x, pol_x(v))); }22392240INLINE void2241RgX_shift_inplace_init(long v)2242{ if (v) (void)cgetg(v, t_VECSMALL); }2243/* shift polynomial in place. assume v free cells have been left before x */2244INLINE GEN2245RgX_shift_inplace(GEN x, long v)2246{2247long i, lx;2248GEN z;2249if (!v) return x;2250lx = lg(x);2251if (lx == 2) return x;2252z = x + lx;2253/* stackdummy's from normalizepol */2254while (lg(z) != v) z += lg(z);2255z += v;2256for (i = lx-1; i >= 2; i--) gel(--z,0) = gel(x,i);2257for (i = 0; i < v; i++) gel(--z,0) = gen_0;2258z -= 2;2259z[1] = x[1];2260z[0] = evaltyp(t_POL) | evallg(lx+v);2261stackdummy((pari_sp)z, (pari_sp)x); return z;2262}226322642265/* LINEAR ALGEBRA */2266INLINE GEN2267zv_to_ZV(GEN x) { return vecsmall_to_vec(x); }2268INLINE GEN2269zc_to_ZC(GEN x) { return vecsmall_to_col(x); }2270INLINE GEN2271ZV_to_zv(GEN x) { return vec_to_vecsmall(x); }2272INLINE GEN2273zx_to_zv(GEN x, long N) { return Flx_to_Flv(x,N); }2274INLINE GEN2275zv_to_zx(GEN x, long sv) { return Flv_to_Flx(x,sv); }2276INLINE GEN2277zm_to_zxV(GEN x, long sv) { return Flm_to_FlxV(x,sv); }2278INLINE GEN2279zero_zm(long x, long y) { return zero_Flm(x,y); }2280INLINE GEN2281zero_zv(long x) { return zero_Flv(x); }2282INLINE GEN2283zm_transpose(GEN x) { return Flm_transpose(x); }2284INLINE GEN2285zm_copy(GEN x) { return Flm_copy(x); }2286INLINE GEN2287zv_copy(GEN x) { return Flv_copy(x); }2288INLINE GEN2289zm_row(GEN x, long i) { return Flm_row(x,i); }22902291INLINE GEN2292ZC_hnfrem(GEN x, GEN y) { return ZC_hnfremdiv(x,y,NULL); }2293INLINE GEN2294ZM_hnfrem(GEN x, GEN y) { return ZM_hnfdivrem(x,y,NULL); }2295INLINE GEN2296ZM_lll(GEN x, double D, long f) { return ZM_lll_norms(x,D,f,NULL); }2297INLINE void2298RgM_dimensions(GEN x, long *m, long *n) { *n = lg(x)-1; *m = *n? nbrows(x): 0; }2299INLINE GEN2300RgM_shallowcopy(GEN x)2301{2302long l;2303GEN y = cgetg_copy(x, &l);2304while (--l > 0) gel(y,l) = leafcopy(gel(x,l));2305return y;2306}2307INLINE GEN2308F2m_copy(GEN x) { return RgM_shallowcopy(x); }23092310INLINE GEN2311F3m_copy(GEN x) { return RgM_shallowcopy(x); }23122313INLINE GEN2314Flm_copy(GEN x) { return RgM_shallowcopy(x); }23152316/* divisibility: return 1 if y[i] | x[i] for all i, 0 otherwise. Assume2317* x,y are ZV of the same length */2318INLINE int2319ZV_dvd(GEN x, GEN y)2320{2321long i, l = lg(x);2322for (i=1; i < l; i++)2323if ( ! dvdii( gel(x,i), gel(y,i) ) ) return 0;2324return 1;2325}23262327/* Fq */2328INLINE GEN2329Fq_red(GEN x, GEN T, GEN p)2330{ return typ(x)==t_INT? Fp_red(x,p): FpXQ_red(x,T,p); }2331INLINE GEN2332Fq_to_FpXQ(GEN x, GEN T, GEN p /*unused*/)2333{2334(void) p;2335return typ(x)==t_INT ? scalarpol(x, get_FpX_var(T)): x;2336}2337INLINE GEN2338Rg_to_Fq(GEN x, GEN T, GEN p) { return T? Rg_to_FpXQ(x,T,p): Rg_to_Fp(x,p); }23392340INLINE GEN2341gener_Fq_local(GEN T, GEN p, GEN L)2342{ return T? gener_FpXQ_local(T,p, L)2343: pgener_Fp_local(p, L); }23442345/* FpXQX */2346INLINE GEN2347FpXQX_div(GEN x, GEN y, GEN T, GEN p) { return FpXQX_divrem(x, y, T, p, NULL); }2348INLINE GEN2349FlxqX_div(GEN x, GEN y, GEN T, ulong p) { return FlxqX_divrem(x, y, T, p, NULL); }2350INLINE GEN2351F2xqX_div(GEN x, GEN y, GEN T) { return F2xqX_divrem(x, y, T, NULL); }23522353INLINE GEN2354FpXY_Fq_evaly(GEN Q, GEN y, GEN T, GEN p, long vx)2355{ return T ? FpXY_FpXQ_evaly(Q, y, T, p, vx): FpXY_evaly(Q, y, p, vx); }23562357/* FqX */2358INLINE GEN2359FqX_red(GEN z, GEN T, GEN p) { return T? FpXQX_red(z, T, p): FpX_red(z, p); }2360INLINE GEN2361FqX_add(GEN x,GEN y,GEN T,GEN p) { return T? FpXX_add(x,y,p): FpX_add(x,y,p); }2362INLINE GEN2363FqX_neg(GEN x,GEN T,GEN p) { return T? FpXX_neg(x,p): FpX_neg(x,p); }2364INLINE GEN2365FqX_sub(GEN x,GEN y,GEN T,GEN p) { return T? FpXX_sub(x,y,p): FpX_sub(x,y,p); }2366INLINE GEN2367FqX_Fp_mul(GEN P, GEN u, GEN T, GEN p)2368{ return T? FpXX_Fp_mul(P, u, p): FpX_Fp_mul(P, u, p); }2369INLINE GEN2370FqX_Fq_mul(GEN P, GEN U, GEN T, GEN p)2371{ return typ(U)==t_INT ? FqX_Fp_mul(P, U, T, p): FpXQX_FpXQ_mul(P, U, T, p); }2372INLINE GEN2373FqX_mul(GEN x, GEN y, GEN T, GEN p)2374{ return T? FpXQX_mul(x, y, T, p): FpX_mul(x, y, p); }2375INLINE GEN2376FqX_mulu(GEN x, ulong y, GEN T, GEN p)2377{ return T? FpXX_mulu(x, y, p): FpX_mulu(x, y, p); }2378INLINE GEN2379FqX_sqr(GEN x, GEN T, GEN p)2380{ return T? FpXQX_sqr(x, T, p): FpX_sqr(x, p); }2381INLINE GEN2382FqX_powu(GEN x, ulong n, GEN T, GEN p)2383{ return T? FpXQX_powu(x, n, T, p): FpX_powu(x, n, p); }2384INLINE GEN2385FqX_halve(GEN x, GEN T, GEN p)2386{ return T? FpXX_halve(x, p): FpX_halve(x, p); }2387INLINE GEN2388FqX_div(GEN x, GEN y, GEN T, GEN p)2389{ return T? FpXQX_divrem(x,y,T,p,NULL): FpX_divrem(x,y,p,NULL); }2390INLINE GEN2391FqX_get_red(GEN S, GEN T, GEN p)2392{ return T? FpXQX_get_red(S,T,p): FpX_get_red(S,p); }2393INLINE GEN2394FqX_rem(GEN x, GEN y, GEN T, GEN p)2395{ return T? FpXQX_rem(x,y,T,p): FpX_rem(x,y,p); }2396INLINE GEN2397FqX_divrem(GEN x, GEN y, GEN T, GEN p, GEN *z)2398{ return T? FpXQX_divrem(x,y,T,p,z): FpX_divrem(x,y,p,z); }2399INLINE GEN2400FqX_div_by_X_x(GEN x, GEN y, GEN T, GEN p, GEN *z)2401{ return T? FpXQX_div_by_X_x(x,y,T,p,z): FpX_div_by_X_x(x,y,p,z); }2402INLINE GEN2403FqX_halfgcd(GEN P,GEN Q,GEN T,GEN p)2404{return T? FpXQX_halfgcd(P,Q,T,p): FpX_halfgcd(P,Q,p);}2405INLINE GEN2406FqX_gcd(GEN P,GEN Q,GEN T,GEN p)2407{return T? FpXQX_gcd(P,Q,T,p): FpX_gcd(P,Q,p);}2408INLINE GEN2409FqX_extgcd(GEN P,GEN Q,GEN T,GEN p, GEN *U, GEN *V)2410{ return T? FpXQX_extgcd(P,Q,T,p,U,V): FpX_extgcd(P,Q,p,U,V); }2411INLINE GEN2412FqX_normalize(GEN z, GEN T, GEN p)2413{ return T? FpXQX_normalize(z, T, p): FpX_normalize(z, p); }2414INLINE GEN2415FqX_deriv(GEN f, GEN T, GEN p) { return T? FpXX_deriv(f, p): FpX_deriv(f, p); }2416INLINE GEN2417FqX_integ(GEN f, GEN T, GEN p) { return T? FpXX_integ(f, p): FpX_integ(f, p); }2418INLINE GEN2419FqX_factor(GEN f, GEN T, GEN p)2420{ return T?FpXQX_factor(f, T, p): FpX_factor(f, p); }2421INLINE GEN2422FqX_factor_squarefree(GEN f, GEN T, GEN p)2423{ return T ? FpXQX_factor_squarefree(f, T, p): FpX_factor_squarefree(f, p); }2424INLINE GEN2425FqX_ddf(GEN f, GEN T, GEN p)2426{ return T ? FpXQX_ddf(f, T, p): FpX_ddf(f, p); }2427INLINE GEN2428FqX_degfact(GEN f, GEN T, GEN p)2429{ return T?FpXQX_degfact(f, T, p): FpX_degfact(f, p); }2430INLINE GEN2431FqX_roots(GEN f, GEN T, GEN p)2432{ return T?FpXQX_roots(f, T, p): FpX_roots(f, p); }2433INLINE GEN2434FqX_to_mod(GEN f, GEN T, GEN p)2435{ return T?FpXQX_to_mod(f, T, p): FpX_to_mod(f, p); }24362437/*FqXQ*/2438INLINE GEN2439FqXQ_add(GEN x, GEN y, GEN S/*unused*/, GEN T, GEN p)2440{ (void)S; return T? FpXX_add(x,y,p): FpX_add(x,y,p); }2441INLINE GEN2442FqXQ_sub(GEN x, GEN y, GEN S/*unused*/, GEN T, GEN p)2443{ (void)S; return T? FpXX_sub(x,y,p): FpX_sub(x,y,p); }2444INLINE GEN2445FqXQ_div(GEN x, GEN y, GEN S, GEN T, GEN p)2446{ return T? FpXQXQ_div(x,y,S,T,p): FpXQ_div(x,y,S,p); }2447INLINE GEN2448FqXQ_inv(GEN x, GEN S, GEN T, GEN p)2449{ return T? FpXQXQ_inv(x,S,T,p): FpXQ_inv(x,S,p); }2450INLINE GEN2451FqXQ_invsafe(GEN x, GEN S, GEN T, GEN p)2452{ return T? FpXQXQ_invsafe(x,S,T,p): FpXQ_inv(x,S,p); }2453INLINE GEN2454FqXQ_mul(GEN x, GEN y, GEN S, GEN T, GEN p)2455{ return T? FpXQXQ_mul(x,y,S,T,p): FpXQ_mul(x,y,S,p); }2456INLINE GEN2457FqXQ_sqr(GEN x, GEN S, GEN T, GEN p)2458{ return T? FpXQXQ_sqr(x,S,T,p): FpXQ_sqr(x,S,p); }2459INLINE GEN2460FqXQ_pow(GEN x, GEN n, GEN S, GEN T, GEN p)2461{ return T? FpXQXQ_pow(x,n,S,T,p): FpXQ_pow(x,n,S,p); }24622463/*FqXn*/2464INLINE GEN2465FqXn_expint(GEN x, long n, GEN T, GEN p)2466{ return T? FpXQXn_expint(x,n,T,p): FpXn_expint(x,n,p); }2467INLINE GEN2468FqXn_exp(GEN x, long n, GEN T, GEN p)2469{ return T? FpXQXn_exp(x,n,T,p): FpXn_exp(x,n,p); }2470INLINE GEN2471FqXn_inv(GEN x, long n, GEN T, GEN p)2472{ return T? FpXQXn_inv(x,n,T,p): FpXn_inv(x,n,p); }2473INLINE GEN2474FqXn_mul(GEN x, GEN y, long n, GEN T, GEN p)2475{ return T? FpXQXn_mul(x, y, n, T, p): FpXn_mul(x, y, n, p); }2476INLINE GEN2477FqXn_sqr(GEN x, long n, GEN T, GEN p)2478{ return T? FpXQXn_sqr(x,n,T,p): FpXn_sqr(x,n,p); }24792480/*FpXQ*/2481INLINE GEN2482FpXQ_add(GEN x,GEN y,GEN T/*unused*/,GEN p)2483{ (void)T; return FpX_add(x,y,p); }2484INLINE GEN2485FpXQ_sub(GEN x,GEN y,GEN T/*unused*/,GEN p)2486{ (void)T; return FpX_sub(x,y,p); }24872488/*Flxq*/2489INLINE GEN2490Flxq_add(GEN x,GEN y,GEN T/*unused*/,ulong p)2491{ (void)T; return Flx_add(x,y,p); }2492INLINE GEN2493Flxq_sub(GEN x,GEN y,GEN T/*unused*/,ulong p)2494{ (void)T; return Flx_sub(x,y,p); }24952496/* F2x */24972498INLINE ulong2499F2x_coeff(GEN x,long v)2500{2501ulong u=(ulong)x[2+divsBIL(v)];2502return (u>>remsBIL(v))&1UL;2503}25042505INLINE void2506F2x_clear(GEN x,long v)2507{2508ulong* u=(ulong*)&x[2+divsBIL(v)];2509*u&=~(1UL<<remsBIL(v));2510}25112512INLINE void2513F2x_set(GEN x,long v)2514{2515ulong* u=(ulong*)&x[2+divsBIL(v)];2516*u|=1UL<<remsBIL(v);2517}25182519INLINE void2520F2x_flip(GEN x,long v)2521{2522ulong* u=(ulong*)&x[2+divsBIL(v)];2523*u^=1UL<<remsBIL(v);2524}25252526/* F2v */25272528INLINE ulong2529F2v_coeff(GEN x,long v) { return F2x_coeff(x,v-1); }25302531INLINE void2532F2v_clear(GEN x,long v) { F2x_clear(x,v-1); }25332534INLINE void2535F2v_set(GEN x,long v) { F2x_set(x,v-1); }25362537INLINE void2538F2v_flip(GEN x,long v) { F2x_flip(x,v-1); }25392540/* F2m */25412542INLINE ulong2543F2m_coeff(GEN x, long a, long b) { return F2v_coeff(gel(x,b), a); }25442545INLINE void2546F2m_clear(GEN x, long a, long b) { F2v_clear(gel(x,b), a); }25472548INLINE void2549F2m_set(GEN x, long a, long b) { F2v_set(gel(x,b), a); }25502551INLINE void2552F2m_flip(GEN x, long a, long b) { F2v_flip(gel(x,b), a); }25532554/* F3m */25552556INLINE ulong2557F3m_coeff(GEN x, long a, long b) { return F3v_coeff(gel(x,b), a); }25582559INLINE void2560F3m_set(GEN x, long a, long b, ulong c) { F3v_set(gel(x,b), a, c); }25612562/* ARITHMETIC */2563INLINE GEN2564matpascal(long n) { return matqpascal(n, NULL); }2565INLINE long2566Z_issquare(GEN x) { return Z_issquareall(x, NULL); }2567INLINE long2568Z_ispower(GEN x, ulong k) { return Z_ispowerall(x, k, NULL); }2569INLINE GEN2570sqrti(GEN x) { return sqrtremi(x,NULL); }2571INLINE GEN2572gaddgs(GEN y, long s) { return gaddsg(s,y); }2573INLINE int2574gcmpgs(GEN y, long s) { return -gcmpsg(s,y); }2575INLINE int2576gequalgs(GEN y, long s) { return gequalsg(s,y); }2577INLINE GEN2578gmaxsg(long s, GEN y) { return gmaxgs(y,s); }2579INLINE GEN2580gminsg(long s, GEN y) { return gmings(y,s); }2581INLINE GEN2582gmulgs(GEN y, long s) { return gmulsg(s,y); }2583INLINE GEN2584gsubgs(GEN y, long s) { return gaddgs(y, -s); }2585INLINE GEN2586gdivsg(long s, GEN y) { return gdiv(stoi(s), y); }25872588INLINE GEN2589gmax_shallow(GEN x, GEN y) { return gcmp(x,y)<0? y: x; }2590INLINE GEN2591gmin_shallow(GEN x, GEN y) { return gcmp(x,y)<0? x: y; }25922593/* x t_COMPLEX */2594INLINE GEN2595cxnorm(GEN x) { return gadd(gsqr(gel(x,1)), gsqr(gel(x,2))); }2596/* q t_QUAD */2597INLINE GEN2598quadnorm(GEN q)2599{2600GEN X = gel(q,1), b = gel(X,3), c = gel(X,2);2601GEN z, u = gel(q,3), v = gel(q,2);2602if (typ(u) == t_INT && typ(v) == t_INT) /* generic case */2603{2604z = signe(b)? mulii(v, addii(u,v)): sqri(v);2605return addii(z, mulii(c, sqri(u)));2606}2607else2608{2609z = signe(b)? gmul(v, gadd(u,v)): gsqr(v);2610return gadd(z, gmul(c, gsqr(u)));2611}2612}2613/* x a t_QUAD, return the attached discriminant */2614INLINE GEN2615quad_disc(GEN x)2616{2617GEN Q = gel(x,1), b = gel(Q,3), c = gel(Q,2), c4 = shifti(c,2);2618if (is_pm1(b)) return subsi(1, c4);2619togglesign_safe(&c4); return c4;2620}2621INLINE GEN2622qfb_disc3(GEN x, GEN y, GEN z) { return subii(sqri(y), shifti(mulii(x,z),2)); }2623INLINE GEN2624qfb_disc(GEN x) { return gel(x,4); }26252626INLINE GEN2627sqrfrac(GEN x)2628{2629GEN z = cgetg(3,t_FRAC);2630gel(z,1) = sqri(gel(x,1));2631gel(z,2) = sqri(gel(x,2)); return z;2632}26332634INLINE void2635normalize_frac(GEN z) {2636if (signe(gel(z,2)) < 0) { togglesign(gel(z,1)); setabssign(gel(z,2)); }2637}26382639INLINE GEN2640powii(GEN x, GEN n)2641{2642long ln = lgefint(n);2643if (ln == 3) {2644GEN z;2645if (signe(n) > 0) return powiu(x, n[2]);2646z = cgetg(3, t_FRAC);2647gel(z,1) = gen_1;2648gel(z,2) = powiu(x, n[2]);2649return z;2650}2651if (ln == 2) return gen_1; /* rare */2652/* should never happen */2653return powgi(x, n); /* overflow unless x = 0, 1, -1 */2654}2655INLINE GEN2656powIs(long n) {2657switch(n & 3)2658{2659case 1: return mkcomplex(gen_0,gen_1);2660case 2: return gen_m1;2661case 3: return mkcomplex(gen_0,gen_m1);2662}2663return gen_1;2664}26652666/*******************************************************************/2667/* */2668/* ASSIGNMENTS */2669/* */2670/*******************************************************************/2671INLINE void mpexpz(GEN x, GEN z)2672{ pari_sp av = avma; gaffect(mpexp(x), z); set_avma(av); }2673INLINE void mplogz(GEN x, GEN z)2674{ pari_sp av = avma; gaffect(mplog(x), z); set_avma(av); }2675INLINE void mpcosz(GEN x, GEN z)2676{ pari_sp av = avma; gaffect(mpcos(x), z); set_avma(av); }2677INLINE void mpsinz(GEN x, GEN z)2678{ pari_sp av = avma; gaffect(mpsin(x), z); set_avma(av); }2679INLINE void gnegz(GEN x, GEN z)2680{ pari_sp av = avma; gaffect(gneg(x), z); set_avma(av); }2681INLINE void gabsz(GEN x, long prec, GEN z)2682{ pari_sp av = avma; gaffect(gabs(x,prec), z); set_avma(av); }2683INLINE void gaddz(GEN x, GEN y, GEN z)2684{ pari_sp av = avma; gaffect(gadd(x,y), z); set_avma(av); }2685INLINE void gsubz(GEN x, GEN y, GEN z)2686{ pari_sp av = avma; gaffect(gsub(x,y), z); set_avma(av); }2687INLINE void gmulz(GEN x, GEN y, GEN z)2688{ pari_sp av = avma; gaffect(gmul(x,y), z); set_avma(av); }2689INLINE void gdivz(GEN x, GEN y, GEN z)2690{ pari_sp av = avma; gaffect(gdiv(x,y), z); set_avma(av); }2691INLINE void gdiventz(GEN x, GEN y, GEN z)2692{ pari_sp av = avma; gaffect(gdivent(x,y), z); set_avma(av); }2693INLINE void gmodz(GEN x, GEN y, GEN z)2694{ pari_sp av = avma; gaffect(gmod(x,y), z); set_avma(av); }2695INLINE void gmul2nz(GEN x, long s, GEN z)2696{ pari_sp av = avma; gaffect(gmul2n(x,s), z); set_avma(av); }2697INLINE void gshiftz(GEN x, long s, GEN z)2698{ pari_sp av = avma; gaffect(gshift(x,s), z); set_avma(av); }26992700/*******************************************************************/2701/* */2702/* ELLIPTIC CURVES */2703/* */2704/*******************************************************************/2705INLINE GEN ell_get_a1(GEN e) { return gel(e,1); }2706INLINE GEN ell_get_a2(GEN e) { return gel(e,2); }2707INLINE GEN ell_get_a3(GEN e) { return gel(e,3); }2708INLINE GEN ell_get_a4(GEN e) { return gel(e,4); }2709INLINE GEN ell_get_a6(GEN e) { return gel(e,5); }2710INLINE GEN ell_get_b2(GEN e) { return gel(e,6); }2711INLINE GEN ell_get_b4(GEN e) { return gel(e,7); }2712INLINE GEN ell_get_b6(GEN e) { return gel(e,8); }2713INLINE GEN ell_get_b8(GEN e) { return gel(e,9); }2714INLINE GEN ell_get_c4(GEN e) { return gel(e,10); }2715INLINE GEN ell_get_c6(GEN e) { return gel(e,11); }2716INLINE GEN ell_get_disc(GEN e) { return gel(e,12); }2717INLINE GEN ell_get_j(GEN e) { return gel(e,13); }2718INLINE long ell_get_type(GEN e) { return mael(e,14,1); }2719INLINE GEN ellff_get_field(GEN x) { return gmael(x, 15, 1); }2720INLINE GEN ellff_get_a4a6(GEN x) { return gmael(x, 15, 2); }2721INLINE GEN ellQp_get_zero(GEN x) { return gmael(x, 15, 1); }2722INLINE long ellQp_get_prec(GEN E) { GEN z = ellQp_get_zero(E); return valp(z); }2723INLINE GEN ellQp_get_p(GEN E) { GEN z = ellQp_get_zero(E); return gel(z,2); }2724INLINE long ellR_get_prec(GEN x) { return nbits2prec(mael3(x, 15, 1, 1)); }2725INLINE long ellR_get_sign(GEN x) { return mael3(x, 15, 1, 2); }2726INLINE GEN ellnf_get_nf(GEN x) { return checknf_i(gmael(x,15,1)); }2727INLINE GEN ellnf_get_bnf(GEN x) { return checkbnf_i(gmael(x,15,1)); }27282729INLINE int checkell_i(GEN e) { return typ(e) == t_VEC && lg(e) == 17; }2730INLINE int ell_is_inf(GEN z) { return lg(z) == 2; }2731INLINE GEN ellinf(void) { return mkvec(gen_0); }27322733/*******************************************************************/2734/* */2735/* ALGEBRAIC NUMBER THEORY */2736/* */2737/*******************************************************************/2738INLINE GEN modpr_get_pr(GEN x) { return gel(x,3); }2739INLINE GEN modpr_get_p(GEN x) { return pr_get_p(modpr_get_pr(x)); }2740INLINE GEN modpr_get_T(GEN x) { return lg(x) == 4? NULL: gel(x,4); }27412742INLINE GEN pr_get_p(GEN pr) { return gel(pr,1); }2743INLINE GEN pr_get_gen(GEN pr){ return gel(pr,2); }2744/* .[2] instead of itos works: e and f are small positive integers */2745INLINE long pr_get_e(GEN pr) { return gel(pr,3)[2]; }2746INLINE long pr_get_f(GEN pr) { return gel(pr,4)[2]; }2747INLINE GEN pr_get_tau(GEN pr){ return gel(pr,5); }2748INLINE int2749pr_is_inert(GEN P) { return typ(pr_get_tau(P)) == t_INT; }2750INLINE GEN2751pr_norm(GEN pr) { return powiu(pr_get_p(pr), pr_get_f(pr)); }2752INLINE ulong2753upr_norm(GEN pr) { return upowuu(pr_get_p(pr)[2], pr_get_f(pr)); }27542755/* assume nf a genuine nf */2756INLINE long2757nf_get_varn(GEN nf) { return varn(gel(nf,1)); }2758INLINE GEN2759nf_get_pol(GEN nf) { return gel(nf,1); }2760INLINE long2761nf_get_degree(GEN nf) { return degpol( nf_get_pol(nf) ); }2762INLINE long2763nf_get_r1(GEN nf) { GEN x = gel(nf,2); return itou(gel(x,1)); }2764INLINE long2765nf_get_r2(GEN nf) { GEN x = gel(nf,2); return itou(gel(x,2)); }2766INLINE GEN2767nf_get_disc(GEN nf) { return gel(nf,3); }2768INLINE GEN2769nf_get_index(GEN nf) { return gel(nf,4); }2770INLINE GEN2771nf_get_M(GEN nf) { return gmael(nf,5,1); }2772INLINE GEN2773nf_get_G(GEN nf) { return gmael(nf,5,2); }2774INLINE GEN2775nf_get_roundG(GEN nf) { return gmael(nf,5,3); }2776INLINE GEN2777nf_get_Tr(GEN nf) { return gmael(nf,5,4); }2778INLINE GEN2779nf_get_diff(GEN nf) { return gmael(nf,5,5); }2780INLINE GEN2781nf_get_ramified_primes(GEN nf) { return gmael(nf,5,8); }2782INLINE GEN2783nf_get_roots(GEN nf) { return gel(nf,6); }2784INLINE GEN2785nf_get_zk(GEN nf)2786{2787GEN y = gel(nf,7), D = gel(y, 1);2788if (typ(D) == t_POL) D = gel(D, 2);2789if (!equali1(D)) y = gdiv(y, D);2790return y;2791}2792INLINE GEN2793nf_get_zkprimpart(GEN nf)2794{2795GEN y = gel(nf,7);2796/* test for old format of nf.zk: non normalized */2797if (!equali1(gel(nf,4)) && gequal1(gel(y,1))) y = Q_remove_denom(y,NULL);2798return y;2799}2800INLINE GEN2801nf_get_zkden(GEN nf)2802{2803GEN y = gel(nf,7), D = gel(y,1);2804if (typ(D) == t_POL) D = gel(D,2);2805/* test for old format of nf.zk: non normalized */2806if (!equali1(gel(nf,4)) && equali1(D)) D = Q_denom(y);2807return D;2808}2809INLINE GEN2810nf_get_invzk(GEN nf) { return gel(nf,8); }2811INLINE void2812nf_get_sign(GEN nf, long *r1, long *r2)2813{2814GEN x = gel(nf,2);2815*r1 = itou(gel(x,1));2816*r2 = itou(gel(x,2));2817}28182819INLINE GEN2820cyc_get_expo(GEN c) { return lg(c) == 1? gen_1: gel(c,1); }2821INLINE GEN2822abgrp_get_no(GEN x) { return gel(x,1); }2823INLINE GEN2824abgrp_get_cyc(GEN x) { return gel(x,2); }2825INLINE GEN2826abgrp_get_gen(GEN x) { return gel(x,3); }2827INLINE GEN2828bnf_get_nf(GEN bnf) { return gel(bnf,7); }2829INLINE GEN2830bnf_get_clgp(GEN bnf) { return gmael(bnf,8,1); }2831INLINE GEN2832bnf_get_no(GEN bnf) { return abgrp_get_no(bnf_get_clgp(bnf)); }2833INLINE GEN2834bnf_get_cyc(GEN bnf) { return abgrp_get_cyc(bnf_get_clgp(bnf)); }2835INLINE GEN2836bnf_get_gen(GEN bnf) { return abgrp_get_gen(bnf_get_clgp(bnf)); }2837INLINE GEN2838bnf_get_reg(GEN bnf) { return gmael(bnf,8,2); }2839INLINE GEN2840bnf_get_logfu(GEN bnf) { return gel(bnf,3); }2841INLINE GEN2842bnf_get_sunits(GEN bnf)2843{ GEN s = gmael(bnf,8,3); return typ(s) == t_INT? NULL: s; }2844INLINE GEN2845bnf_get_tuU(GEN bnf) { return gmael3(bnf,8,4,2); }2846INLINE long2847bnf_get_tuN(GEN bnf) { return gmael3(bnf,8,4,1)[2]; }2848INLINE GEN2849bnf_get_fu_nocheck(GEN bnf) { return gmael(bnf,8,5); }2850INLINE GEN2851bnf_get_fu(GEN bnf) {2852GEN fu = bnf_build_units(bnf), nf = bnf_get_nf(bnf);2853long i, l;2854if (typ(fu) == t_MAT) pari_err(e_MISC,"missing units in bnf");2855l = lg(fu)-1; fu = vecslice(fu, 2, l);2856for (i = 1; i < l; i++) gel(fu,i) = nf_to_scalar_or_alg(nf, gel(fu,i));2857return fu;2858}28592860INLINE GEN2861bnr_get_bnf(GEN bnr) { return gel(bnr,1); }2862INLINE GEN2863bnr_get_bid(GEN bnr) { return gel(bnr,2); }2864INLINE GEN2865bnr_get_mod(GEN bnr) { return gmael(bnr,2,1); }2866INLINE GEN2867bnr_get_nf(GEN bnr) { return gmael(bnr,1,7); }2868INLINE GEN2869bnr_get_clgp(GEN bnr) { return gel(bnr,5); }2870INLINE GEN2871bnr_get_no(GEN bnr) { return abgrp_get_no(bnr_get_clgp(bnr)); }2872INLINE GEN2873bnr_get_cyc(GEN bnr) { return abgrp_get_cyc(bnr_get_clgp(bnr)); }2874INLINE GEN2875bnr_get_gen_nocheck(GEN bnr) { return abgrp_get_gen(bnr_get_clgp(bnr)); }2876INLINE GEN2877bnr_get_gen(GEN bnr) {2878GEN G = bnr_get_clgp(bnr);2879if (lg(G) != 4)2880pari_err(e_MISC,"missing bnr generators: please use bnrinit(,,1)");2881return gel(G,3);2882}28832884INLINE GEN2885bid_get_mod(GEN bid) { return gel(bid,1); }2886INLINE GEN2887bid_get_ideal(GEN bid) { return gmael(bid,1,1); }2888INLINE GEN2889bid_get_arch(GEN bid) { return gmael(bid,1,2); }2890INLINE GEN2891bid_get_grp(GEN bid) { return gel(bid,2); }2892INLINE GEN2893bid_get_fact(GEN bid) { return gmael(bid,3,1); }2894INLINE GEN2895bid_get_fact2(GEN bid) { return gmael(bid,3,2); }2896INLINE GEN2897bid_get_sprk(GEN bid) { return gmael(bid,4,1); }2898INLINE GEN2899bid_get_sarch(GEN bid) { return gmael(bid,4,2); }2900INLINE GEN2901bid_get_archp(GEN bid) { return gmael3(bid,4,2,2); }2902INLINE GEN2903bid_get_U(GEN bid) { return gel(bid,5); }2904INLINE GEN2905bid_get_no(GEN bid) { return abgrp_get_no(bid_get_grp(bid)); }2906INLINE GEN2907bid_get_cyc(GEN bid) { return abgrp_get_cyc(bid_get_grp(bid)); }2908INLINE GEN2909bid_get_gen_nocheck(GEN bid) { return abgrp_get_gen(bid_get_grp(bid)); }2910INLINE GEN2911bid_get_gen(GEN bid) {2912GEN G = bid_get_grp(bid);2913if (lg(G) != 4) pari_err(e_MISC,"missing bid generators. Use idealstar(,,2)");2914return abgrp_get_gen(G);2915}29162917INLINE GEN2918znstar_get_N(GEN G) { return gmael(G,1,1); }2919INLINE GEN2920znstar_get_faN(GEN G) { return gel(G,3); }2921INLINE GEN2922znstar_get_no(GEN G) { return abgrp_get_no(gel(G,2)); }2923INLINE GEN2924znstar_get_cyc(GEN G) { return abgrp_get_cyc(gel(G,2)); }2925INLINE GEN2926znstar_get_gen(GEN G) { return abgrp_get_gen(gel(G,2)); }2927INLINE GEN2928znstar_get_conreycyc(GEN G) { return gmael(G,4,5); }2929INLINE GEN2930znstar_get_conreygen(GEN G) { return gmael(G,4,4); }2931INLINE GEN2932znstar_get_Ui(GEN G) { return gmael(G,4,3); }2933INLINE GEN2934znstar_get_U(GEN G) { return gel(G,5); }2935INLINE GEN2936znstar_get_pe(GEN G) { return gmael(G,4,1); }2937INLINE GEN2938gal_get_pol(GEN gal) { return gel(gal,1); }2939INLINE GEN2940gal_get_p(GEN gal) { return gmael(gal,2,1); }2941INLINE GEN2942gal_get_e(GEN gal) { return gmael(gal,2,2); }2943INLINE GEN2944gal_get_mod(GEN gal) { return gmael(gal,2,3); }2945INLINE GEN2946gal_get_roots(GEN gal) { return gel(gal,3); }2947INLINE GEN2948gal_get_invvdm(GEN gal) { return gel(gal,4); }2949INLINE GEN2950gal_get_den(GEN gal) { return gel(gal,5); }2951INLINE GEN2952gal_get_group(GEN gal) { return gel(gal,6); }2953INLINE GEN2954gal_get_gen(GEN gal) { return gel(gal,7); }2955INLINE GEN2956gal_get_orders(GEN gal) { return gel(gal,8); }29572958/* assume rnf a genuine rnf */2959INLINE long2960rnf_get_degree(GEN rnf) { return degpol(rnf_get_pol(rnf)); }2961INLINE long2962rnf_get_nfdegree(GEN rnf) { return degpol(nf_get_pol(rnf_get_nf(rnf))); }2963INLINE long2964rnf_get_absdegree(GEN rnf) { return degpol(gmael(rnf,11,1)); }2965INLINE GEN2966rnf_get_idealdisc(GEN rnf) { return gmael(rnf,3,1); }2967INLINE GEN2968rnf_get_k(GEN rnf) { return gmael(rnf,11,3); }2969INLINE GEN2970rnf_get_alpha(GEN rnf) { return gmael(rnf, 11, 2); }2971INLINE GEN2972rnf_get_nf(GEN rnf) { return gel(rnf,10); }2973INLINE GEN2974rnf_get_nfzk(GEN rnf) { return gel(rnf,2); }2975INLINE GEN2976rnf_get_polabs(GEN rnf) { return gmael(rnf,11,1); }2977INLINE GEN2978rnf_get_pol(GEN rnf) { return gel(rnf,1); }2979INLINE GEN2980rnf_get_disc(GEN rnf) { return gel(rnf,3); }2981INLINE GEN2982rnf_get_index(GEN rnf) { return gel(rnf,4); }2983INLINE GEN2984rnf_get_ramified_primes(GEN rnf) { return gel(rnf,5); }2985INLINE long2986rnf_get_varn(GEN rnf) { return varn(gel(rnf,1)); }2987INLINE GEN2988rnf_get_nfpol(GEN rnf) { return gmael(rnf,10,1); }2989INLINE long2990rnf_get_nfvarn(GEN rnf) { return varn(gmael(rnf,10,1)); }2991INLINE GEN2992rnf_get_zk(GEN rnf) { return gel(rnf,7); }2993INLINE GEN2994rnf_get_map(GEN rnf) { return gel(rnf,11); }2995INLINE GEN2996rnf_get_invzk(GEN rnf) { return gel(rnf,8); }29972998/* I integral ZM (not HNF), G ZM, rounded Cholesky form of a weighted2999* T2 matrix. Reduce I wrt G */3000INLINE GEN3001idealpseudored(GEN I, GEN G)3002{ return ZM_mul(I, ZM_lll(ZM_mul(G, I), 0.99, LLL_IM)); }30033004/* Same I, G; m in I with T2(m) small */3005INLINE GEN3006idealpseudomin(GEN I, GEN G)3007{3008GEN u = ZM_lll(ZM_mul(G, I), 0.99, LLL_IM);3009return ZM_ZC_mul(I, gel(u,1));3010}3011/* Same I,G; irrational m in I with T2(m) small */3012INLINE GEN3013idealpseudomin_nonscalar(GEN I, GEN G)3014{3015GEN u = ZM_lll(ZM_mul(G, I), 0.99, LLL_IM);3016GEN m = ZM_ZC_mul(I, gel(u,1));3017if (ZV_isscalar(m) && lg(u) > 2) m = ZM_ZC_mul(I, gel(u,2));3018return m;3019}3020/* Same I,G; t_VEC of irrational m in I with T2(m) small */3021INLINE GEN3022idealpseudominvec(GEN I, GEN G)3023{3024long i, j, k, n = lg(I)-1;3025GEN x, L, b = idealpseudored(I, G);3026L = cgetg(1 + (n*(n+1))/2, t_VEC);3027for (i = k = 1; i <= n; i++)3028{3029x = gel(b,i);3030if (!ZV_isscalar(x)) gel(L,k++) = x;3031}3032for (i = 2; i <= n; i++)3033for (j = 1; j < i; j++)3034{3035x = ZC_add(gel(b,i),gel(b,j));3036if (!ZV_isscalar(x)) gel(L,k++) = x;3037}3038setlg(L,k); return L;3039}30403041INLINE GEN3042idealred_elt(GEN nf, GEN I) {3043pari_sp av = avma;3044GEN u = idealpseudomin(I, nf_get_roundG(nf));3045return gerepileupto(av, u);3046}3047INLINE GEN3048idealred(GEN nf, GEN I) { return idealred0(nf, I, NULL); }30493050INLINE GEN3051idealchineseinit(GEN nf, GEN x)3052{ return idealchinese(nf,x,NULL); }30533054/*******************************************************************/3055/* */3056/* CLOSURES */3057/* */3058/*******************************************************************/3059INLINE long closure_arity(GEN C) { return ((ulong)C[1])&ARITYBITS; }3060INLINE long closure_is_variadic(GEN C) { return !!(((ulong)C[1])&VARARGBITS); }3061INLINE const char *closure_codestr(GEN C) { return GSTR(gel(C,2))-1; }3062INLINE GEN closure_get_code(GEN C) { return gel(C,2); }3063INLINE GEN closure_get_oper(GEN C) { return gel(C,3); }3064INLINE GEN closure_get_data(GEN C) { return gel(C,4); }3065INLINE GEN closure_get_dbg(GEN C) { return gel(C,5); }3066INLINE GEN closure_get_text(GEN C) { return gel(C,6); }3067INLINE GEN closure_get_frame(GEN C) { return gel(C,7); }30683069/*******************************************************************/3070/* */3071/* ERRORS */3072/* */3073/*******************************************************************/3074INLINE long3075err_get_num(GEN e) { return e[1]; }3076INLINE GEN3077err_get_compo(GEN e, long i) { return gel(e, i+1); }30783079INLINE void3080pari_err_BUG(const char *f) { pari_err(e_BUG,f); }3081INLINE void3082pari_err_CONSTPOL(const char *f) { pari_err(e_CONSTPOL, f); }3083INLINE void3084pari_err_COPRIME(const char *f, GEN x, GEN y) { pari_err(e_COPRIME, f,x,y); }3085INLINE void3086pari_err_DIM(const char *f) { pari_err(e_DIM, f); }3087INLINE void3088pari_err_FILE(const char *f, const char *g) { pari_err(e_FILE, f,g); }3089INLINE void3090pari_err_FILEDESC(const char *f, long n) { pari_err(e_FILEDESC, f,n); }3091INLINE void3092pari_err_FLAG(const char *f) { pari_err(e_FLAG,f); }3093INLINE void3094pari_err_IMPL(const char *f) { pari_err(e_IMPL,f); }3095INLINE void3096pari_err_INV(const char *f, GEN x) { pari_err(e_INV,f,x); }3097INLINE void3098pari_err_IRREDPOL(const char *f, GEN x) { pari_err(e_IRREDPOL, f,x); }3099INLINE void3100pari_err_DOMAIN(const char *f, const char *v, const char *op, GEN l, GEN x) { pari_err(e_DOMAIN, f,v,op,l,x); }3101INLINE void3102pari_err_COMPONENT(const char *f, const char *op, GEN l, GEN x) { pari_err(e_COMPONENT, f,op,l,x); }3103INLINE void3104pari_err_MAXPRIME(ulong c) { pari_err(e_MAXPRIME, c); }3105INLINE void3106pari_err_OP(const char *f, GEN x, GEN y) { pari_err(e_OP, f,x,y); }3107INLINE void3108pari_err_OVERFLOW(const char *f) { pari_err(e_OVERFLOW, f); }3109INLINE void3110pari_err_PREC(const char *f) { pari_err(e_PREC,f); }3111INLINE void3112pari_err_PACKAGE(const char *f) { pari_err(e_PACKAGE,f); }3113INLINE void3114pari_err_PRIME(const char *f, GEN x) { pari_err(e_PRIME, f,x); }3115INLINE void3116pari_err_MODULUS(const char *f, GEN x, GEN y) { pari_err(e_MODULUS, f,x,y); }3117INLINE void3118pari_err_ROOTS0(const char *f) { pari_err(e_ROOTS0, f); }3119INLINE void3120pari_err_SQRTN(const char *f, GEN x) { pari_err(e_SQRTN, f,x); }3121INLINE void3122pari_err_TYPE(const char *f, GEN x) { pari_err(e_TYPE, f,x); }3123INLINE void3124pari_err_TYPE2(const char *f, GEN x, GEN y) { pari_err(e_TYPE2, f,x,y); }3125INLINE void3126pari_err_VAR(const char *f, GEN x, GEN y) { pari_err(e_VAR, f,x,y); }3127INLINE void3128pari_err_PRIORITY(const char *f, GEN x, const char *op, long v)3129{ pari_err(e_PRIORITY, f,x,op,v); }313031313132