Testing latest pari + WASM + node.js... and it works?! Wow.
License: GPL3
ubuntu2004
/* Copyright (C) 2000, 2012 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#include "pari.h"15#include "paripriv.h"16/*******************************************************************/17/* */18/* Conversion --> t_SER */19/* */20/*******************************************************************/21static GEN22RgX_to_ser_i(GEN x, long l, long v, int copy)23{24long i = 2, lx = lg(x), vx = varn(x);25GEN y;26if (lx == 2) return zeroser(vx, minss(l - 2, v));27if (l <= 2)28{29if (l == 2 && v != LONG_MAX) return zeroser(vx, v);30pari_err_BUG("RgX_to_ser (l < 2)");31}32y = cgetg(l,t_SER);33if (v == LONG_MAX) { v = 1; lx = 3; } /* e.g. Mod(0,3) * x^0 */34else if (v)35{36long w = v;37while (isrationalzero(gel(x,2))) { x++; w--; }38lx -= v;39if (w)40{ /* keep type information, e.g. Mod(0,3) + x */41GEN z = gel(x,2); /* = 0 */42if (lx <= 2) gel(y,2) = copy? gcopy(z): z;43else { x += w; gel(y,2) = gadd(gel(x,2), z); }44i++;45}46}47y[1] = evalvarn(vx) | evalvalp(v); /* must come here because of LONG_MAX */48if (lx > l) lx = l;49/* 2 <= lx <= l */50if (copy)51for (; i <lx; i++) gel(y,i) = gcopy(gel(x,i));52else53for (; i <lx; i++) gel(y,i) = gel(x,i);54for ( ; i < l; i++) gel(y,i) = gen_0;55return normalize(y);56}57/* enlarge/truncate t_POL x to a t_SER with lg l */58GEN59RgX_to_ser(GEN x, long l) { return RgX_to_ser_i(x, l, RgX_val(x), 0); }60GEN61RgX_to_ser_inexact(GEN x, long l)62{63long i, lx = lg(x);64int first = 1;65for (i = 2; i < lx && gequal0(gel(x,i)); i++) /* ~ RgX_valrem + normalize */66if (first && !isexactzero(gel(x,i)))67{68pari_warn(warner,"normalizing a series with 0 leading term");69first = 0;70}71return RgX_to_ser_i(x, l, i - 2, 0);72}73GEN74rfrac_to_ser(GEN x, long l)75{76GEN d = gel(x,2);77if (l == 2)78{79long v = varn(d);80return zeroser(varn(d), gvaluation(x, pol_x(v)));81}82return gdiv(gel(x,1), RgX_to_ser(d, l));83}8485static GEN86RgV_to_ser_i(GEN x, long v, long l, int copy)87{88long j, lx = minss(lg(x), l-1);89GEN y;90if (lx == 1) return zeroser(v, l-2);91y = cgetg(l, t_SER); y[1] = evalvarn(v)|evalvalp(0);92x--;93if (copy)94for (j = 2; j <= lx; j++) gel(y,j) = gcopy(gel(x,j));95else96for (j = 2; j <= lx; j++) gel(y,j) = gel(x,j);97for ( ; j < l; j++) gel(y,j) = gen_0;98return normalize(y);99}100GEN101RgV_to_ser(GEN x, long v, long l) { return RgV_to_ser_i(x, v, l, 0); }102103/* x a t_SER, prec >= 0 */104GEN105sertoser(GEN x, long prec)106{107long i, lx = lg(x), l;108GEN y;109if (lx == 2) return zeroser(varn(x), prec);110l = prec+2; lx = minss(lx, l);111y = cgetg(l,t_SER); y[1] = x[1];112for (i = 2; i < lx; i++) gel(y,i) = gel(x,i);113for ( ; i < l; i++) gel(y,i) = gen_0;114return y;115}116117/* R(1/x) = x^v * n/d, val(n) = val(d) = 0 */118long119rfracrecip(GEN *pn, GEN *pd)120{121long v = degpol(*pd);122if (typ(*pn) == t_POL && varn(*pn) == varn(*pd))123{124v -= degpol(*pn);125(void)RgX_valrem(*pn, pn); *pn = RgX_recip(*pn);126}127(void)RgX_valrem(*pd, pd); *pd = RgX_recip(*pd);128return v;129}130131/* R(1/x) + O(x^N) */132GEN133rfracrecip_to_ser_absolute(GEN R, long N)134{135GEN n = gel(R,1), d = gel(R,2);136long v = rfracrecip(&n, &d); /* R(1/x) = x^v * n/d, val(n) = val(d) = 0 */137if (N <= v) return zeroser(varn(d), N);138R = gdiv(n, RgX_to_ser(d, N-v+2));139setvalp(R, v); return R;140}141142/* assume prec >= 0 */143GEN144scalarser(GEN x, long v, long prec)145{146long i, l;147GEN y;148149if (gequal0(x))150{151if (isrationalzero(x)) return zeroser(v, prec);152if (!isexactzero(x)) prec--;153y = cgetg(3, t_SER);154y[1] = evalsigne(0) | _evalvalp(prec) | evalvarn(v);155gel(y,2) = gcopy(x); return y;156}157l = prec + 2; y = cgetg(l, t_SER);158y[1] = evalsigne(1) | _evalvalp(0) | evalvarn(v);159gel(y,2) = gcopy(x); for (i=3; i<l; i++) gel(y,i) = gen_0;160return y;161}162163/* assume x a t_[SER|POL], apply gtoser to all coeffs */164static GEN165coefstoser(GEN x, long v, long prec)166{167long i, lx;168GEN y = cgetg_copy(x, &lx); y[1] = x[1];169for (i=2; i<lx; i++) gel(y,i) = gtoser(gel(x,i), v, prec);170return y;171}172173static void174err_ser_priority(GEN x, long v) { pari_err_PRIORITY("Ser", x, "<", v); }175/* x a t_POL */176static GEN177poltoser(GEN x, long v, long prec)178{179long s = varncmp(varn(x), v);180if (s < 0) err_ser_priority(x,v);181if (s > 0) return scalarser(x, v, prec);182return RgX_to_ser_i(x, prec+2, RgX_val(x), 1);183}184/* x a t_RFRAC */185static GEN186rfractoser(GEN x, long v, long prec)187{188long s = varncmp(varn(gel(x,2)), v);189pari_sp av;190if (s < 0) err_ser_priority(x,v);191if (s > 0) return scalarser(x, v, prec);192av = avma; return gerepileupto(av, rfrac_to_ser(x, prec+2));193}194GEN195toser_i(GEN x)196{197switch(typ(x))198{199case t_SER: return x;200case t_POL: return RgX_to_ser_inexact(x, precdl+2);201case t_RFRAC: return rfrac_to_ser(x, precdl+2);202}203return NULL;204}205206/* conversion: prec ignored if t_VEC or t_SER in variable v */207GEN208gtoser(GEN x, long v, long prec)209{210long tx = typ(x);211212if (v < 0) v = 0;213if (prec < 0) pari_err_DOMAIN("Ser", "precision", "<", gen_0, stoi(prec));214if (tx == t_SER)215{216long s = varncmp(varn(x), v);217if (s < 0) return coefstoser(x, v, prec);218else if (s > 0) return scalarser(x, v, prec);219return gcopy(x);220}221if (is_scalar_t(tx)) return scalarser(x,v,prec);222switch(tx)223{224case t_POL: return poltoser(x, v, prec);225case t_RFRAC: return rfractoser(x, v, prec);226case t_QFB: return RgV_to_ser_i(x, v, 4+1, 1);227case t_VECSMALL: x = zv_to_ZV(x);/*fall through*/228case t_VEC: case t_COL:229if (varncmp(gvar(x), v) <= 0) pari_err_PRIORITY("Ser", x, "<=", v);230return RgV_to_ser_i(x, v, lg(x)+1, 1);231}232pari_err_TYPE("Ser",x);233return NULL; /* LCOV_EXCL_LINE */234}235/* impose prec */236GEN237gtoser_prec(GEN x, long v, long prec)238{239pari_sp av = avma;240if (v < 0) v = 0;241if (prec < 0) pari_err_DOMAIN("Ser", "precision", "<", gen_0, stoi(prec));242switch(typ(x))243{244case t_SER: if (varn(x) != v) break;245return gerepilecopy(av, sertoser(x, prec));246case t_QFB:247x = RgV_to_ser_i(mkvec3(gel(x,1),gel(x,2),gel(x,3)), v, prec+2, 1);248return gerepileupto(av, x);249case t_VECSMALL: x = zv_to_ZV(x);/*fall through*/250case t_VEC: case t_COL:251if (varncmp(gvar(x), v) <= 0) pari_err_PRIORITY("Ser", x, "<=", v);252return RgV_to_ser_i(x, v, prec+2, 1);253}254return gtoser(x, v, prec);255}256GEN257Ser0(GEN x, long v, GEN d, long prec)258{259if (!d) return gtoser(x, v, prec);260if (typ(d) != t_INT)261{262d = gceil(d);263if (typ(d) != t_INT) pari_err_TYPE("Ser [precision]",d);264}265return gtoser_prec(x, v, itos(d));266}267268269