[ 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)