Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

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

28486 views
License: GPL3
ubuntu2004
1
/* Copyright (C) 2021 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
#define DEBUGLEVEL DEBUGLEVEL_mat
19
20
GEN
21
zero_F3v(long m)
22
{
23
long l = nbits2nlong(2*m);
24
GEN v = const_vecsmall(l+1, 0);
25
v[1] = m;
26
return v;
27
}
28
29
GEN
30
zero_F3m_copy(long m, long n)
31
{
32
long i;
33
GEN M = cgetg(n+1, t_MAT);
34
for (i = 1; i <= n; i++)
35
gel(M,i)= zero_F3v(m);
36
return M;
37
}
38
#define TRITS_IN_LONG (BITS_IN_LONG>>1)
39
#define TRITS_MASK (ULONG_MAX/3UL)
40
#define TWOPOTTRITS_IN_LONG (TWOPOTBITS_IN_LONG-1)
41
42
ulong
43
F3v_coeff(GEN x,long v)
44
{
45
long pos = (v-1)>>TWOPOTTRITS_IN_LONG;
46
long r = (v-1)&(BITS_IN_LONG-1);
47
ulong u=(ulong)x[2+pos];
48
return (u>>(2*r))&3UL;
49
}
50
51
void
52
F3v_clear(GEN x, long v)
53
{
54
long pos = (v-1)>>TWOPOTTRITS_IN_LONG;
55
long r = (v-1)&(BITS_IN_LONG-1);
56
ulong *u=(ulong*)&x[2+pos];
57
*u&=~(3UL<<(2*r));
58
}
59
60
void
61
F3v_set(GEN x, long v, ulong n)
62
{
63
long pos = (v-1)>>TWOPOTTRITS_IN_LONG;
64
long r = (v-1)&(BITS_IN_LONG-1);
65
ulong *u=(ulong*)&x[2+pos];
66
*u&=~(3UL<<(2*r));
67
*u|=(n<<(2*r));
68
}
69
70
INLINE void
71
F3v_setneg(GEN x, long v)
72
{
73
long pos = (v-1)>>TWOPOTTRITS_IN_LONG;
74
long r = (v-1)&(BITS_IN_LONG-1);
75
ulong *u=(ulong*)&x[2+pos];
76
if ((*u>>(2*r))&3UL)
77
*u^=(3UL<<(2*r));
78
}
79
80
INLINE void
81
F3m_setneg(GEN x, long a, long b) { F3v_setneg(gel(x,b), a); }
82
83
static ulong
84
bitswap(ulong a)
85
{
86
const ulong m = TRITS_MASK;
87
return ((a&m)<<1)|((a>>1)&m);
88
}
89
90
static ulong
91
F3_add(ulong a, ulong b)
92
{
93
ulong c = a^b^bitswap(a&b);
94
return c&~bitswap(c);
95
}
96
97
static ulong
98
F3_sub(ulong a, ulong b)
99
{
100
ulong bi = bitswap(b);
101
ulong c = a^bi^bitswap(a&bi);
102
return c&~bitswap(c);
103
}
104
105
/* Allow lg(y)<lg(x) */
106
static void
107
F3v_add_inplace(GEN x, GEN y)
108
{
109
long n = lg(y);
110
long i;
111
for (i = 2; i < n; i++)
112
x[i] = F3_add(x[i], y[i]);
113
}
114
115
/* Allow lg(y)<lg(x) */
116
static void
117
F3v_sub_inplace(GEN x, GEN y)
118
{
119
long n = lg(y);
120
long i;
121
for (i = 2; i < n; i++)
122
x[i] = F3_sub(x[i], y[i]);
123
}
124
125
GEN
126
Flv_to_F3v(GEN x)
127
{
128
long l = lg(x)-1;
129
GEN z = cgetg(nbits2lg(2*l), t_VECSMALL);
130
long i,j,k;
131
z[1] = l;
132
for(i=1,k=1,j=BITS_IN_LONG; i<=l; i++,j+=2)
133
{
134
if (j==BITS_IN_LONG) { j=0; z[++k]=0; }
135
z[k] |= (uel(x,i)%3)<<j;
136
}
137
return z;
138
}
139
140
GEN
141
Flm_to_F3m(GEN x) { pari_APPLY_same(Flv_to_F3v(gel(x,i))) }
142
143
GEN
144
ZV_to_F3v(GEN x)
145
{
146
long l = lg(x)-1;
147
GEN z = cgetg(nbits2lg(2*l), t_VECSMALL);
148
long i,j,k;
149
z[1] = l;
150
for(i=1,k=1,j=BITS_IN_LONG; i<=l; i++,j+=2)
151
{
152
if (j==BITS_IN_LONG) { j=0; z[++k]=0; }
153
z[k] |= umodiu(gel(x,i),3)<<j;
154
}
155
return z;
156
}
157
158
GEN
159
ZM_to_F3m(GEN x) { pari_APPLY_same(ZV_to_F3v(gel(x,i))) }
160
161
GEN
162
RgV_to_F3v(GEN x)
163
{
164
long l = lg(x)-1;
165
GEN z = cgetg(nbits2lg(2*l), t_VECSMALL);
166
long i,j,k;
167
z[1] = l;
168
for(i=1,k=1,j=BITS_IN_LONG; i<=l; i++,j+=2)
169
{
170
if (j==BITS_IN_LONG) { j=0; z[++k]=0; }
171
z[k] |= Rg_to_Fl(gel(x,i),3)<<j;
172
}
173
return z;
174
}
175
176
GEN
177
RgM_to_F3m(GEN x) { pari_APPLY_same(RgV_to_F3v(gel(x,i))) }
178
179
GEN
180
F3v_to_Flv(GEN x)
181
{
182
long l=x[1]+1;
183
GEN z=cgetg(l, t_VECSMALL);
184
long i,j,k;
185
for (i=2,k=1; i<lg(x); i++)
186
for (j=0; j<BITS_IN_LONG && k<l; j+=2,k++)
187
z[k] = (uel(x,i)>>j)&3UL;
188
return z;
189
}
190
191
GEN
192
F3m_to_Flm(GEN z)
193
{
194
long i, l = lg(z);
195
GEN x = cgetg(l,t_MAT);
196
for (i=1; i<l; i++) gel(x,i) = F3v_to_Flv(gel(z,i));
197
return x;
198
}
199
200
GEN
201
F3m_to_ZM(GEN x) { return Flm_to_ZM(F3m_to_Flm(x)); }
202
203
/* in place, destroy x */
204
GEN
205
F3m_ker_sp(GEN x, long deplin)
206
{
207
GEN y, c, d;
208
long i, j, k, r, m, n;
209
210
n = lg(x)-1;
211
m = mael(x,1,1); r=0;
212
213
d = cgetg(n+1, t_VECSMALL);
214
c = const_F2v(m);
215
for (k=1; k<=n; k++)
216
{
217
GEN xk = gel(x,k);
218
for (j=1; j<=m; j++)
219
if (F2v_coeff(c,j))
220
if (F3m_coeff(x,j,k)) break;
221
if (j>m)
222
{
223
if (deplin) {
224
GEN c = zero_F3v(n);
225
for (i=1; i<k; i++)
226
F3v_set(c, i, F3v_coeff(xk, d[i]));
227
F3v_set(c, k, 1);
228
return c;
229
}
230
r++; d[k] = 0;
231
}
232
else
233
{
234
ulong xkj = F3v_coeff(xk,j);
235
F3v_clear(xk, j);
236
F2v_clear(c,j); d[k] = j;
237
for (i=k+1; i<=n; i++)
238
{
239
GEN xi = gel(x,i);
240
ulong u = F3v_coeff(xi,j);
241
if (u)
242
{
243
if (u==xkj) F3v_sub_inplace(xi, xk);
244
else F3v_add_inplace(xi, xk);
245
}
246
}
247
F3v_set(xk, j, 2);
248
if (xkj==1)
249
for (i=k+1; i<=n; i++) F3m_setneg(x,j,i);
250
}
251
}
252
if (deplin) return NULL;
253
y = zero_F3m_copy(n,r);
254
for (j=k=1; j<=r; j++,k++)
255
{
256
GEN C = gel(y,j);
257
while (d[k]) k++;
258
for (i=1; i<k; i++)
259
if (d[i])
260
F3v_set(C,i,F3m_coeff(x,d[i],k));
261
F3v_set(C, k, 1);
262
}
263
return y;
264
}
265
266
GEN
267
F3m_ker(GEN x) { return F3m_ker_sp(F3m_copy(x), 0); }
268
269
INLINE GEN
270
F3m_F3c_mul_i(GEN x, GEN y, long lx, long l)
271
{
272
long j;
273
GEN z = zero_F3v(l);
274
275
for (j=1; j<lx; j++)
276
{
277
ulong c = F3v_coeff(y,j);
278
if (!c) continue;
279
if (c==1)
280
F3v_add_inplace(z,gel(x,j));
281
else
282
F3v_sub_inplace(z,gel(x,j));
283
}
284
return z;
285
}
286
287
GEN
288
F3m_mul(GEN x, GEN y)
289
{
290
long i,j,l,lx=lg(x), ly=lg(y);
291
GEN z;
292
if (ly==1) return cgetg(1,t_MAT);
293
z = cgetg(ly,t_MAT);
294
if (lx==1)
295
{
296
for (i=1; i<ly; i++) gel(z,i) = mkvecsmall(0);
297
return z;
298
}
299
l = coeff(x,1,1);
300
for (j=1; j<ly; j++) gel(z,j) = F3m_F3c_mul_i(x, gel(y,j), lx, l);
301
return z;
302
}
303
304
GEN
305
F3m_row(GEN x, long j)
306
{
307
long i, l = lg(x);
308
GEN V = zero_F3v(l-1);
309
for(i = 1; i < l; i++)
310
F3v_set(V,i,F3m_coeff(x,j,i));
311
return V;
312
}
313
314
GEN
315
F3m_transpose(GEN x)
316
{
317
long i, dx, lx = lg(x);
318
GEN y;
319
if (lx == 1) return cgetg(1,t_MAT);
320
dx = coeff(x,1,1); y = cgetg(dx+1,t_MAT);
321
for (i=1; i<=dx; i++) gel(y,i) = F3m_row(x,i);
322
return y;
323
}
324
325