]> www.ginac.de Git - cln.git/blob - src/modinteger/cl_MI_int.h
Replace CL_REQUIRE/CL_PROVIDE(cl_C_ring) with portable code.
[cln.git] / src / modinteger / cl_MI_int.h
1 // m = 0 : Z/mZ \isomorph Z
2
3 namespace cln {
4
5 static void int_fprint (cl_heap_modint_ring* R, std::ostream& stream, const _cl_MI &x)
6 {
7         fprint(stream,R->_retract(x));
8 }
9
10 static const cl_I int_reduce_modulo (cl_heap_modint_ring* R, const cl_I& x)
11 {
12         unused R;
13         return x; // reducing modulo 0 does nothing
14 }
15
16 // This is the only case where canonhom is injective.
17 static const _cl_MI int_canonhom (cl_heap_modint_ring* R, const cl_I& x)
18 {
19         return _cl_MI(R, x);
20 }
21
22 // This is the only case where retract is surjective.
23 static const cl_I int_retract (cl_heap_modint_ring* R, const _cl_MI& x)
24 {
25         unused R;
26         return x.rep;
27 }
28
29 // This is the only case where random yields an error.
30 static const _cl_MI int_random (cl_heap_modint_ring* R, random_state& randomstate)
31 {
32         unused R;
33         unused randomstate;
34         throw runtime_exception("Z / 0 Z not a finite set - no equidistributed random function.");
35 #if ((defined(__sparc__) || defined(__sparc64__)) && !defined(__GNUC__)) // Sun CC wants a return value
36         return _cl_MI(R, 0);
37 #endif
38 }
39
40 static const _cl_MI int_zero (cl_heap_modint_ring* R)
41 {
42         return _cl_MI(R, 0);
43 }
44
45 static bool int_zerop (cl_heap_modint_ring* R, const _cl_MI& x)
46 {
47         unused R;
48         return zerop(x.rep);
49 }
50
51 static const _cl_MI int_plus (cl_heap_modint_ring* R, const _cl_MI& x, const _cl_MI& y)
52 {
53         return _cl_MI(R, x.rep + y.rep);
54 }
55
56 static const _cl_MI int_minus (cl_heap_modint_ring* R, const _cl_MI& x, const _cl_MI& y)
57 {
58         return _cl_MI(R, x.rep - y.rep);
59 }
60
61 static const _cl_MI int_uminus (cl_heap_modint_ring* R, const _cl_MI& x)
62 {
63         return _cl_MI(R, - x.rep);
64 }
65
66 static const _cl_MI int_one (cl_heap_modint_ring* R)
67 {
68         return _cl_MI(R, 1);
69 }
70
71 static const _cl_MI int_mul (cl_heap_modint_ring* R, const _cl_MI& x, const _cl_MI& y)
72 {
73         return _cl_MI(R, x.rep * y.rep);
74 }
75
76 static const _cl_MI int_square (cl_heap_modint_ring* R, const _cl_MI& x)
77 {
78         return _cl_MI(R, square(x.rep));
79 }
80
81 static const cl_MI_x int_recip (cl_heap_modint_ring* R, const _cl_MI& x)
82 {
83         var const cl_I& xr = x.rep;
84         if (eq(xr,1) || eq(xr,-1)) { return cl_MI(R,x); }
85         if (zerop(xr)) { throw division_by_0_exception(); }
86         return cl_notify_composite(R,xr);
87 }
88
89 static const cl_MI_x int_div (cl_heap_modint_ring* R, const _cl_MI& x, const _cl_MI& y)
90 {
91         var const cl_I& yr = y.rep;
92         if (eq(yr,1)) { return cl_MI(R,x.rep); }
93         if (eq(yr,-1)) { return cl_MI(R,-x.rep); }
94         if (zerop(yr)) { throw division_by_0_exception(); }
95         return cl_notify_composite(R,yr);
96 }
97
98 static const _cl_MI int_expt_pos (cl_heap_modint_ring* R, const _cl_MI& x, const cl_I& y)
99 {
100         return _cl_MI(R, expt_pos(x.rep,y));
101 }
102
103 static const cl_MI_x int_expt (cl_heap_modint_ring* R, const _cl_MI& x, const cl_I& y)
104 {
105         if (eq(x.rep,1)) { return cl_MI(R,1); }
106         if (eq(x.rep,-1)) { return cl_MI(R,evenp(y)?1:-1); }
107         if (!minusp(y)) {
108                 if (zerop(y))
109                         return cl_MI(R,1);
110                 else
111                         return cl_MI(R,expt_pos(x.rep,y));
112         }
113         // y < 0, x nonunit.
114         if (zerop(x.rep)) { throw division_by_0_exception(); }
115         return cl_notify_composite(R,x.rep);
116 }
117
118 static cl_modint_setops int_setops = {
119         int_fprint,
120         modint_equal,
121         int_random
122 };
123 static cl_modint_addops int_addops = {
124         int_zero,
125         int_zerop,
126         int_plus,
127         int_minus,
128         int_uminus
129 };
130 static cl_modint_mulops int_mulops = {
131         int_one,
132         int_canonhom,
133         int_mul,
134         int_square,
135         int_expt_pos,
136         int_recip,
137         int_div,
138         int_expt,
139         int_reduce_modulo,
140         int_retract
141 };
142
143 class cl_heap_modint_ring_int : public cl_heap_modint_ring {
144         SUBCLASS_cl_heap_modint_ring()
145 public:
146         // Constructor.
147         cl_heap_modint_ring_int () : cl_heap_modint_ring (0, &int_setops, &int_addops, &int_mulops) {}
148         // Virtual destructor.
149         ~cl_heap_modint_ring_int () {}
150 };
151
152 }  // namespace cln