Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Testing latest pari + WASM + node.js... and it works?! Wow.

28485 views
License: GPL3
ubuntu2004
1
/* Copyright (C) 2000, 2012 The PARI group.
2
3
This file is part of the PARI/GP package.
4
5
PARI/GP is free software; you can redistribute it and/or modify it under the
6
terms of the GNU General Public License as published by the Free Software
7
Foundation; either version 2 of the License, or (at your option) any later
8
version. It is distributed in the hope that it will be useful, but WITHOUT
9
ANY WARRANTY WHATSOEVER.
10
11
Check the License for details. You should have received a copy of it, along
12
with the package; see the file 'COPYING'. If not, write to the Free Software
13
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
14
15
#include "pari.h"
16
#include "paripriv.h"
17
/*******************************************************************/
18
/* */
19
/* Conversion --> t_SER */
20
/* */
21
/*******************************************************************/
22
static GEN
23
RgX_to_ser_i(GEN x, long l, long v, int copy)
24
{
25
long i = 2, lx = lg(x), vx = varn(x);
26
GEN y;
27
if (lx == 2) return zeroser(vx, minss(l - 2, v));
28
if (l <= 2)
29
{
30
if (l == 2 && v != LONG_MAX) return zeroser(vx, v);
31
pari_err_BUG("RgX_to_ser (l < 2)");
32
}
33
y = cgetg(l,t_SER);
34
if (v == LONG_MAX) { v = 1; lx = 3; } /* e.g. Mod(0,3) * x^0 */
35
else if (v)
36
{
37
long w = v;
38
while (isrationalzero(gel(x,2))) { x++; w--; }
39
lx -= v;
40
if (w)
41
{ /* keep type information, e.g. Mod(0,3) + x */
42
GEN z = gel(x,2); /* = 0 */
43
if (lx <= 2) gel(y,2) = copy? gcopy(z): z;
44
else { x += w; gel(y,2) = gadd(gel(x,2), z); }
45
i++;
46
}
47
}
48
y[1] = evalvarn(vx) | evalvalp(v); /* must come here because of LONG_MAX */
49
if (lx > l) lx = l;
50
/* 2 <= lx <= l */
51
if (copy)
52
for (; i <lx; i++) gel(y,i) = gcopy(gel(x,i));
53
else
54
for (; i <lx; i++) gel(y,i) = gel(x,i);
55
for ( ; i < l; i++) gel(y,i) = gen_0;
56
return normalize(y);
57
}
58
/* enlarge/truncate t_POL x to a t_SER with lg l */
59
GEN
60
RgX_to_ser(GEN x, long l) { return RgX_to_ser_i(x, l, RgX_val(x), 0); }
61
GEN
62
RgX_to_ser_inexact(GEN x, long l)
63
{
64
long i, lx = lg(x);
65
int first = 1;
66
for (i = 2; i < lx && gequal0(gel(x,i)); i++) /* ~ RgX_valrem + normalize */
67
if (first && !isexactzero(gel(x,i)))
68
{
69
pari_warn(warner,"normalizing a series with 0 leading term");
70
first = 0;
71
}
72
return RgX_to_ser_i(x, l, i - 2, 0);
73
}
74
GEN
75
rfrac_to_ser(GEN x, long l)
76
{
77
GEN d = gel(x,2);
78
if (l == 2)
79
{
80
long v = varn(d);
81
return zeroser(varn(d), gvaluation(x, pol_x(v)));
82
}
83
return gdiv(gel(x,1), RgX_to_ser(d, l));
84
}
85
86
static GEN
87
RgV_to_ser_i(GEN x, long v, long l, int copy)
88
{
89
long j, lx = minss(lg(x), l-1);
90
GEN y;
91
if (lx == 1) return zeroser(v, l-2);
92
y = cgetg(l, t_SER); y[1] = evalvarn(v)|evalvalp(0);
93
x--;
94
if (copy)
95
for (j = 2; j <= lx; j++) gel(y,j) = gcopy(gel(x,j));
96
else
97
for (j = 2; j <= lx; j++) gel(y,j) = gel(x,j);
98
for ( ; j < l; j++) gel(y,j) = gen_0;
99
return normalize(y);
100
}
101
GEN
102
RgV_to_ser(GEN x, long v, long l) { return RgV_to_ser_i(x, v, l, 0); }
103
104
/* x a t_SER, prec >= 0 */
105
GEN
106
sertoser(GEN x, long prec)
107
{
108
long i, lx = lg(x), l;
109
GEN y;
110
if (lx == 2) return zeroser(varn(x), prec);
111
l = prec+2; lx = minss(lx, l);
112
y = cgetg(l,t_SER); y[1] = x[1];
113
for (i = 2; i < lx; i++) gel(y,i) = gel(x,i);
114
for ( ; i < l; i++) gel(y,i) = gen_0;
115
return y;
116
}
117
118
/* R(1/x) = x^v * n/d, val(n) = val(d) = 0 */
119
long
120
rfracrecip(GEN *pn, GEN *pd)
121
{
122
long v = degpol(*pd);
123
if (typ(*pn) == t_POL && varn(*pn) == varn(*pd))
124
{
125
v -= degpol(*pn);
126
(void)RgX_valrem(*pn, pn); *pn = RgX_recip(*pn);
127
}
128
(void)RgX_valrem(*pd, pd); *pd = RgX_recip(*pd);
129
return v;
130
}
131
132
/* R(1/x) + O(x^N) */
133
GEN
134
rfracrecip_to_ser_absolute(GEN R, long N)
135
{
136
GEN n = gel(R,1), d = gel(R,2);
137
long v = rfracrecip(&n, &d); /* R(1/x) = x^v * n/d, val(n) = val(d) = 0 */
138
if (N <= v) return zeroser(varn(d), N);
139
R = gdiv(n, RgX_to_ser(d, N-v+2));
140
setvalp(R, v); return R;
141
}
142
143
/* assume prec >= 0 */
144
GEN
145
scalarser(GEN x, long v, long prec)
146
{
147
long i, l;
148
GEN y;
149
150
if (gequal0(x))
151
{
152
if (isrationalzero(x)) return zeroser(v, prec);
153
if (!isexactzero(x)) prec--;
154
y = cgetg(3, t_SER);
155
y[1] = evalsigne(0) | _evalvalp(prec) | evalvarn(v);
156
gel(y,2) = gcopy(x); return y;
157
}
158
l = prec + 2; y = cgetg(l, t_SER);
159
y[1] = evalsigne(1) | _evalvalp(0) | evalvarn(v);
160
gel(y,2) = gcopy(x); for (i=3; i<l; i++) gel(y,i) = gen_0;
161
return y;
162
}
163
164
/* assume x a t_[SER|POL], apply gtoser to all coeffs */
165
static GEN
166
coefstoser(GEN x, long v, long prec)
167
{
168
long i, lx;
169
GEN y = cgetg_copy(x, &lx); y[1] = x[1];
170
for (i=2; i<lx; i++) gel(y,i) = gtoser(gel(x,i), v, prec);
171
return y;
172
}
173
174
static void
175
err_ser_priority(GEN x, long v) { pari_err_PRIORITY("Ser", x, "<", v); }
176
/* x a t_POL */
177
static GEN
178
poltoser(GEN x, long v, long prec)
179
{
180
long s = varncmp(varn(x), v);
181
if (s < 0) err_ser_priority(x,v);
182
if (s > 0) return scalarser(x, v, prec);
183
return RgX_to_ser_i(x, prec+2, RgX_val(x), 1);
184
}
185
/* x a t_RFRAC */
186
static GEN
187
rfractoser(GEN x, long v, long prec)
188
{
189
long s = varncmp(varn(gel(x,2)), v);
190
pari_sp av;
191
if (s < 0) err_ser_priority(x,v);
192
if (s > 0) return scalarser(x, v, prec);
193
av = avma; return gerepileupto(av, rfrac_to_ser(x, prec+2));
194
}
195
GEN
196
toser_i(GEN x)
197
{
198
switch(typ(x))
199
{
200
case t_SER: return x;
201
case t_POL: return RgX_to_ser_inexact(x, precdl+2);
202
case t_RFRAC: return rfrac_to_ser(x, precdl+2);
203
}
204
return NULL;
205
}
206
207
/* conversion: prec ignored if t_VEC or t_SER in variable v */
208
GEN
209
gtoser(GEN x, long v, long prec)
210
{
211
long tx = typ(x);
212
213
if (v < 0) v = 0;
214
if (prec < 0) pari_err_DOMAIN("Ser", "precision", "<", gen_0, stoi(prec));
215
if (tx == t_SER)
216
{
217
long s = varncmp(varn(x), v);
218
if (s < 0) return coefstoser(x, v, prec);
219
else if (s > 0) return scalarser(x, v, prec);
220
return gcopy(x);
221
}
222
if (is_scalar_t(tx)) return scalarser(x,v,prec);
223
switch(tx)
224
{
225
case t_POL: return poltoser(x, v, prec);
226
case t_RFRAC: return rfractoser(x, v, prec);
227
case t_QFB: return RgV_to_ser_i(x, v, 4+1, 1);
228
case t_VECSMALL: x = zv_to_ZV(x);/*fall through*/
229
case t_VEC: case t_COL:
230
if (varncmp(gvar(x), v) <= 0) pari_err_PRIORITY("Ser", x, "<=", v);
231
return RgV_to_ser_i(x, v, lg(x)+1, 1);
232
}
233
pari_err_TYPE("Ser",x);
234
return NULL; /* LCOV_EXCL_LINE */
235
}
236
/* impose prec */
237
GEN
238
gtoser_prec(GEN x, long v, long prec)
239
{
240
pari_sp av = avma;
241
if (v < 0) v = 0;
242
if (prec < 0) pari_err_DOMAIN("Ser", "precision", "<", gen_0, stoi(prec));
243
switch(typ(x))
244
{
245
case t_SER: if (varn(x) != v) break;
246
return gerepilecopy(av, sertoser(x, prec));
247
case t_QFB:
248
x = RgV_to_ser_i(mkvec3(gel(x,1),gel(x,2),gel(x,3)), v, prec+2, 1);
249
return gerepileupto(av, x);
250
case t_VECSMALL: x = zv_to_ZV(x);/*fall through*/
251
case t_VEC: case t_COL:
252
if (varncmp(gvar(x), v) <= 0) pari_err_PRIORITY("Ser", x, "<=", v);
253
return RgV_to_ser_i(x, v, prec+2, 1);
254
}
255
return gtoser(x, v, prec);
256
}
257
GEN
258
Ser0(GEN x, long v, GEN d, long prec)
259
{
260
if (!d) return gtoser(x, v, prec);
261
if (typ(d) != t_INT)
262
{
263
d = gceil(d);
264
if (typ(d) != t_INT) pari_err_TYPE("Ser [precision]",d);
265
}
266
return gtoser_prec(x, v, itos(d));
267
}
268
269