Macaulay2 Engine
Loading...
Searching...
No Matches
aring-zzp-ffpack.cpp
Go to the documentation of this file.
1// Copyright 2011 Michael E. Stillman
2
4#include "exceptions.hpp"
5#include "ringmap.hpp"
6
7namespace M2 {
8
10 : mFfpackField(FieldType(static_cast<double>(charact))),
12 mCharac(charact),
13 mDimension(1),
15{
16 assert(FieldType::maxCardinality() >= mCharac);
17}
18
20 const ElementType elem,
21 bool print_one,
22 bool print_plus,
23 bool print_parens) const
24{
25 (void) print_parens;
26 STT a = static_cast<STT>(elem);
27 if (a == 1 and not print_one) return;
28 if (a > 0 and print_plus) o << "+";
29 o << a;
30}
31
35
37{
38 for (UTT currIntElem = 2; currIntElem < mCharac; currIntElem++)
39 {
40 ElementType currElem;
41 set_from_long(currElem, currIntElem);
42 bool found = true;
43 ElementType tmpElem = currElem;
44 for (UTT count = 0; count < mCharac - 2; count++)
45 {
46 mult(tmpElem, tmpElem, currElem);
47 if (is_equal(currElem, tmpElem)) found = false;
48 }
49 if (found)
50 {
51 std::cerr << "generator = " << currElem << std::endl;
52 return currElem;
53 }
54 }
55 throw exc::internal_error("program logic in ffpack code is wrong if we get to this error");
56}
57
59{
60 return not mFfpackField.isZero(f);
61}
62
64{
65 return mFfpackField.isZero(f);
66}
67
69{
70 return mFfpackField.areEqual(f, g);
71}
72
76 const ElementType g) const
77{
78 if (f < g) return -1;
79 if (f > g) return 1;
80
81 return 0;
82}
83
84// 'init', 'init_set' functions
85
87{
88 // assert(0 == mFfpackField.zero);
89 result = 0;
90}
91
93{
94 // assert(0 == mFfpackField.zero);
95 result = 0;
96}
97
99{
100 result = a;
101}
102
105{
106 mFfpackField.init(result, a);
107}
108
110{
111 unsigned long b = static_cast<UTT>(mpz_fdiv_ui(a, mCharac));
112 mFfpackField.init(result, b);
113}
114
116{
117 ElementType n, d;
118 set_from_mpz(n, mpq_numref(a));
119 set_from_mpz(d, mpq_denref(a));
120 if (is_zero(d)) return false;
121 divide(result, n, d);
122 return true;
123}
124
125// arithmetic
127{
128 mFfpackField.neg(result, a);
129}
130
134{
135 if (mFfpackField.isZero(a)) throw exc::division_by_zero_error();
136 mFfpackField.inv(result, a);
137}
138
140 const ElementType a) const
141{
142 assert(not is_zero(a));
143 mFfpackField.inv(result, a);
144}
145
147 const ElementType a,
148 const ElementType b) const
149{
150 mFfpackField.add(result, a, b);
151}
152
154 const ElementType a,
155 const ElementType b) const
156{
157 mFfpackField.sub(result, a, b);
158}
159
162 const ElementType a,
163 const ElementType b) const
164{
165 ElementType nega = a;
166 mFfpackField.negin(nega);
167 mFfpackField.axpyin(c, nega, b);
168}
169
171 const ElementType a,
172 const ElementType b) const
173{
174 mFfpackField.mul(result, a, b);
175}
176
178 const ElementType a,
179 const ElementType b) const
180{
181 if (mFfpackField.isZero(b))
183 mFfpackField.div(result, a, b);
184}
185
187 const ElementType a,
188 STT n) const
189{
190 if (is_zero(a))
191 {
192 if (n < 0)
194 else if (n == 0)
196 else
198 return;
199 }
201 set(base, a);
202 if (n < 0)
203 {
204 invert(base, base);
205 n = -n;
206 }
207 n = n % (mCharac - 1);
209 if (n == 0) return;
210
211 // Now use doubling algorithm
212 for (;;)
213 {
214 if ((n % 2) != 0) mFfpackField.mulin(result, base); // result *= base
215 n >>= 1;
216 if (n == 0)
217 return;
218 else
219 mFfpackField.mulin(base, base); // base = base^2
220 }
221}
222
226 const ElementType a,
227 mpz_srcptr n) const
228{
229 if (is_zero(a))
230 {
231 if (mpz_sgn(n) < 0)
233 else if (mpz_sgn(n) == 0)
235 else
237 }
238 else
239 {
240 // a != 0
241 STT n1 = static_cast<STT>(mpz_fdiv_ui(n, mFfpackField.cardinality() - 1));
242 power(result, a, n1);
243 }
244}
245
248{
249 ElementType tmp = a;
250 a = b;
251 b = tmp;
252}
253
258
260 const ElementType b,
261 ElementType &x,
262 ElementType &y) const
263{
264 // x = mFfpackField.one;
265 x = 1.;
266 divide(y, a, b);
267 negate(y, y);
268}
269
275
277 const ElementType f,
278 int first_var, // not used here. See ringmap.cpp
279 ring_elem &result) const
280{
281 (void) first_var;
282 // translate f to map->target()
283 long a = static_cast<long>(f);
284 result = map->get_ring()->from_long(a);
285}
286};
287
288// Local Variables:
289// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
290// indent-tabs-mode: nil
291// End:
M2::ARingZZpFFPACK — Z/p via FFLAS-FFPACK's Givaro::Modular<double> field.
bool set_from_mpq(ElementType &result, mpq_srcptr a) const
void divide(ElementType &result, const ElementType a, const ElementType b) const
test doc
void subtract_multiple(ElementType &result, const ElementType a, const ElementType b) const
void add(ElementType &result, const ElementType a, const ElementType b) const
void invert(ElementType &result, const ElementType a) const
void set_from_mpz(ElementType &result, mpz_srcptr a) const
void power(ElementType &result, const ElementType a, const STT n) const
void set_from_long(ElementType &result, long a) const
ElementType computeGenerator() const
void elem_text_out(buffer &o, const ElementType a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
FieldType::RandIter mFfpackRandomIterator
void subtract(ElementType &result, const ElementType a, const ElementType b) const
const FieldType mFfpackField
std::make_signed< UTT >::type STT
int compare_elems(const ElementType f, const ElementType g) const
bool is_equal(const ElementType f, const ElementType g) const
void eval(const RingMap *map, const ElementType f, int first_var, ring_elem &result) const
void power_mpz(ElementType &result, const ElementType a, mpz_srcptr n) const
void random(ElementType &result) const
void init(ElementType &result) const
Givaro::Modular< double > FieldType
void set_zero(ElementType &result) const
bool is_unit(const ElementType f) const
void swap(ElementType &a, ElementType &b) const
void negate(ElementType &result, const ElementType a) const
UTT mDimension
same as extensionDegree
void syzygy(const ElementType a, const ElementType b, ElementType &x, ElementType &y) const
returns x,y s.y. x*a + y*b == 0. if possible, x is set to 1. no need to consider the case a==0 or b==...
void mult(ElementType &result, const ElementType a, const ElementType b) const
void copy(ElementType &result, const ElementType a) const
void unsafeInvert(ElementType &result, const ElementType a) const
FieldType::Element ElementType
void set(ElementType &result, ElementType a) const
bool is_zero(const ElementType f) const
virtual ring_elem from_long(long n) const =0
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
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
static CanonicalForm base
Definition factory.cpp:289
VALGRIND_MAKE_MEM_DEFINED & result(result)
Definition aring-CC.cpp:3
volatile int x
RingMap — engine representation of a ring homomorphism.