Gröbner basis project
Codebase for research into Gröbner basis computation
polynomial_array.cpp
1 #ifndef __POLYNOMIAL_ARRAY_CPP_
2 #define __POLYNOMIAL_ARRAY_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 "polynomial_array.hpp"
22 
24  const Constant_Polynomial * poly, bool at_end
25 ) {
26  p = poly;
27  if (at_end) i = p->m - 1;
28  else i = p->head;
29 }
30 
31 Constant_Polynomial_Iterator::~Constant_Polynomial_Iterator() { }
32 
34  const
35 { return p->M[i];}
36 
37 const Prime_Field_Element &
39 { return p->A[i]; }
40 
42 
44 
46 
47 bool Constant_Polynomial_Iterator::canMoveRight() const { return i + 1 < p->m; }
48 
49 bool Constant_Polynomial_Iterator::canMoveLeft() const { return i - 1 < p->head; }
50 
52 { return i < p->head or i == p->m; }
53 
55  unsigned length,
56  Polynomial_Ring & R,
57  const Monomial *mons,
58  const Prime_Field_Element *coeffs,
59  const Monomial_Ordering * order
60 ) : Abstract_Polynomial(R, order)
61 {
62  if (order == nullptr) {
63  if (mons[0].monomial_ordering() == nullptr)
64  order = generic_grevlex_ptr;
65  else
66  order = mons[0].monomial_ordering();
67  }
68  m = length;
69  M = (Monomial *)calloc(m, sizeof(Monomial));
70  A = (Prime_Field_Element *)calloc(m, sizeof(Prime_Field_Element));
71  for (unsigned i = 0; i < m; ++i) {
73  M[i].initialize_exponents(mons[i].num_vars());
74  M[i] = mons[i];
75  if (order != M[i].monomial_ordering())
76  M[i].set_monomial_ordering(order);
77  A[i] = coeffs[i];
78  }
79  head = 0;
80 }
81 
84  const list<Monomial> & mons,
85  const list<Prime_Field_Element> & coeffs,
86  const Monomial_Ordering * order
87 ) : Abstract_Polynomial(R, order)
88 {
89  if (order == nullptr) {
90  if (mons.front().monomial_ordering() == nullptr)
91  order = generic_grevlex_ptr;
92  else
93  order = mons.front().monomial_ordering();
94  }
95  m = mons.size();
96  M = (Monomial *)calloc(m, sizeof(Monomial));
97  A = (Prime_Field_Element *)calloc(m, sizeof(Prime_Field_Element));
98  auto Mi = mons.begin();
99  auto Ai = coeffs.begin();
100  unsigned i = 0;
101  while (Mi != mons.end()) {
103  M[i].initialize_exponents(Mi->num_vars());
104  M[i] = *Mi;
105  if (order != Mi->monomial_ordering())
106  M[i].set_monomial_ordering(order);
107  A[i] = *Ai;
108  ++Mi; ++Ai; ++i;
109  }
110  head = 0;
111 }
112 
114  unsigned length,
115  Polynomial_Ring & R,
116  const Monomial_Ordering * order
117 ) : Abstract_Polynomial(R, order)
118 {
119  m = length;
120  M = (Monomial *)malloc(m*sizeof(Monomial));
121  A = (Prime_Field_Element *)malloc(m*sizeof(Prime_Field_Element));
122  for (unsigned i = 0; i < m; ++i) {
125  M[i].set_monomial_ordering(order);
126  }
127  head = 0;
128 }
129 
131  Polynomial_Ring & R,
132  const Monomial_Ordering * order,
133  uint64_t size,
134  uint64_t * AM
135 ) : Abstract_Polynomial(R, order) {
136  m = size;
137  Prime_Field & F = R.ground_field();
138  M = (Monomial *)malloc(m*sizeof(Monomial));
139  A = (Prime_Field_Element *)malloc(m*sizeof(Prime_Field_Element));
140  unsigned j = 0;
141  for (unsigned i = 0; i < m; ++i) {
142  A[i].assign(AM[j++], &F);
145  for (NVAR_TYPE k = 0; k < number_of_variables(); ++k)
146  M[i].set_exponent(k, AM[j++]);
147  M[i].set_monomial_ordering(order);
148  }
149  head = 0;
150 }
151 
152 uint64_t * Constant_Polynomial::serialized(uint64_t & size) {
153  NVAR_TYPE n = number_of_variables();
154  /*uint64_t * result = (uint64_t *)malloc(
155  sizeof(uint64_t)*m*(n+1)
156  );*/
157  uint64_t * result = new uint64_t[m*(n+1)];
158  unsigned j = 0;
159  for (unsigned i = 0; i < m; ++i) {
160  result[j++] = A[i].value();
161  for (NVAR_TYPE k = 0; k < n; ++k)
162  result[j++] = M[i][k];
163  }
164  size = m*(n+1);
165  return result;
166 }
167 
168 Constant_Polynomial::~Constant_Polynomial() {
169  for (unsigned i = head; i < m; ++i)
170  M[i].deinitialize();
171  free(M); free(A); M = nullptr; A = nullptr;
172 }
173 
175  const Monomial_Ordering * order, bool sort_anew
176 ) {
177  for (int i = head; i < m; ++i)
178  M[i].set_monomial_ordering(order);
179  if (sort_anew)
180  sort_by_order();
181 }
182 
184 {
185  // insertion sort, as we don't expect worst case
186  for (int i = head + 1; i < m; ++i) {
187  int j = i;
188  Monomial t(M[i]);
189  Prime_Field_Element c(A[i]);
190  for (/* */; j > head and t > M[j-1]; --j) {
191  A[j] = A[j-1];
192  M[j] = M[j-1];
193  }
194  if (i != j) {
195  A[j] = c;
196  M[j] = t;
197  }
198  }
199 }
200 
202 
204  return A[head];
205 }
206 
207 unsigned Constant_Polynomial::length() const { return m - head; }
208 
210  return m == head or A[head].is_zero();
211 }
212 
214  Monomial empty(M[0].num_vars());
215  Prime_Field_Element zero(0, A[0].field());
216  Monomial newM [] { empty };
217  Prime_Field_Element newA [] { zero };
218  return new Constant_Polynomial(1, R, newM, newA, monomial_ordering());
219 }
220 
222 const {
223  Constant_Polynomial *result = new Constant_Polynomial(*this);
224  for (unsigned i = head; i < m + 1; ++i)
225  result->M[i] *= t;
226  return result;
227 }
228 
230  const Prime_Field_Element &c
231 ) const {
232  Constant_Polynomial *result = new Constant_Polynomial(*this);
233  for (unsigned i = head; i < m; ++i)
234  result->A[i] *= c;
235  return result;
236 }
237 
240 { return new Constant_Polynomial_Iterator(this); }
241 
243 { return new Constant_Polynomial_Iterator(this); }
244 
246 { return new Constant_Polynomial_Iterator(this, true); }
247 
250 {
252  m = p.length();
253  M = (Monomial *)malloc(m*sizeof(Monomial));
254  A = (Prime_Field_Element *)malloc(m*sizeof(Prime_Field_Element));
255  for (unsigned i = 0; i < m and !pi->fellOff(); pi->moveRight())
256  {
259  M[i] = pi->currMonomial();
260  A[i] = pi->currCoeff();
261  ++i;
262  }
263  head = 0;
264  delete pi;
265 }
266 
268  Constant_Polynomial * poly)
269 {
270  p = poly;
271  i = p->head;
272 }
273 
274 Mutable_Constant_Polynomial_Iterator::~Mutable_Constant_Polynomial_Iterator() { }
275 
277 
279 
281 
283  return i < p->head or i >= p->m;
284 }
285 
287  return p->M[i];
288 }
289 
291  return p->A[i];
292 }
293 
295  p->A[i] = a;
296 }
297 
299  p->M[i] = t;
300 }
301 
302 #endif
The general class of a polynomial.
Definition: polynomial.hpp:101
virtual void restart_iteration() override
This should move the iterator to the leading term.
virtual bool canMoveLeft() const override
virtual bool fellOff() const override
Monomial * M
array of monomials, in one-to-one correspondence with A
const Monomial_Ordering * monomial_ordering() const
reports leading monomial’s monomial ordering
Definition: polynomial.hpp:130
virtual void moveLeft() override
Moves left in the polynomial, to the next larger monomial.
virtual Prime_Field & ground_field() const
ground field
Constant_Polynomial_Iterator(const Constant_Polynomial *q, bool at_end=false)
Creates an iterator for poly and starts at the leading term.
A Constant_Polynomial is a polynomial that should not change.
virtual const Monomial & currMonomial() const override
Reports the monomial at the current position.
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?
Definition: fields.hpp:180
virtual Prime_Field_Element leading_coefficient() const override
Constant_Polynomial(unsigned length, Polynomial_Ring &R, const Monomial *mons, const Prime_Field_Element *coeffs, const Monomial_Ordering *order=nullptr)
virtual void set_currCoeff(const Prime_Field_Element &a) override
change coefficient in current position
virtual const Prime_Field_Element & currCoeff() const =0
Reports the coefficient at the current position.
virtual void moveRight() override
Moves right in the polynomial, to the next smaller monomial.
virtual bool fellOff() const override
Information necessary for a field modulo a prime.
Definition: fields.hpp:49
virtual Polynomial_Iterator * begin() const override
iterator to the first element
void set_monomial_ordering(const Monomial_Ordering *mord)
sets the Monomial_Ordering associated with this Monomial
Definition: monomial.cpp:211
virtual const Monomial & currMonomial() const override
Reports the monomial at the current position.
const Constant_Polynomial * p
the polynomial we iterate on
virtual Constant_Polynomial * zero_polynomial() const override
uint64_t * serialized(uint64_t &size)
Prime_Field_Element * A
array of coefficients, in one-to-one correspondence with M
virtual Polynomial_Iterator * end() const override
iterator to the last element
virtual Constant_Polynomial * monomial_multiple(const Monomial &t) const override
friend class Constant_Polynomial_Iterator
to iterate without changing this
virtual void moveRight() override
Moves right in the polynomial, to the next smaller monomial.
virtual const Prime_Field_Element & currCoeff() const override
Reports the coefficient at the current position.
virtual const Prime_Field_Element & currCoeff() const override
Reports the coefficient at the current position.
NVAR_TYPE num_vars() const
number of variables
Definition: monomial.hpp:130
virtual void set_currMonomial(const Monomial &t) override
change monomial in current position
virtual bool fellOff() const =0
virtual Monomial & leading_monomial() const override
virtual void sort_by_order() override
sort by order
Implementation of monomials.
Definition: monomial.hpp:69
Element of a field of prime characteristic.
Definition: fields.hpp:137
interface to a monomial ordering
unsigned number_of_variables() const
number of variables – all monomials should agree with this (though it is never tested by the class) ...
Definition: polynomial.cpp:29
Encapsulates information about a polynomial ring for easy access: ground field, number of indetermina...
virtual bool canMoveRight() const override
Can this iterator move right, or would it fall off?
void initialize_exponents(NVAR_TYPE number_of_vars)
allocates memory for exponents This is useful when you want to allocate an array of monomials...
Definition: monomial.cpp:65
Iterates through a Constant_Polynomial.
virtual Constant_Polynomial_Iterator * new_iterator() const override
an iterator that poses no risk of modifying the polynomial
virtual void set_monomial_ordering(const Monomial_Ordering *order, bool sort_anew=true) override
sets the ordering of monomials in this polynomial
const Monomial_Ordering * monomial_ordering() const
the Monomial_Ordering associated with this Monomial
Definition: monomial.hpp:165
long i
current position in p’s array
Used to iterate through a polynomial.
Definition: polynomial.hpp:224
virtual void restart_iteration() override
This should move the iterator to the leading term.
virtual const Monomial & currMonomial() const =0
Reports the monomial at the current position.
virtual Constant_Polynomial * scalar_multiple(const Prime_Field_Element &c) const override
virtual void moveLeft() override
Moves left in the polynomial, to the next larger monomial.
virtual unsigned length() const override
COEF_TYPE value() const
The value of the element. This always satisfies .
Definition: fields.cpp:76
Polynomial_Ring & R
data about polynomial ring
Definition: polynomial.hpp:207
Mutable_Constant_Polynomial_Iterator(Constant_Polynomial *poly)
Creates an iterator for poly and starts at its leading term.
unsigned m
position after last monomial
virtual unsigned length() const =0
number of monomials
void assign(COEF_TYPE val, Prime_Field *K)
for initializing arrays of Prime_Field_Element
Definition: fields.hpp:187
Polynomial_Ring & base_ring() const
ring in which this polynomial resides
Definition: polynomial.cpp:25
virtual bool is_zero() const override
unsigned head
location of leading term in array (always farther left)
void common_initialization(const Monomial_Ordering *ord=nullptr)
things all Monomial initializers must do
Definition: monomial.hpp:74