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