1 #ifndef __F4_REDUCTION_CPP__ 2 #define __F4_REDUCTION_CPP__ 21 #include "f4_reduction.hpp" 22 #include "algorithm_buchberger_basic.hpp" 28 list<Monomial *>::iterator & ti,
29 list<Monomial *>::iterator stop,
30 list<Abstract_Polynomial *>::iterator & pi,
33 while (ti != stop and **ti > u) {
40 const list<Critical_Pair_Basic *> & P,
41 const list<Abstract_Polynomial *> & B
42 ) : G(B), Rx(P.front()->first()->base_ring()) {
50 mord = P.front()->first()->monomial_ordering();
54 strategies.back()->at_generation_tasks(p->first_multiplier());
55 if (p->second() !=
nullptr)
56 strategies.back()->pre_reduction_tasks(p->second_multiplier().log(), *(p->second()));
58 add_monomials(mi, ri, p->first(), p->first_multiplier(),
true);
59 if (p->second() !=
nullptr) {
70 bool found = ((*ri) !=
nullptr);
71 while (not found and g !=
G.end()) {
72 if ((**mi).divisible_by((*g)->leading_monomial())) {
76 u /= (*g)->leading_monomial();
95 for (
unsigned i = 0; i <
rows; ++i)
100 for (
unsigned i = 0; i <
cols*
rows; ++i)
106 for (
unsigned i = 0; i <
strategies.size(); ++i)
110 auto p = cp->first();
111 auto t = cp->first_multiplier();
115 bool head_found =
false;
116 for (
unsigned i = 0; i <
cols; ++i) {
117 if ((not pi->fellOff()) and
M[i]->like_multiple(pi->currMonomial(), t)) {
118 *(
A + row*cols + i) = pi->currCoeff();
121 if (not head_found) {
140 list<Monomial *>::iterator & t1,
141 list<Abstract_Polynomial *>::iterator & r1,
152 find_position(t1,
M_build.end(), r1, *t);
164 }
else if (**t1 != *t) {
170 auto t2(t1);
auto r2(r1);
176 find_position(t2,
M_build.end(), r2, *t);
180 }
else if (**t2 != *t) {
192 if (strat !=
nullptr)
203 for (
unsigned i = 0; i <
rows; ++i) {
205 for (
unsigned j = 0; j <
cols; ++j) {
206 cout <<
A[i*cols + j];
215 for (
unsigned i = 0; i <
cols; ++i) {
216 cout << *(
M[i]) <<
" to be reduced by ";
220 cout <<
R[i]->leading_monomial() << endl;
225 bool is_zero_so_far =
true;
226 for (
unsigned i = 0; is_zero_so_far and i <
rows; ++i)
228 return is_zero_so_far;
232 NVAR_TYPE n =
M[0]->num_vars();
233 EXP_TYPE * u =
new EXP_TYPE[n];
234 for (
unsigned k : my_rows) {
236 for (
unsigned i =
heads[k]; i <
cols; ++i) {
238 if ((not
A[k*cols + i].
is_zero()) and
R[i] !=
nullptr) {
243 for (NVAR_TYPE k = 0; k < n; ++k)
253 while (not
M[j]->like_multiple(u, t)) ++j;
254 bool was_zero =
A[k*cols + j].
is_zero();
256 if (was_zero and not
A[k*cols + j].
is_zero())
258 else if (not was_zero and
A[k*cols + j].
is_zero())
275 unsigned cores = std::thread::hardware_concurrency();
276 unsigned num_threads = (cores <
rows) ? cores :
rows;
277 set<unsigned> * thread_rows =
new set<unsigned>[num_threads];
279 for (
unsigned k = 0; k <
rows; ++k)
280 thread_rows[k % num_threads].insert(k);
281 thread * workers =
new thread[num_threads];
282 for (
unsigned c = 0; c < num_threads; ++c)
286 for (
unsigned c = 0; c < num_threads; ++c)
289 delete [] thread_rows;
293 for (
unsigned i = 0; i <
rows; ++i) {
295 for (
unsigned j = 0; j <
rows; ++j) {
299 auto a =
A[j*
cols + c];
322 vector<Constant_Polynomial *> result;
323 NVAR_TYPE n =
M[0]->num_vars();
324 for (
unsigned i = 0; i <
rows; ++i) {
336 A_final[k] =
A[i*cols + j]*scale;
359 list<Constant_Polynomial *>
f4_control(
const list<Abstract_Polynomial *> &F) {
360 time_t start_f4 = time(
nullptr);
361 cout <<
"computation started at " << asctime(localtime(&start_f4)) << endl;
362 unsigned number_of_spolys = 0;
363 list<Abstract_Polynomial *>
G;
364 list<Critical_Pair_Basic *> P;
374 bool verbose =
false;
375 bool very_verbose =
false;
376 list<Critical_Pair_Basic *> Pnew;
377 while (not P.empty()) {
381 report_front_pair(p, StrategyFlags::SUGAR_STRATEGY);
386 for (
auto pi = P.begin(); pi != P.end(); ++pi) {
389 for (
auto qi = Pnew.begin(); qi != Pnew.end(); ++qi)
393 report_front_pair(p, StrategyFlags::SUGAR_STRATEGY);
402 report_front_pair(p, StrategyFlags::SUGAR_STRATEGY);
409 number_of_spolys += Pnew.size();
416 cout <<
"\tmatrix reduced to zero\n";
419 vector<Constant_Polynomial *>
R = s.
finalize();
421 cout <<
"\tadded " << r->leading_monomial() << endl;
422 very_verbose =
false;
423 if (very_verbose) { cout <<
"\tadded "; r->println(); }
424 gm_update(P, G, r, StrategyFlags::SUGAR_STRATEGY);
428 cout << number_of_spolys <<
" s-polynomials computed and reduced\n";
430 cout << G.size() <<
" polynomials before interreduction\n";
433 cout << G.size() <<
" polynomials after interreduction\n";
434 list<Constant_Polynomial *> B;
437 time_t end_f4 = time(
nullptr);
438 double duration = difftime(end_f4, start_f4);
439 cout <<
"computation ended at " << asctime(localtime(&end_f4)) << endl;
440 cout <<
"parallel f4 took " << duration <<
" seconds\n";
DEG_TYPE total_degree(NVAR_TYPE m=0) const
Sum of exponents of the first m variables.
The general class of a polynomial.
unsigned rows
number of rows in the polynomial
vector< Monomial * > M
monomials for each column
A Constant_Polynomial is a polynomial that should not change.
bool is_zero()
returns true iff all the entries are 0
vector< Abstract_Polynomial * > R
finalized list of indices of reducers for the corresponding monomials of f
void sort_pairs_by_strategy(list< T *> &P)
Applies the strategy to find the “smallest” critical pair.
virtual Polynomial_Iterator * new_iterator() const =0
An iterator that poses no risk of modifying the polynomial.
virtual void moveRight()=0
Moves right in the polynomial, to the next smaller monomial.
bool is_zero() const
Is this the additive identity?
virtual const Prime_Field_Element & currCoeff() const =0
Reports the coefficient at the current position.
void gm_update(list< Critical_Pair_Basic *> &P, list< Abstract_Polynomial *> &G, Abstract_Polynomial *r, StrategyFlags strategy)
Implementation of Gebauer-Moeller algorithm. Based on description in Becker and Weispfenning (1993)...
list< Monomial * > M_build
monomials while building
void print_matrix(bool show_data=false)
prints the matrix
Information necessary for a field modulo a prime.
void set_monomial_ordering(const Monomial_Ordering *mord)
sets the Monomial_Ordering associated with this Monomial
virtual Monomial & leading_monomial() const =0
leading monomial – call after sort_by_order()!
vector< Poly_Sugar_Data * > strategies
strategy data for each polynomial
const Monomial & lcm() const
lcm of leading monomials of polynomials
void reduce_my_rows(const set< unsigned > &)
reduces the specified set of rows, suitable for multithreading
void advance_head(unsigned i)
advances head; useful after a computation
list< Abstract_Polynomial * > R_build
indices of reducers for the corresponding elements of M
Prime_Field & ground_field()
ground field – all coefficients should be in this field
void reduce_by_old()
reduces polynomials
virtual void at_generation_tasks()
hook called while first generating polynomial
~F4_Reduction_Data()
releases space for the matrix and deletes any strategies not already set to nullptr ...
list< Abstract_Polynomial * > reduce_basis(list< Abstract_Polynomial *>G)
Remove redundant polynomials from G.
vector< Constant_Polynomial * > finalize()
converts this to a Constant_Polynomial and returns the result
NVAR_TYPE num_vars() const
number of variables
virtual bool fellOff() const =0
unsigned cols
number of columns in the polynomial
Implementation of monomials.
Element of a field of prime characteristic.
F4_Reduction_Data(const list< Critical_Pair_Basic *> &P, const list< Abstract_Polynomial *> &B)
encapsulation of one step of the F4 algorithm for the polynomials indicated by P and B ...
polynomial-related data for a sugar strategy
const Monomial_Ordering * mord
how the monomials are ordered
void initialize_exponents(NVAR_TYPE number_of_vars)
allocates memory for exponents This is useful when you want to allocate an array of monomials...
void set_strategy(Poly_Strategy_Data *psd)
sets the polynomial’s strategy to psd
void add_monomials(list< Monomial *>::iterator &ti, list< Abstract_Polynomial *>::iterator &ri, const Abstract_Polynomial *g, const Monomial &u, bool new_row=false)
adds monomials of to M_build
Used to iterate through a polynomial.
void initialize_many(const list< Critical_Pair_Basic *> &P)
creates the matrix
COEF_TYPE inverse() const
Returns the multiplicative inverse of this.
virtual const Monomial & currMonomial() const =0
Reports the monomial at the current position.
void list_reducers()
lists the reducers selected for each column, in order
list< Constant_Polynomial * > f4_control(const list< Abstract_Polynomial *> &F)
equivalent to buchberger(), but for Faugère’s F4 algorithm
void reduce_by_new()
reduces polynomials
Implementation of Faugère’s F4 algorithm.
Controls the creation of s-polynomials.
Prime_Field_Element * A
coefficient data
void report_critical_pairs(const list< T *>P, bool verbose=false)
A brief report on the number of critical pairs. If verbose is true, also lists them.
Polynomial_Ring & Rx
polynomial ring
vector< unsigned > nonzero_entries
number of nonzero entries of each row of A
vector< unsigned > heads
head of the polynomial (location of leading term)
void common_initialization(const Monomial_Ordering *ord=nullptr)
things all Monomial initializers must do
const list< Abstract_Polynomial * > & G
current basis of ideal
virtual Poly_Strategy_Data * strategy() const
strategy related information