Gröbner basis project
Codebase for research into Gröbner basis computation
test_4by4.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 
19 
20 #include <set>
21 #include <cstdlib>
22 #include <cstring>
23 #include <iostream>
24 
25 using std::set;
26 using std::cout; using std::endl;
27 
28 #include "system_constants.hpp"
29 
30 #include "fields.hpp"
31 #include "monomial.hpp"
32 #include "polynomial.hpp"
33 
34 #include "dynamic_engine.hpp"
35 
36 #include "algorithm_buchberger_basic.hpp"
37 #include "algorithm_buchberger_dynamic.hpp"
38 
39 int main(int argc, char *argv[]) {
40  if (argc < 3 or (strcmp(argv[2],"stat") and strcmp(argv[2],"dyn"))) {
41  cout << "Need to know method (usually 2), then if dynamic (stat or dyn).\n";
42  return 1;
43  }
44  // obtain method -- don't screw it up b/c we don't check it
45  SPolyCreationFlags method = (SPolyCreationFlags )atoi(argv[1]);
46  bool static_algorithm = true;
47  DynamicSolver solver = GLPK_SOLVER;
48  DynamicHeuristic heuristic;
49  if (!strcmp(argv[2],"dyn")) {
50  unsigned heur_opt_location = 4;
51  if (
52  argc < 4 or
53  (strcmp(argv[3],"skel") and strcmp(argv[3],"glpk")
54  and strcmp(argv[3],"simpl") and strcmp(argv[3],"ppl"))
55  ) {
56  cout << "For a dynamic algorithm, we also need the solver:\n";
57  cout << "\tskeleton (skel) or simplex (glpk or simpl).\n";
58  return 2;
59  }
60  static_algorithm = false;
61  if (!strcmp(argv[3],"skel")) solver = SKELETON_SOLVER;
62  else if (!strcmp(argv[3],"ppl")) solver = PPL_SOLVER;
63  // obtain heuristic
64  if (argc < heur_opt_location + 1 or
65  argv[heur_opt_location][0] != 'h' or argv[heur_opt_location][1] != 'e' or
66  argv[heur_opt_location][2] != 'u' or argv[heur_opt_location][3] != 'r'
67  ) {
68  cout << "Need to know heuristic. Use format heur=...\n";
69  return 1;
70  }
71  heuristic = (DynamicHeuristic )atoi(&(argv[heur_opt_location][5]));
72  }
73  // set up the field
74  Prime_Field F17 = Prime_Field(32003);
75  Polynomial_Ring R(32, F17);
76  Prime_Field_Element a = F17.unity();
77  // set up our polynomials
78  // first poly
79  EXP_TYPE e11 [] {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t11(32, e11);
80  EXP_TYPE e12 [] {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; Monomial t12(32, e12);
81  EXP_TYPE e13 [] {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0}; Monomial t13(32, e13);
82  EXP_TYPE e14 [] {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}; Monomial t14(32, e14);
83  EXP_TYPE e15 [] {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t15(32, e15);
84  EXP_TYPE e16 [] {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t16(32, e16);
85  Monomial M1 [] { t11, t12, t13, t14, t15, t16 };
86  Prime_Field_Element C1 [] { -a, a, a, a, -a, -a };
87  Constant_Polynomial f1(6, R, M1, C1);
88  f1.sort_by_order();
89  // second poly
90  EXP_TYPE e21 [] {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t21(32, e21);
91  EXP_TYPE e22 [] {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t22(32, e22);
92  EXP_TYPE e23 [] {0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t23(32, e23);
93  EXP_TYPE e24 [] {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}; Monomial t24(32, e24);
94  EXP_TYPE e25 [] {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0}; Monomial t25(32, e25);
95  EXP_TYPE e26 [] {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0}; Monomial t26(32, e26);
96  EXP_TYPE e27 [] {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t27(32, e27);
97  EXP_TYPE e28 [] {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t28(32, e28);
98  Monomial M2 [] { t21, t22, t23, t24, t25, t26, t27, t28 };
99  Prime_Field_Element C2 [] { -a, a, -a, a, a, a, -a, -a };
100  Constant_Polynomial f2(8, R, M2, C2);
101  f2.sort_by_order();
102  // third poly
103  EXP_TYPE e31 [] {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t31(32, e31);
104  EXP_TYPE e32 [] {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t32(32, e32);
105  EXP_TYPE e33 [] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t33(32, e33);
106  EXP_TYPE e34 [] {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t34(32, e34);
107  EXP_TYPE e35 [] {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}; Monomial t35(32, e35);
108  EXP_TYPE e36 [] {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}; Monomial t36(32, e36);
109  EXP_TYPE e37 [] {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}; Monomial t37(32, e37);
110  EXP_TYPE e38 [] {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t38(32, e38);
111  Monomial M3 [] { t31, t32, t33, t34, t35, t36, t37, t38 };
112  Prime_Field_Element C3 [] { a, -a, -a, -a, a, a, a, -a };
113  Constant_Polynomial f3(8, R, M3, C3);
114  f3.sort_by_order();
115  // fourth poly
116  EXP_TYPE e41 [] {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t41(32, e41);
117  EXP_TYPE e42 [] {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t42(32, e42);
118  EXP_TYPE e43 [] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t43(32, e43);
119  EXP_TYPE e44 [] {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}; Monomial t44(32, e44);
120  EXP_TYPE e45 [] {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0}; Monomial t45(32, e45);
121  EXP_TYPE e46 [] {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t46(32, e46);
122  EXP_TYPE e47 [] {0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; Monomial t47(32, e47);
123  EXP_TYPE e48 [] {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t48(32, e48);
124  Monomial M4 [] { t41, t42, t43, t44, t45, t46, t47, t48 };
125  Prime_Field_Element C4 [] { -a, a, -a, a, a, -a, a, -a };
126  Constant_Polynomial f4(8, R, M4, C4);
127  f4.sort_by_order();
128  // fifth poly
129  EXP_TYPE e51 [] {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; Monomial t51(32, e51);
130  EXP_TYPE e52 [] {0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}; Monomial t52(32, e52);
131  EXP_TYPE e53 [] {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t53(32, e53);
132  EXP_TYPE e54 [] {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}; Monomial t54(32, e54);
133  EXP_TYPE e55 [] {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; Monomial t55(32, e55);
134  EXP_TYPE e56 [] {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0}; Monomial t56(32, e56);
135  EXP_TYPE e57 [] {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0}; Monomial t57(32, e57);
136  EXP_TYPE e58 [] {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}; Monomial t58(32, e58);
137  Monomial M5 [] { t51, t52, t53, t54, t55, t56, t57, t58 };
138  Prime_Field_Element C5 [] { -a, -a, a, -a, a, a, a, -a };
139  Constant_Polynomial f5(8, R, M5, C5);
140  f5.sort_by_order();
141  // sixth poly
142  EXP_TYPE e61 [] {0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; Monomial t61(32, e61);
143  EXP_TYPE e62 [] {0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}; Monomial t62(32, e62);
144  EXP_TYPE e63 [] {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t63(32, e63);
145  EXP_TYPE e64 [] {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0}; Monomial t64(32, e64);
146  EXP_TYPE e65 [] {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0}; Monomial t65(32, e65);
147  EXP_TYPE e66 [] {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}; Monomial t66(32, e66);
148  Monomial M6 [] { t61, t62, t63, t64, t65, t66 };
149  Prime_Field_Element C6 [] { -a, -a, a, a, a, -a };
150  Constant_Polynomial f6(6, R, M6, C6);
151  f6.sort_by_order();
152  // seventh poly
153  EXP_TYPE e71 [] {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; Monomial t71(32, e71);
154  EXP_TYPE e72 [] {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}; Monomial t72(32, e72);
155  EXP_TYPE e73 [] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}; Monomial t73(32, e73);
156  EXP_TYPE e74 [] {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t74(32, e74);
157  EXP_TYPE e75 [] {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}; Monomial t75(32, e75);
158  EXP_TYPE e76 [] {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}; Monomial t76(32, e76);
159  EXP_TYPE e77 [] {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}; Monomial t77(32, e77);
160  EXP_TYPE e78 [] {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}; Monomial t78(32, e78);
161  Monomial M7 [] { t71, t72, t73, t74, t75, t76, t77, t78 };
162  Prime_Field_Element C7 [] { -a, -a, -a, a, a, -a, a, a };
163  Constant_Polynomial f7(8, R, M7, C7);
164  f7.sort_by_order();
165  // eighth poly
166  EXP_TYPE e81 [] {0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}; Monomial t81(32, e81);
167  EXP_TYPE e82 [] {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}; Monomial t82(32, e82);
168  EXP_TYPE e83 [] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}; Monomial t83(32, e83);
169  EXP_TYPE e84 [] {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; Monomial t84(32, e84);
170  EXP_TYPE e85 [] {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}; Monomial t85(32, e85);
171  EXP_TYPE e86 [] {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0}; Monomial t86(32, e86);
172  EXP_TYPE e87 [] {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}; Monomial t87(32, e87);
173  EXP_TYPE e88 [] {0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}; Monomial t88(32, e88);
174  Monomial M8 [] { t81, t82, t83, t84, t85, t86, t87, t88 };
175  Prime_Field_Element C8 [] { -a, -a, -a, a, a, -a, a, a };
176  Constant_Polynomial f8(8, R, M8, C8);
177  f8.sort_by_order();
178  // message
179  cout << "Computing a Groebner basis for\n\t" << f1 << ",\n\t" << f2
180  << "\n\t" << f3 << "\n\t" << f4
181  << "\n\t" << f5 << "\n\t" << f6
182  << "\n\t" << f7 << "\n\t" << f8
183  << endl;
184  // compute basis
185  list<Abstract_Polynomial *> F;
186  F.push_back(&f1); F.push_back(&f2); F.push_back(&f3); F.push_back(&f4);
187  F.push_back(&f5); F.push_back(&f6); F.push_back(&f7); F.push_back(&f8);
188  list<Constant_Polynomial *> G;
189  if (static_algorithm) G = buchberger(F, method, StrategyFlags::SUGAR_STRATEGY);
190  else G = buchberger_dynamic(
191  F, method, StrategyFlags::SUGAR_STRATEGY, nullptr, heuristic, solver, true
192  );
193  auto ordering = static_cast<const CachedWGrevlex_Ordering *>(
194  G.front()->monomial_ordering()
195  );
196  cout << "Basis:\n";
197  while (not G.empty()) {
198  auto g = G.front();
199  G.pop_front();
200  cout << '\t' << g->leading_monomial() << endl;
201  //delete g;
202  }
203  if (not static_algorithm) {
204  delete [] ordering->order_weights();
205  delete ordering;
206  }
207  //check_correctness(G, SUGAR_STRATEGY);
208  cout << "bye\n";
209 }
virtual const WT_TYPE * order_weights() const override
the weights that define this ordering
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
DynamicHeuristic
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...
DynamicSolver
used by buchberger_dynamic() to decide which solver to use
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
the weighted grevlex ordering for a specified number of variables, with cached weights for each monom...