Testing latest pari + WASM + node.js... and it works?! Wow.
License: GPL3
ubuntu2004
/* Copyright (C) 2021 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"1617#define DEBUGLEVEL DEBUGLEVEL_mat1819GEN20zero_F3v(long m)21{22long l = nbits2nlong(2*m);23GEN v = const_vecsmall(l+1, 0);24v[1] = m;25return v;26}2728GEN29zero_F3m_copy(long m, long n)30{31long i;32GEN M = cgetg(n+1, t_MAT);33for (i = 1; i <= n; i++)34gel(M,i)= zero_F3v(m);35return M;36}37#define TRITS_IN_LONG (BITS_IN_LONG>>1)38#define TRITS_MASK (ULONG_MAX/3UL)39#define TWOPOTTRITS_IN_LONG (TWOPOTBITS_IN_LONG-1)4041ulong42F3v_coeff(GEN x,long v)43{44long pos = (v-1)>>TWOPOTTRITS_IN_LONG;45long r = (v-1)&(BITS_IN_LONG-1);46ulong u=(ulong)x[2+pos];47return (u>>(2*r))&3UL;48}4950void51F3v_clear(GEN x, long v)52{53long pos = (v-1)>>TWOPOTTRITS_IN_LONG;54long r = (v-1)&(BITS_IN_LONG-1);55ulong *u=(ulong*)&x[2+pos];56*u&=~(3UL<<(2*r));57}5859void60F3v_set(GEN x, long v, ulong n)61{62long pos = (v-1)>>TWOPOTTRITS_IN_LONG;63long r = (v-1)&(BITS_IN_LONG-1);64ulong *u=(ulong*)&x[2+pos];65*u&=~(3UL<<(2*r));66*u|=(n<<(2*r));67}6869INLINE void70F3v_setneg(GEN x, long v)71{72long pos = (v-1)>>TWOPOTTRITS_IN_LONG;73long r = (v-1)&(BITS_IN_LONG-1);74ulong *u=(ulong*)&x[2+pos];75if ((*u>>(2*r))&3UL)76*u^=(3UL<<(2*r));77}7879INLINE void80F3m_setneg(GEN x, long a, long b) { F3v_setneg(gel(x,b), a); }8182static ulong83bitswap(ulong a)84{85const ulong m = TRITS_MASK;86return ((a&m)<<1)|((a>>1)&m);87}8889static ulong90F3_add(ulong a, ulong b)91{92ulong c = a^b^bitswap(a&b);93return c&~bitswap(c);94}9596static ulong97F3_sub(ulong a, ulong b)98{99ulong bi = bitswap(b);100ulong c = a^bi^bitswap(a&bi);101return c&~bitswap(c);102}103104/* Allow lg(y)<lg(x) */105static void106F3v_add_inplace(GEN x, GEN y)107{108long n = lg(y);109long i;110for (i = 2; i < n; i++)111x[i] = F3_add(x[i], y[i]);112}113114/* Allow lg(y)<lg(x) */115static void116F3v_sub_inplace(GEN x, GEN y)117{118long n = lg(y);119long i;120for (i = 2; i < n; i++)121x[i] = F3_sub(x[i], y[i]);122}123124GEN125Flv_to_F3v(GEN x)126{127long l = lg(x)-1;128GEN z = cgetg(nbits2lg(2*l), t_VECSMALL);129long i,j,k;130z[1] = l;131for(i=1,k=1,j=BITS_IN_LONG; i<=l; i++,j+=2)132{133if (j==BITS_IN_LONG) { j=0; z[++k]=0; }134z[k] |= (uel(x,i)%3)<<j;135}136return z;137}138139GEN140Flm_to_F3m(GEN x) { pari_APPLY_same(Flv_to_F3v(gel(x,i))) }141142GEN143ZV_to_F3v(GEN x)144{145long l = lg(x)-1;146GEN z = cgetg(nbits2lg(2*l), t_VECSMALL);147long i,j,k;148z[1] = l;149for(i=1,k=1,j=BITS_IN_LONG; i<=l; i++,j+=2)150{151if (j==BITS_IN_LONG) { j=0; z[++k]=0; }152z[k] |= umodiu(gel(x,i),3)<<j;153}154return z;155}156157GEN158ZM_to_F3m(GEN x) { pari_APPLY_same(ZV_to_F3v(gel(x,i))) }159160GEN161RgV_to_F3v(GEN x)162{163long l = lg(x)-1;164GEN z = cgetg(nbits2lg(2*l), t_VECSMALL);165long i,j,k;166z[1] = l;167for(i=1,k=1,j=BITS_IN_LONG; i<=l; i++,j+=2)168{169if (j==BITS_IN_LONG) { j=0; z[++k]=0; }170z[k] |= Rg_to_Fl(gel(x,i),3)<<j;171}172return z;173}174175GEN176RgM_to_F3m(GEN x) { pari_APPLY_same(RgV_to_F3v(gel(x,i))) }177178GEN179F3v_to_Flv(GEN x)180{181long l=x[1]+1;182GEN z=cgetg(l, t_VECSMALL);183long i,j,k;184for (i=2,k=1; i<lg(x); i++)185for (j=0; j<BITS_IN_LONG && k<l; j+=2,k++)186z[k] = (uel(x,i)>>j)&3UL;187return z;188}189190GEN191F3m_to_Flm(GEN z)192{193long i, l = lg(z);194GEN x = cgetg(l,t_MAT);195for (i=1; i<l; i++) gel(x,i) = F3v_to_Flv(gel(z,i));196return x;197}198199GEN200F3m_to_ZM(GEN x) { return Flm_to_ZM(F3m_to_Flm(x)); }201202/* in place, destroy x */203GEN204F3m_ker_sp(GEN x, long deplin)205{206GEN y, c, d;207long i, j, k, r, m, n;208209n = lg(x)-1;210m = mael(x,1,1); r=0;211212d = cgetg(n+1, t_VECSMALL);213c = const_F2v(m);214for (k=1; k<=n; k++)215{216GEN xk = gel(x,k);217for (j=1; j<=m; j++)218if (F2v_coeff(c,j))219if (F3m_coeff(x,j,k)) break;220if (j>m)221{222if (deplin) {223GEN c = zero_F3v(n);224for (i=1; i<k; i++)225F3v_set(c, i, F3v_coeff(xk, d[i]));226F3v_set(c, k, 1);227return c;228}229r++; d[k] = 0;230}231else232{233ulong xkj = F3v_coeff(xk,j);234F3v_clear(xk, j);235F2v_clear(c,j); d[k] = j;236for (i=k+1; i<=n; i++)237{238GEN xi = gel(x,i);239ulong u = F3v_coeff(xi,j);240if (u)241{242if (u==xkj) F3v_sub_inplace(xi, xk);243else F3v_add_inplace(xi, xk);244}245}246F3v_set(xk, j, 2);247if (xkj==1)248for (i=k+1; i<=n; i++) F3m_setneg(x,j,i);249}250}251if (deplin) return NULL;252y = zero_F3m_copy(n,r);253for (j=k=1; j<=r; j++,k++)254{255GEN C = gel(y,j);256while (d[k]) k++;257for (i=1; i<k; i++)258if (d[i])259F3v_set(C,i,F3m_coeff(x,d[i],k));260F3v_set(C, k, 1);261}262return y;263}264265GEN266F3m_ker(GEN x) { return F3m_ker_sp(F3m_copy(x), 0); }267268INLINE GEN269F3m_F3c_mul_i(GEN x, GEN y, long lx, long l)270{271long j;272GEN z = zero_F3v(l);273274for (j=1; j<lx; j++)275{276ulong c = F3v_coeff(y,j);277if (!c) continue;278if (c==1)279F3v_add_inplace(z,gel(x,j));280else281F3v_sub_inplace(z,gel(x,j));282}283return z;284}285286GEN287F3m_mul(GEN x, GEN y)288{289long i,j,l,lx=lg(x), ly=lg(y);290GEN z;291if (ly==1) return cgetg(1,t_MAT);292z = cgetg(ly,t_MAT);293if (lx==1)294{295for (i=1; i<ly; i++) gel(z,i) = mkvecsmall(0);296return z;297}298l = coeff(x,1,1);299for (j=1; j<ly; j++) gel(z,j) = F3m_F3c_mul_i(x, gel(y,j), lx, l);300return z;301}302303GEN304F3m_row(GEN x, long j)305{306long i, l = lg(x);307GEN V = zero_F3v(l-1);308for(i = 1; i < l; i++)309F3v_set(V,i,F3m_coeff(x,j,i));310return V;311}312313GEN314F3m_transpose(GEN x)315{316long i, dx, lx = lg(x);317GEN y;318if (lx == 1) return cgetg(1,t_MAT);319dx = coeff(x,1,1); y = cgetg(dx+1,t_MAT);320for (i=1; i<=dx; i++) gel(y,i) = F3m_row(x,i);321return y;322}323324325