Macaulay2 Engine
Loading...
Searching...
No Matches
RingRRRTest.cpp
Go to the documentation of this file.
1// Copyright 2013 Michael E. Stillman
2
31
32#include "RingTest.hpp"
33#include "aring-glue.hpp"
34#include "aring-RRR.hpp"
35
37
38bool almostEqual(const RingRRR *R, int nbits, ring_elem a, ring_elem b)
39{
40 mpfr_t epsilon;
41 mpfr_init2(epsilon, 100);
42 mpfr_set_ui_2exp(epsilon, 1, -nbits, MPFR_RNDN);
43
44 ring_elem c = R->subtract(a, b);
45 bool ret = mpfr_cmpabs(c.get_mpfr(), epsilon) < 0;
46
47 mpfr_clear(epsilon);
48 return ret;
49}
50
51template <>
53{
54 if (index < 50) return R.from_long(index - 25);
55 return R.random();
56}
57
58TEST(RingRRR, create)
59{
60 RingRRR *R = RingRRR::create(std::make_unique<M2::ARingRRR>(100));
61 EXPECT_TRUE(R != nullptr);
62
63 EXPECT_TRUE(dynamic_cast<const Z_mod *>(R) == nullptr);
64 EXPECT_TRUE(dynamic_cast<const RingRRR *>(R) != nullptr);
65 EXPECT_FALSE(R->is_ZZ());
66 // FIXME: not implemented: EXPECT_TRUE(R->is_RRR());
67 // FIXME: string vs char*: EXPECT_EQ(ringName(*R), "RRR_100");
68}
70{
71 RingRRR *R = RingRRR::create(std::make_unique<M2::ARingRRR>(100));
72 EXPECT_TRUE(R->is_equal(R->one(), R->from_long(1)));
73 EXPECT_TRUE(R->is_equal(R->minus_one(), R->from_long(-1)));
74 EXPECT_TRUE(R->is_equal(R->zero(), R->from_long(0)));
75 EXPECT_TRUE(R->is_zero(R->from_long(0)));
76}
77TEST(RingRRR, negate)
78{
79 RingRRR *R = RingRRR::create(std::make_unique<M2::ARingRRR>(100));
81}
83{
84 RingRRR *R = RingRRR::create(std::make_unique<M2::ARingRRR>(100));
86
87 for (int i = 0; i < ntrials; i++)
88 {
89 // test: (a+b) + (-b) == a
90 ring_elem a = gen.nextElement();
91 ring_elem b = gen.nextElement();
92 ring_elem c = R->add(a, b);
93 ring_elem d = R->negate(b);
94 ring_elem e = R->add(c, d); // should be a
95 EXPECT_TRUE(almostEqual(R, 98, a, e));
96 }
97}
99{
100 RingRRR *R = RingRRR::create(std::make_unique<M2::ARingRRR>(100));
102}
103TEST(RingRRR, multDivide)
104{
105 RingRRR *R = RingRRR::create(std::make_unique<M2::ARingRRR>(100));
107 for (int i = 0; i < ntrials; i++)
108 {
109 // test: (a*b) // b == a
110 ring_elem a = gen.nextElement();
111 ring_elem b = gen.nextElement();
112 ring_elem c = R->mult(a, b);
113 if (R->is_zero(b))
114 EXPECT_TRUE(R->is_zero(c));
115 else
116 {
117 ring_elem d = R->divide(c, b);
118 EXPECT_TRUE(almostEqual(R, 94, d, a));
119 }
120 }
121}
122TEST(RingRRR, axioms)
123{
124 RingRRR *R = RingRRR::create(std::make_unique<M2::ARingRRR>(100));
126 for (int i = 0; i < ntrials; i++)
127 {
128 ring_elem a = gen.nextElement();
129 ring_elem b = gen.nextElement();
130 ring_elem c = gen.nextElement();
131
132 // Test commutativity
133 // test: a*b = b*a
134 // test: a+b == b+a
135 ring_elem d = R->add(a, b);
136 ring_elem e = R->add(b, a);
137 EXPECT_TRUE(R->is_equal(d, e));
138 d = R->mult(a, b);
139 e = R->mult(b, a);
140 EXPECT_TRUE(almostEqual(R, 98, d, e));
141
142 // Test associativity
143 // test: a+(b+c) == (a+b)+c
144 // test: a*(b*c) == (a*b)*c
145 d = R->add(a, R->add(b, c));
146 e = R->add(R->add(a, b), c);
147 EXPECT_TRUE(almostEqual(R, 94, d, e));
148 d = R->mult(a, R->mult(b, c));
149 e = R->mult(R->mult(a, b), c);
150 EXPECT_TRUE(almostEqual(R, 94, d, e));
151
152 // Test distributivity
153 // test: a*(b+c) == a*b + a*c
154 d = R->mult(a, R->add(b, c));
155 e = R->add(R->mult(a, b), R->mult(a, c));
156 EXPECT_TRUE(almostEqual(R, 92, d, e));
157 }
158}
160{
161 RingRRR *R = RingRRR::create(std::make_unique<M2::ARingRRR>(100));
162
163 mpz_t gmp1;
164 mpz_init(gmp1);
166 for (int i = 0; i < ntrials; i++)
167 {
168 ring_elem a = gen.nextElement();
169 // TODO: what should the answer here be?
170 // EXPECT_TRUE(R->is_equal(R->power(a, 0), R->one())); // 0^0 == 1 too?
171 EXPECT_TRUE(R->is_equal(R->power(a, 1), a));
172
173 int e1 = rawRandomInt(10) + 1;
174 int e2 = rawRandomInt(10) + 1;
175 // std::cout << "(" << e1 << "," << e2 << ")" << std::endl;
176 ring_elem b = R->power(a, e1);
177 ring_elem c = R->power(a, e2);
178 ring_elem d = R->power(a, e1 + e2);
179 EXPECT_TRUE(almostEqual(R, 96, R->mult(b, c), d));
180
181 // Make sure that powers via mpz work (at least for small exponents)
182 mpz_set_si(gmp1, e1);
183 ring_elem b1 = R->power(a, gmp1);
184 EXPECT_TRUE(R->is_equal(b1, b));
185 }
186 mpz_clear(gmp1);
187}
188TEST(RingRRR, syzygy)
189{
190 // NOTE: RingRRR::syzygy, CCC::syzygy are not useful functions.
191 // Should we remove these tests, and the corresponding functions?
192 RingRRR *R = RingRRR::create(std::make_unique<M2::ARingRRR>(100));
193
195 for (int i = 0; i < ntrials; i++)
196 {
197 ring_elem u, v;
198 ring_elem a = gen.nextElement();
199 ring_elem b = gen.nextElement();
200 if (R->is_zero(b)) continue;
201
202 // special cases (note: b != 0 for rest of routine)
203 // syzygy(0,b) returns (1,0)
204 R->syzygy(R->zero(), b, u, v);
205 EXPECT_TRUE(R->is_equal(u, R->one()));
206 EXPECT_TRUE(R->is_equal(v, R->zero()));
207 // syzygy(a,1) returns (1,-a)
208 R->syzygy(a, R->one(), u, v);
209 EXPECT_TRUE(R->is_equal(u, R->one()));
210 EXPECT_TRUE(almostEqual(R, 98, v, R->negate(a)));
211 // syzygy(a,-1) returns (1,a)
212 R->syzygy(a, R->minus_one(), u, v);
213 EXPECT_TRUE(R->is_equal(u, R->one()));
214 EXPECT_TRUE(almostEqual(R, 98, v, a));
215 R->syzygy(a, b, u, v);
216 ring_elem result = R->add(R->mult(a, u), R->mult(b, v));
217 EXPECT_TRUE(almostEqual(R, 94, result, R->zero()));
218 }
219}
220
221// Local Variables:
222// compile-command: "make -C $M2BUILDDIR/Macaulay2/e/unit-tests check "
223// indent-tabs-mode: nil
224// End:
const int ntrials
Definition ARingTest.hpp:42
M2::ConcreteRing< M2::ARingRRR > RingRRR
ring_elem getElement< RingRRR >(const RingRRR &R, int index)
bool almostEqual(const RingRRR *R, int nbits, ring_elem a, ring_elem b)
TEST(RingRRR, create)
void testRingSubtract(const T *R, int ntrials)
Definition RingTest.hpp:126
void testRingNegate(const T *R, int ntrials)
Definition RingTest.hpp:98
Shared gtest fixture for the legacy Ring-based Ring*Test.cpp suite.
M2::ARingRRR — arbitrary-precision real numbers backed by MPFR.
ConcreteRing<RingType> — the templated bridge between aring and the legacy Ring API.
virtual ring_elem mult(const ring_elem f, const ring_elem g) const
virtual bool is_zero(const ring_elem f) const
virtual ring_elem from_long(long n) const
virtual ring_elem negate(const ring_elem f) const
virtual ring_elem divide(const ring_elem f, const ring_elem g) const
virtual ring_elem subtract(const ring_elem f, const ring_elem g) const
virtual void syzygy(const ring_elem f, const ring_elem g, ring_elem &x, ring_elem &y) const
static ConcreteRing< M2::ARingRRR > * create(std::unique_ptr< M2::ARingRRR > R)
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.
virtual ring_elem random() const
virtual bool is_equal(const ring_elem f, const ring_elem g) const
virtual ring_elem add(const ring_elem f, const ring_elem g) const
virtual bool is_ZZ() const
Definition ring.hpp:171
ring_elem one() const
Definition ring.hpp:357
ring_elem zero() const
Definition ring.hpp:359
ring_elem minus_one() const
Definition ring.hpp:358
ring_elem nextElement()
Definition RingTest.hpp:83
Engine-side Z/p ring for small primes (p < 32767), using a discrete-log (Zech) representation.
Definition ZZp.hpp:63
void subtract(int &result, int a, int b)
VALGRIND_MAKE_MEM_DEFINED & result(result)
std::ostringstream & ones(std::ostringstream &o, int len)
int32_t rawRandomInt(int32_t max)
Definition random.cpp:44
mpfr_srcptr get_mpfr() const
Definition ringelem.hpp:130