numerix_doc 0.4
|
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