Gröbner basis project
Codebase for research into Gröbner basis computation
dense_univariate_integer_poly.cpp
1 #ifndef __DENSE_UNIVARIATE_INTEGER_POLY_CPP_
2 #define __DENSE_UNIVARIATE_INTEGER_POLY_CPP_
3 
4 /*****************************************************************************\
5 * This file is part of DynGB. *
6 * *
7 * DynGB is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * Foobar is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with DynGB. If not, see <http://www.gnu.org/licenses/>. *
19 \*****************************************************************************/
20 
21 #include "dense_univariate_integer_poly.hpp"
22 
23 using std::cout; using std::endl;
24 
26  DEG_TYPE n
27 ) {
28  coeffs = new COEF_TYPE [n];
29  for (DEG_TYPE i = 0; i < n; ++i)
30  coeffs[i] = 0;
31  size = n;
32  deg = 0;
33 }
34 
37 ) {
38  size = p.size;
39  deg = p.deg;
40  coeffs = new COEF_TYPE[size];
41  for (DEG_TYPE i = 0; i <= deg; ++i)
42  coeffs[i] = p.coeffs[i];
43 }
44 
46  DEG_TYPE n, int64_t * C
47 ) {
48  size = n + 1;
49  deg = n;
50  coeffs = new COEF_TYPE[size] { 0 };
51  for (DEG_TYPE i = 0; i <= deg; ++i)
52  coeffs[i] = C[i];
53 }
54 
56  if (n + 1 > size) {
57  COEF_TYPE * new_nums = new COEF_TYPE [n + 1];
58  for (DEG_TYPE i = 0; i < deg + 1; ++i)
59  new_nums[i] = coeffs[i];
60  delete [] coeffs;
61  coeffs = new_nums;
62  for (DEG_TYPE i = deg + 1; i < n + 1; ++i)
63  coeffs[i] = 0;
64  size = n + 1;
65  }
66 }
67 
69  DEG_TYPE k, COEF_TYPE a
70 ) {
71  coeffs[k] = a;
72  if (k > deg and a != 0) { deg = k; }
73  else if (k == deg and a == 0) {
74  while (deg > 0 and coeffs[deg] == 0) { --deg; }
75  }
76 }
77 
79  for (DEG_TYPE i = 0; i <= deg; ++i)
80  if (coeffs[i] != 0)
81  set_coefficient(i, coeffs[i] * a);
82 }
83 
85  DEG_TYPE k
86 ) {
87  expand_poly(deg + k);
88  for (DEG_TYPE i = deg; i > 0; --i) {
89  if (coeffs[i] != 0) {
90  set_coefficient(i + k, coeffs[i]);
91  set_coefficient(i, 0);
92  }
93  }
94  set_coefficient(k, coeffs[0]);
95  set_coefficient(0, 0);
96 }
97 
100 ) {
101  DEG_TYPE n = deg + q.deg + 1; // add 1 in case deg == q.deg == 0
102  DEG_TYPE nq = q.deg;
103  n = (n > size) ? n : size;
104  COEF_TYPE * new_nums = new COEF_TYPE [n] { 0 };
105  COEF_TYPE * b = q.coeffs;
106  /*for (DEG_TYPE i = 0; i < n; ++i)
107  new_nums[i] = 0;*/
108  for (DEG_TYPE i = 0; i < deg + 1; ++i)
109  for (DEG_TYPE j = 0; j < nq + 1; ++j)
110  if (coeffs[i] != 0 and b[j] != 0)
111  new_nums[i + j] += coeffs[i] * b[j];
112  delete [] coeffs;
113  coeffs = new_nums;
114  size = n;
115  deg = deg + q.deg;
116 }
117 
119  for (DEG_TYPE i = 0; i <= deg; ++i)
120  if (coeffs[i] != 0)
121  coeffs[i] = -coeffs[i];
122 }
123 
126 ) {
127  DEG_TYPE new_deg = (deg > q.deg) ? deg : q.deg;
128  expand_poly(new_deg);
129  deg = new_deg;
130  for (DEG_TYPE i = 0; i <= q.deg; ++i)
131  if (q.coeffs[i] != 0)
132  set_coefficient(i, coeffs[i] + q.coeffs[i]);
133 }
134 
138 ) const {
139  DEG_TYPE m = (deg < q.degree()) ? deg : q.degree();
140  DEG_TYPE n = (deg > q.degree()) ? deg : q.degree();
142  DEG_TYPE i = 0;
143  for ( /* already initialized */ ; i <= n; ++i)
144  r.set_coefficient(i, coeffs[i] - q.coeff(i));
145  // only one of the next two while loops should be executed
146  while (i < deg) {
147  r.set_coefficient(i, coeffs[i]);
148  ++i;
149  }
150  while (i < q.degree()) {
151  r.set_coefficient(i, -q.coeff(i));
152  ++i;
153  }
154  return r;
155 }
156 
157 #endif
void set_coefficient(DEG_TYPE k, COEF_TYPE a)
set the coefficient of to
void scale_by(COEF_TYPE a)
multiplies every monomial by a constant
void multiply_by_monomial_of_degree(DEG_TYPE)
a hopefully efficient multiplication algorithm
Dense_Univariate_Integer_Polynomial operator-(const Dense_Univariate_Integer_Polynomial &) const
returns the result of subtracting the other from this
Dense_Univariate_Integer_Polynomial(DEG_TYPE)
construct with the number of expected terms
DEG_TYPE deg
degree of the polynomial (largest nonzero exponent)
COEF_TYPE coeff(DEG_TYPE k) const
the th coefficient
void expand_poly(DEG_TYPE)
expand to allow for higher-degree monomials
quick-’n-dirty Dense_Univariate integer polynomial class
void multiply_by(const Dense_Univariate_Integer_Polynomial &)
highly inefficient polynomial multiplication ( )
DEG_TYPE size
number of slots for coefficients
void add(const Dense_Univariate_Integer_Polynomial &q)
reasonably efficient, given our dense representation
DEG_TYPE degree() const
the polynomial’s degree (exponent of largest nonzero term)
COEF_TYPE * coeffs
list of numerators; index 0 is the constant’s