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