00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00022
00023
00024
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>
00041 struct vec_unary_helper<neg_op,
00042 modular<modulus<C, V>, W>,
00043 modular<modulus<C, V>, W>,
00044 1> {
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, 1>:: op (dest, s, R::get_modulus ()); }
00049 };
00050
00051 template<typename C, typename V, typename W, nat n>
00052 struct vec_unary_helper<neg_op,
00053 modular<modulus<C, V>, W>,
00054 modular<modulus<C, V>, W>,
00055 n> {
00056 typedef modulus<C, V> M;
00057 typedef modular<M, W> R;
00058 static void op (R* dest, const R* s) {
00059 vec_neg_mod_helper<R, M, n>:: op (dest, s, R::get_modulus ()); }
00060 };
00061
00062
00063 template<typename R, typename M, nat n>
00064 struct vec_add_mod_helper {
00065 static const nat n1= (n>>1), n2= n-n1;
00066 static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00067 vec_add_mod_helper <R, M, n1>::op (dest , s1 , s2 , m);
00068 vec_add_mod_helper <R, M, n2>::op (dest+n1, s1+n1, s2+n1, m); }
00069 };
00070
00071 template<typename R, typename M>
00072 struct vec_add_mod_helper<R, M, 1> {
00073 static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00074 dest[0] = s1[0];
00075 add_mod (dest->rep, s2->rep, m); }
00076 };
00077
00078 template<typename C, typename V, typename W>
00079 struct vec_binary_helper<add_op,
00080 modular<modulus<C, V>, W>,
00081 modular<modulus<C, V>, W>,
00082 modular<modulus<C, V>, W>,
00083 1> {
00084 typedef modulus<C, V> M;
00085 typedef modular<M, W> R;
00086 static void op (R* dest, const R* s1, const R* s2) {
00087 vec_add_mod_helper<R, M, 1>:: op (dest, s1, s2, R::get_modulus ()); }
00088 };
00089
00090 template<typename C, typename V, typename W, nat n>
00091 struct vec_binary_helper<add_op,
00092 modular<modulus<C, V>, W>,
00093 modular<modulus<C, V>, W>,
00094 modular<modulus<C, V>, W>,
00095 n> {
00096 typedef modulus<C, V> M;
00097 typedef modular<M, W> R;
00098 static void op (R* dest, const R* s1, const R* s2) {
00099 vec_add_mod_helper<R, M, n>:: op (dest, s1, s2, R::get_modulus ()); }
00100 };
00101
00102
00103 template<typename R, typename M, nat n>
00104 struct vec_sub_mod_helper {
00105 static const nat n1= (n>>1), n2= n-n1;
00106 static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00107 vec_sub_mod_helper <R, M, n1>::op (dest , s1 , s2 , m);
00108 vec_sub_mod_helper <R, M, n2>::op (dest+n1, s1+n1, s2+n1, m); }
00109 };
00110
00111 template<typename R, typename M>
00112 struct vec_sub_mod_helper<R, M, 1> {
00113 static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00114 dest[0] = s1[0];
00115 sub_mod (dest->rep, s2->rep, m); }
00116 };
00117
00118 template<typename C, typename V, typename W>
00119 struct vec_binary_helper<sub_op,
00120 modular<modulus<C, V>, W>,
00121 modular<modulus<C, V>, W>,
00122 modular<modulus<C, V>, W>,
00123 1> {
00124 typedef modulus<C, V> M;
00125 typedef modular<M, W> R;
00126 static void op (R* dest, const R* s1, const R* s2) {
00127 vec_sub_mod_helper<R, M, 1>:: op (dest, s1, s2, R::get_modulus ()); }
00128 };
00129
00130 template<typename C, typename V, typename W, nat n>
00131 struct vec_binary_helper<sub_op,
00132 modular<modulus<C, V>, W>,
00133 modular<modulus<C, V>, W>,
00134 modular<modulus<C, V>, W>,
00135 n> {
00136 typedef modulus<C, V> M;
00137 typedef modular<M, W> R;
00138 static void op (R* dest, const R* s1, const R* s2) {
00139 vec_sub_mod_helper<R, M, n>:: op (dest, s1, s2, R::get_modulus ()); }
00140 };
00141
00142
00143 template<typename R, typename M, nat n>
00144 struct vec_mul_mod_helper {
00145 static const nat n1= (n>>1), n2= n-n1;
00146 static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00147 vec_mul_mod_helper <R, M, n1>::op (dest , s1 , s2 , m);
00148 vec_mul_mod_helper <R, M, n2>::op (dest+n1, s1+n1, s2+n1, m); }
00149 };
00150
00151 template<typename R, typename M>
00152 struct vec_mul_mod_helper<R, M, 1> {
00153 static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00154 dest[0] = s1[0];
00155 mul_mod (dest->rep, s2->rep, m); }
00156 };
00157
00158 template<typename C, typename V, typename W>
00159 struct vec_binary_helper<mul_op,
00160 modular<modulus<C, V>, W>,
00161 modular<modulus<C, V>, W>,
00162 modular<modulus<C, V>, W>,
00163 1> {
00164 typedef modulus<C, V> M;
00165 typedef modular<M, W> R;
00166 static void op (R* dest, const R* s1, const R* s2) {
00167 vec_mul_mod_helper<R, M, 1>:: op (dest, s1, s2, R::get_modulus ()); }
00168 };
00169
00170 template<typename C, typename V, typename W, nat n>
00171 struct vec_binary_helper<mul_op,
00172 modular<modulus<C, V>, W>,
00173 modular<modulus<C, V>, W>,
00174 modular<modulus<C, V>, W>,
00175 n> {
00176 typedef modulus<C, V> M;
00177 typedef modular<M, W> R;
00178 static void op (R* dest, const R* s1, const R* s2) {
00179 vec_mul_mod_helper<R, M, n>:: op (dest, s1, s2, R::get_modulus ()); }
00180 };
00181
00182
00183 template<typename R, typename M, nat n>
00184 struct vec_div_mod_helper {
00185 static const nat n1= (n>>1), n2= n-n1;
00186 static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00187 vec_div_mod_helper <R, M, n1>::op (dest , s1 , s2 , m);
00188 vec_div_mod_helper <R, M, n2>::op (dest+n1, s1+n1, s2+n1, m); }
00189 };
00190
00191 template<typename R, typename M>
00192 struct vec_div_mod_helper<R, M, 1> {
00193 static inline void op (R* dest, const R* s1, const R* s2, const M& m) {
00194 dest[0] = s1[0];
00195 div_mod (dest->rep, s2->rep, m); }
00196 };
00197
00198 template<typename C, typename V, typename W>
00199 struct vec_binary_helper<div_op,
00200 modular<modulus<C, V>, W>,
00201 modular<modulus<C, V>, W>,
00202 modular<modulus<C, V>, W>,
00203 1> {
00204 typedef modulus<C, V> M;
00205 typedef modular<M, W> R;
00206 static void op (R* dest, const R* s1, const R* s2) {
00207 vec_div_mod_helper<R, M, 1>:: op (dest, s1, s2, R::get_modulus ()); }
00208 };
00209
00210 template<typename C, typename V, typename W, nat n>
00211 struct vec_binary_helper<div_op,
00212 modular<modulus<C, V>, W>,
00213 modular<modulus<C, V>, W>,
00214 modular<modulus<C, V>, W>,
00215 n> {
00216 typedef modulus<C, V> M;
00217 typedef modular<M, W> R;
00218 static void op (R* dest, const R* s1, const R* s2) {
00219 vec_div_mod_helper<R, M, n>:: op (dest, s1, s2, R::get_modulus ()); }
00220 };
00221
00222
00223
00224
00225
00226 template<typename V, typename W>
00227 struct vector_variant_helper<modular<modulus<char,V>, W> > {
00228 typedef vector_unrolled<16,vector_unrolled<32> > VV;
00229 };
00230
00231 template<typename V, typename W>
00232 struct vector_variant_helper<modular<modulus<signed char,V>, W> > {
00233 typedef vector_unrolled<16,vector_unrolled<32> > VV;
00234 };
00235
00236 template<typename V, typename W>
00237 struct vector_variant_helper<modular<modulus<unsigned char,V>, W> > {
00238 typedef vector_unrolled<16,vector_unrolled<32> > VV;
00239 };
00240
00241 template<typename V, typename W>
00242 struct vector_variant_helper<modular<modulus<short int,V>, W> > {
00243 typedef vector_unrolled<8,vector_unrolled<32> > VV;
00244 };
00245
00246 template<typename V, typename W>
00247 struct vector_variant_helper<modular<modulus<short unsigned int,V>, W> > {
00248 typedef vector_unrolled<8,vector_unrolled<32> > VV;
00249 };
00250
00251 template<typename V, typename W>
00252 struct vector_variant_helper<modular<modulus<int,V>, W> > {
00253 typedef vector_unrolled<4,vector_unrolled<16> > VV;
00254 };
00255
00256 template<typename V, typename W>
00257 struct vector_variant_helper<modular<modulus<unsigned int,V>, W> > {
00258 typedef vector_unrolled<4,vector_unrolled<16> > VV;
00259 };
00260
00261 template<typename V, typename W>
00262 struct vector_variant_helper<modular<modulus<long int,V>, W> > {
00263 typedef vector_unrolled<4,vector_unrolled<16> > VV;
00264 };
00265
00266 template<typename V, typename W>
00267 struct vector_variant_helper<modular<modulus<long unsigned int,V>, W> > {
00268 typedef vector_unrolled<4,vector_unrolled<16> > VV;
00269 };
00270
00271 template<typename V, typename W>
00272 struct vector_variant_helper<modular<modulus<long long int,V>, W> > {
00273 typedef vector_unrolled<2,vector_unrolled<8> > VV;
00274 };
00275
00276 template<typename V, typename W>
00277 struct vector_variant_helper<modular<modulus<long long unsigned int,V>, W> > {
00278 typedef vector_unrolled<2,vector_unrolled<8> > VV;
00279 };
00280
00281 }
00282 #endif //__MMX__VECTOR_MODULAR__HPP