20 const std::vector<std::string> &names,
21 const std::vector<ElementType> &extensions)
24 assert(names.size() >= 1);
25 mNumVars =
static_cast<int>(names.size());
29 assert(extensions.size() <= names.size());
30 for (
size_t i = 0; i < names.size(); i++)
32 if (extensions.size() < i)
42 const std::vector<std::string> &names)
44 std::vector<ElementType> extensions;
49 const std::vector<std::string> &new_names)
58 const std::vector<ElementType> &extensions)
77 for (
int i = 0; i <= deg; i++)
result->polys[i] =
nullptr;
87 for (
int i = 0; i <= deg; i++)
result->coeffs[i] = 0;
94 if (f ==
nullptr)
return;
103 if (f ==
nullptr)
return;
106 for (
int i = 0; i <= f->deg; i++)
mBaseRing.clear(f->coeffs[i]);
111 for (
int i = 0; i <= f->deg; i++)
clear(level - 1, f->polys[i]);
120 if (f ==
nullptr)
return;
122 for (
int j = fdeg; j >= 0; --j)
123 if (f->
polys[j] !=
nullptr)
134 if (f ==
nullptr)
return nullptr;
139 for (
int i = 0; i <= f->
deg; i++)
148 if (f->
len <= newdeg)
152 for (
int i = 0; i <= f->
deg; i++) newelems[i] = fp[i];
153 for (
int i = f->
deg + 1; i < newdeg + 1; i++) newelems[i] =
nullptr;
168 for (
size_t i = 0; i <
n_vars() - 1; i++) o <<
varNames()[i] <<
",";
189 if (f ==
nullptr)
return 0;
193 for (
int i = 0; i <= f->
deg; i++)
194 if (f->
coeffs[i] != 0) nterms++;
198 for (
int i = 0; i <= f->
deg; i++)
199 if (f->
polys[i] !=
nullptr) nterms++;
207 if (f ==
nullptr)
return false;
208 if (f->
deg != 0)
return false;
230 bool needs_parens = p_parens && (nterms >= 2);
234 if (p_plus) o <<
'+';
239 bool one =
is_one(level, f);
243 if (p_plus) o <<
"+";
248 const std::string &this_varname =
varNames()[level];
252 bool firstterm =
true;
253 for (
int i = f->
deg; i >= 0; i--)
256 if (!firstterm || p_plus) o <<
"+";
258 if (i == 0 || f->
coeffs[i] != 1)
260 if (i > 0) o << this_varname;
263 if (needs_parens) o <<
")";
267 bool firstterm =
true;
268 for (
int i = f->
deg; i >= 0; i--)
269 if (f->
polys[i] !=
nullptr)
271 bool this_p_parens = p_parens || (i > 0);
278 p_plus || !firstterm,
280 else if (p_plus || !firstterm)
282 if (i > 0) o << this_varname;
287 if (needs_parens) o <<
")";
294 if (v > level)
return nullptr;
295 int which = (v == 0 ? 1 : 0);
298 result->coeffs[which] = 1;
299 for (
int i = 1; i <= level; i++)
301 which = (i == v ? 1 : 0);
313 if (g ==
nullptr)
return true;
316 if (g ==
nullptr || f->
deg != g->
deg)
return false;
321 for (
int i = 0; i <= f->
deg; i++)
322 if (fp[i] != gp[i])
return false;
328 for (
int i = 0; i <= f->
deg; i++)
329 if (!
is_equal(level - 1, fp[i], gp[i]))
return false;
335 if (g ==
nullptr)
return;
346 for (
int i = 0; i <= gdeg; i++)
349 for (
int i = 0; i <= gdeg; i++)
354 else if (gdeg == fdeg)
360 if (f ==
nullptr)
return;
364 for (
int i = 0; i <= deg; i++)
369 for (
int i = 0; i <= deg; i++)
376 if (g ==
nullptr)
return;
388 for (
int i = 0; i <= gdeg; i++)
391 for (
int i = 0; i <= gdeg; i++)
396 else if (gdeg == fdeg)
405 if (f ==
nullptr)
return;
410 for (
int i = 0; i <= deg; i++)
415 for (
int i = 0; i <= deg; i++)
422 if (f ==
nullptr)
return;
M2::ARingTower — iterated finite-field extension tower for very large GF(p^k).
void text_out(buffer &o) const
ARingPolynomial ElementType
ARingTower(const BaseRingType &baseRing, const std::vector< std::string > &names, const std::vector< ElementType > &extensions)
void copy(elem &result, elem a) const
void dealloc_poly(ARingPolynomial &f) const
void reset_degree(ARingPolynomial &f) const
const ARingZZpFFPACK & baseRing() const
void increase_capacity(int newdeg, ARingPolynomial &f) const
const std::vector< std::string > mVarNames
ARingZZpFFPACK BaseRingType
ARingPolynomial alloc_poly_n(int deg) const
std::vector< ElementType > mExtensions
bool is_equal(ElementType f, ElementType g) const
const std::vector< std::string > & varNames() const
ARingPolynomial alloc_poly_0(int deg) const
void mult_by_coeff(ARingPolynomial &f, const BaseCoefficientType &b) const
BaseRingType::ElementType BaseCoefficientType
void negate_in_place(int level, ARingPolynomial &f) const
void clear(elem &f) const
bool is_one(int level, const ARingPolynomial f) const
void add_in_place(int level, ARingPolynomial &f, const ARingPolynomial g) const
const ARingZZpFFPACK & mBaseRing
static ARingTower * create(const BaseRingType &baseRing, const std::vector< std::string > &names)
void elem_text_out(buffer &o, ElementType a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
unsigned long characteristic() const
ARingPolynomial var(int level, int v) const
void subtract_in_place(int level, ARingPolynomial &f, const ARingPolynomial g) const
void extensions_text_out(buffer &o) const
FieldType::Element ElementType
wrapper for the FFPACK::ModularBalanced<double> field implementation
static int n_nonzero_terms(int level, const TowerPolynomial f)
struct ARingPolynomialStruct * ARingPolynomial
VALGRIND_MAKE_MEM_DEFINED & result(result)
ARingZZpFFPACK::ElementType * coeffs
Heap-allocated node of an ARingTower polynomial: a dense degree-indexed coefficient array that recurs...