Macaulay2 Engine
Loading...
Searching...
No Matches
RingCCCTest.cpp
Go to the documentation of this file.
1// Copyright 2013 Michael E. Stillman
2
31
32#include "RingTest.hpp"
33
34#include "ZZp.hpp"
35#include "aring-glue.hpp"
36
38
39bool almostEqual(const RingCCC *R, int nbits, ring_elem a, ring_elem b)
40{
41 mpfr_t epsilon;
42 mpfr_init2(epsilon, 100);
43 mpfr_set_ui_2exp(epsilon, 1, -nbits, MPFR_RNDN);
44
45 ring_elem f = R->subtract(a, b);
46 auto f1 = BIGCC_RE(f);
47 bool re_is_zero = (mpfr_cmpabs(f1, epsilon) < 0);
48 auto f2 = BIGCC_IM(f);
49 bool im_is_zero = (mpfr_cmpabs(f2, epsilon) < 0);
50
51 bool ret = re_is_zero && im_is_zero;
52 mpfr_clear(epsilon);
53 return ret;
54}
55
56template <>
58{
59 if (index < 50) return R.from_long(index - 25);
60 return R.random();
61}
62
64TEST(RingCCC, create)
65{
66 RingCCC *R = RingCCC::create(100);
67 EXPECT_TRUE(R != nullptr);
68
69 EXPECT_TRUE(dynamic_cast<const Z_mod *>(R) == nullptr);
70 EXPECT_TRUE(dynamic_cast<const RingCCC *>(R) != nullptr);
71 EXPECT_FALSE(R->is_ZZ());
72 // FIXME: not implemented: EXPECT_TRUE(R->is_CCC());
73 // FIXME: string vs char*: EXPECT_EQ(ringName(*R), "CCC_100");
74}
76{
77 RingCCC *R = RingCCC::create(100);
78 EXPECT_TRUE(R->is_equal(R->one(), R->from_long(1)));
79 EXPECT_TRUE(R->is_equal(R->minus_one(), R->from_long(-1)));
80 EXPECT_TRUE(R->is_equal(R->zero(), R->from_long(0)));
81 EXPECT_TRUE(R->is_zero(R->from_long(0)));
82}
83TEST(RingCCC, negate)
84{
85 RingCCC *R = RingCCC::create(100);
87}
89{
90 RingCCC *R = RingCCC::create(100);
92
93 for (int i = 0; i < ntrials; i++)
94 {
95 // test: (a+b) + (-b) == a
96 ring_elem a = gen.nextElement();
97 ring_elem b = gen.nextElement();
98 ring_elem c = R->add(a, b);
99 ring_elem d = R->negate(b);
100 ring_elem e = R->add(c, d); // should be a
101 EXPECT_TRUE(almostEqual(R, 98, a, e));
102 }
103}
109TEST(RingCCC, multDivide)
110{
111 RingCCC *R = RingCCC::create(100);
113 for (int i = 0; i < ntrials; i++)
114 {
115 // test: (a*b) // b == a
116 ring_elem a = gen.nextElement();
117 ring_elem b = gen.nextElement();
118 ring_elem c = R->mult(a, b);
119 if (R->is_zero(b))
120 EXPECT_TRUE(R->is_zero(c));
121 else
122 {
123 ring_elem d = R->divide(c, b);
124 EXPECT_TRUE(almostEqual(R, 94, d, a));
125 }
126 }
127}
128TEST(RingCCC, axioms)
129{
130 RingCCC *R = RingCCC::create(100);
132 for (int i = 0; i < ntrials; i++)
133 {
134 ring_elem a = gen.nextElement();
135 ring_elem b = gen.nextElement();
136 ring_elem c = gen.nextElement();
137
138 // Test commutativity
139 // test: a*b = b*a
140 // test: a+b == b+a
141 ring_elem d = R->add(a, b);
142 ring_elem e = R->add(b, a);
143 EXPECT_TRUE(R->is_equal(d, e));
144 d = R->mult(a, b);
145 e = R->mult(b, a);
146 EXPECT_TRUE(almostEqual(R, 98, d, e));
147
148 // Test associativity
149 // test: a+(b+c) == (a+b)+c
150 // test: a*(b*c) == (a*b)*c
151 d = R->add(a, R->add(b, c));
152 e = R->add(R->add(a, b), c);
153 EXPECT_TRUE(almostEqual(R, 94, d, e));
154 d = R->mult(a, R->mult(b, c));
155 e = R->mult(R->mult(a, b), c);
156 EXPECT_TRUE(almostEqual(R, 94, d, e));
157
158 // Test distributivity
159 // test: a*(b+c) == a*b + a*c
160 d = R->mult(a, R->add(b, c));
161 e = R->add(R->mult(a, b), R->mult(a, c));
162#if 0
163 mpfr_printf("a=(%.20Rf,%.20Rf)\n",BIGCC_RE(a), BIGCC_IM(a));
164 mpfr_printf("b=(%.20Rf,%.20Rf)\n",BIGCC_RE(b), BIGCC_IM(b));
165 mpfr_printf("a*(b+c)=(%.20Rf,%.20Rf)\n",BIGCC_RE(d), BIGCC_IM(d));
166 mpfr_printf("a*b+a*c=(%.20Rf,%.20Rf)\n",BIGCC_RE(e), BIGCC_IM(e));
167#endif
168 EXPECT_TRUE(almostEqual(R, 92, d, e));
169 }
170}
172{
173 RingCCC *R = RingCCC::create(100);
174
175 mpz_t gmp1;
176 mpz_init(gmp1);
178 for (int i = 0; i < ntrials; i++)
179 {
180 ring_elem a = gen.nextElement();
181 // TODO: what should the answer here be?
182 // EXPECT_TRUE(R->is_equal(R->power(a, 0), R->one())); // 0^0 == 1 too?
183 EXPECT_TRUE(R->is_equal(R->power(a, 1), a));
184
185 int e1 = rawRandomInt(10) + 1;
186 int e2 = rawRandomInt(10) + 1;
187 // std::cout << "(" << e1 << "," << e2 << ")" << std::endl;
188 ring_elem b = R->power(a, e1);
189 ring_elem c = R->power(a, e2);
190 ring_elem d = R->power(a, e1 + e2);
191#if 0
192 ring_elem e = R->mult(b,c);
193 mpfr_printf("b=(%.30Rf,%.30Rf)\n",BIGCC_RE(b), BIGCC_IM(b));
194 mpfr_printf("c=(%.30Rf,%.30Rf)\n",BIGCC_RE(c), BIGCC_IM(c));
195 mpfr_printf("d=(%.30Rf,%.30Rf)\n",BIGCC_RE(d), BIGCC_IM(d));
196 mpfr_printf("e=(%.30Rf,%.30Rf)\n",BIGCC_RE(e), BIGCC_IM(e));
197#endif
198 EXPECT_TRUE(almostEqual(R, 80, R->mult(b, c), d));
199
200 // Make sure that powers via mpz work (at least for small exponents)
201 mpz_set_si(gmp1, e1);
202 ring_elem b1 = R->power(a, gmp1);
203 EXPECT_TRUE(R->is_equal(b1, b));
204 }
205 mpz_clear(gmp1);
206}
207TEST(RingCCC, syzygy)
208{
209 // NOTE: RingCCC::syzygy, RingCCC::syzygy are not useful functions.
210 // Should we remove these tests, and the corresponding functions?
211 RingCCC *R = RingCCC::create(100);
212
214 for (int i = 0; i < ntrials; i++)
215 {
216 ring_elem u, v;
217 ring_elem a = gen.nextElement();
218 ring_elem b = gen.nextElement();
219 if (R->is_zero(b)) continue;
220
221 // special cases (note: b != 0 for rest of routine)
222 // syzygy(0,b) returns (1,0)
223 R->syzygy(R->zero(), b, u, v);
224 EXPECT_TRUE(R->is_equal(u, R->one()));
225 EXPECT_TRUE(R->is_equal(v, R->zero()));
226 // syzygy(a,1) returns (1,-a)
227 R->syzygy(a, R->one(), u, v);
228 EXPECT_TRUE(R->is_equal(u, R->one()));
229 EXPECT_TRUE(almostEqual(R, 98, v, R->negate(a)));
230 // syzygy(a,-1) returns (1,a)
231 R->syzygy(a, R->minus_one(), u, v);
232 EXPECT_TRUE(R->is_equal(u, R->one()));
233 EXPECT_TRUE(almostEqual(R, 98, v, a));
234 R->syzygy(a, b, u, v);
235 ring_elem result = R->add(R->mult(a, u), R->mult(b, v));
236 EXPECT_TRUE(almostEqual(R, 94, result, R->zero()));
237 }
238}
239
240// Local Variables:
241// compile-command: "make -C $M2BUILDDIR/Macaulay2/e/unit-tests check "
242// indent-tabs-mode: nil
243// End:
const int ntrials
Definition ARingTest.hpp:42
ring_elem getElement< RingCCC >(const RingCCC &R, int index)
TEST(RingCCC, create)
M2::ConcreteRing< M2::ARingCCC > RingCCC
bool almostEqual(const RingCCC *R, int nbits, ring_elem a, ring_elem b)
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.
Legacy Z_mod — a Ring-derived Z/p with log / exp tables.
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::ARingCCC > * create(std::unique_ptr< M2::ARingCCC > 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
#define BIGCC_RE(f)
Definition ringelem.hpp:210
#define BIGCC_IM(f)
Definition ringelem.hpp:209