2014 Eurobot fork
Dependencies: mbed-rtos mbed QEI
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:
Generated on Wed Jul 13 2022 18:42:00 by 1.7.2