algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/vector_modular.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : vector_modular.hpp
00004 * DESCRIPTION: header for low level vectorial computations over modular
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__VECTOR_MODULAR__HPP
00014 #define __MMX__VECTOR_MODULAR__HPP
00015 #include <numerix/modular.hpp>
00016 #include <algebramix/vector_unrolled.hpp>
00017 
00018 namespace mmx {
00019 
00020 /******************************************************************************
00021 * Optimized unrolling for modular operations
00022 ******************************************************************************/
00023 
00024 // neg_op
00025 template<typename R, typename M, nat n>
00026 struct vec_neg_mod_helper {
00027   static const nat n1= (n>>1), n2= n-n1;
00028   static inline void op (R* dest, const R* s, const M& m) {
00029     vec_neg_mod_helper <R, M, n1>::op (dest   , s   , m);
00030     vec_neg_mod_helper <R, M, n2>::op (dest+n1, s+n1, m); }
00031 };
00032 
00033 template<typename R, typename M>
00034 struct vec_neg_mod_helper<R, M, 1> {
00035   static inline void op (R* dest, const R* s, const M& m) {
00036     dest[0] = s[0];
00037     neg_mod (dest->rep, m); }
00038 };
00039 
00040 template<typename C, typename V, typename W, nat n>
00041 struct vec_unary_helper<neg_op,
00042                         modular<modulus<C, V>, W>,
00043                         modular<modulus<C, V>, W>,
00044                         n> {    
00045   typedef modulus<C, V> M;
00046   typedef modular<M, W> R;
00047   static void op (R* dest, const R* s) {
00048     vec_neg_mod_helper<R, M, n>:: op (dest, s, R::get_modulus ()); }
00049 };
00050 
00051 // add_op
00052 template<typename R, typename M, nat n>
00053 struct vec_add_mod_helper {
00054   static const nat n1= (n>>1), n2= n-n1;
00055   static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00056     vec_add_mod_helper <R, M, n1>::op (dest   , s1   , s2   , m);
00057     vec_add_mod_helper <R, M, n2>::op (dest+n1, s1+n1, s2+n1, m); }
00058 };
00059 
00060 template<typename R, typename M>
00061 struct vec_add_mod_helper<R, M, 1> {
00062   static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00063     dest[0] = s1[0];
00064     add_mod (dest->rep, s2->rep, m); }
00065 };
00066 
00067 template<typename C, typename V, typename W, nat n>
00068 struct vec_binary_helper<add_op,
00069                          modular<modulus<C, V>, W>,
00070                          modular<modulus<C, V>, W>,
00071                          modular<modulus<C, V>, W>,
00072                          n> {   
00073   typedef modulus<C, V> M;
00074   typedef modular<M, W> R;
00075   static void op (R* dest, const R* s1, const R* s2) {
00076     vec_add_mod_helper<R, M, n>:: op (dest, s1, s2, R::get_modulus ()); }
00077 };
00078 
00079 // sub_op
00080 template<typename R, typename M, nat n>
00081 struct vec_sub_mod_helper {
00082   static const nat n1= (n>>1), n2= n-n1;
00083   static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00084     vec_sub_mod_helper <R, M, n1>::op (dest   , s1   , s2   , m);
00085     vec_sub_mod_helper <R, M, n2>::op (dest+n1, s1+n1, s2+n1, m); }
00086 };
00087 
00088 template<typename R, typename M>
00089 struct vec_sub_mod_helper<R, M, 1> {
00090   static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00091     dest[0] = s1[0];
00092     sub_mod (dest->rep, s2->rep, m); }
00093 };
00094 
00095 template<typename C, typename V, typename W, nat n>
00096 struct vec_binary_helper<sub_op,
00097                          modular<modulus<C, V>, W>,
00098                          modular<modulus<C, V>, W>,
00099                          modular<modulus<C, V>, W>,
00100                          n> {   
00101   typedef modulus<C, V> M;
00102   typedef modular<M, W> R;
00103   static void op (R* dest, const R* s1, const R* s2) {
00104     vec_sub_mod_helper<R, M, n>:: op (dest, s1, s2, R::get_modulus ()); }
00105 };
00106 
00107 // mul_op
00108 template<typename R, typename M, nat n>
00109 struct vec_mul_mod_helper {
00110   static const nat n1= (n>>1), n2= n-n1;
00111   static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00112     vec_mul_mod_helper <R, M, n1>::op (dest   , s1   , s2   , m);
00113     vec_mul_mod_helper <R, M, n2>::op (dest+n1, s1+n1, s2+n1, m); }
00114 };
00115 
00116 template<typename R, typename M>
00117 struct vec_mul_mod_helper<R, M, 1> {
00118   static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00119     dest[0] = s1[0];
00120     mul_mod (dest->rep, s2->rep, m); }
00121 };
00122 
00123 template<typename C, typename V, typename W, nat n>
00124 struct vec_binary_helper<mul_op,
00125                          modular<modulus<C, V>, W>,
00126                          modular<modulus<C, V>, W>,
00127                          modular<modulus<C, V>, W>,
00128                          n> {   
00129   typedef modulus<C, V> M;
00130   typedef modular<M, W> R;
00131   static void op (R* dest, const R* s1, const R* s2) {
00132     vec_mul_mod_helper<R, M, n>:: op (dest, s1, s2, R::get_modulus ()); }
00133 };
00134 
00135 // div_op
00136 template<typename R, typename M, nat n>
00137 struct vec_div_mod_helper {
00138   static const nat n1= (n>>1), n2= n-n1;
00139   static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00140     vec_div_mod_helper <R, M, n1>::op (dest   , s1   , s2   , m);
00141     vec_div_mod_helper <R, M, n2>::op (dest+n1, s1+n1, s2+n1, m); }
00142 };
00143 
00144 template<typename R, typename M>
00145 struct vec_div_mod_helper<R, M, 1> {
00146   static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00147     dest[0] = s1[0];
00148     div_mod (dest->rep, s2->rep, m); }
00149 };
00150 
00151 template<typename C, typename V, typename W, nat n>
00152 struct vec_binary_helper<div_op,
00153                          modular<modulus<C, V>, W>,
00154                          modular<modulus<C, V>, W>,
00155                          modular<modulus<C, V>, W>,
00156                          n> {   
00157   typedef modulus<C, V> M;
00158   typedef modular<M, W> R;
00159   static void op (R* dest, const R* s1, const R* s2) {
00160     vec_div_mod_helper<R, M, n>:: op (dest, s1, s2, R::get_modulus ()); }
00161 };
00162 
00163 /******************************************************************************
00164 * Use modular vector operations by default
00165 ******************************************************************************/
00166 
00167 template<typename V, typename W>
00168 struct vector_variant_helper<modular<modulus<char,V>, W> > {
00169   typedef vector_unrolled<16,vector_unrolled<32> > VV;
00170 };
00171 
00172 template<typename V, typename W>
00173 struct vector_variant_helper<modular<modulus<signed char,V>, W> > {
00174   typedef vector_unrolled<16,vector_unrolled<32> > VV;
00175 };
00176 
00177 template<typename V, typename W>
00178 struct vector_variant_helper<modular<modulus<unsigned char,V>, W> > {
00179   typedef vector_unrolled<16,vector_unrolled<32> > VV;
00180 };
00181 
00182 template<typename V, typename W>
00183 struct vector_variant_helper<modular<modulus<short int,V>, W> > {
00184   typedef vector_unrolled<8,vector_unrolled<32> > VV;
00185 };
00186 
00187 template<typename V, typename W>
00188 struct vector_variant_helper<modular<modulus<short unsigned int,V>, W> > {
00189   typedef vector_unrolled<8,vector_unrolled<32> > VV;
00190 };
00191 
00192 template<typename V, typename W>
00193 struct vector_variant_helper<modular<modulus<int,V>, W> > {
00194   typedef vector_unrolled<4,vector_unrolled<16> > VV;
00195 };
00196 
00197 template<typename V, typename W>
00198 struct vector_variant_helper<modular<modulus<unsigned int,V>, W> > {
00199   typedef vector_unrolled<4,vector_unrolled<16> > VV;
00200 };
00201 
00202 template<typename V, typename W>
00203 struct vector_variant_helper<modular<modulus<long int,V>, W> > {
00204   typedef vector_unrolled<4,vector_unrolled<16> > VV;
00205 };
00206 
00207 template<typename V, typename W>
00208 struct vector_variant_helper<modular<modulus<long unsigned int,V>, W> > {
00209   typedef vector_unrolled<4,vector_unrolled<16> > VV;
00210 };
00211 
00212 template<typename V, typename W>
00213 struct vector_variant_helper<modular<modulus<long long int,V>, W> > {
00214   typedef vector_unrolled<2,vector_unrolled<8> > VV;
00215 };
00216 
00217 template<typename V, typename W>
00218 struct vector_variant_helper<modular<modulus<long long unsigned int,V>, W> > {
00219   typedef vector_unrolled<2,vector_unrolled<8> > VV;
00220 };
00221 
00222 } // namespace mmx
00223 #endif //__MMX__VECTOR_MODULAR__HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines