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, 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
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
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
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
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
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 }
00223 #endif //__MMX__VECTOR_MODULAR__HPP