1 // ===============================================================
2 // Copyright(c)'1994-2009 by The Givaro group
3 // This file is part of Givaro.
4 // Givaro is governed by the CeCILL-B license under French law
5 // and abiding by the rules of distribution of free software.
6 // see the COPYRIGHT file for more details.
7 // Time-stamp: <19 Oct 10 18:35:20 Jean-Guillaume.Dumas@imag.fr>
8 // Author: J-G. Dumas
9 // Description: Quotients over a Ring domain
10 // ===============================================================
11 #ifndef __GIVARO_quotient_domain_H
12 #define __GIVARO_quotient_domain_H
13 #include <givaro/givpower.h>
14 #ifndef GIVABS
15 #define GIVABS(a) ((a)>0?(a):-(a))
16 #endif
17 
18 namespace Givaro {
19     template<class RingDom>
20     struct QuotientDom : public RingDom {
21     public :
22         // -- Self_t
23         typedef          QuotientDom<RingDom>	Self_t;
24 
25         // -- Exported types
26         typedef	     RingDom			Ring_t;
27         typedef typename RingDom::Element		Ring_E;
28         typedef Ring_E				Element;
29         typedef Ring_E				Rep;
30     protected :
31         Rep _modulo;
32 
33     public :
QuotientDomQuotientDom34         QuotientDom (const RingDom& R, const Element& Mod ) : Ring_t(R), _modulo(Mod) {}
QuotientDomQuotientDom35         QuotientDom (const Self_t& F) : Ring_t(static_cast<const Ring_t&>(F)), _modulo(F._modulo) {}
36 
initQuotientDom37         Rep& init(Rep& a) const
38         { return Ring_t::modin(Ring_t::init(a),_modulo); }
39 
40         template<class XXX>
initQuotientDom41         Rep& init(Rep& p, const XXX &cste ) const
42         {
43             return Ring_t::modin(Ring_t::init(p,cste),_modulo);
44         }
45 
assignQuotientDom46         Rep& assign(Rep& p) const
47         {
48             return Ring_t::modin(p,_modulo);
49         }
assignQuotientDom50         Rep& assign(Rep& p, const Rep& Q) const
51         {
52             return Ring_t::modin(Ring_t::assign(p,Q),_modulo);
53         }
54 
55         // -- Comparaison operator
isZeroQuotientDom56         int isZero  ( const Rep& P ) const
57         { return Ring_t::isZero(P); }
isOneQuotientDom58         int isOne   ( const Rep& P ) const
59         { return Ring_t::isOne(P); }
isMOneQuotientDom60         int isMOne   ( const Rep& P ) const
61         { return Ring_t::isMOne(P); }
62 
areEqualQuotientDom63         int areEqual ( const Rep& P, const Rep& Q ) const
64         {
65             return Ring_t::areEqual(P, Q);
66         }
areNEqualQuotientDom67         int areNEqual( const Rep& P, const Rep& Q ) const
68         {
69             return Ring_t::areNEqual(P, Q) ;
70         }
71 
72         // --
readQuotientDom73         std::istream& read ( std::istream& i ) {
74             char tmp;
75             return Ring_t::read(Ring_t::read(i) >> tmp);
76         }
writeQuotientDom77         std::ostream& write( std::ostream& o ) const
78         {
79             return Ring_t::write( Ring_t::write(o) << '/', _modulo);
80         }
readQuotientDom81         std::istream& read ( std::istream& i, Rep& n) const
82         {
83             return Ring_t::read(i,n);
84         }
writeQuotientDom85         std::ostream& write( std::ostream& o, const Rep& n) const
86         {
87             return Ring_t::write(o,n);
88         }
89 
90         // -- Arithmetics operators
mulinQuotientDom91         Rep& mulin ( Rep& q, const Rep& a ) const
92         {
93             return Ring_t::modin(Ring_t::mulin(q,a), _modulo);
94         }
mulQuotientDom95         Rep& mul   ( Rep& q, const Rep& a, const Rep& b ) const
96         {
97             return Ring_t::modin(Ring_t::mul(q,a,b), _modulo);
98         }
addinQuotientDom99         Rep& addin ( Rep& r, const Rep& u ) const
100         {
101             return Ring_t::modin(Ring_t::addin(r,u), _modulo);
102         }
addQuotientDom103         Rep& add ( Rep& r, const Rep& u, const Rep& v ) const
104         {
105             return Ring_t::modin(Ring_t::add(r,u,v), _modulo);
106         }
subinQuotientDom107         Rep& subin ( Rep& r, const Rep& u ) const
108         {
109             return Ring_t::modin(Ring_t::subin(r,u), _modulo);
110         }
subQuotientDom111         Rep& sub ( Rep& r, const Rep& u, const Rep& v ) const
112         {
113             return Ring_t::modin(Ring_t::sub(r,u,v), _modulo);
114         }
neginQuotientDom115         Rep& negin ( Rep& r ) const
116         {
117             return Ring_t::modin(Ring_t::negin(r),_modulo);
118         }
negQuotientDom119         Rep& neg ( Rep& r, const Rep& u ) const
120         {
121             return Ring_t::modin(Ring_t::neg(r,u),_modulo);
122         }
invinQuotientDom123         Rep& invin ( Rep& q) const
124         {
125             Rep t; Ring_t::invmod(t,q,_modulo);
126             return Ring_t::assign(q,t);
127         }
invQuotientDom128         Rep& inv( Rep& r, const Rep& u) const
129         {
130             return Ring_t::invmod(r,u,_modulo);
131         }
132 
divinQuotientDom133         Rep& divin ( Rep& q, const Rep& a ) const
134         {
135             Rep t;
136             return this->mulin(q,this->inv(t,a));
137         }
divQuotientDom138         Rep& div   ( Rep& q, const Rep& a, const Rep& b ) const
139         {
140             return this->mulin(this->inv(q, b),a);
141         }
axpyQuotientDom142         Rep& axpy  (Rep& r, const Rep& a, const Rep& x, const Rep& y) const
143         {
144             return Ring_t::modin(Ring_t::axpy(r,a,x,y), _modulo);
145         }
axpyinQuotientDom146         Rep& axpyin(Rep& r, const Rep& a, const Rep& x) const
147         {
148             return Ring_t::modin(Ring_t::axpyin(r,a,x), _modulo);
149         }
150         // -- maxpy: r <- y - a * x
maxpyQuotientDom151         Rep& maxpy  (Rep& r, const Rep& a, const Rep& x, const Rep& y) const
152         {
153             return Ring_t::modin(Ring_t::maxpy(r,a,x,y), _modulo);
154         }
155         // -- axmyin: r <- a * x - r
axmyinQuotientDom156         Rep& axmyin(Rep& r, const Rep& a, const Rep& x) const
157         {
158             return Ring_t::modin(Ring_t::axmyin(r,a,x), _modulo);
159         }
160         // -- maxpyin: r <- r - a * x
maxpyinQuotientDom161         Rep& maxpyin(Rep& r, const Rep& a, const Rep& x) const
162         {
163             return Ring_t::modin(Ring_t::maxpyin(r,a,x), _modulo);
164         }
165         // -- axmy: r <- a * x - y
axmyQuotientDom166         Rep& axmy  (Rep& r, const Rep& a, const Rep& x, const Rep& y) const
167         {
168             return Ring_t::modin(Ring_t::axmy(r,a,x,y), _modulo);
169         }
170         // -- misc
171         // -- W <-- P^n
powQuotientDom172         Rep& pow( Rep& W, const Rep& P, long n) const
173         {
174             unsigned long l = (unsigned long)GIVABS(n);
175             if (n>0)
176                 return dom_power(W, P, l, *this);
177             else {
178                 Rep invP; this->inv(invP,P);
179                 return dom_power(W, invP, l, *this);
180             }
181         }
182         // -- Random generators
183         template< class RandIter >
randomQuotientDom184         Rep& random(RandIter& g, Rep& r) const
185         {
186             return Ring_t::modin(Ring_t::random(g, r),_modulo);
187         }
188 
189         template< class RandIter, class XXX >
randomQuotientDom190         Rep& random(RandIter& g, Rep& r, const XXX& s) const
191         {
192             return Ring_t::modin(Ring_t::random(g, r, s),_modulo);
193         }
194 
195         template< class RandIter > Rep&
nonzerorandomQuotientDom196         nonzerorandom(RandIter& g, Rep& r) const
197         {
198             return Ring_t::modin(Ring_t::nonzerorandom(g, r),_modulo);
199         }
200         template< class RandIter, class XXX  >
nonzerorandomQuotientDom201         Rep& nonzerorandom(RandIter& g, Rep& r, const XXX& s) const
202         {
203             return Ring_t::modin(Ring_t::nonzerorandom(g, r, s),_modulo);
204         }
205 
206     };
207 
208 } // Givaro
209 
210 #endif
211 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
212 // vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
213