Gröbner basis project
Codebase for research into Gröbner basis computation
fields.cpp
1 #ifndef __FIELDS_CPP_
2 #define __FIELDS_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 "fields.hpp"
22 
23 Prime_Field::Prime_Field(UCOEF_TYPE modulus, bool show_modulus) {
24  m = modulus;
25  Fi = new COEF_TYPE [m] {0};
26  Fi[1] = 1;
27  Fi[m-1] = m - 1;
28  for (UCOEF_TYPE a = 2; a < m - 1; ++a) {
29  bool negative = true;
30  COEF_TYPE s = 1; COEF_TYPE t = 0;
31  COEF_TYPE u = 0; COEF_TYPE v = 1;
32  COEF_TYPE c = (COEF_TYPE )m; COEF_TYPE d = a;
33  while (d != 0) {
34  COEF_TYPE q = c / d; COEF_TYPE r = c - q*d;
35  COEF_TYPE w = u*q + s; COEF_TYPE x = v*q + t;
36  s = u; t = v; u = w; v = x;
37  c = d; d = r;
38  negative = not negative;
39  }
40  if (negative) Fi[a] = m - t; else Fi[a] = t;
41  }
42  print_modulus = show_modulus;
43 }
44 
46  m = F.m;
47  Fi = new COEF_TYPE [m];
48  for (unsigned i = 0; i < m; ++i)
49  Fi[i] = F.Fi[i];
51 }
52 
53 Prime_Field::~Prime_Field() { delete [] Fi; }
54 
55 COEF_TYPE Prime_Field::inverse(COEF_TYPE a) {
56  return Fi[a];
57 }
58 
60 
62 
64  : F(field)
65 { a = 0; m = F->modulus(); }
66 
68  : F(field)
69 {
70  a = value;
71  m = F->modulus();
72  if (a > m) a %= m;
73  while (a < 0) a += m;
74 }
75 
76 COEF_TYPE Prime_Field_Element::value() const { return a; }
77 
78 unsigned Prime_Field_Element::modulus() const { return m; }
79 
81 
82 bool Prime_Field_Element::like(const Prime_Field_Element & b) const { return m == b.m; }
83 
84 COEF_TYPE Prime_Field_Element::inverse() const { return F->inverse(a); }
85 
86 //bool Prime_Field_Element::is_zero() const { return a == 0; }
87 
88 bool Prime_Field_Element::is_one() const { return a == 1; }
89 
91 
93  a += other.a;
94  if (a >= m) a -= m;
95 }
96 
98  a -= other.a;
99  if (a < 0) a += m;
100 }
101 
103  a *= other.a;
104  if (a >= m) a %= m;
105 }
106 
107 void Prime_Field_Element::operator *=(const COEF_TYPE b) {
108  a *= b;
109  if (a >= m) a %= m;
110 }
111 
113  a *= other.inverse();
114  if (a >= m) a %= m;
115 }
116 
119  const Prime_Field_Element &b)
120 {
121  Prime_Field_Element c(a.a, a.F);
122  c.a += b.a;
123  c.a %= c.m;
124  return c;
125 }
126 
129  const Prime_Field_Element &b)
130 {
131  Prime_Field_Element c(a.a, a.F);
132  c.a -= b.a;
133  while (c.a < 0) c.a += c.m;
134  return c;
135 }
136 
139  const Prime_Field_Element &b)
140 {
141  Prime_Field_Element c(a.a, a.F);
142  c.a *= b.a;
143  c.a %= c.m;
144  return c;
145 }
146 
148  const int b)
149 {
150  Prime_Field_Element c(a.a, a.F);
151  c.a += b;
152  c.a %= c.m;
153  return c;
154 }
155 
157  const int b)
158 {
159  Prime_Field_Element c(a.a, a.F);
160  c.a -= b;
161  while (c.a < 0) c.a += c.m;
162  return c;
163 }
164 
166  const int b)
167 {
168  Prime_Field_Element c(a.a, a.F);
169  c.a *= b;
170  c.a %= c.m;
171  return c;
172 }
173 
175 {
176  Prime_Field_Element c(-a.a, a.F);
177  return c;
178 }
179 
180 ostream & operator <<(ostream & os, const Prime_Field_Element &a)
181 {
182  os << a.a;
183  if (a.F->get_print_modulus())
184  os << '_' << a.m;
185  return os;
186 }
187 
189  return Prime_Field_Element(1,this);
190 }
191 
193  return Prime_Field_Element(0,this);
194 }
195 
196 #endif
friend Prime_Field_Element operator-(const Prime_Field_Element &, const Prime_Field_Element &)
Does not modify this.
Definition: fields.cpp:128
COEF_TYPE * Fi
for , is multiplicative inverse of , mod
Definition: fields.hpp:114
void operator-=(const Prime_Field_Element &other)
decreases the value of this.
Definition: fields.cpp:97
unsigned m
the number’ modulus, stored here to avoid the expense of accessing it in .
Definition: fields.hpp:268
friend Prime_Field_Element operator*(const Prime_Field_Element &, const Prime_Field_Element &)
Does not modify this.
Definition: fields.cpp:138
Prime_Field * field() const
The field this element lies in.
Definition: fields.cpp:80
void operator+=(const Prime_Field_Element &other)
increases the value of this.
Definition: fields.cpp:92
void operator/=(const Prime_Field_Element &other)
Changes the value of this.
Definition: fields.cpp:112
Prime_Field_Element zero()
“zero” is the additive identity.
Definition: fields.cpp:192
Information necessary for a field modulo a prime.
Definition: fields.hpp:49
UCOEF_TYPE m
characteristic/modulus of the field
Definition: fields.hpp:109
bool get_print_modulus()
indicates whether to print the modulus
Definition: fields.cpp:61
void negate()
“Negates” this.
Definition: fields.cpp:90
Prime_Field_Element unity()
“unity” is the multiplicative identity.
Definition: fields.cpp:188
COEF_TYPE inverse(COEF_TYPE a)
Returns the inverse of , modulo .
Definition: fields.cpp:55
bool print_modulus
determines whether a coefficient&#39;s modulus is printed
Definition: fields.hpp:118
COEF_TYPE a
the number’s value; descendants should ensure
Definition: fields.hpp:263
unsigned modulus() const
Returns the field&#39;s modulus.
Definition: fields.hpp:85
Prime_Field(UCOEF_TYPE modulus, bool show_modulus=false)
Please read detailed information.
Definition: fields.cpp:23
Element of a field of prime characteristic.
Definition: fields.hpp:137
unsigned modulus() const
The field&#39;s modulus.
Definition: fields.cpp:78
bool is_one() const
Is this the multiplicative identity?
Definition: fields.cpp:88
Prime_Field * F
the field this element lives in; used to find inverses
Definition: fields.hpp:259
Prime_Field_Element(Prime_Field *field)
Constructs a prime field element in the specified field, with the value 0.
Definition: fields.cpp:63
void operator*=(const Prime_Field_Element &other)
multiply the value of this by other
Definition: fields.cpp:102
void set_print_modulus(bool b)
determines whether to print the modulus
Definition: fields.cpp:59
bool like(const Prime_Field_Element &b) const
true iff this and b have the same modulus.
Definition: fields.cpp:82
COEF_TYPE inverse() const
Returns the multiplicative inverse of this.
Definition: fields.cpp:84
COEF_TYPE value() const
The value of the element. This always satisfies .
Definition: fields.cpp:76
friend Prime_Field_Element operator+(const Prime_Field_Element &, const Prime_Field_Element &)
Does not modify this.
Definition: fields.cpp:118