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