ICRS Eurobot 2013

Dependencies:   mbed mbed-rtos Servo QEI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers VectorFunctions.h Source File

VectorFunctions.h

00001 /*
00002  * Tiny Vector Matrix Library
00003  * Dense Vector Matrix Libary of Tiny size using Expression Templates
00004  *
00005  * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * $Id: VectorFunctions.h,v 1.37 2007-06-23 15:58:58 opetzold Exp $
00022  */
00023 
00024 #ifndef TVMET_VECTOR_FUNCTIONS_H
00025 #define TVMET_VECTOR_FUNCTIONS_H
00026 
00027 #include <tvmet/Extremum.h>
00028 
00029 namespace tvmet {
00030 
00031 
00032 /*********************************************************
00033  * PART I: DECLARATION
00034  *********************************************************/
00035 
00036 
00037 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00038  * Vector arithmetic functions add, sub, mul and div
00039  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00040 
00041 
00042 /*
00043  * function(Vector<T1, Sz>, Vector<T2, Sz>)
00044  * function(Vector<T, Sz>, XprVector<E, Sz>)
00045  * function(XprVector<E, Sz>, Vector<T, Sz>)
00046  */
00047 #define TVMET_DECLARE_MACRO(NAME)                \
00048 template<class T1, class T2, std::size_t Sz>            \
00049 XprVector<                            \
00050   XprBinOp<                            \
00051     Fcnl_##NAME<T1, T2>,                    \
00052     VectorConstReference<T1, Sz>,                \
00053     VectorConstReference<T2, Sz>                \
00054   >,                                \
00055   Sz                                \
00056 >                                \
00057 NAME (const Vector<T1, Sz>& lhs,                \
00058       const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;    \
00059                                 \
00060 template<class E, class T, std::size_t Sz>            \
00061 XprVector<                            \
00062   XprBinOp<                            \
00063     Fcnl_##NAME<typename E::value_type, T>,            \
00064     XprVector<E, Sz>,                        \
00065     VectorConstReference<T, Sz>                    \
00066   >,                                \
00067   Sz                                \
00068 >                                \
00069 NAME (const XprVector<E, Sz>& lhs,                \
00070       const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;    \
00071                                 \
00072 template<class E, class T, std::size_t Sz>            \
00073 XprVector<                            \
00074   XprBinOp<                            \
00075     Fcnl_##NAME<T, typename E::value_type>,            \
00076     VectorConstReference<T, Sz>,                \
00077     XprVector<E, Sz>                        \
00078   >,                                \
00079   Sz                                \
00080 >                                \
00081 NAME (const Vector<T, Sz>& lhs,                    \
00082       const XprVector<E, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00083 
00084 TVMET_DECLARE_MACRO(add)        // per se element wise
00085 TVMET_DECLARE_MACRO(sub)        // per se element wise
00086 TVMET_DECLARE_MACRO(mul)        // per se element wise
00087 namespace element_wise {
00088   TVMET_DECLARE_MACRO(div)        // not defined for vectors
00089 }
00090 
00091 #undef TVMET_DECLARE_MACRO
00092 
00093 
00094 /*
00095  * function(Vector<T, Sz>, POD)
00096  * function(POD, Vector<T, Sz>)
00097  * Note: - operations +,-,*,/ are per se element wise
00098  */
00099 #define TVMET_DECLARE_MACRO(NAME, POD)                \
00100 template<class T, std::size_t Sz>                \
00101 XprVector<                            \
00102   XprBinOp<                            \
00103     Fcnl_##NAME< T, POD >,                    \
00104     VectorConstReference<T, Sz>,                \
00105     XprLiteral< POD >                        \
00106   >,                                \
00107   Sz                                \
00108 >                                \
00109 NAME (const Vector<T, Sz>& lhs,                 \
00110       POD rhs) TVMET_CXX_ALWAYS_INLINE;                \
00111                                 \
00112 template<class T, std::size_t Sz>                \
00113 XprVector<                            \
00114   XprBinOp<                            \
00115     Fcnl_##NAME< POD, T>,                    \
00116     XprLiteral< POD >,                        \
00117     VectorConstReference<T, Sz>                    \
00118   >,                                \
00119   Sz                                \
00120 >                                \
00121 NAME (POD lhs,                             \
00122       const Vector<T, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00123 
00124 TVMET_DECLARE_MACRO(add, int)
00125 TVMET_DECLARE_MACRO(sub, int)
00126 TVMET_DECLARE_MACRO(mul, int)
00127 TVMET_DECLARE_MACRO(div, int)
00128 
00129 #if defined(TVMET_HAVE_LONG_LONG)
00130 TVMET_DECLARE_MACRO(add, long long int)
00131 TVMET_DECLARE_MACRO(sub, long long int)
00132 TVMET_DECLARE_MACRO(mul, long long int)
00133 TVMET_DECLARE_MACRO(div, long long int)
00134 #endif
00135 
00136 TVMET_DECLARE_MACRO(add, float)
00137 TVMET_DECLARE_MACRO(sub, float)
00138 TVMET_DECLARE_MACRO(mul, float)
00139 TVMET_DECLARE_MACRO(div, float)
00140 
00141 TVMET_DECLARE_MACRO(add, double)
00142 TVMET_DECLARE_MACRO(sub, double)
00143 TVMET_DECLARE_MACRO(mul, double)
00144 TVMET_DECLARE_MACRO(div, double)
00145 
00146 #if defined(TVMET_HAVE_LONG_DOUBLE)
00147 TVMET_DECLARE_MACRO(add, long double)
00148 TVMET_DECLARE_MACRO(sub, long double)
00149 TVMET_DECLARE_MACRO(mul, long double)
00150 TVMET_DECLARE_MACRO(div, long double)
00151 #endif
00152 
00153 #undef TVMET_DECLARE_MACRO
00154 
00155 
00156 #if defined(TVMET_HAVE_COMPLEX)
00157 /*
00158  * function(Vector<std::complex<T>, Sz>, std::complex<T>)
00159  * function(std::complex<T>, Vector<std::complex<T>, Sz>)
00160  * Note: per se element wise
00161  * \todo type promotion
00162  */
00163 #define TVMET_DECLARE_MACRO(NAME)                    \
00164 template<class T, std::size_t Sz>                    \
00165 XprVector<                                \
00166   XprBinOp<                                \
00167     Fcnl_##NAME< std::complex<T>, std::complex<T> >,            \
00168     VectorConstReference< std::complex<T>, Sz>,                \
00169     XprLiteral< std::complex<T> >                    \
00170   >,                                    \
00171   Sz                                    \
00172 >                                    \
00173 NAME (const Vector<std::complex<T>, Sz>& lhs,                \
00174       const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;        \
00175                                     \
00176 template<class T, std::size_t Sz>                    \
00177 XprVector<                                \
00178   XprBinOp<                                \
00179     Fcnl_##NAME< std::complex<T>, std::complex<T> >,            \
00180     XprLiteral< std::complex<T> >,                    \
00181     VectorConstReference< std::complex<T>, Sz>                \
00182   >,                                    \
00183   Sz                                    \
00184 >                                    \
00185 NAME (const std::complex<T>& lhs,                    \
00186       const Vector< std::complex<T>, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00187 
00188 TVMET_DECLARE_MACRO(add)
00189 TVMET_DECLARE_MACRO(sub)
00190 TVMET_DECLARE_MACRO(mul)
00191 TVMET_DECLARE_MACRO(div)
00192 
00193 #undef TVMET_DECLARE_MACRO
00194 
00195 #endif // defined(TVMET_HAVE_COMPLEX)
00196 
00197 
00198 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00199  * vector specific functions
00200  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00201 
00202 
00203 template<class T, std::size_t Sz>
00204 typename NumericTraits<T>::sum_type
00205 sum(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00206 
00207 
00208 template<class T, std::size_t Sz>
00209 typename NumericTraits<T>::sum_type
00210 product(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00211 
00212 
00213 template<class T1, class T2, std::size_t Sz>
00214 typename PromoteTraits<T1, T2>::value_type
00215 dot(const Vector<T1, Sz>& lhs,
00216     const Vector<T2, Sz>& rhs) TVMET_CXX_ALWAYS_INLINE;
00217 
00218 
00219 template<class T1, class T2>
00220 Vector<typename PromoteTraits<T1, T2>::value_type, 3>
00221 cross(const Vector<T1, 3>& lhs,
00222       const Vector<T2, 3>& rhs) TVMET_CXX_ALWAYS_INLINE;
00223 
00224 
00225 template<class T, std::size_t Sz>
00226 typename NumericTraits<T>::sum_type
00227 norm1(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00228 
00229 
00230 template<class T, std::size_t Sz>
00231 typename NumericTraits<T>::sum_type
00232 norm2(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00233 
00234 
00235 template<class T, std::size_t Sz>
00236 XprVector<
00237   XprBinOp<
00238     Fcnl_div<T, T>,
00239     VectorConstReference<T, Sz>,
00240     XprLiteral< T >
00241   >,
00242   Sz
00243 >
00244 normalize(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00245 
00246 
00247 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00248  * min/max unary functions
00249  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00250 
00251 template<class E, std::size_t Sz>
00252 Extremum<typename E::value_type, std::size_t, vector_tag>
00253 maximum(const XprVector<E, Sz>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
00254 
00255 
00256 template<class T, std::size_t Sz>
00257 Extremum<T, std::size_t, vector_tag>
00258 maximum(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00259 
00260 
00261 template<class E, std::size_t Sz>
00262 Extremum<typename E::value_type, std::size_t, vector_tag>
00263 minimum(const XprVector<E, Sz>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
00264 
00265 
00266 template<class T, std::size_t Sz>
00267 Extremum<T, std::size_t, vector_tag>
00268 minimum(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00269 
00270 
00271 template<class E, std::size_t Sz>
00272 typename E::value_type
00273 max(const XprVector<E, Sz>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
00274 
00275 
00276 template<class T, std::size_t Sz>
00277 T max(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00278 
00279 
00280 template<class E, std::size_t Sz>
00281 typename E::value_type
00282 min(const XprVector<E, Sz>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
00283 
00284 
00285 template<class T, std::size_t Sz>
00286 T min(const Vector<T, Sz>& v) TVMET_CXX_ALWAYS_INLINE;
00287 
00288 
00289 template<class T, std::size_t Sz>
00290 XprVector<
00291   VectorConstReference<T, Sz>,
00292   Sz
00293 >
00294 cvector_ref(const T* mem) TVMET_CXX_ALWAYS_INLINE;
00295 
00296 
00297 /*********************************************************
00298  * PART II: IMPLEMENTATION
00299  *********************************************************/
00300 
00301 
00302 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00303  * Vector arithmetic functions add, sub, mul and div
00304  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00305 
00306 
00307 /*
00308  * function(Vector<T1, Sz>, Vector<T2, Sz>)
00309  * function(Vector<T, Sz>, XprVector<E, Sz>)
00310  * function(XprVector<E, Sz>, Vector<T, Sz>)
00311  */
00312 #define TVMET_IMPLEMENT_MACRO(NAME)                    \
00313 template<class T1, class T2, std::size_t Sz>                \
00314 inline                                    \
00315 XprVector<                                \
00316   XprBinOp<                                \
00317     Fcnl_##NAME<T1, T2>,                        \
00318     VectorConstReference<T1, Sz>,                    \
00319     VectorConstReference<T2, Sz>                    \
00320   >,                                    \
00321   Sz                                    \
00322 >                                    \
00323 NAME (const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) {        \
00324   typedef XprBinOp <                            \
00325     Fcnl_##NAME<T1, T2>,                        \
00326     VectorConstReference<T1, Sz>,                    \
00327     VectorConstReference<T2, Sz>                    \
00328   >                            expr_type;    \
00329   return XprVector<expr_type, Sz>(                    \
00330     expr_type(lhs.const_ref(), rhs.const_ref()));            \
00331 }                                    \
00332                                     \
00333 template<class E, class T, std::size_t Sz>                \
00334 inline                                    \
00335 XprVector<                                \
00336   XprBinOp<                                \
00337     Fcnl_##NAME<typename E::value_type, T>,                \
00338     XprVector<E, Sz>,                            \
00339     VectorConstReference<T, Sz>                        \
00340   >,                                    \
00341   Sz                                    \
00342 >                                    \
00343 NAME (const XprVector<E, Sz>& lhs, const Vector<T, Sz>& rhs) {        \
00344   typedef XprBinOp<                            \
00345      Fcnl_##NAME<typename E::value_type, T>,                \
00346     XprVector<E, Sz>,                            \
00347     VectorConstReference<T, Sz>                        \
00348   >                              expr_type;    \
00349   return XprVector<expr_type, Sz>(                    \
00350     expr_type(lhs, rhs.const_ref()));                    \
00351 }                                    \
00352                                     \
00353 template<class E, class T, std::size_t Sz>                \
00354 inline                                    \
00355 XprVector<                                \
00356   XprBinOp<                                \
00357     Fcnl_##NAME<T, typename E::value_type>,                \
00358     VectorConstReference<T, Sz>,                    \
00359     XprVector<E, Sz>                            \
00360   >,                                    \
00361   Sz                                    \
00362 >                                    \
00363 NAME (const Vector<T, Sz>& lhs, const XprVector<E, Sz>& rhs) {        \
00364   typedef XprBinOp<                            \
00365     Fcnl_##NAME<T, typename E::value_type>,                \
00366     VectorConstReference<T, Sz>,                    \
00367     XprVector<E, Sz>                            \
00368   >                              expr_type;    \
00369   return XprVector<expr_type, Sz>(                    \
00370     expr_type(lhs.const_ref(), rhs));                    \
00371 }
00372 
00373 TVMET_IMPLEMENT_MACRO(add)        // per se element wise
00374 TVMET_IMPLEMENT_MACRO(sub)        // per se element wise
00375 TVMET_IMPLEMENT_MACRO(mul)        // per se element wise
00376 namespace element_wise {
00377   TVMET_IMPLEMENT_MACRO(div)        // not defined for vectors
00378 }
00379 
00380 #undef TVMET_IMPLEMENT_MACRO
00381 
00382 
00383 /*
00384  * function(Vector<T, Sz>, POD)
00385  * function(POD, Vector<T, Sz>)
00386  * Note: - operations +,-,*,/ are per se element wise
00387  */
00388 #define TVMET_IMPLEMENT_MACRO(NAME, POD)                \
00389 template<class T, std::size_t Sz>                    \
00390 inline                                    \
00391 XprVector<                                \
00392   XprBinOp<                                \
00393     Fcnl_##NAME< T, POD >,                        \
00394     VectorConstReference<T, Sz>,                    \
00395     XprLiteral< POD >                            \
00396   >,                                    \
00397   Sz                                    \
00398 >                                    \
00399 NAME (const Vector<T, Sz>& lhs, POD rhs) {                \
00400   typedef XprBinOp<                            \
00401     Fcnl_##NAME<T, POD >,                        \
00402     VectorConstReference<T, Sz>,                    \
00403     XprLiteral< POD >                            \
00404   >                            expr_type;    \
00405   return XprVector<expr_type, Sz>(                    \
00406     expr_type(lhs.const_ref(), XprLiteral< POD >(rhs)));        \
00407 }                                    \
00408                                     \
00409 template<class T, std::size_t Sz>                    \
00410 inline                                    \
00411 XprVector<                                \
00412   XprBinOp<                                \
00413     Fcnl_##NAME< POD, T>,                        \
00414     XprLiteral< POD >,                            \
00415     VectorConstReference<T, Sz>                        \
00416   >,                                    \
00417   Sz                                    \
00418 >                                    \
00419 NAME (POD lhs, const Vector<T, Sz>& rhs) {                \
00420   typedef XprBinOp<                            \
00421     Fcnl_##NAME< POD, T>,                        \
00422     XprLiteral< POD >,                            \
00423     VectorConstReference<T, Sz>                        \
00424   >                            expr_type;    \
00425   return XprVector<expr_type, Sz>(                    \
00426     expr_type(XprLiteral< POD >(lhs), rhs.const_ref()));        \
00427 }
00428 
00429 TVMET_IMPLEMENT_MACRO(add, int)
00430 TVMET_IMPLEMENT_MACRO(sub, int)
00431 TVMET_IMPLEMENT_MACRO(mul, int)
00432 TVMET_IMPLEMENT_MACRO(div, int)
00433 
00434 #if defined(TVMET_HAVE_LONG_LONG)
00435 TVMET_IMPLEMENT_MACRO(add, long long int)
00436 TVMET_IMPLEMENT_MACRO(sub, long long int)
00437 TVMET_IMPLEMENT_MACRO(mul, long long int)
00438 TVMET_IMPLEMENT_MACRO(div, long long int)
00439 #endif
00440 
00441 TVMET_IMPLEMENT_MACRO(add, float)
00442 TVMET_IMPLEMENT_MACRO(sub, float)
00443 TVMET_IMPLEMENT_MACRO(mul, float)
00444 TVMET_IMPLEMENT_MACRO(div, float)
00445 
00446 TVMET_IMPLEMENT_MACRO(add, double)
00447 TVMET_IMPLEMENT_MACRO(sub, double)
00448 TVMET_IMPLEMENT_MACRO(mul, double)
00449 TVMET_IMPLEMENT_MACRO(div, double)
00450 
00451 #if defined(TVMET_HAVE_LONG_DOUBLE)
00452 TVMET_IMPLEMENT_MACRO(add, long double)
00453 TVMET_IMPLEMENT_MACRO(sub, long double)
00454 TVMET_IMPLEMENT_MACRO(mul, long double)
00455 TVMET_IMPLEMENT_MACRO(div, long double)
00456 #endif
00457 
00458 #undef TVMET_IMPLEMENT_MACRO
00459 
00460 
00461 #if defined(TVMET_HAVE_COMPLEX)
00462 /*
00463  * function(Vector<std::complex<T>, Sz>, std::complex<T>)
00464  * function(std::complex<T>, Vector<std::complex<T>, Sz>)
00465  * Note: per se element wise
00466  * \todo type promotion
00467  */
00468 #define TVMET_IMPLEMENT_MACRO(NAME)                        \
00469 template<class T, std::size_t Sz>                        \
00470 inline                                        \
00471 XprVector<                                    \
00472   XprBinOp<                                    \
00473     Fcnl_##NAME< std::complex<T>, std::complex<T> >,                \
00474     VectorConstReference< std::complex<T>, Sz>,                    \
00475     XprLiteral< std::complex<T> >                        \
00476   >,                                        \
00477   Sz                                        \
00478 >                                        \
00479 NAME (const Vector<std::complex<T>, Sz>& lhs, const std::complex<T>& rhs) {    \
00480   typedef XprBinOp<                                \
00481     Fcnl_##NAME< std::complex<T>, std::complex<T> >,                \
00482     VectorConstReference< std::complex<T>, Sz>,                    \
00483     XprLiteral< std::complex<T> >                        \
00484   >                            expr_type;        \
00485   return XprVector<expr_type, Sz>(                        \
00486     expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));        \
00487 }                                        \
00488                                         \
00489 template<class T, std::size_t Sz>                        \
00490 inline                                        \
00491 XprVector<                                    \
00492   XprBinOp<                                    \
00493     Fcnl_##NAME< std::complex<T>, std::complex<T> >,                \
00494     XprLiteral< std::complex<T> >,                        \
00495     VectorConstReference< std::complex<T>, Sz>                    \
00496   >,                                        \
00497   Sz                                        \
00498 >                                        \
00499 NAME (const std::complex<T>& lhs, const Vector< std::complex<T>, Sz>& rhs) {    \
00500   typedef XprBinOp<                                \
00501     Fcnl_##NAME< std::complex<T>, std::complex<T> >,                \
00502     XprLiteral< std::complex<T> >,                        \
00503     VectorConstReference< std::complex<T>, Sz>                    \
00504   >                            expr_type;        \
00505   return XprVector<expr_type, Sz>(                        \
00506     expr_type(XprLiteral< std::complex<T> >(lhs), rhs.const_ref()));        \
00507 }
00508 
00509 TVMET_IMPLEMENT_MACRO(add)
00510 TVMET_IMPLEMENT_MACRO(sub)
00511 TVMET_IMPLEMENT_MACRO(mul)
00512 TVMET_IMPLEMENT_MACRO(div)
00513 
00514 #undef TVMET_IMPLEMENT_MACRO
00515 
00516 #endif // defined(TVMET_HAVE_COMPLEX)
00517 
00518 
00519 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00520  * vector specific functions
00521  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00522 
00523 
00524 /**
00525  * \fn sum(const Vector<T, Sz>& v)
00526  * \brief Compute the sum of the vector.
00527  * \ingroup _unary_function
00528  *
00529  * Simply compute the sum of the given vector as:
00530  * \f[
00531  * \sum_{i = 0}^{Sz-1} v[i]
00532  * \f]
00533  */
00534 template<class T, std::size_t Sz>
00535 inline
00536 typename NumericTraits<T>::sum_type
00537 sum(const Vector<T, Sz>& v) {
00538   return meta::Vector<Sz>::sum(v);
00539 }
00540 
00541 
00542 /**
00543  * \fn product(const Vector<T, Sz>& v)
00544  * \brief Compute the product of the vector elements.
00545  * \ingroup _unary_function
00546  *
00547  * Simply computer the product of the given vector as:
00548  * \f[
00549  * \prod_{i = 0}^{Sz - 1} v[i]
00550  * \f]
00551  */
00552 template<class T, std::size_t Sz>
00553 inline
00554 typename NumericTraits<T>::sum_type
00555 product(const Vector<T, Sz>& v) {
00556   return meta::Vector<Sz>::product(v);
00557 }
00558 
00559 
00560 /**
00561  * \fn dot(const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs)
00562  * \brief Compute the dot/inner product
00563  * \ingroup _binary_function
00564  *
00565  * Compute the dot product as:
00566  * \f[
00567  * \sum_{i = 0}^{Sz - 1} ( lhs[i] * rhs[i] )
00568  * \f]
00569  * where lhs is a column vector and rhs is a row vector, both vectors
00570  * have the same dimension.
00571  */
00572 template<class T1, class T2, std::size_t Sz>
00573 inline
00574 typename PromoteTraits<T1, T2>::value_type
00575 dot(const Vector<T1, Sz>& lhs, const Vector<T2, Sz>& rhs) {
00576   return meta::Vector<Sz>::dot(lhs, rhs);
00577 }
00578 
00579 
00580 /**
00581  * \fn cross(const Vector<T1, 3>& lhs, const Vector<T2, 3>& rhs)
00582  * \brief Compute the cross/outer product
00583  * \ingroup _binary_function
00584  * \note working only for vectors of size = 3
00585  * \todo Implement vector outer product as ET and MT, returning a XprVector
00586  */
00587 template<class T1, class T2>
00588 inline
00589 Vector<typename PromoteTraits<T1, T2>::value_type, 3>
00590 cross(const Vector<T1, 3>& lhs, const Vector<T2, 3>& rhs) {
00591   typedef typename PromoteTraits<T1, T2>::value_type    value_type;
00592   return Vector<value_type, 3>(lhs(1)*rhs(2) - rhs(1)*lhs(2),
00593                    rhs(0)*lhs(2) - lhs(0)*rhs(2),
00594                    lhs(0)*rhs(1) - rhs(0)*lhs(1));
00595 }
00596 
00597 
00598 /**
00599  * \fn norm1(const Vector<T, Sz>& v)
00600  * \brief The \f$l_1\f$ norm of a vector v.
00601  * \ingroup _unary_function
00602  * The norm of any vector is just the square root of the dot product of
00603  * a vector with itself, or
00604  *
00605  * \f[
00606  * |Vector<T, Sz> v| = |v| = \sum_{i=0}^{Sz-1}\,|v[i]|
00607  * \f]
00608  */
00609 template<class T, std::size_t Sz>
00610 inline
00611 typename NumericTraits<T>::sum_type
00612 norm1(const Vector<T, Sz>& v) {
00613   return sum(abs(v));
00614 }
00615 
00616 
00617 /**
00618  * \fn norm2(const Vector<T, Sz>& v)
00619  * \brief The euklidian norm (or \f$l_2\f$ norm) of a vector v.
00620  * \ingroup _unary_function
00621  * The norm of any vector is just the square root of the dot product of
00622  * a vector with itself, or
00623  *
00624  * \f[
00625  * |Vector<T, Sz> v| = |v| = \sqrt{ \sum_{i=0}^{Sz-1}\,v[i]^2 }
00626  * \f]
00627  *
00628  * \note The internal cast for Vector<int> avoids warnings on sqrt.
00629  */
00630 template<class T, std::size_t Sz>
00631 inline
00632 typename NumericTraits<T>::sum_type
00633 norm2(const Vector<T, Sz>& v) {
00634   return static_cast<T>( std::sqrt(static_cast<typename NumericTraits<T>::float_type>(dot(v, v))) );
00635 }
00636 
00637 
00638 /**
00639  * \fn normalize(const Vector<T, Sz>& v)
00640  * \brief Normalize the given vector.
00641  * \ingroup _unary_function
00642  * \sa norm2
00643  *
00644  * using the equation:
00645  * \f[
00646  * \frac{Vector<T, Sz> v}{\sqrt{ \sum_{i=0}^{Sz-1}\,v[i]^2 }}
00647  * \f]
00648  */
00649 template<class T, std::size_t Sz>
00650 inline
00651 XprVector<
00652   XprBinOp<
00653     Fcnl_div<T, T>,
00654     VectorConstReference<T, Sz>,
00655     XprLiteral< T >
00656   >,
00657   Sz
00658 >
00659 normalize(const Vector<T, Sz>& v) {
00660   typedef XprBinOp<
00661     Fcnl_div<T, T>,
00662     VectorConstReference<T, Sz>,
00663     XprLiteral< T >
00664   >                            expr_type;
00665   return XprVector<expr_type, Sz>(
00666     expr_type(v.const_ref(), XprLiteral< T >(norm2(v))));
00667 }
00668 
00669 
00670 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00671  * min/max unary functions
00672  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00673 
00674 
00675 /**
00676  * \fn maximum(const XprVector<E, Sz>& e)
00677  * \brief Find the maximum of a vector expression
00678  * \ingroup _unary_function
00679  */
00680 template<class E, std::size_t Sz>
00681 inline
00682 Extremum<typename E::value_type, std::size_t, vector_tag>
00683 maximum(const XprVector<E, Sz>& e) {
00684   typedef typename E::value_type             value_type;
00685 
00686   value_type                         m_max(e(0));
00687   std::size_t                         m_idx(0);
00688 
00689   // this loop is faster than meta templates!
00690   for(std::size_t i = 1; i != Sz; ++i) {
00691     if(e(i) > m_max) {
00692       m_max = e(i);
00693       m_idx = i;
00694     }
00695   }
00696 
00697   return Extremum<value_type, std::size_t, vector_tag>(m_max, m_idx);
00698 }
00699 
00700 
00701 /**
00702  * \fn maximum(const Vector<T, Sz>& v)
00703  * \brief Find the maximum of a vector
00704  * \ingroup _unary_function
00705  */
00706 template<class T, std::size_t Sz>
00707 inline
00708 Extremum<T, std::size_t, vector_tag>
00709 maximum(const Vector<T, Sz>& v) { return maximum(v.as_expr()); }
00710 
00711 
00712 /**
00713  * \fn minimum(const XprVector<E, Sz>& e)
00714  * \brief Find the minimum of a vector expression
00715  * \ingroup _unary_function
00716  */
00717 template<class E, std::size_t Sz>
00718 inline
00719 Extremum<typename E::value_type, std::size_t, vector_tag>
00720 minimum(const XprVector<E, Sz>& e) {
00721   typedef typename E::value_type             value_type;
00722 
00723   value_type                         m_min(e(0));
00724   std::size_t                         m_idx(0);
00725 
00726   // this loop is faster than meta templates!
00727   for(std::size_t i = 1; i != Sz; ++i) {
00728     if(e(i) < m_min) {
00729       m_min = e(i);
00730       m_idx = i;
00731     }
00732   }
00733 
00734   return Extremum<value_type, std::size_t, vector_tag>(m_min, m_idx);
00735 }
00736 
00737 
00738 /**
00739  * \fn minimum(const Vector<T, Sz>& v)
00740  * \brief Find the minimum of a vector
00741  * \ingroup _unary_function
00742  */
00743 template<class T, std::size_t Sz>
00744 inline
00745 Extremum<T, std::size_t, vector_tag>
00746 minimum(const Vector<T, Sz>& v) { return minimum(v.as_expr()); }
00747 
00748 
00749 /**
00750  * \fn max(const XprVector<E, Sz>& e)
00751  * \brief Find the maximum of a vector expression
00752  * \ingroup _unary_function
00753  */
00754 template<class E, std::size_t Sz>
00755 inline
00756 typename E::value_type
00757 max(const XprVector<E, Sz>& e) {
00758   typedef typename E::value_type             value_type;
00759 
00760   value_type                         m_max(e(0));
00761 
00762   // this loop is faster than meta templates!
00763   for(std::size_t i = 1; i != Sz; ++i)
00764     if(e(i) > m_max)
00765       m_max = e(i);
00766 
00767   return m_max;
00768 }
00769 
00770 
00771 /**
00772  * \fn max(const Vector<T, Sz>& v)
00773  * \brief Find the maximum of a vector
00774  * \ingroup _unary_function
00775  */
00776 template<class T, std::size_t Sz>
00777 inline
00778 T max(const Vector<T, Sz>& v) {
00779   typedef T                         value_type;
00780   typedef typename Vector<T, Sz>::const_iterator    const_iterator;
00781 
00782   const_iterator                    iter(v.begin());
00783   const_iterator                    last(v.end());
00784   value_type                         temp(*iter);
00785 
00786   for( ; iter != last; ++iter)
00787     if(*iter > temp)
00788       temp = *iter;
00789 
00790   return temp;
00791 }
00792 
00793 
00794 /**
00795  * \fn min(const XprVector<E, Sz>& e)
00796  * \brief Find the minimum of a vector expression
00797  * \ingroup _unary_function
00798  */
00799 template<class E, std::size_t Sz>
00800 inline
00801 typename E::value_type
00802 min(const XprVector<E, Sz>& e) {
00803   typedef typename E::value_type             value_type;
00804 
00805   value_type                         m_min(e(0));
00806 
00807   // this loop is faster than meta templates!
00808   for(std::size_t i = 1; i != Sz; ++i)
00809     if(e(i) < m_min)
00810       m_min = e(i);
00811 
00812   return m_min;
00813 }
00814 
00815 
00816 /**
00817  * \fn min(const Vector<T, Sz>& v)
00818  * \brief Find the minimum of a vector
00819  * \ingroup _unary_function
00820  */
00821 template<class T, std::size_t Sz>
00822 inline
00823 T min(const Vector<T, Sz>& v) {
00824   typedef T                         value_type;
00825   typedef typename Vector<T, Sz>::const_iterator    const_iterator;
00826 
00827   const_iterator                    iter(v.begin());
00828   const_iterator                    last(v.end());
00829   value_type                         temp(*iter);
00830 
00831   for( ; iter != last; ++iter)
00832     if(*iter < temp)
00833       temp = *iter;
00834 
00835   return temp;
00836 }
00837 
00838 
00839 /**
00840  * \fn cvector_ref(const T* mem)
00841  * \brief Creates an expression wrapper for a C like vector arrays.
00842  * \ingroup _unary_function
00843  *
00844  * This is like creating a vector of external data, as described
00845  * at \ref construct. With this function you wrap an expression
00846  * around a C style vector array and you can operate directly with it
00847  * as usual.
00848  *
00849  * \par Example:
00850  * \code
00851  * static float vertices[N][3] = {
00852  *   {-1,  0,  1}, { 1,  0,  1}, ...
00853  * };
00854  * ...
00855  * typedef Vector<float, 3>            vector_type;
00856  * ...
00857  * vector_type V( cross(cvector_ref<float, 3>(&vertices[0][0]),
00858  *                      cvector_ref<float, 3>(&vertices[1][0])) );
00859  * \endcode
00860  *
00861  * \since release 1.6.0
00862  */
00863 template<class T, std::size_t Sz>
00864 inline
00865 XprVector<
00866   VectorConstReference<T, Sz>,
00867   Sz
00868 >
00869 cvector_ref(const T* mem) {
00870   typedef VectorConstReference<T, Sz>        expr_type;
00871 
00872   return XprVector<expr_type, Sz>(expr_type(mem));
00873 }
00874 
00875 
00876 } // namespace tvmet
00877 
00878 #endif // TVMET_VECTOR_FUNCTIONS_H
00879 
00880 // Local Variables:
00881 // mode:C++
00882 // tab-width:8
00883 // End: