algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : vector_fixed.hpp 00004 * DESCRIPTION: inlined low-level vector operations of a fixed size 00005 * COPYRIGHT : (C) 2007 Joris van der Hoeven and 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_FIXED__HPP 00014 #define __MMX__VECTOR_FIXED__HPP 00015 #include <basix/vector_naive.hpp> 00016 00017 namespace mmx { 00018 00019 /****************************************************************************** 00020 * Inlined vectorial operations of a fixed size 00021 ******************************************************************************/ 00022 00023 template<typename Op, typename T, nat n> 00024 struct vec_nullary_helper { 00025 static const nat n1= (n>>1), n2= n-n1; 00026 static inline void op (T* dest) { 00027 vec_nullary_helper <Op, T, n1>::op (dest); 00028 vec_nullary_helper <Op, T, n2>::op (dest+n1); 00029 } 00030 }; 00031 00032 template<typename Op, typename T> 00033 struct vec_nullary_helper<Op, T, 1> { 00034 static inline void op (T* dest) { 00035 Op::set_op (*dest); 00036 } 00037 }; 00038 00039 template<typename Op, typename T, typename C, nat n> 00040 struct vec_unary_helper { 00041 static const nat n1= (n>>1), n2= n-n1; 00042 static inline void op (T* dest, const C* s) { 00043 vec_unary_helper <Op, T, C, n1>::op (dest , s ); 00044 vec_unary_helper <Op, T, C, n2>::op (dest+n1, s+n1); 00045 } 00046 }; 00047 00048 template<typename Op, typename T, typename C> 00049 struct vec_unary_helper<Op, T, C, 1> { 00050 static inline void op (T* dest, const C* s) { 00051 Op::set_op (*dest, *s); 00052 } 00053 }; 00054 00055 template<typename Op, typename T, typename C1, typename C2, nat n> 00056 struct vec_binary_helper { 00057 static const nat n1= (n>>1), n2= n-n1; 00058 static inline void op (T* dest, const C1* s1, const C2* s2) { 00059 vec_binary_helper <Op, T, C1, C2, n1>::op (dest , s1 , s2 ); 00060 vec_binary_helper <Op, T, C1, C2, n2>::op (dest+n1, s1+n1, s2+n1); 00061 } 00062 }; 00063 00064 template<typename Op, typename T, typename C1, typename C2> 00065 struct vec_binary_helper<Op, T, C1, C2, 1> { 00066 static inline void op (T* dest, const C1* s1, const C2* s2) { 00067 Op::set_op (*dest, *s1, *s2); 00068 } 00069 }; 00070 00071 template<typename Op, typename T, typename X, nat n> 00072 struct vec_unary_scalar_helper { 00073 static const nat n1= (n>>1), n2= n-n1; 00074 static inline void op (T* dest, const X& x) { 00075 vec_unary_scalar_helper <Op, T, X, n1>::op (dest , x); 00076 vec_unary_scalar_helper <Op, T, X, n2>::op (dest+n1, x); 00077 } 00078 }; 00079 00080 template<typename Op, typename T, typename X> 00081 struct vec_unary_scalar_helper<Op, T, X, 1> { 00082 static inline void op (T* dest, const X& x) { 00083 Op::set_op (*dest, x); 00084 } 00085 }; 00086 00087 template<typename Op, typename T, typename C, typename X, nat n> 00088 struct vec_binary_scalar_helper { 00089 static const nat n1= (n>>1), n2= n-n1; 00090 static inline void op (T* dest, const C* s, const X& x) { 00091 vec_binary_scalar_helper <Op, T, C, X, n1>::op (dest , s , x); 00092 vec_binary_scalar_helper <Op, T, C, X, n2>::op (dest+n1, s+n1, x); 00093 } 00094 }; 00095 00096 template<typename Op, typename T, typename C, typename X> 00097 struct vec_binary_scalar_helper<Op, T, C, X, 1> { 00098 static inline void op (T* dest, const C* s, const X& x) { 00099 Op::set_op (*dest, *s, x); 00100 } 00101 }; 00102 00103 template<typename Op, typename C, nat n> 00104 struct vec_unary_test_helper { 00105 static const nat n1= (n>>1), n2= n-n1; 00106 static inline void op (const C* s) { 00107 if (!vec_unary_test_helper <Op, C, n1>::op (s)) return false; 00108 return vec_unary_test_helper <Op, C, n2>::op (s+n1); 00109 } 00110 }; 00111 00112 template<typename Op, typename C> 00113 struct vec_unary_test_helper<Op, C, 1> { 00114 static inline void op (const C* s) { 00115 return Op::op (*s); 00116 } 00117 }; 00118 00119 template<typename Op, typename C1, typename C2, nat n> 00120 struct vec_binary_test_helper { 00121 static const nat n1= (n>>1), n2= n-n1; 00122 static inline bool op (const C1* s1, const C2* s2) { 00123 return vec_binary_test_helper <Op, C1, C2, n1>::op (s1 , s2) 00124 && vec_binary_test_helper <Op, C1, C2, n2>::op (s1+n1, s2+n1); 00125 } 00126 }; 00127 00128 template<typename Op, typename C1, typename C2> 00129 struct vec_binary_test_helper<Op, C1, C2, 1> { 00130 static inline bool op (const C1* s1, const C2* s2) { 00131 return !Op::not_op (*s1, *s2); 00132 } 00133 }; 00134 00135 template<typename Op, typename C, typename X, nat n> 00136 struct vec_binary_test_scalar_helper { 00137 static const nat n1= (n>>1), n2= n-n1; 00138 static inline bool op (const C* s, const X& x) { 00139 return vec_binary_test_scalar_helper <Op, C, X, n1>::op (s , x) 00140 && vec_binary_test_scalar_helper <Op, C, X, n2>::op (s+n1, x); 00141 } 00142 }; 00143 00144 template<typename Op, typename C, typename X> 00145 struct vec_binary_test_scalar_helper<Op, C, X, 1> { 00146 static inline bool op (const C* s, const X& x) { 00147 return !Op::not_op (*s, x); 00148 } 00149 }; 00150 00151 template<typename Op, typename R, typename C, nat n> 00152 struct vec_unary_big_helper { 00153 static const nat n1= (n>>1), n2= n-n1; 00154 static inline void set_op (R& r, const C* s) { 00155 vec_unary_big_helper <Op, R, C, n1>::set_op (r, s); 00156 vec_unary_big_helper <Op, R, C, n2>::set_op (r, s+n1); 00157 } 00158 static inline void set_op (R& r, const C* s, const format<C>& fm) { 00159 vec_unary_big_helper <Op, R, C, n1>::set_op (r, s, fm); 00160 vec_unary_big_helper <Op, R, C, n2>::set_op (r, s+n1, fm); 00161 } 00162 }; 00163 00164 template<typename Op, typename R, typename C> 00165 struct vec_unary_big_helper<Op, R, C, 1> { 00166 static inline void set_op (R& r, const C* s) { 00167 Op::set_op (r, *s); 00168 } 00169 static inline void set_op (R& r, const C* s, const format<C>& fm) { 00170 (void) fm; 00171 Op::set_op (r, *s); 00172 } 00173 }; 00174 00175 template<typename Op, typename C1, typename C2, nat n> 00176 struct vec_binary_big_helper { 00177 static const nat n1= (n>>1), n2= n-n1; 00178 static inline void _op (C1& r, const C1* s1, const C2* s2) { 00179 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2); 00180 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1); 00181 } 00182 static inline void _op (C1& r, const C1* s1, const C2* s2, 00183 const format<C1>& fm1, const format<C2>& fm2) { 00184 (void) fm1; (void) fm2; 00185 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2); 00186 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1); 00187 } 00188 static inline C1 op (const C1* s1, const C2* s2) { 00189 C1 r= Op::template neutral<C1> (); 00190 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2); 00191 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1); 00192 return r; 00193 } 00194 static inline C1 op (const C1* s1, const C2* s2, 00195 const format<C1>& fm1, const format<C2>& fm2) { 00196 C1 r= get_sample (binary_map<Op> (fm1, fm2)); 00197 Op::set_neutral (r); 00198 vec_binary_big_helper <Op, C1, C2, n1>::_op (r, s1 , s2); 00199 vec_binary_big_helper <Op, C1, C2, n2>::_op (r, s1+n1, s2+n1); 00200 return r; 00201 } 00202 }; 00203 00204 template<typename Op, typename C1, typename C2> 00205 struct vec_binary_big_helper<Op, C1, C2, 1> { 00206 static inline void _op (C1& r, const C1* s1, const C2* s2) { 00207 Op::set_op (r, *s1, *s2); 00208 } 00209 static inline void _op (C1& r, const C1* s1, const C2* s2, 00210 const format<C1>& fm1, const format<C2>& fm2) { 00211 (void) fm1; (void) fm2; 00212 Op::set_op (r, *s1, *s2); 00213 } 00214 static inline C1 op (const C1* s1, const C2* s2) { 00215 C1 r= Op::template neutral<C1> (); 00216 Op::set_op (r, *s1, *s2); 00217 return r; 00218 } 00219 static inline C1 op (const C1* s1, const C2* s2, 00220 const format<C1>& fm1, const format<C2>& fm2) { 00221 C1 r= get_sample (binary_map<Op> (fm1, fm2)); 00222 Op::set_neutral (r); 00223 Op::set_op (r, *s1, *s2); 00224 return r; 00225 } 00226 }; 00227 00228 // Special speedup for mul_add 00229 template<typename C1, typename C2> 00230 struct vec_binary_big_helper<mul_add_op, C1, C2, 2> { 00231 static inline void _op (C1& r, const C1* s1, const C2* s2) { 00232 r += (*s1) * (*s2) + (*(s1+1)) * (*(s2+1)); 00233 } 00234 static inline void _op (C1& r, const C1* s1, const C2* s2, 00235 const format<C1>& fm1, const format<C2>& fm2) { 00236 (void) fm1; (void) fm2; 00237 r += (*s1) * (*s2) + (*(s1+1)) * (*(s2+1)); 00238 } 00239 static inline C1 op (const C1* s1, const C2* s2) { 00240 return (*s1) * (*s2) + (*(s1+1)) * (*(s2+1)); 00241 } 00242 static inline C1 op (const C1* s1, const C2* s2, 00243 const format<C1>& fm1, const format<C2>& fm2) { 00244 (void) fm1; (void) fm2; 00245 return (*s1) * (*s2) + (*(s1+1)) * (*(s2+1)); 00246 } 00247 }; 00248 00249 } // namespace mmx 00250 #endif //__MMX__VECTOR_FIXED__HPP