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