[ VIGRA Homepage | Class Index | Function Index | File Index | Main Page ]

details vigra/tinyvector.hxx VIGRA

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

© Ullrich Köthe (koethe@informatik.uni-hamburg.de)
Cognitive Systems Group, University of Hamburg, Germany

html generated using doxygen and Python
VIGRA 1.3.3 (18 Aug 2005)