Macaulay2 Engine
Loading...
Searching...
No Matches
ARingZZpTest.cpp
Go to the documentation of this file.
1// Copyright 2012-2013 Michael E. Stillman
2
30
31#include <cstdio>
32#include <string>
33#include <iostream>
34#include <sstream>
35#include <memory>
36#include <gtest/gtest.h>
37#include <mpfr.h>
38
39#include "reader.hpp"
40#include "ZZp.hpp"
41#include "aring-zzp-ffpack.hpp"
42#include "aring-zzp.hpp"
43#include "ARingTest.hpp"
44
45static bool maxH_initialized = false;
46static mpz_t maxH;
47
49{
51 {
52 maxH_initialized = true;
53 mpz_init(maxH);
54 mpz_set_str(maxH, "100000000000", 10);
55 }
56 return rawRandomInteger(maxH);
57}
58
59template <>
61 int index,
63{
64 if (index < 50)
65 R.set_from_long(result, index - 25);
66 else
67 {
69 R.set_from_mpz(result, a);
70 }
71}
72
73template <typename RT>
74void testCoerceToLongInteger(const RT& R)
75{
76 long top1 = (R.characteristic() > 10000 ? 10000 : R.characteristic());
77 long bottom2 = (R.characteristic() > 10000 ? R.characteristic() - 10000 : 0);
78 for (long i = 0; i < top1; i++)
79 {
80 typename RT::ElementType a;
81 R.init(a);
82 R.set_from_long(a, i);
83 long b = R.coerceToLongInteger(a);
84 if (b < 0) b += R.characteristic();
85 EXPECT_EQ(b, i);
86 }
87 for (long i = bottom2; i < R.characteristic(); i++)
88 {
89 typename RT::ElementType a;
90 R.init(a);
91 R.set_from_long(a, i);
92 long b = R.coerceToLongInteger(a);
93 if (b < 0) b += R.characteristic();
94 EXPECT_EQ(b, i);
95 }
96}
97TEST(RingZZp, create)
98{
99 const Z_mod* R = Z_mod::create(101);
100 EXPECT_FALSE(R == nullptr);
101 buffer o;
102 o << "Ring being tested: ";
103 R->text_out(o);
104 fprintf(stdout, "%s\n", o.str());
105}
106
107TEST(ARingZZp, create)
108{
109 M2::ARingZZp R(101);
110
112 buffer o;
113
115 R.init(a);
116 gen.nextElement(a);
117
118 EXPECT_EQ(ringName(R), "AZZ/101");
119 EXPECT_EQ(R.cardinality(), 101);
120 EXPECT_EQ(R.characteristic(), 101);
121 // Now check what the generator is, as an integer
122 R.init(a);
123 R.set_var(a, 0);
124 R.elem_text_out(o, a, true, true, false);
125 std::cout << "generator is " << o.str() << std::endl;
126 R.clear(a);
127}
128
129TEST(ARingZZp, arithmetic101)
130{
131 M2::ARingZZp R(101);
134}
135
136TEST(ARingZZp, arithmetic32749)
137{
138 M2::ARingZZp R(32749);
141}
142
143TEST(ARingZZp, arithmetic2)
144{
145 M2::ARingZZp R(2);
148}
149
150TEST(ARingZZp, arithmetic3)
151{
152 M2::ARingZZp R(3);
155}
156
157TEST(ARingZZp, fromStream)
158{
159 std::istringstream i("+1234 +345 -235*a");
160 M2::ARingZZp R(32003);
162 R.init(a);
163 while (true)
164 {
165 while (isspace(i.peek())) i.get();
166
167 if (!isdigit(i.peek()) && i.peek() != '+' && i.peek() != '-') break;
168
169 fromStream(i, R, a);
170
171 buffer o;
172 R.elem_text_out(o, a);
173 std::cout << o.str() << " peek: " << i.peek() << std::endl;
174 }
175 R.clear(a);
176}
177
178template <>
180 int index,
182{
183 if (index < 50)
184 R.set_from_long(result, index - 25);
185 else
186 {
188 R.set_from_mpz(result, a);
189 }
190}
191
192TEST(ARingZZpFFPACK, create)
193{
194 M2::ARingZZpFFPACK R(101);
195
196 EXPECT_EQ(ringName(R), "ZZpFPACK(101,1)");
197 testSomeMore(R);
198
199 std::cout << "max modulus for ffpack zzp: "
200 << M2::ARingZZpFFPACK::getMaxModulus() << std::endl;
201
203 R.init(a);
204 R.set_from_long(a, 99);
205 R.set_from_long(a, 101);
206 R.set_from_long(a, 103);
207 R.clear(a);
208}
209
210TEST(ARingZZpFFPACK, arithmetic101)
211{
212 M2::ARingZZpFFPACK R(101);
214}
215
216// TODO: commented out because it appears wrong. Perhaps p=2 isn't allowed
217// here?
218// strange: does not fail on my thinkpad...
219TEST(ARingZZpFFPACK, arithmetic2)
220{
223
225}
226
227TEST(ARingZZpFFPACK, arithmetic3)
228{
231
233}
234
235TEST(ARingZZpFFPACK, arithmetic66000007)
236{
237 M2::ARingZZpFFPACK R(66000007);
238
240
241 testCoercions(R);
243 testAdd(R, ntrials);
248 testPower(R, ntrials);
250}
251
252// TODO: commented out because it takes too long:
253// Actually: now this characteristic seems too big?!
254TEST(ARingZZpFFPACK, arithmetic67108859)
255{
256 M2::ARingZZpFFPACK R(67108859);
257
259
260 testCoercions(R);
262 testAdd(R, ntrials);
267 testPower(R, ntrials);
269}
270
271TEST(ARingZZpFFPACK, arithmetic33500479)
272{
273 M2::ARingZZpFFPACK R(33500479);
274
276
277 testCoercions(R);
279 testAdd(R, ntrials);
284 testPower(R, ntrials);
286}
287
288TEST(ARingZZp, read)
289{
290 std::string a = "-42378489327498312749c3";
291 std::istringstream i(a);
292
293 M2::ARingZZp R(101);
294 M2::Reader<M2::ARingZZp> reader(R);
296 R.init(b);
297 R.init(c);
298 reader.read(i, b);
299 R.set_from_long(c, 3);
300
301 EXPECT_TRUE(R.is_equal(b, c));
302}
303
305// Flint ZZ/p arithmetic ///
307#include "../aring-zzp-flint.hpp"
308template <>
310 int index,
312{
313 if (index < 50)
314 R.set_from_long(result, index - 25);
315 else
316 {
318 R.set_from_mpz(result, a);
319 }
320}
321
322TEST(ARingZZpFlint, create)
323{
324 M2::ARingZZpFlint R(101);
325
326 EXPECT_EQ(ringName(R), "AZZFlint/101");
327 testSomeMore(R);
328
330 R.init(a);
331 R.set_from_long(a, 99);
332 R.set_from_long(a, 101);
333 R.set_from_long(a, 103);
334 R.clear(a);
335}
336
337TEST(ARingZZpFlint, arithmetic101)
338{
339 M2::ARingZZpFlint R(101);
342}
343
344TEST(ARingZZpFlint, arithmetic2)
345{
349}
350
351TEST(ARingZZpFlint, arithmetic3)
352{
356}
357
358TEST(ARingZZpFlint, arithmetic66000007)
359{
360 M2::ARingZZpFlint R(66000007);
361
363
364 testCoercions(R);
366 testAdd(R, ntrials);
371 testPower(R, ntrials);
373}
374
375TEST(ARingZZpFlint, arithmetic67108859)
376{
377 M2::ARingZZpFlint R(67108859);
378
380
381 testCoercions(R);
383 testAdd(R, ntrials);
388 testPower(R, ntrials);
390}
391
392TEST(ARingZZpFlint, arithmetic33500479)
393{
394 M2::ARingZZpFlint R(33500479);
395
397
398 testCoercions(R);
400 testAdd(R, ntrials);
405 testPower(R, ntrials);
407}
408
409TEST(ARingZZpFlint, arithmetic9223372036854775783)
410{
411 // largest prime < 2^63
412 if (sizeof(unsigned long) <= 4)
413 std::cout << "seems to be a 32bit machine: skipping the test" << std::endl;
414 else
415 {
416 M2::ARingZZpFlint R(9223372036854775783L);
417
419
420 testCoercions(R);
422 testAdd(R, ntrials);
427 // testPower(R, ntrials); // this test fails: as it expects the
428 // characteristic to fit into an int.
430 }
431}
432
433// Even though flint handles primes up to 2^64-1, M2 assumes that the
434// characteristic is < 2^63. If needed, we could change the type of
435// the characteristic to unsigned long, but that would have further
436// complications.
437TEST(ARingZZpFlint, arithmetic18446744073709551557)
438{
439 // largest prime < 2^64
440 if (sizeof(unsigned long) <= 4)
441 std::cout << "seems to be a 32bit machine: skipping the test" << std::endl;
442 else
443 {
444 M2::ARingZZpFlint R(18446744073709551557UL);
445
446 // testCoerceToLongInteger(R); // this fails for charac > 2^63
447
448 testCoercions(R);
450 testAdd(R, ntrials);
455 // testPower(R, ntrials); // this test fails: as it expects the
456 // characteristic to fit into an int.
458 }
459}
460
461// Local Variables:
462// compile-command: "make -C $M2BUILDDIR/Macaulay2/e/unit-tests check "
463// indent-tabs-mode: nil
464// End:
void testAdd(const T &R, int ntrials)
void testNegate(const T &R, int ntrials)
void testReciprocal(const T &R, int ntrials)
void testPower(const T &R, int ntrials)
void testCoercions(const T &R)
std::istream & fromStream(std::istream &i, const T &R, typename T::ElementType &result)
void testAxioms(const T &R, int ntrials)
void testFiniteField(const T &R, int ntrials)
const int ntrials
Definition ARingTest.hpp:42
void testSubtract(const T &R, int ntrials)
void testSomeMore(const T &R)
Definition ARingTest.hpp:72
void testMultiply(const T &R, int ntrials)
std::string ringName(const T &R)
Shared gtest harness for the ARing*Test.cpp suite.
void testCoerceToLongInteger(const RT &R)
void getElement< M2::ARingZZpFlint >(const M2::ARingZZpFlint &R, int index, M2::ARingZZpFlint::ElementType &result)
void getElement< M2::ARingZZp >(const M2::ARingZZp &R, int index, M2::ARingZZp::ElementType &result)
TEST(RingZZp, create)
static bool maxH_initialized
gmp_ZZ getRandomInteger()
static mpz_t maxH
void getElement< M2::ARingZZpFFPACK >(const M2::ARingZZpFFPACK &R, int index, M2::ARingZZpFFPACK::ElementType &result)
Legacy Z_mod — a Ring-derived Z/p with log / exp tables.
M2::ARingZZpFFPACK — Z/p via FFLAS-FFPACK's Givaro::Modular<double> field.
M2::ARingZZpFlint — Z/p via FLINT's nmod_t precomputed-reciprocal reduction.
M2::ARingZZp — portable Z/p for small primes via log / exp tables.
void nextElement(typename RingType::ElementType &result)
Definition ARingTest.hpp:56
void set_from_long(elem &result, long a) const
size_t characteristic() const
Definition aring-zzp.hpp:90
void init(elem &result) const
static void clear(elem &result)
void elem_text_out(buffer &o, ElementType a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
Definition aring-zzp.cpp:74
void set_from_mpz(elem &result, mpz_srcptr a) const
size_t cardinality() const
Definition aring-zzp.hpp:91
bool is_equal(ElementType f, ElementType g) const
void set_var(elem &result, int v) const
void set_from_mpz(ElementType &result, mpz_srcptr a) const
void set_from_long(ElementType &result, long a) const
static void clear(ElementType &result)
void init(ElementType &result) const
static double getMaxModulus()
FieldType::Element ElementType
wrapper for the FFPACK::ModularBalanced<double> field implementation
static void clear(ElementType &result)
void set_from_mpz(ElementType &result, mpz_srcptr a) const
void set_from_long(ElementType &result, long a) const
void init(ElementType &result) const
aring-style adapter for Z/p with p a word-size prime, backed by FLINT's nmod_* routines.
aring-style adapter for Z/p using a discrete-log (Zech) representation: every non-zero residue is its...
Definition aring-zzp.hpp:67
void read(std::istream &i, ElementType &result)
virtual void text_out(buffer &o) const
Definition ZZp.cpp:72
static Z_mod * create(int p)
Definition ZZp.cpp:64
Engine-side Z/p ring for small primes (p < 32767), using a discrete-log (Zech) representation.
Definition ZZp.hpp:63
char * str()
Definition buffer.hpp:72
void testDivide()
VALGRIND_MAKE_MEM_DEFINED & result(result)
mpz_srcptr gmp_ZZ
Definition m2-types.h:141
gmp_ZZ rawRandomInteger(gmp_ZZ maxN)
Definition random.cpp:66
M2::Reader<RingType> — parse a single ring element from a std::istream.