Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Eurobot_2012_Secondary by
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 Tue Jul 12 2022 21:02:14 by
1.7.2
