SourceForge Logo Tiny Vector Matrix library using Expression Templates Sourceforge Project Page

include/tvmet/VectorFunctions.h

Go to the documentation of this file.
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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:

Author: