Gröbner basis project
Codebase for research into Gröbner basis computation
test_cab_es5.cpp
1 /*****************************************************************************\
2 * This file is part of DynGB. *
3 * *
4 * DynGB is free software: you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation, either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * Foobar is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with DynGB. If not, see <http://www.gnu.org/licenses/>. *
16 \*****************************************************************************/
17 
18 #include <set>
19 #include <cstdlib>
20 #include <cstring>
21 #include <iostream>
22 
23 using std::set;
24 using std::cout; using std::endl;
25 
26 #include "system_constants.hpp"
27 
28 #include "fields.hpp"
29 #include "monomial.hpp"
30 #include "polynomial.hpp"
31 
32 #include "dynamic_engine.hpp"
33 
34 #include "algorithm_buchberger_basic.hpp"
35 #include "algorithm_buchberger_dynamic.hpp"
36 
37 int main(int argc, char *argv[]) {
38  if (argc != 3 or (strcmp(argv[2],"stat") and strcmp(argv[2],"dyn"))) {
39  cout << "need to know method (usually 2) and then if dynamic (stat or dyn)\n";
40  return 1;
41  }
42  // obtain method -- don't screw it up b/c we don't check it
43  SPolyCreationFlags method = (SPolyCreationFlags )atoi(argv[1]);
44  bool static_algorithm = true;
45  if (!strcmp(argv[2],"dyn")) static_algorithm = false;
46  // set up the field
47  Prime_Field FF = Prime_Field(32003);
48  string X [9] = {"a", "b", "c", "d", "r", "s", "t", "x", "y"} ;
49  Polynomial_Ring R(9, FF, X );
50  Prime_Field_Element a = FF.unity();
51  DEG_TYPE e0 [] { 0, 0, 0, 0, 0, 0 };
52  // set up our polynomials
53  // first poly
54  Monomial bx { 0, 1, 0, 0, 0, 0, 0, 1, 0 };
55  Monomial ay { 1, 0, 0, 0, 0, 0, 0, 0, 1 };
56  Monomial M1 [] { bx, ay };
57  Prime_Field_Element C1 [] { a, -a };
58  Constant_Polynomial f1(2, R, M1, C1);
59  f1.sort_by_order();
60  // second poly
61  Monomial dx { 0, 0, 0, 1, 0, 0, 0, 1, 0 };
62  Monomial d1 { 0, 0, 0, 1, 0, 0, 0, 0, 0 };
63  Monomial cy { 0, 0, 1, 0, 0, 0, 0, 0, 1 };
64  Monomial y1 { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
65  Monomial M2 [] { dx, d1, cy, y1 };
66  Prime_Field_Element C2 [] { a, -a, -a, a };
67  Constant_Polynomial f2(4, R, M2, C2);
68  f2.sort_by_order();
69  // third poly
70  Monomial b2 { 0, 2, 0, 0, 0, 0, 0, 0, 0 };
71  Monomial a2 { 2, 0, 0, 0, 0, 0, 0, 0, 0 };
72  Monomial r2 { 0, 0, 0, 0, 2, 0, 0, 0, 0 };
73  Monomial M3 [] { b2, a2, r2 };
74  Prime_Field_Element C3 [] { a, a, -a };
75  Constant_Polynomial f3(3, R, M3, C3);
76  f3.sort_by_order();
77  // fourth poly
78  Monomial c2 { 0, 0, 2, 0, 0, 0, 0, 0, 0 };
79  Monomial c1 { 0, 0, 1, 0, 0, 0, 0, 0, 0 };
80  Monomial one { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
81  Monomial d2 { 0, 0, 0, 2, 0, 0, 0, 0, 0 };
82  Monomial s2 { 0, 0, 0, 0, 0, 2, 0, 0, 0 };
83  Monomial M4 [] { c2, c1, one, d2, s2 };
84  Prime_Field_Element C4 [] { a, -a*2, a, a, -a };
85  Constant_Polynomial f4(5, R, M4, C4);
86  f4.sort_by_order();
87  // fifth poly
88  Monomial ac { 1, 0, 1, 0, 0, 0, 0, 0, 0 };
89  Monomial bd { 0, 1, 0, 1, 0, 0, 0, 0, 0 };
90  Monomial t2 { 0, 0, 0, 0, 0, 0, 2, 0, 0 };
91  Monomial M5 [] { a2, ac, c2, b2, bd, d2, t2 };
92  Prime_Field_Element C5 [] { a, -a*2, a, a, -a*2, a, -a };
93  Constant_Polynomial f5(7, R, M5, C5);
94  f5.sort_by_order();
95  // message
96  cout << "Computing a Groebner basis for\n\t" << f1
97  << ",\n\t" << f2
98  << ",\n\t" << f3
99  << ",\n\t" << f4
100  << ",\n\t" << f5
101  << endl;
102  // compute basis
103  list<Abstract_Polynomial *> F;
104  F.push_back(&f1); F.push_back(&f2); F.push_back(&f3);
105  F.push_back(&f4); F.push_back(&f5);
106  list<Constant_Polynomial *> G;
107  if (static_algorithm) G = buchberger(F, method, StrategyFlags::SUGAR_STRATEGY);
108  else G = buchberger_dynamic(
109  F, method, StrategyFlags::SUGAR_STRATEGY, nullptr,
110  DynamicHeuristic::ORD_HILBERT_THEN_DEG
111  );
112  cout << "Basis:\n";
113  for (Constant_Polynomial * g : G) {
114  cout << '\t';
115  g->leading_monomial().print(true, cout, R.name_list());
116  delete g;
117  }
118  cout << "bye\n";
119 }
A Constant_Polynomial is a polynomial that should not change.
list< Constant_Polynomial * > buchberger(const list< Abstract_Polynomial *> &F, SPolyCreationFlags method, StrategyFlags strategy, WT_TYPE *strategy_weights)
Implementation of Buchberger’s algorithm.
Information necessary for a field modulo a prime.
Definition: fields.hpp:49
Prime_Field_Element unity()
“unity” is the multiplicative identity.
Definition: fields.cpp:188
SPolyCreationFlags
flag indicating which structure to use for an s-polynomial
Implementation of monomials.
Definition: monomial.hpp:69
Element of a field of prime characteristic.
Definition: fields.hpp:137
Encapsulates information about a polynomial ring for easy access: ground field, number of indetermina...
list< Constant_Polynomial * > buchberger_dynamic(const list< Abstract_Polynomial *> &F, SPolyCreationFlags method, StrategyFlags strategy, WT_TYPE *strategy_weights, DynamicHeuristic heuristic, DynamicSolver solver_type, bool analyze_inputs)
implementation of the dynamic Buchberger algorithm