numerix_doc 0.4
/Users/mourrain/Devel/mmx/numerix/include/numerix/modulus_naive.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : modulus_naive.hpp
00004 * DESCRIPTION: modulus for modular arithmetic
00005 * COPYRIGHT  : (C) 2008  Gregoire Lecerf
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00011 ******************************************************************************/
00012 
00013 #ifndef __MMX__MODULUS_NAIVE__HPP
00014 #define __MMX__MODULUS_NAIVE__HPP
00015 #include "basix/port.hpp"
00016 
00017 namespace mmx {
00018 #define TMPL template<typename C, typename M>
00019 
00020 /******************************************************************************
00021 * Naive reduction through remaindering
00022 ******************************************************************************/
00023 
00024 struct modulus_normalization_naive {
00027   template<typename C> static inline bool
00028   normalize (C& p) { return true; }
00029 };
00030 
00031 template<typename V>
00032 struct modulus_reduction_naive : public V {
00033   TMPL static inline void 
00034   reduce_mod (C& dest, const M& m) {
00035     if (m.p != 0) dest = rem (dest, m.p); }
00036 
00037   TMPL static inline void 
00038   reduce_mod (C& dest, const M& m, C& carry) {
00039     if (m.p != 0) {
00040       carry= quo (dest, m.p);
00041       dest = rem (dest, m.p);
00042     }
00043     else
00044       carry= 0; }
00045 
00046   TMPL static inline void 
00047   reduce_mod (C& dest, const C& s, const M& m) {
00048     if (m.p != 0) dest = rem (s, m.p); else dest = s; }
00049 
00050   TMPL static inline void 
00051   reduce_mod (C& dest, const C& s, const M& m, C& carry) {
00052     if (m.p != 0) {
00053       carry= quo (s, m.p);
00054       dest = rem (s, m.p);
00055     }
00056     else {
00057       carry= 0;
00058       dest= s;
00059     } }
00060 };
00061 
00062 /******************************************************************************
00063 * In place operations
00064 ******************************************************************************/
00065 
00066 template<typename V>
00067 struct modulus_add_naive : public V {
00068 
00069   TMPL static inline void 
00070   neg_mod (C& dest, const M& m) {
00071     dest = - dest;
00072     V::reduce_mod (dest, m);}
00073 
00074   TMPL static inline void 
00075   neg_mod (C& dest, const M& m, C& carry) {
00076     dest= carry - dest;
00077     V::reduce_mod (dest, m, carry); }
00078 
00079   TMPL static inline void 
00080   neg_mod (C& dest, const C& s, const M& m) {
00081     V::reduce_mod (dest, -s, m);}
00082 
00083   TMPL static inline void 
00084   neg_mod (C& dest, const C& s, const M& m, C& carry) {
00085     V::reduce_mod (dest, carry - s, m, carry); }
00086 
00087   TMPL static inline void 
00088   add_mod (C& dest, const C& s, const M& m) {
00089     dest += s;
00090     V::reduce_mod (dest, m); }
00091 
00092   TMPL static inline void 
00093   add_mod (C& dest, const C& s, const M& m, C& carry) {
00094     dest += s + carry;
00095     V::reduce_mod (dest, m, carry); }
00096 
00097   TMPL static inline void 
00098   add_mod (C& dest, const C& s1, const C& s2, const M& m) {
00099     V::reduce_mod (dest, s1 + s2, m); }
00100 
00101   TMPL static inline void 
00102   add_mod (C& dest, const C& s1, const C& s2, const M& m, C& carry) {
00103     V::reduce_mod (dest, s1 + s2 + carry, m, carry); }
00104 
00105   TMPL static inline void 
00106   sub_mod (C& dest, const C& s, const M& m) {
00107     dest -= s;
00108     V::reduce_mod (dest, m); }
00109 
00110   TMPL static inline void 
00111   sub_mod (C& dest, const C& s, const M& m, C& carry) {
00112     dest -= s + carry;
00113     V::reduce_mod (dest, m, carry); }
00114 
00115   TMPL static inline void 
00116   sub_mod (C& dest, const C& s1, const C& s2, const M& m) {
00117     V::reduce_mod (dest, s1 - s2, m); }
00118 
00119   TMPL static inline void 
00120   sub_mod (C& dest, const C& s1, const C& s2, const M& m, C& carry) {
00121     V::reduce_mod (dest, s1 - s2 + carry, m, carry); }
00122 
00123 };
00124   
00125 template<typename V>
00126 struct modulus_mul_naive : public V {
00127 
00128   TMPL static inline void 
00129   mul_mod (C& dest, const C& s, const M& m) {
00130     dest *= s;
00131     V::reduce_mod (dest, m); }
00132 
00133   TMPL static inline void 
00134   mul_mod (C& dest, const C& s, const M& m, C& carry) {
00135     dest *= s;
00136     dest += carry;
00137     V::reduce_mod (dest, m, carry); }
00138 
00139   TMPL static inline void 
00140   mul_mod (C& dest, const C& s1, const C& s2, const M& m) {
00141     V::reduce_mod (dest, s1 * s2, m); }
00142 
00143   TMPL static inline void 
00144   mul_mod (C& dest, const C& s1, const C& s2, const M& m, C& carry) {
00145     V::reduce_mod (dest, s1 * s2 + carry, m, carry); }
00146 };
00147 
00148 template<typename V>
00149 struct modulus_inv_naive : public V {
00150 
00151   TMPL static inline void 
00152   inv_mod (C& dest, const M& m) {
00153     (void) m;
00154     if ((dest == (C) 1) || (dest == (C) -1)) return;
00155     ERROR ("inv_mod: argument is not invertible"); }
00156 
00157   TMPL static inline void 
00158   inv_mod (C& dest, const C& s, const M& m) {
00159     (void) m;
00160     if ((s == (C) 1) || (s == (C) -1)) { dest = s; return; }
00161     ERROR ("inv_mod: argument is not invertible"); }
00162 };
00163 
00164 template<typename V>
00165 struct modulus_div_naive : public V {
00166 
00167   TMPL static inline void 
00168   div_mod (C& dest, const C& s, const M& m) {
00169     C t = s;
00170     V::inv_mod (t, m);
00171     V::mul_mod (dest, t, m); }
00172 
00173   TMPL static inline void 
00174   div_mod (C& dest, const C& s1, const C& s2, const M& m) {
00175     C t;
00176     V::inv_mod (t, s2, m);
00177     V::mul_mod (dest, s1, t, m); }
00178 };
00179 
00180 /******************************************************************************
00181 * Naive encoding is identity
00182 ******************************************************************************/
00183 
00184 template<typename V>
00185 struct modulus_encoding_naive : public V {
00186 
00187   TMPL static inline void 
00188   encode_mod (C& dest, const C& s, const M& m) {
00189     dest = s;
00190     V::reduce_mod (dest, m); }
00191 
00192   TMPL static inline void 
00193   decode_mod (C& dest, const C& s, const M& m) {
00194     (void) m;
00195     dest = s; }
00196 };
00197 
00198 /******************************************************************************
00199 * Naive modulus
00200 ******************************************************************************/
00201 
00202 struct modulus_naive:
00203   public modulus_encoding_naive<
00204          modulus_div_naive<
00205          modulus_inv_naive<
00206          modulus_mul_naive<
00207          modulus_add_naive<
00208          modulus_reduction_naive<
00209          modulus_normalization_naive> > > > > > {};
00210 
00211 /******************************************************************************
00212 * Default variant helper
00213 ******************************************************************************/
00214 
00215 template<typename C>
00216 struct modulus_variant_helper { typedef modulus_naive MV; };
00217 
00218 #undef TMPL
00219 } // namespace mmx
00220 #endif //__MMX__MODULUS_NAIVE__HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines