Gröbner basis project
Codebase for research into Gröbner basis computation
dense_univariate_rational_poly_old.cpp
1 #ifndef __DENSE_UNIVARIATE_RATIONAL_POLY_CPP_
2 #define __DENSE_UNIVARIATE_RATIONAL_POLY_CPP_
3 
4 #include "dense_univariate_rational_poly.hpp"
5 
6 template <typename T, typename U>
7 void divide_by_common_term(T & a, U & b) {
8  T c = (a < 0) ? -a : a;
9  //U d = (b < 0) ? -b : b;
10  U d = b;
11  while (d != 0) {
12  T r = c % d;
13  c = d;
14  d = r;
15  }
16  a /= c;
17  b /= c;
18 }
19 
21  DEG_TYPE n
22 ) {
23  numerators = new COEF_TYPE [n];
24  denominators = new UCOEF_TYPE [n];
25  for (DEG_TYPE i = 0; i < n; ++i) {
26  numerators[i] = 0;
27  denominators[i] = 1;
28  }
29  size = n;
30  deg = 0;
31 }
32 
35 ) {
36  size = other.size;
37  deg = other.deg;
38  numerators = new COEF_TYPE [size] { 0 };
39  denominators = new UCOEF_TYPE [size] { 1 };
40  DEG_TYPE i = 0;
41  for (/* */; i <= deg; ++i) {
42  numerators[i] = other.numerator(i);
43  denominators[i] = other.denominator(i);
44  }
45  for (/* */; i < size; ++i) {
46  numerators[i] = 0;
47  denominators[i] = 1;
48  }
49 }
50 
52  DEG_TYPE n, int64_t * nums, uint64_t * denoms
53 ) {
54  size = n + 1;
55  deg = n;
56  numerators = new COEF_TYPE [size] { 0 };
57  denominators = new UCOEF_TYPE [size] { 1 };
58  for (DEG_TYPE i = 0; i <= deg; ++i) {
59  numerators[i] = nums[i];
60  denominators[i] = denoms[i];
61  }
62 }
63 
65  if (n + 1 > size) {
66  COEF_TYPE * new_nums = new COEF_TYPE [n + 1];
67  UCOEF_TYPE * new_dens = new UCOEF_TYPE [n + 1];
68  for (DEG_TYPE i = 0; i < deg + 1; ++i) {
69  new_nums[i] = numerators[i];
70  new_dens[i] = denominators[i];
71  }
72  delete [] numerators;
73  delete [] denominators;
74  numerators = new_nums;
75  denominators = new_dens;
76  for (DEG_TYPE i = deg + 1; i < n + 1; ++i) {
77  numerators[i] = 0;
78  denominators[i] = 1;
79  }
80  size = n + 1;
81  }
82 }
83 
85  for (DEG_TYPE i = 0; i <= deg; ++i)
86  if (numerators[i] != 0)
88 }
89 
91  COEF_TYPE a, UCOEF_TYPE b
92 ) {
93  for (DEG_TYPE i = 0; i <= deg; ++i)
94  if (numerators[i] != 0) {
95  set_coefficient(i, numerators[i] * a, numerators[i] * b);
96  }
97 }
98 
100  DEG_TYPE k
101 ) {
102  expand_poly(deg + k);
103  for (DEG_TYPE i = deg; i > 0; --i) {
104  if (numerators[i] != 0) {
105  set_coefficient(i + k, numerators[i], denominators[i]);
106  set_coefficient(i, 0, 1);
107  }
108  }
110  set_coefficient(0, 0, 1);
111 }
112 
115 ) {
116  DEG_TYPE n = deg + q.deg + 1; // add 1 in case deg == q.deg == 0
117  n = (n > size) ? n : size;
118  COEF_TYPE * new_nums = new COEF_TYPE [n];
119  UCOEF_TYPE * new_dens = new UCOEF_TYPE [n];
120  for (DEG_TYPE i = 0; i < n; ++i) {
121  new_nums[i] = 0;
122  new_dens[i] = 1;
123  }
124  for (DEG_TYPE i = 0; i < deg + 1; ++i)
125  for (DEG_TYPE j = 0; j < q.deg + 1; ++j) {
126  if (numerators[i] != 0 and q.numerators[j] != 0) {
127  COEF_TYPE new_a = numerators[i] * q.numerators[j];
128  UCOEF_TYPE new_b = denominators[i] * q.denominators[j];
129  new_nums[i + j] = new_nums[i + j] * new_b + new_dens[i + j] * new_a;
130  new_dens[i + j] *= new_b;
131  divide_by_common_term<COEF_TYPE, UCOEF_TYPE>(new_nums[i + j], new_dens[i + j]);
132  }
133  }
134  delete [] numerators;
135  delete [] denominators;
136  numerators = new_nums;
137  denominators = new_dens;
138  size = n;
139  deg = deg + q.deg;
140 }
141 
143  for (DEG_TYPE i = 0; i <= deg; ++i)
144  if (numerators[i] != 0)
145  numerators[i] = -numerators[i];
146 }
147 
150 ) {
151  DEG_TYPE new_deg = (deg > q.deg) ? deg : q.deg;
152  expand_poly(new_deg);
153  deg = new_deg;
154  for (DEG_TYPE i = 0; i <= q.deg; ++i) {
155  if (q.numerators[i] != 0) {
156  numerators[i] = numerators[i] * q.denominators[i]
157  + q.numerators[i] * denominators[i];
158  denominators[i] *= q.denominators[i];
159  if (numerators[i] != 0)
161  }
162  }
163  if (numerators[deg] == 0) {
164  DEG_TYPE i = deg;
165  while (i > 0 and numerators[i] == 0)
166  --i;
167  deg = i;
168  }
169 }
170 
173 ) {
174  DEG_TYPE new_deg = (deg > q.deg) ? deg : q.deg;
175  expand_poly(new_deg);
176  deg = new_deg;
177  for (DEG_TYPE i = 0; i <= q.deg; ++i) {
178  if (q.numerators[i] != 0) {
179  numerators[i] = numerators[i] * q.denominators[i]
180  - q.numerators[i] * denominators[i];
181  denominators[i] *= q.denominators[i];
182  if (numerators[i] != 0)
184  }
185  }
186  if (numerators[deg] == 0) {
187  DEG_TYPE i = deg;
188  while (i > 0 and numerators[i] == 0)
189  --i;
190  deg = i;
191  }
192 }
193 
196  const Dense_Univariate_Rational_Polynomial & other) const {
197  DEG_TYPE m = (deg < other.degree()) ? deg : other.degree();
198  DEG_TYPE n = (deg > other.degree()) ? deg : other.degree();
200  DEG_TYPE i = 0;
201  for ( /* already initialized */; i <= m; ++i)
202  result.set_coefficient(i,
203  numerators[i] * other.denominator(i)
204  - other.numerator(i) * denominators[i],
205  denominators[i] * other.denominator(i)
206  );
207  // only one of the next two loops will be performed
208  while (i < deg) {
209  result.set_coefficient(i, numerators[i], denominators[i]);
210  ++i;
211  }
212  while (i < other.degree()) {
213  result.set_coefficient(i, -other.numerator(i), other.denominator(i));
214  ++i;
215  }
216  return result;
217 }
218 
219 #endif
COEF_TYPE * numerators
list of numerators; index 0 is the constant’s
MPZCOEF_TYPE numerator(DEG_TYPE k) const
returns the th numerator
void set_coefficient(DEG_TYPE k, long a, unsigned long b)
set the coefficient of to
DEG_TYPE size
number of slots for coefficients
void multiply_by(const Dense_Univariate_Rational_Polynomial &)
highly inefficient polynomial multiplication ( )
void add(const Dense_Univariate_Rational_Polynomial &)
adds other to this
void expand_poly(DEG_TYPE)
expand to allow for higher-degree monomials
void subtract(const Dense_Univariate_Rational_Polynomial &)
subtracts other from this
void multiply_by_monomial_of_degree(DEG_TYPE)
a hopefully efficient multiplication algorithm
DEG_TYPE deg
degree of the polynomial (largest nonzero exponent)
void scale_by(COEF_TYPE a)
multiplies every monomial by a constant integer
quick-’n-dirty Dense_Univariate rational polynomial class
MPZCOEF_TYPE denominator(DEG_TYPE k) const
returns the th denominator
DEG_TYPE degree() const
returns the polynomial’s degree
void divide_by_common_term(COEF_TYPE &, UCOEF_TYPE &)
divides out the common term of the two given numbers
Dense_Univariate_Rational_Polynomial(DEG_TYPE)
construct with the number of expected terms
Dense_Univariate_Rational_Polynomial operator-(const Dense_Univariate_Rational_Polynomial &) const
returns the difference between this and the other
UCOEF_TYPE * denominators
list of denominators; index 0 is the constant’s