algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/vector_fixed.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines