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

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
VIGRA 1.6.0 (13 Aug 2008)