[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]
00001 /************************************************************************/ 00002 /* */ 00003 /* Copyright 1998-2002 by Ullrich Koethe */ 00004 /* Cognitive Systems Group, University of Hamburg, Germany */ 00005 /* */ 00006 /* This file is part of the VIGRA computer vision library. */ 00007 /* ( Version 1.6.0, Aug 13 2008 ) */ 00008 /* The VIGRA Website is */ 00009 /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ 00010 /* Please direct questions, bug reports, and contributions to */ 00011 /* ullrich.koethe@iwr.uni-heidelberg.de or */ 00012 /* vigra@informatik.uni-hamburg.de */ 00013 /* */ 00014 /* Permission is hereby granted, free of charge, to any person */ 00015 /* obtaining a copy of this software and associated documentation */ 00016 /* files (the "Software"), to deal in the Software without */ 00017 /* restriction, including without limitation the rights to use, */ 00018 /* copy, modify, merge, publish, distribute, sublicense, and/or */ 00019 /* sell copies of the Software, and to permit persons to whom the */ 00020 /* Software is furnished to do so, subject to the following */ 00021 /* conditions: */ 00022 /* */ 00023 /* The above copyright notice and this permission notice shall be */ 00024 /* included in all copies or substantial portions of the */ 00025 /* Software. */ 00026 /* */ 00027 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ 00028 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ 00029 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ 00030 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ 00031 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ 00032 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ 00033 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ 00034 /* OTHER DEALINGS IN THE SOFTWARE. */ 00035 /* */ 00036 /************************************************************************/ 00037 00038 00039 #ifndef VIGRA_TINYVECTOR_HXX 00040 #define VIGRA_TINYVECTOR_HXX 00041 00042 #include <cmath> // abs(double) 00043 #include <cstdlib> // abs(int) 00044 #include <iosfwd> // ostream 00045 #include "config.hxx" 00046 #include "error.hxx" 00047 #include "numerictraits.hxx" 00048 #include "mathutil.hxx" 00049 00050 namespace vigra { 00051 00052 using VIGRA_CSTD::abs; 00053 using VIGRA_CSTD::ceil; 00054 using VIGRA_CSTD::floor; 00055 00056 00057 template <class V1, int SIZE, class D1, class D2> 00058 class TinyVectorBase; 00059 00060 template <class V1, int SIZE, class D1, class D2> 00061 inline 00062 typename TinyVectorBase<V1, SIZE, D1, D2>::SquaredNormType 00063 squaredNorm(TinyVectorBase<V1, SIZE, D1, D2> const & t); 00064 00065 00066 namespace detail { 00067 00068 #define VIGRA_EXEC_LOOP(NAME, OPER) \ 00069 template <class T1, class T2> \ 00070 static void NAME(T1 * left, T2 const * right) \ 00071 { \ 00072 for(int i=0; i<LEVEL; ++i) \ 00073 (left[i]) OPER (right[i]); \ 00074 } 00075 00076 #define VIGRA_EXEC_LOOP_SCALAR(NAME, OPER) \ 00077 template <class T1, class T2> \ 00078 static void NAME(T1 * left, T2 right) \ 00079 { \ 00080 for(int i=0; i<LEVEL; ++i) \ 00081 (left[i]) OPER (right); \ 00082 } 00083 00084 template <int LEVEL> 00085 struct ExecLoop 00086 { 00087 template <class T1, class T2> 00088 static void assignCast(T1 * left, T2 const * right) 00089 { 00090 for(int i=0; i<LEVEL; ++i) 00091 left[i] = detail::RequiresExplicitCast<T1>::cast(right[i]); 00092 } 00093 00094 VIGRA_EXEC_LOOP(assign, =) 00095 VIGRA_EXEC_LOOP(add, +=) 00096 VIGRA_EXEC_LOOP(sub, -=) 00097 VIGRA_EXEC_LOOP(mul, *=) 00098 VIGRA_EXEC_LOOP(neg, = -) 00099 VIGRA_EXEC_LOOP(abs, = vigra::abs) 00100 VIGRA_EXEC_LOOP(floor, = vigra::floor) 00101 VIGRA_EXEC_LOOP(ceil, = vigra::ceil) 00102 VIGRA_EXEC_LOOP(fromPromote, = NumericTraits<T1>::fromPromote) 00103 VIGRA_EXEC_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote) 00104 VIGRA_EXEC_LOOP_SCALAR(assignScalar, =) 00105 VIGRA_EXEC_LOOP_SCALAR(mulScalar, *=) 00106 VIGRA_EXEC_LOOP_SCALAR(divScalar, /=) 00107 00108 template <class T1, class T2> 00109 static bool notEqual(T1 const * left, T2 const * right) 00110 { 00111 for(int i=0; i<LEVEL; ++i) 00112 if(left[i] != right[i]) 00113 return true; 00114 return false; 00115 } 00116 00117 template <class T> 00118 static typename NumericTraits<T>::Promote 00119 dot(T const * d) 00120 { 00121 typename NumericTraits<T>::Promote res(*d * *d); 00122 for(int i=1; i<LEVEL; ++i) 00123 res += d[i] * d[i]; 00124 return res; 00125 } 00126 00127 template <class T1, class T2> 00128 static typename PromoteTraits<T1, T2>::Promote 00129 dot(T1 const * left, T2 const * right) 00130 { 00131 typename PromoteTraits<T1, T2>::Promote res(*left * *right); 00132 for(int i=1; i<LEVEL; ++i) 00133 res += left[i] * right[i]; 00134 return res; 00135 } 00136 00137 template <class T> 00138 static typename NormTraits<T>::SquaredNormType 00139 squaredNorm(T const * d) 00140 { 00141 typename NormTraits<T>::SquaredNormType res = vigra::squaredNorm(*d); 00142 for(int i=1; i<LEVEL; ++i) 00143 res += vigra::squaredNorm(d[i]); 00144 return res; 00145 } 00146 }; 00147 00148 template <int LEVEL> 00149 struct UnrollDot 00150 { 00151 template <class T> 00152 static typename NumericTraits<T>::Promote 00153 dot(T const * d) 00154 { 00155 return *d * *d + UnrollDot<LEVEL-1>::dot(d+1); 00156 } 00157 00158 template <class T1, class T2> 00159 static typename PromoteTraits<T1, T2>::Promote 00160 dot(T1 const * left, T2 const * right) 00161 { 00162 return *left * *right + UnrollDot<LEVEL-1>::dot(left+1, right+1); 00163 } 00164 }; 00165 00166 template <> 00167 struct UnrollDot<1> 00168 { 00169 template <class T> 00170 static typename NumericTraits<T>::Promote 00171 dot(T const * d) 00172 { 00173 return *d * *d ; 00174 } 00175 00176 template <class T1, class T2> 00177 static typename PromoteTraits<T1, T2>::Promote 00178 dot(T1 const * left, T2 const * right) 00179 { 00180 return *left * *right; 00181 } 00182 }; 00183 00184 template <int LEVEL> 00185 struct UnrollSquaredNorm 00186 { 00187 template <class T> 00188 static typename NormTraits<T>::SquaredNormType 00189 squaredNorm(T const * d) 00190 { 00191 return vigra::squaredNorm(*d) + UnrollSquaredNorm<LEVEL-1>::squaredNorm(d+1); 00192 } 00193 }; 00194 00195 template <> 00196 struct UnrollSquaredNorm<1> 00197 { 00198 template <class T> 00199 static typename NormTraits<T>::SquaredNormType 00200 squaredNorm(T const * d) 00201 { 00202 return vigra::squaredNorm(*d); 00203 } 00204 }; 00205 00206 #undef VIGRA_EXEC_LOOP 00207 #undef VIGRA_EXEC_LOOP_SCALAR 00208 00209 #define VIGRA_UNROLL_LOOP(NAME, OPER) \ 00210 template <class T1, class T2> \ 00211 static void NAME(T1 * left, T2 const * right) \ 00212 { \ 00213 (*left) OPER (*right); \ 00214 UnrollLoop<LEVEL-1>::NAME(left+1, right+1); \ 00215 } 00216 00217 #define VIGRA_UNROLL_LOOP_SCALAR(NAME, OPER) \ 00218 template <class T1, class T2> \ 00219 static void NAME(T1 * left, T2 right) \ 00220 { \ 00221 (*left) OPER (right); \ 00222 UnrollLoop<LEVEL-1>::NAME(left+1, right); \ 00223 } 00224 00225 00226 template <int LEVEL> 00227 struct UnrollLoop 00228 { 00229 template <class T1, class T2> 00230 static void assignCast(T1 * left, T2 const * right) 00231 { 00232 *left = detail::RequiresExplicitCast<T1>::cast(*right); 00233 UnrollLoop<LEVEL-1>::assignCast(left+1, right+1); 00234 } 00235 00236 VIGRA_UNROLL_LOOP(assign, =) 00237 VIGRA_UNROLL_LOOP(add, +=) 00238 VIGRA_UNROLL_LOOP(sub, -=) 00239 VIGRA_UNROLL_LOOP(mul, *=) 00240 VIGRA_UNROLL_LOOP(neg, = -) 00241 VIGRA_UNROLL_LOOP(abs, = vigra::abs) 00242 VIGRA_UNROLL_LOOP(floor, = vigra::floor) 00243 VIGRA_UNROLL_LOOP(ceil, = vigra::ceil) 00244 VIGRA_UNROLL_LOOP(fromPromote, = NumericTraits<T1>::fromPromote) 00245 VIGRA_UNROLL_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote) 00246 VIGRA_UNROLL_LOOP_SCALAR(assignScalar, =) 00247 VIGRA_UNROLL_LOOP_SCALAR(mulScalar, *=) 00248 VIGRA_UNROLL_LOOP_SCALAR(divScalar, /=) 00249 00250 template <class T1, class T2> 00251 static bool notEqual(T1 const * left, T2 const * right) 00252 { 00253 return (*left != *right) || UnrollLoop<LEVEL - 1>::notEqual(left+1, right+1); 00254 } 00255 00256 template <class T> 00257 static typename NumericTraits<T>::Promote 00258 dot(T const * d) 00259 { 00260 return UnrollDot<LEVEL>::dot(d); 00261 } 00262 00263 template <class T1, class T2> 00264 static typename PromoteTraits<T1, T2>::Promote 00265 dot(T1 const * left, T2 const * right) 00266 { 00267 return UnrollDot<LEVEL>::dot(left, right); 00268 } 00269 00270 template <class T> 00271 static typename NormTraits<T>::SquaredNormType 00272 squaredNorm(T const * d) 00273 { 00274 return UnrollSquaredNorm<LEVEL>::squaredNorm(d); 00275 } 00276 }; 00277 00278 #undef VIGRA_UNROLL_LOOP 00279 #undef VIGRA_UNROLL_LOOP_SCALAR 00280 00281 template <> 00282 struct UnrollLoop<0> 00283 { 00284 template <class T1, class T2> 00285 static void assignCast(T1, T2) {} 00286 template <class T1, class T2> 00287 static void assign(T1, T2) {} 00288 template <class T1, class T2> 00289 static void assignScalar(T1, T2) {} 00290 template <class T1, class T2> 00291 static void add(T1, T2) {} 00292 template <class T1, class T2> 00293 static void sub(T1, T2) {} 00294 template <class T1, class T2> 00295 static void mul(T1, T2) {} 00296 template <class T1, class T2> 00297 static void mulScalar(T1, T2) {} 00298 template <class T1, class T2> 00299 static void div(T1, T2) {} 00300 template <class T1, class T2> 00301 static void divScalar(T1, T2) {} 00302 template <class T1, class T2> 00303 static void fromPromote(T1, T2) {} 00304 template <class T1, class T2> 00305 static void fromRealPromote(T1, T2) {} 00306 template <class T1, class T2> 00307 static void neg(T1, T2) {} 00308 template <class T1, class T2> 00309 static void abs(T1, T2) {} 00310 template <class T1, class T2> 00311 static void floor(T1, T2) {} 00312 template <class T1, class T2> 00313 static void ceil(T1, T2) {} 00314 template <class T1, class T2> 00315 static bool notEqual(T1, T2) { return false; } 00316 }; 00317 00318 template <bool PREDICATE> 00319 struct TinyVectorIf 00320 { 00321 template <class T, class F> 00322 struct res 00323 { 00324 typedef T type; 00325 }; 00326 }; 00327 00328 template <> 00329 struct TinyVectorIf<false> 00330 { 00331 template <class T, class F> 00332 struct res 00333 { 00334 typedef F type; 00335 }; 00336 }; 00337 00338 template <int SIZE> 00339 struct LoopType 00340 { 00341 typedef typename TinyVectorIf<SIZE < 5>:: 00342 template res<UnrollLoop<SIZE>, ExecLoop<SIZE> >::type type; 00343 }; 00344 00345 struct DontInit {}; 00346 00347 inline DontInit dontInit() {return DontInit(); } 00348 00349 } // namespace detail 00350 00351 template <class T, int SIZE> 00352 class TinyVector; 00353 00354 template <class T, int SIZE> 00355 class TinyVectorView; 00356 00357 /********************************************************/ 00358 /* */ 00359 /* TinyVectorBase */ 00360 /* */ 00361 /********************************************************/ 00362 00363 /** \brief Base class for fixed size vectors. 00364 00365 This class contains functionality shared by 00366 \ref TinyVector and \ref TinyVectorView, and enables these classes 00367 to be freely mixed within expressions. It is typically not used directly. 00368 00369 <b>\#include</b> <<a href="tinyvector_8hxx-source.html">vigra/tinyvector.hxx</a>><br> 00370 Namespace: vigra 00371 **/ 00372 template <class VALUETYPE, int SIZE, class DATA, class DERIVED> 00373 class TinyVectorBase 00374 { 00375 TinyVectorBase(TinyVectorBase const &); // do not use 00376 00377 TinyVectorBase & operator=(TinyVectorBase const & other); // do not use 00378 00379 protected: 00380 00381 typedef typename detail::LoopType<SIZE>::type Loop; 00382 00383 TinyVectorBase() 00384 {} 00385 00386 public: 00387 /** STL-compatible definition of valuetype 00388 */ 00389 typedef VALUETYPE value_type; 00390 00391 /** reference (return of operator[]). 00392 */ 00393 typedef VALUETYPE & reference; 00394 00395 /** const reference (return of operator[] const). 00396 */ 00397 typedef VALUETYPE const & const_reference; 00398 00399 /** pointer (return of operator->). 00400 */ 00401 typedef VALUETYPE * pointer; 00402 00403 /** const pointer (return of operator-> const). 00404 */ 00405 typedef VALUETYPE const * const_pointer; 00406 00407 /** STL-compatible definition of iterator 00408 */ 00409 typedef value_type * iterator; 00410 00411 /** STL-compatible definition of const iterator 00412 */ 00413 typedef value_type const * const_iterator; 00414 00415 /** STL-compatible definition of size_type 00416 */ 00417 typedef unsigned int size_type; 00418 00419 /** STL-compatible definition of difference_type 00420 */ 00421 typedef int difference_type; 00422 00423 /** the scalar type for the outer product 00424 */ 00425 typedef double scalar_multiplier; 00426 00427 /** the vector's squared norm type 00428 */ 00429 typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType; 00430 00431 /** the vector's norm type 00432 */ 00433 typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType; 00434 00435 /** the vector's size 00436 */ 00437 enum { static_size = SIZE }; 00438 00439 /** Initialize from another sequence (must have length SIZE!) 00440 */ 00441 template <class Iterator> 00442 void init(Iterator i, Iterator end) 00443 { 00444 vigra_precondition(end-i == SIZE, 00445 "TinyVector::init(): Sequence has wrong size."); 00446 Loop::assignCast(data_, i); 00447 } 00448 00449 /** Component-wise add-assignment 00450 */ 00451 template <class T1, class D1, class D2> 00452 DERIVED & operator+=(TinyVectorBase<T1, SIZE, D1, D2> const & r) 00453 { 00454 Loop::add(data_, r.begin()); 00455 return static_cast<DERIVED &>(*this); 00456 } 00457 00458 /** Component-wise subtract-assignment 00459 */ 00460 template <class T1, class D1, class D2> 00461 DERIVED & operator-=(TinyVectorBase<T1, SIZE, D1, D2> const & r) 00462 { 00463 Loop::sub(data_, r.begin()); 00464 return static_cast<DERIVED &>(*this); 00465 } 00466 00467 /** Component-wise multiply-assignment 00468 */ 00469 template <class T1, class D1, class D2> 00470 DERIVED & operator*=(TinyVectorBase<T1, SIZE, D1, D2> const & r) 00471 { 00472 Loop::mul(data_, r.begin()); 00473 return static_cast<DERIVED &>(*this); 00474 } 00475 00476 /** Component-wise scalar multiply-assignment 00477 */ 00478 DERIVED & operator*=(double r) 00479 { 00480 Loop::mulScalar(data_, r); 00481 return static_cast<DERIVED &>(*this); 00482 } 00483 00484 /** Component-wise scalar divide-assignment 00485 */ 00486 DERIVED & operator/=(double r) 00487 { 00488 Loop::divScalar(data_, r); 00489 return static_cast<DERIVED &>(*this); 00490 } 00491 00492 /** Calculate magnitude. 00493 */ 00494 NormType magnitude() const 00495 { 00496 return sqrt(static_cast<typename 00497 SquareRootTraits<SquaredNormType>::SquareRootArgument>(squaredMagnitude())); 00498 } 00499 00500 /** Calculate squared magnitude. 00501 */ 00502 SquaredNormType squaredMagnitude() const 00503 { 00504 return Loop::squaredNorm(data_); 00505 } 00506 00507 /** Access component by index. 00508 */ 00509 reference operator[](difference_type i) { return data_[i]; } 00510 00511 /** Get component by index. 00512 */ 00513 const_reference operator[](difference_type i) const { return data_[i]; } 00514 00515 /** Get random access iterator to begin of vector. 00516 */ 00517 iterator begin() { return data_; } 00518 /** Get random access iterator past-the-end of vector. 00519 */ 00520 iterator end() { return data_ + SIZE; } 00521 00522 /** Get const random access iterator to begin of vector. 00523 */ 00524 const_iterator begin() const { return data_; } 00525 00526 /** Get const random access iterator past-the-end of vector. 00527 */ 00528 const_iterator end() const { return data_ + SIZE; } 00529 00530 /** Size of TinyVector vector always equals the template parameter SIZE. 00531 */ 00532 size_type size() const { return SIZE; } 00533 00534 pointer data() { return data_; } 00535 00536 const_pointer data() const { return data_; } 00537 00538 00539 protected: 00540 DATA data_; 00541 }; 00542 00543 /** \brief Class for fixed size vectors. 00544 00545 This class contains an array of size SIZE of the specified VALUETYPE. 00546 The interface conforms to STL vector, except that there are no functions 00547 that change the size of a TinyVector. 00548 00549 \ref TinyVectorOperators "Arithmetic operations" 00550 on TinyVectors are defined as component-wise applications of these 00551 operations. Addition and subtraction of two TinyVectors 00552 (+=, -=, +, -, unary -), multiplication and division of an 00553 TinyVector with a double, and NumericTraits/PromoteTraits are defined, 00554 so that TinyVector fulfills the requirements of \ref LinearAlgebraConcept "Linear Algebra". 00555 00556 VIGRA algorithms typically use \ref vigra::VectorAccessor to access 00557 TinyVectors as a whole, or specific components of them. 00558 00559 See also:<br> 00560 <UL style="list-style-image:url(documents/bullet.gif)"> 00561 <LI> \ref vigra::TinyVectorBase 00562 <LI> \ref vigra::TinyVectorView 00563 <LI> \ref TinyVectorTraits 00564 <LI> \ref TinyVectorOperators 00565 </UL> 00566 00567 <b>\#include</b> <<a href="tinyvector_8hxx-source.html">vigra/tinyvector.hxx</a>><br> 00568 Namespace: vigra 00569 **/ 00570 template <class T, int SIZE> 00571 class TinyVector 00572 : public TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> > 00573 { 00574 typedef TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> > BaseType; 00575 typedef typename BaseType::Loop Loop; 00576 00577 public: 00578 00579 typedef typename BaseType::value_type value_type; 00580 typedef typename BaseType::reference reference; 00581 typedef typename BaseType::const_reference const_reference; 00582 typedef typename BaseType::pointer pointer; 00583 typedef typename BaseType::const_pointer const_pointer; 00584 typedef typename BaseType::iterator iterator; 00585 typedef typename BaseType::const_iterator const_iterator; 00586 typedef typename BaseType::size_type size_type; 00587 typedef typename BaseType::difference_type difference_type; 00588 typedef typename BaseType::scalar_multiplier scalar_multiplier; 00589 typedef typename BaseType::SquaredNormType SquaredNormType; 00590 typedef typename BaseType::NormType NormType; 00591 00592 /** Construction with constant value 00593 */ 00594 explicit TinyVector(value_type const & initial) 00595 : BaseType() 00596 { 00597 Loop::assignScalar(BaseType::begin(), initial); 00598 } 00599 00600 /** Construction with explicit values. 00601 Call only if SIZE == 2 00602 */ 00603 TinyVector(value_type const & i1, value_type const & i2) 00604 : BaseType() 00605 { 00606 BaseType::data_[0] = i1; 00607 BaseType::data_[1] = i2; 00608 } 00609 00610 /** Construction with explicit values. 00611 Call only if SIZE == 3 00612 */ 00613 TinyVector(value_type const & i1, value_type const & i2, value_type const & i3) 00614 : BaseType() 00615 { 00616 BaseType::data_[0] = i1; 00617 BaseType::data_[1] = i2; 00618 BaseType::data_[2] = i3; 00619 } 00620 00621 /** Construction with explicit values. 00622 Call only if SIZE == 4 00623 */ 00624 TinyVector(value_type const & i1, value_type const & i2, 00625 value_type const & i3, value_type const & i4) 00626 : BaseType() 00627 { 00628 BaseType::data_[0] = i1; 00629 BaseType::data_[1] = i2; 00630 BaseType::data_[2] = i3; 00631 BaseType::data_[3] = i4; 00632 } 00633 00634 /** Default constructor (initializes all components with zero) 00635 */ 00636 TinyVector() 00637 : BaseType() 00638 { 00639 Loop::assignScalar(BaseType::data_, NumericTraits<value_type>::zero()); 00640 } 00641 00642 /** Copy constructor. 00643 */ 00644 TinyVector(TinyVector const & r) 00645 : BaseType() 00646 { 00647 Loop::assign(BaseType::data_, r.data_); 00648 } 00649 00650 /** Constructor from C array. 00651 */ 00652 explicit TinyVector(const_pointer data) 00653 : BaseType() 00654 { 00655 Loop::assign(BaseType::data_, data); 00656 } 00657 00658 /** Copy assignment. 00659 */ 00660 TinyVector & operator=(TinyVector const & r) 00661 { 00662 Loop::assign(BaseType::data_, r.data_); 00663 return *this; 00664 } 00665 00666 /** Copy with type conversion. 00667 */ 00668 template <class U, class DATA, class DERIVED> 00669 TinyVector(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r) 00670 : BaseType() 00671 { 00672 Loop::assignCast(BaseType::data_, r.begin()); 00673 } 00674 00675 /** Copy assignment with type conversion. 00676 */ 00677 template <class U, class DATA, class DERIVED> 00678 TinyVector & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r) 00679 { 00680 Loop::assignCast(BaseType::data_, r.begin()); 00681 return *this; 00682 } 00683 00684 explicit TinyVector(detail::DontInit) 00685 : BaseType() 00686 {} 00687 }; 00688 00689 /** \brief Wrapper for fixed size vectors. 00690 00691 This class wraps an array of size SIZE of the specified VALUETYPE. 00692 Thus, the array can be accessed with an interface similar to 00693 that of std::vector (except that there are no functions 00694 that change the size of a TinyVectorView). The TinyVectorView 00695 does <em>not</em> assume ownership of the given memory. 00696 00697 \ref TinyVectorOperators "Arithmetic operations" 00698 on TinyVectorViews are defined as component-wise applications of these 00699 operations. Addition and subtraction of two TinyVectorViews 00700 (+=, -=, +, -, unary -), multiplication and division of an 00701 TinyVectorViews with a double, and NumericTraits/PromoteTraits are defined, 00702 so that TinyVectorView fulfills the requirements of \ref LinearAlgebraConcept "Linear Algebra". 00703 00704 VIGRA algorithms typically use \ref vigra::VectorAccessor to access 00705 TinyVectorViews as a whole, or specific components of them. 00706 00707 <b>See also:</b> 00708 <ul> 00709 <li> \ref vigra::TinyVectorBase 00710 <li> \ref vigra::TinyVector 00711 <li> \ref TinyVectorTraits 00712 <li> \ref TinyVectorOperators 00713 </ul> 00714 00715 <b>\#include</b> <<a href="tinyvector_8hxx-source.html">vigra/tinyvector.hxx</a>><br> 00716 Namespace: vigra 00717 **/ 00718 template <class T, int SIZE> 00719 class TinyVectorView 00720 : public TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> > 00721 { 00722 typedef TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> > BaseType; 00723 typedef typename BaseType::Loop Loop; 00724 00725 public: 00726 00727 typedef typename BaseType::value_type value_type; 00728 typedef typename BaseType::reference reference; 00729 typedef typename BaseType::const_reference const_reference; 00730 typedef typename BaseType::pointer pointer; 00731 typedef typename BaseType::const_pointer const_pointer; 00732 typedef typename BaseType::iterator iterator; 00733 typedef typename BaseType::const_iterator const_iterator; 00734 typedef typename BaseType::size_type size_type; 00735 typedef typename BaseType::difference_type difference_type; 00736 typedef typename BaseType::scalar_multiplier scalar_multiplier; 00737 typedef typename BaseType::SquaredNormType SquaredNormType; 00738 typedef typename BaseType::NormType NormType; 00739 00740 /** Default constructor 00741 (pointer to wrapped data is NULL). 00742 */ 00743 TinyVectorView() 00744 : BaseType() 00745 { 00746 BaseType::data_ = 0; 00747 } 00748 00749 /** Construct view for given data array 00750 */ 00751 TinyVectorView(const_pointer data) 00752 : BaseType() 00753 { 00754 BaseType::data_ = const_cast<pointer>(data); 00755 } 00756 00757 /** Copy constructor (shallow copy). 00758 */ 00759 TinyVectorView(TinyVectorView const & other) 00760 : BaseType() 00761 { 00762 BaseType::data_ = const_cast<pointer>(other.data_); 00763 } 00764 00765 /** Construct view from other TinyVector. 00766 */ 00767 template <class DATA, class DERIVED> 00768 TinyVectorView(TinyVectorBase<T, SIZE, DATA, DERIVED> const & other) 00769 : BaseType() 00770 { 00771 BaseType::data_ = const_cast<pointer>(other.data()); 00772 } 00773 00774 /** Copy the data (not the pointer) of the rhs. 00775 */ 00776 TinyVectorView & operator=(TinyVectorView const & r) 00777 { 00778 Loop::assign(BaseType::data_, r.begin()); 00779 return *this; 00780 } 00781 00782 /** Copy the data of the rhs with cast. 00783 */ 00784 template <class U, class DATA, class DERIVED> 00785 TinyVectorView & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r) 00786 { 00787 Loop::assignCast(BaseType::data_, r.begin()); 00788 return *this; 00789 } 00790 }; 00791 00792 /********************************************************/ 00793 /* */ 00794 /* TinyVector Comparison */ 00795 /* */ 00796 /********************************************************/ 00797 00798 /** \addtogroup TinyVectorOperators Functions for TinyVector 00799 00800 \brief Implement basic arithmetic and equality for TinyVector. 00801 00802 These functions fulfill the requirements of a Linear Space (vector space). 00803 Return types are determined according to \ref TinyVectorTraits. 00804 00805 <b>\#include</b> <<a href="tinyvector_8hxx-source.html">vigra/tinyvector.hxx</a>><br> 00806 Namespace: vigra 00807 */ 00808 //@{ 00809 /// component-wise equal 00810 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4> 00811 inline bool 00812 operator==(TinyVectorBase<V1, SIZE, D1, D2> const & l, 00813 TinyVectorBase<V2, SIZE, D3, D4> const & r) 00814 { 00815 return !(l != r); 00816 } 00817 00818 /// component-wise not equal 00819 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4> 00820 inline bool 00821 operator!=(TinyVectorBase<V1, SIZE, D1, D2> const & l, 00822 TinyVectorBase<V2, SIZE, D3, D4> const & r) 00823 { 00824 typedef typename detail::LoopType<SIZE>::type ltype; 00825 return ltype::notEqual(l.begin(), r.begin()); 00826 } 00827 00828 /********************************************************/ 00829 /* */ 00830 /* TinyVector Output */ 00831 /* */ 00832 /********************************************************/ 00833 00834 /// stream output 00835 template <class V1, int SIZE, class DATA, class DERIVED> 00836 std::ostream & 00837 operator<<(std::ostream & out, TinyVectorBase<V1, SIZE, DATA, DERIVED> const & l) 00838 { 00839 out << "("; 00840 int i; 00841 for(i=0; i<SIZE-1; ++i) 00842 out << l[i] << ", "; 00843 out << l[i] << ")"; 00844 return out; 00845 } 00846 //@} 00847 00848 /********************************************************/ 00849 /* */ 00850 /* TinyVector-Traits */ 00851 /* */ 00852 /********************************************************/ 00853 00854 /** \page TinyVectorTraits Numeric and Promote Traits of TinyVector 00855 The numeric and promote traits for TinyVectors follow 00856 the general specifications for \ref NumericPromotionTraits. 00857 They are implemented in terms of the traits of the basic types by 00858 partial template specialization: 00859 00860 \code 00861 00862 template <class T, int SIZE> 00863 struct NumericTraits<TinyVector<T, SIZE> > 00864 { 00865 typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote; 00866 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote; 00867 00868 typedef typename NumericTraits<T>::isIntegral isIntegral; 00869 typedef VigraFalseType isScalar; 00870 typedef typename NumericTraits<T>::isSigned isSigned; 00871 00872 // etc. 00873 }; 00874 00875 template <class T, int SIZE> 00876 struct NormTraits<TinyVector<T, SIZE> > 00877 { 00878 typedef TinyVector<T, SIZE> Type; 00879 typedef typename Type::SquaredNormType SquaredNormType; 00880 typedef typename Type::NormType NormType; 00881 }; 00882 00883 template <class T1, class T2, SIZE> 00884 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> > 00885 { 00886 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote; 00887 }; 00888 \endcode 00889 00890 <b>\#include</b> <<a href="tinyvector_8hxx-source.html">vigra/tinyvector.hxx</a>><br> 00891 Namespace: vigra 00892 00893 On compilers that don't support pertial template specialization (e.g. 00894 MS VisualC++), the traits classes are explicitly specialized for 00895 <TT>TinyVector<VALUETYPE, SIZE></TT> with 00896 <TT>VALUETYPE = unsigned char | int | float | double</TT> and <TT>SIZE = 2 | 3 | 4</TT>. 00897 00898 */ 00899 00900 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION) 00901 00902 template <class T, int SIZE> 00903 struct NumericTraits<TinyVector<T, SIZE> > 00904 { 00905 typedef TinyVector<T, SIZE> Type; 00906 typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote; 00907 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote; 00908 typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote; 00909 typedef T ValueType; 00910 00911 typedef typename NumericTraits<T>::isIntegral isIntegral; 00912 typedef VigraFalseType isScalar; 00913 typedef typename NumericTraits<T>::isSigned isSigned; 00914 typedef VigraFalseType isOrdered; 00915 typedef VigraFalseType isComplex; 00916 00917 static TinyVector<T, SIZE> zero() { 00918 return TinyVector<T, SIZE>(NumericTraits<T>::zero()); 00919 } 00920 static TinyVector<T, SIZE> one() { 00921 return TinyVector<T, SIZE>(NumericTraits<T>::one()); 00922 } 00923 static TinyVector<T, SIZE> nonZero() { 00924 return TinyVector<T, SIZE>(NumericTraits<T>::nonZero()); 00925 } 00926 00927 template <class D1, class D2> 00928 static Promote toPromote(TinyVectorBase<T, SIZE, D1, D2> const & v) 00929 { 00930 return Promote(v); 00931 } 00932 00933 template <class D1, class D2> 00934 static RealPromote toRealPromote(TinyVectorBase<T, SIZE, D1, D2> const & v) 00935 { 00936 return RealPromote(v); 00937 } 00938 00939 template <class D1, class D2> 00940 static TinyVector<T, SIZE> 00941 fromPromote(TinyVectorBase<typename NumericTraits<T>::Promote, SIZE, D1, D2> const & v) 00942 { 00943 TinyVector<T, SIZE> res(detail::dontInit()); 00944 typedef typename detail::LoopType<SIZE>::type ltype; 00945 ltype::fromPromote(res.begin(), v.begin()); 00946 return res; 00947 } 00948 00949 template <class D1, class D2> 00950 static TinyVector<T, SIZE> 00951 fromRealPromote(TinyVectorBase<typename NumericTraits<T>::RealPromote, SIZE, D1, D2> const & v) 00952 { 00953 TinyVector<T, SIZE> res(detail::dontInit()); 00954 typedef typename detail::LoopType<SIZE>::type ltype; 00955 ltype::fromRealPromote(res.begin(), v.begin()); 00956 return res; 00957 } 00958 }; 00959 00960 template <class T, int SIZE> 00961 struct NumericTraits<TinyVectorView<T, SIZE> > 00962 : public NumericTraits<TinyVector<T, SIZE> > 00963 { 00964 typedef TinyVector<T, SIZE> Type; 00965 typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote; 00966 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote; 00967 typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote; 00968 typedef T ValueType; 00969 00970 typedef typename NumericTraits<T>::isIntegral isIntegral; 00971 typedef VigraFalseType isScalar; 00972 typedef typename NumericTraits<T>::isSigned isSigned; 00973 typedef VigraFalseType isOrdered; 00974 typedef VigraFalseType isComplex; 00975 }; 00976 00977 template <class T, int SIZE> 00978 struct NormTraits<TinyVector<T, SIZE> > 00979 { 00980 typedef TinyVector<T, SIZE> Type; 00981 typedef typename Type::SquaredNormType SquaredNormType; 00982 typedef typename Type::NormType NormType; 00983 }; 00984 00985 template <class T, int SIZE> 00986 struct NormTraits<TinyVectorView<T, SIZE> > 00987 { 00988 typedef TinyVector<T, SIZE> Type; 00989 typedef typename Type::SquaredNormType SquaredNormType; 00990 typedef typename Type::NormType NormType; 00991 }; 00992 00993 template <class T1, class T2, int SIZE> 00994 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> > 00995 { 00996 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote; 00997 }; 00998 00999 template <class T1, class T2, int SIZE> 01000 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVectorView<T2, SIZE> > 01001 { 01002 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote; 01003 }; 01004 01005 template <class T1, class T2, int SIZE> 01006 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVector<T2, SIZE> > 01007 { 01008 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote; 01009 }; 01010 01011 template <class T1, class T2, int SIZE> 01012 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVectorView<T2, SIZE> > 01013 { 01014 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote; 01015 }; 01016 01017 template <class T, int SIZE> 01018 struct PromoteTraits<TinyVector<T, SIZE>, double > 01019 { 01020 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote; 01021 }; 01022 01023 template <class T, int SIZE> 01024 struct PromoteTraits<double, TinyVector<T, SIZE> > 01025 { 01026 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote; 01027 }; 01028 01029 template <class T, int SIZE> 01030 struct PromoteTraits<TinyVectorView<T, SIZE>, double > 01031 { 01032 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote; 01033 }; 01034 01035 template <class T, int SIZE> 01036 struct PromoteTraits<double, TinyVectorView<T, SIZE> > 01037 { 01038 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote; 01039 }; 01040 01041 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION 01042 01043 01044 #define TINYVECTOR_NUMTRAITS(T, SIZE) \ 01045 template<>\ 01046 struct NumericTraits<TinyVector<T, SIZE> >\ 01047 {\ 01048 typedef TinyVector<T, SIZE> Type;\ 01049 typedef TinyVector<NumericTraits<T>::Promote, SIZE> Promote;\ 01050 typedef TinyVector<NumericTraits<T>::RealPromote, SIZE> RealPromote;\ 01051 typedef TinyVector<NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;\ 01052 typedef T ValueType; \ 01053 typedef NumericTraits<T>::isIntegral isIntegral;\ 01054 typedef VigraFalseType isScalar;\ 01055 typedef NumericTraits<T>::isSigned isSigned; \ 01056 typedef VigraFalseType isOrdered;\ 01057 typedef VigraFalseType isComplex;\ 01058 \ 01059 static TinyVector<T, SIZE> zero() { \ 01060 return TinyVector<T, SIZE>(NumericTraits<T>::zero()); \ 01061 }\ 01062 static TinyVector<T, SIZE> one() { \ 01063 return TinyVector<T, SIZE>(NumericTraits<T>::one()); \ 01064 }\ 01065 static TinyVector<T, SIZE> nonZero() { \ 01066 return TinyVector<T, SIZE>(NumericTraits<T>::nonZero()); \ 01067 }\ 01068 \ 01069 static Promote toPromote(TinyVector<T, SIZE> const & v) { \ 01070 return Promote(v); \ 01071 }\ 01072 static RealPromote toRealPromote(TinyVector<T, SIZE> const & v) { \ 01073 return RealPromote(v); \ 01074 }\ 01075 static TinyVector<T, SIZE> fromPromote(Promote const & v) { \ 01076 TinyVector<T, SIZE> res;\ 01077 TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\ 01078 Promote::const_iterator s = v.begin();\ 01079 for(; d != dend; ++d, ++s)\ 01080 *d = NumericTraits<T>::fromPromote(*s);\ 01081 return res;\ 01082 }\ 01083 static TinyVector<T, SIZE> fromRealPromote(RealPromote const & v) {\ 01084 TinyVector<T, SIZE> res;\ 01085 TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\ 01086 RealPromote::const_iterator s = v.begin();\ 01087 for(; d != dend; ++d, ++s)\ 01088 *d = NumericTraits<T>::fromRealPromote(*s);\ 01089 return res;\ 01090 }\ 01091 }; \ 01092 template<>\ 01093 struct NormTraits<TinyVector<T, SIZE> >\ 01094 {\ 01095 typedef TinyVector<T, SIZE> Type;\ 01096 typedef Type::SquaredNormType SquaredNormType; \ 01097 typedef Type::NormType NormType; \ 01098 }; 01099 01100 #define TINYVECTOR_PROMTRAITS1(type1, SIZE) \ 01101 template<> \ 01102 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type1, SIZE> > \ 01103 { \ 01104 typedef TinyVector<PromoteTraits<type1, type1>::Promote, SIZE> Promote; \ 01105 static Promote toPromote(TinyVector<type1, SIZE> const & v) { \ 01106 return static_cast<Promote>(v); } \ 01107 }; 01108 01109 #define TINYVECTOR_PROMTRAITS2(type1, type2, SIZE) \ 01110 template<> \ 01111 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type2, SIZE> > \ 01112 { \ 01113 typedef TinyVector<PromoteTraits<type1, type2>::Promote, SIZE> Promote; \ 01114 static Promote toPromote(TinyVector<type1, SIZE> const & v) { \ 01115 return static_cast<Promote>(v); } \ 01116 static Promote toPromote(TinyVector<type2, SIZE> const & v) { \ 01117 return static_cast<Promote>(v); } \ 01118 }; 01119 01120 #define TINYVECTOR_TRAITS(SIZE) \ 01121 TINYVECTOR_NUMTRAITS(unsigned char, SIZE)\ 01122 TINYVECTOR_NUMTRAITS(int, SIZE)\ 01123 TINYVECTOR_NUMTRAITS(float, SIZE)\ 01124 TINYVECTOR_NUMTRAITS(double, SIZE)\ 01125 TINYVECTOR_PROMTRAITS1(unsigned char, SIZE)\ 01126 TINYVECTOR_PROMTRAITS1(int, SIZE)\ 01127 TINYVECTOR_PROMTRAITS1(float, SIZE)\ 01128 TINYVECTOR_PROMTRAITS1(double, SIZE)\ 01129 TINYVECTOR_PROMTRAITS2(float, unsigned char, SIZE)\ 01130 TINYVECTOR_PROMTRAITS2(unsigned char, float, SIZE)\ 01131 TINYVECTOR_PROMTRAITS2(int, unsigned char, SIZE)\ 01132 TINYVECTOR_PROMTRAITS2(unsigned char, int, SIZE)\ 01133 TINYVECTOR_PROMTRAITS2(int, float, SIZE)\ 01134 TINYVECTOR_PROMTRAITS2(float, int, SIZE)\ 01135 TINYVECTOR_PROMTRAITS2(double, unsigned char, SIZE)\ 01136 TINYVECTOR_PROMTRAITS2(unsigned char, double, SIZE)\ 01137 TINYVECTOR_PROMTRAITS2(int, double, SIZE)\ 01138 TINYVECTOR_PROMTRAITS2(double, int, SIZE)\ 01139 TINYVECTOR_PROMTRAITS2(double, float, SIZE)\ 01140 TINYVECTOR_PROMTRAITS2(float, double, SIZE) 01141 01142 TINYVECTOR_TRAITS(2) 01143 TINYVECTOR_TRAITS(3) 01144 TINYVECTOR_TRAITS(4) 01145 01146 #undef TINYVECTOR_NUMTRAITS 01147 #undef TINYVECTOR_PROMTRAITS1 01148 #undef TINYVECTOR_PROMTRAITS2 01149 #undef TINYVECTOR_TRAITS 01150 01151 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION 01152 01153 01154 /********************************************************/ 01155 /* */ 01156 /* TinyVector-Arithmetic */ 01157 /* */ 01158 /********************************************************/ 01159 01160 /** \addtogroup TinyVectorOperators 01161 */ 01162 //@{ 01163 01164 /// component-wise addition 01165 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4> 01166 inline 01167 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote 01168 operator+(TinyVectorBase<V1, SIZE, D1, D2> const & l, 01169 TinyVectorBase<V2, SIZE, D3, D4> const & r) 01170 { 01171 return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) += r; 01172 } 01173 01174 /// component-wise subtraction 01175 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4> 01176 inline 01177 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote 01178 operator-(TinyVectorBase<V1, SIZE, D1, D2> const & l, 01179 TinyVectorBase<V2, SIZE, D3, D4> const & r) 01180 { 01181 return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) -= r; 01182 } 01183 01184 /// component-wise multiplication 01185 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4> 01186 inline 01187 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote 01188 operator*(TinyVectorBase<V1, SIZE, D1, D2> const & l, 01189 TinyVectorBase<V2, SIZE, D3, D4> const & r) 01190 { 01191 return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) *= r; 01192 } 01193 01194 /// component-wise left scalar multiplication 01195 template <class V, int SIZE, class D1, class D2> 01196 inline 01197 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote 01198 operator*(double v, TinyVectorBase<V, SIZE, D1, D2> const & r) 01199 { 01200 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(r) *= v; 01201 } 01202 01203 /// component-wise right scalar multiplication 01204 template <class V, int SIZE, class D1, class D2> 01205 inline 01206 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote 01207 operator*(TinyVectorBase<V, SIZE, D1, D2> const & l, double v) 01208 { 01209 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) *= v; 01210 } 01211 01212 /// component-wise scalar division 01213 template <class V, int SIZE, class D1, class D2> 01214 inline 01215 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote 01216 operator/(TinyVectorBase<V, SIZE, D1, D2> const & l, double v) 01217 { 01218 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) /= v; 01219 } 01220 01221 01222 /** Unary negation (construct TinyVector with negative values) 01223 */ 01224 template <class V, int SIZE, class D1, class D2> 01225 inline 01226 TinyVector<V, SIZE> 01227 operator-(TinyVectorBase<V, SIZE, D1, D2> const & v) 01228 { 01229 TinyVector<V, SIZE> res(detail::dontInit()); 01230 typedef typename detail::LoopType<SIZE>::type ltype; 01231 ltype::neg(res.begin(), v.begin()); 01232 return res; 01233 } 01234 01235 /// component-wise absolute value 01236 template <class V, int SIZE, class D1, class D2> 01237 inline 01238 TinyVector<V, SIZE> 01239 abs(TinyVectorBase<V, SIZE, D1, D2> const & v) 01240 { 01241 TinyVector<V, SIZE> res(detail::dontInit()); 01242 typedef typename detail::LoopType<SIZE>::type ltype; 01243 ltype::abs(res.begin(), v.begin()); 01244 return res; 01245 } 01246 01247 /** Apply ceil() function to each vector component. 01248 */ 01249 template <class V, int SIZE, class D1, class D2> 01250 inline 01251 TinyVector<V, SIZE> 01252 ceil(TinyVectorBase<V, SIZE, D1, D2> const & v) 01253 { 01254 TinyVector<V, SIZE> res(detail::dontInit()); 01255 typedef typename detail::LoopType<SIZE>::type ltype; 01256 ltype::ceil(res.begin(), v.begin()); 01257 return res; 01258 } 01259 01260 /** Apply floor() function to each vector component. 01261 */ 01262 template <class V, int SIZE, class D1, class D2> 01263 inline 01264 TinyVector<V, SIZE> 01265 floor(TinyVectorBase<V, SIZE, D1, D2> const & v) 01266 { 01267 TinyVector<V, SIZE> res(detail::dontInit()); 01268 typedef typename detail::LoopType<SIZE>::type ltype; 01269 ltype::floor(res.begin(), v.begin()); 01270 return res; 01271 } 01272 01273 /// cross product 01274 template <class V1, class D1, class D2, class V2, class D3, class D4> 01275 inline 01276 TinyVector<typename PromoteTraits<V1, V2>::Promote, 3> 01277 cross(TinyVectorBase<V1, 3, D1, D2> const & r1, 01278 TinyVectorBase<V2, 3, D3, D4> const & r2) 01279 { 01280 typedef TinyVector<typename PromoteTraits<V1, V2>::Promote, 3> 01281 Res; 01282 return Res(r1[1]*r2[2] - r1[2]*r2[1], 01283 r1[2]*r2[0] - r1[0]*r2[2], 01284 r1[0]*r2[1] - r1[1]*r2[0]); 01285 } 01286 01287 /// dot product 01288 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4> 01289 inline 01290 typename PromoteTraits<V1, V2>::Promote 01291 dot(TinyVectorBase<V1, SIZE, D1, D2> const & l, 01292 TinyVectorBase<V2, SIZE, D3, D4> const & r) 01293 { 01294 typedef typename detail::LoopType<SIZE>::type ltype; 01295 return ltype::dot(l.begin(), r.begin()); 01296 } 01297 01298 01299 /// squared norm 01300 template <class V1, int SIZE, class D1, class D2> 01301 inline 01302 typename TinyVectorBase<V1, SIZE, D1, D2>::SquaredNormType 01303 squaredNorm(TinyVectorBase<V1, SIZE, D1, D2> const & t) 01304 { 01305 return t.squaredMagnitude(); 01306 } 01307 01308 /// squared norm 01309 template <class V, int SIZE> 01310 inline 01311 typename TinyVector<V, SIZE>::SquaredNormType 01312 squaredNorm(TinyVector<V, SIZE> const & t) 01313 { 01314 return t.squaredMagnitude(); 01315 } 01316 //@} 01317 01318 01319 } // namespace vigra 01320 01321 #endif // VIGRA_TINYVECTOR_HXX
© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) |
html generated using doxygen and Python
|