Macaulay2 Engine
Loading...
Searching...
No Matches
aring-m2-gf.cpp
Go to the documentation of this file.
1// Copyright 2012 Michael E. Stillman
2
3#include <vector>
4#include <iostream>
5
6#include "interface/random.h"
7#include "relem.hpp"
8#include "polyring.hpp"
9#include "aring-m2-gf.hpp"
10#include "ringmap.hpp"
11#include "monoid.hpp"
12#include "interrupted.hpp"
13
14extern "C" void dringelem(const Ring *R, const ring_elem f);
15
16namespace M2 {
17
19 const ring_elem prim)
20 : mCharac(static_cast<int>(R.characteristic())),
23{
24 assert(mOriginalRing.n_quotients() == 1);
25
27 ring_elem f = mOriginalRing.quotient_element(0);
28 Nterm *t = f;
29 mDimension = mOriginalRing.getMonoid()->primary_degree(t->monom);
31 for (int i = 1; i < mDimension; i++) mOrder *= mCharac;
32 mOne = mOrder - 1; // representation for the number 1: p^n - 1.
33 mOrderMinusOne = mOne; // p^n - 1
34 mMinusOne = (mCharac == 2 ? mOne : mOne / 2);
35
36 // Get ready to create mOneTable.
37 VECTOR(ring_elem) polys;
38 polys.push_back(mOriginalRing.from_long(0));
39 polys.push_back(mOriginalRing.copy(mPrimitiveElement));
40
41 ring_elem oneR = mOriginalRing.from_long(1);
42
43 mGeneratorExponent = static_cast<GFElement>(-1);
44 ring_elem x = mOriginalRing.var(0);
46 for (GFElement i = 2; i <= mOne; i++)
47 {
48 ring_elem g = mOriginalRing.mult(polys[i - 1], mPrimitiveElement);
49 polys.push_back(g);
50 if (mOriginalRing.is_equal(g, oneR)) break;
51 if (mOriginalRing.is_equal(g, x)) mGeneratorExponent = i;
52 }
53
54#if 0
55 for (size_t i = 0; i < polys.size(); i++)
56 {
57 std::cerr << i << " ";
58 dringelem(&R, polys[i]);
59 std::cerr << "\n";
60 }
61#endif
62 assert(polys.size() == mOrder);
63 assert(mGeneratorExponent != static_cast<GFElement>(-1));
64
65 // Set 'one_table'.
68
69 for (GFElement i = 1; i <= mOrderMinusOne; i++)
70 {
72 {
73 // first clean up?
74 return;
75 }
76 ring_elem f1 = mOriginalRing.add(polys[i], oneR);
77 GFElement j;
78 for (j = 0; j <= mOrderMinusOne; j++)
79 if (mOriginalRing.is_equal(f1, polys[j])) break;
80 if (j > mOrderMinusOne)
81 {
82 std::cout << "oops: didn't find element " << i << " !!" << std::endl;
83 }
84 mOneTable[i] = j;
85 }
86
87 // Create the ZZ/P ---> GF(Q) inclusion map
89 GFElement a = mOne;
90 ;
91 mFromIntTable[0] = 0;
92 for (GFElement i = 1; i < mCharac; i++)
93 {
94 mFromIntTable[i] = a;
95 a = mOneTable[a];
96 }
97}
98
99void GaloisFieldTable::display(std::ostream &o) const
100{
101 o << "GF(" << mCharac << "^" << mDimension << ")" << std::endl;
102 o << " order = " << mOrder << std::endl;
103 o << " 1 = " << mOne << std::endl;
104 o << " -1 = " << mMinusOne << std::endl;
105 o << " fromZZ: " << std::endl << " ";
106 for (GFElement i = 0; i < mCharac; i++)
107 {
108 if ((i + 1) % 10 == 0) o << std::endl << " ";
109 o << mFromIntTable[i] << " ";
110 }
111 o << std::endl << " oneTable: " << std::endl << " ";
112 for (GFElement i = 0; i < mOrder; i++)
113 {
114 if ((i + 1) % 10 == 0) o << std::endl << " ";
115 o << mOneTable[i] << " ";
116 }
117 o << std::endl;
118}
119
121{
122 // Nothing to do here.
123}
124
127 const std::vector<long> &poly) const
128{
129 result = 0;
130 ElementType a, b;
131 for (long i = 0; i < poly.size(); i++)
132 if (poly[i] != 0)
133 {
134 set_from_long(a, poly[i]);
135 power(b, mGF.generatorExponent(), i);
136 mult(a, a, b);
137 add(result, result, a);
138 }
139}
140
141bool ARingGFM2::promote(const Ring *Rf, const ring_elem f, elem &result) const
142{
143 if (&mGF.ring() != Rf) return false;
144
145 std::vector<long> poly;
146 RingElement F(Rf, f);
149 return true;
150}
151
153 const ElementType &f) const
154{
155 if (f == 0)
156 result = mGF.ring().from_long(0);
157 else if (f == mGF.one())
158 result = mGF.ring().from_long(1);
159 else
160 result = mGF.ring().power(mGF.primitiveElement(), f);
161}
162
163bool ARingGFM2::lift(const Ring *Rg, const elem f, ring_elem &result) const
164{
165 // Rg = Z/p[x]/F(x) ---> GF(p,n)
166 // promotion: need to be able to know the value of 'x'.
167 // lift: need to compute (primite_element)^e
168
169 if (&mGF.ring() != Rg) return false;
170
172 return true;
173}
174
175void ARingGFM2::eval(const RingMap *map,
176 const elem f,
177 int first_var,
178 ring_elem &result) const
179{
180 result = map->get_ring()->power(map->elem(first_var), f);
181}
182
184{
185 o << "GF(" << mGF.characteristic() << "^" << mGF.dimension() << ",M2)";
186}
187
189 elem a,
190 bool p_one,
191 bool p_plus,
192 bool p_parens) const
193{
194 if (a == 0)
195 {
196 o << "0";
197 return;
198 }
199 ring_elem h = mGF.ring().power(mGF.primitiveElement(), a);
200 mGF.ring().elem_text_out(o, h, p_one, p_plus, p_parens);
201 mGF.ring().remove(h);
202}
203}; // namespace M2
204
205// Local Variables:
206// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
207// indent-tabs-mode: nil
208// End:
void dringelem(const Ring *R, const ring_elem f)
Definition debug.cpp:73
M2::ARingGFM2 — native engine Galois field, no FLINT dependency.
void text_out(buffer &o) const
void power(elem &result, elem a, long n) const
void lift_to_original_ring(ring_elem &result, const ElementType &f) const
void elem_text_out(buffer &o, ElementType a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
void fromSmallIntegerCoefficients(ElementType &result, const std::vector< long > &poly) const
bool lift(const Ring *Rg, const elem f, ring_elem &result) const
GaloisFieldTable mGF
ARingGFM2(const PolynomialRing &R, const ring_elem a)
void mult(elem &result, elem a, elem b) const
void add(elem &result, elem a, elem b) const
void set_from_long(elem &result, long a) const
void eval(const RingMap *map, const elem f, int first_var, ring_elem &result) const
bool promote(const Ring *Rf, const ring_elem f, elem &result) const
GaloisFieldTable(const PolynomialRing &R, const ring_elem prim)
const ring_elem mPrimitiveElement
GFElement characteristic() const
GFElement * mFromIntTable
const RingElement * mGenerator
void display(std::ostream &o) const
const PolynomialRing & mOriginalRing
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
virtual ring_elem copy(const ring_elem f) const =0
virtual ring_elem power(const ring_elem f, mpz_srcptr n) const
Exponentiation. This is the default function, if a class doesn't define this.
Definition ring.cpp:109
static RingElement * make_raw(const Ring *R, ring_elem f)
Definition relem.cpp:20
bool getSmallIntegerCoefficients(std::vector< long > &result_coeffs) const
Definition relem.cpp:421
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Definition relem.hpp:67
xxx xxx xxx
Definition ring.hpp:102
const ring_elem elem(int i) const
Definition ringmap.hpp:114
const Ring * get_ring() const
Definition ringmap.hpp:111
Engine-side ring homomorphism: stores, for each source-ring variable, the target-ring element it maps...
Definition ringmap.hpp:60
bool system_interrupted()
system_interrupted() — thread-safe polling predicate for Ctrl+C handling.
VALGRIND_MAKE_MEM_DEFINED & result(result)
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
int GFElement
Definition aring-CC.cpp:3
#define VECTOR(T)
Definition newdelete.hpp:78
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
volatile int x
PolynomialRing — abstract polynomial-ring base, the engine's most-reused class.
Engine-boundary C API for the engine's PRNG and rational / real / complex random draws.
RingElement — tagged (Ring*, ring_elem) pair, the engine's universal element type.
RingMap — engine representation of a ring homomorphism.
int monom[1]
Definition ringelem.hpp:160
Singly linked-list node carrying one term of a polynomial-ring element.
Definition ringelem.hpp:156