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