const GF2 ConstTerm(const GF2X& a) { if (IsZero(a)) return to_GF2(0); else return to_GF2((a.xrep[0] & 1) != 0); }
const GF2 LeadCoeff(const GF2X& a) { if (IsZero(a)) return to_GF2(0); else return to_GF2(1); }
const GF2 coeff(const GF2X& a, long i) { if (i < 0) return to_GF2(0); long wi = i/NTL_BITS_PER_LONG; if (wi >= a.xrep.length()) return to_GF2(0); long bi = i - wi*NTL_BITS_PER_LONG; return to_GF2((a.xrep[wi] & (1UL << bi)) != 0); }
const GF2 vec_GF2::get(long i) const { const vec_GF2& v = *this; if (i < 0 || i >= v.length()) LogicError("vec_GF2: subscript out of range"); long q = i/NTL_BITS_PER_LONG; long p = i - q*NTL_BITS_PER_LONG; if (v.rep[q] & (1UL << p)) return to_GF2(1); else return to_GF2(0); }
const GF2 GF2X::operator[](long i) const { if (i < 0) LogicError("GF2X: subscript out of range"); long wi = i/NTL_BITS_PER_LONG; if (wi >= xrep.length()) LogicError("GF2X: subscript out of range"); long bi = i - wi*NTL_BITS_PER_LONG; return to_GF2((xrep[wi] & (1UL << bi)) != 0); }
void ident(mat_GF2& X, long n) { X.SetDims(n, n); clear(X); long i; for (i = 0; i < n; i++) X.put(i, i, to_GF2(1)); }
NTL_START_IMPL GF2 power(GF2 a, long e) { if (e == 0) { return to_GF2(1); } if (e < 0 && IsZero(a)) ArithmeticError("GF2: division by zero"); return a; }
void inv(GF2& d, mat_GF2& X, const mat_GF2& A) { long n = A.NumRows(); if (A.NumCols() != n) Error("solve: nonsquare matrix"); if (n == 0) { X.SetDims(0, 0); set(d); } long i, j, k, pos; mat_GF2 M; M.SetDims(n, 2*n); vec_GF2 aa; aa.SetLength(2*n); for (i = 0; i < n; i++) { aa = A[i]; aa.SetLength(2*n); aa.put(n+i, 1); M[i] = aa; } long wn = ((2*n) + NTL_BITS_PER_LONG - 1)/NTL_BITS_PER_LONG; for (k = 0; k < n; k++) { long wk = k/NTL_BITS_PER_LONG; long bk = k - wk*NTL_BITS_PER_LONG; _ntl_ulong k_mask = 1UL << bk; pos = -1; for (i = k; i < n; i++) { if (M[i].rep.elts()[wk] & k_mask) { pos = i; break; } } if (pos != -1) { if (k != pos) { swap(M[pos], M[k]); } _ntl_ulong *y = M[k].rep.elts(); for (i = k+1; i < n; i++) { // M[i] = M[i] + M[k]*M[i,k] if (M[i].rep.elts()[wk] & k_mask) { _ntl_ulong *x = M[i].rep.elts(); for (j = wk; j < wn; j++) x[j] ^= y[j]; } } } else { clear(d); return; } } vec_GF2 XX; XX.SetLength(2*n); X.SetDims(n, n); clear(X); for (j = 0; j < n; j++) { XX.SetLength(n+j+1); clear(XX); XX.put(n+j, to_GF2(1)); for (i = n-1; i >= 0; i--) { XX.put(i, XX*M[i]); } XX.SetLength(n); AddToCol(X, j, XX); } set(d); return; }