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

| vigra/tinyvector.hxx |
--- | --- | ---

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*               Copyright 1998-2002 by Ullrich Koethe                  */
    00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
    00005 /*                                                                      */
    00006 /*    This file is part of the VIGRA computer vision library.           */
    00007 /*    ( Version 1.5.0, Dec 07 2006 )                                    */
    00008 /*    The VIGRA Website is                                              */
    00009 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
    00010 /*    Please direct questions, bug reports, and contributions to        */
    00011 /*        koethe@informatik.uni-hamburg.de          or                  */
    00012 /*        vigra@kogs1.informatik.uni-hamburg.de                         */
    00013 /*                                                                      */
    00014 /*    Permission is hereby granted, free of charge, to any person       */
    00015 /*    obtaining a copy of this software and associated documentation    */
    00016 /*    files (the "Software"), to deal in the Software without           */
    00017 /*    restriction, including without limitation the rights to use,      */
    00018 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00019 /*    sell copies of the Software, and to permit persons to whom the    */
    00020 /*    Software is furnished to do so, subject to the following          */
    00021 /*    conditions:                                                       */
    00022 /*                                                                      */
    00023 /*    The above copyright notice and this permission notice shall be    */
    00024 /*    included in all copies or substantial portions of the             */
    00025 /*    Software.                                                         */
    00026 /*                                                                      */
    00027 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00028 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00029 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00030 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00031 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00032 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00033 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00034 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00035 /*                                                                      */
    00036 /************************************************************************/
    00037
    00038
    00039 #ifndef VIGRA_TINYVECTOR_HXX
    00040 #define VIGRA_TINYVECTOR_HXX
    00041
    00042 #include <cmath>    // abs(double)
    00043 #include <cstdlib>  // abs(int)
    00044 #include <iosfwd>   // ostream
    00045 #include "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 LinearAlgebra.
    00555
    00556     VIGRA algorithms typically use \ref vigra::VectorAccessor to access
    00557     TinyVectors as a whole, or specific components of them.
    00558
    00559     See also:<br>
    00560     <DL>
    00561         <DT>
    00562             <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
    00563             \ref vigra::TinyVectorBase
    00564             <DD>
    00565         <DT>
    00566             <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
    00567             \ref vigra::TinyVectorView
    00568             <DD>
    00569         <DT>
    00570             <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
    00571             \ref TinyVectorTraits
    00572             <DD>
    00573         <DT>
    00574             <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
    00575             \ref TinyVectorOperators
    00576             <DD>
    00577     </DL>
    00578
    00579     <b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/tinyvector.hxx</a>"<br>
    00580     Namespace: vigra
    00581 **/
    00582 template <class T, int SIZE>
    00583 class TinyVector
    00584 : public TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> >
    00585 {
    00586     typedef TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> > BaseType;
    00587     typedef typename BaseType::Loop Loop;
    00588
    00589   public:
    00590
    00591     typedef typename BaseType::value_type value_type;
    00592     typedef typename BaseType::reference reference;
    00593     typedef typename BaseType::const_reference const_reference;
    00594     typedef typename BaseType::pointer pointer;
    00595     typedef typename BaseType::const_pointer const_pointer;
    00596     typedef typename BaseType::iterator iterator;
    00597     typedef typename BaseType::const_iterator const_iterator;
    00598     typedef typename BaseType::size_type size_type;
    00599     typedef typename BaseType::difference_type difference_type;
    00600     typedef typename BaseType::scalar_multiplier scalar_multiplier;
    00601     typedef typename BaseType::SquaredNormType SquaredNormType;
    00602     typedef typename BaseType::NormType NormType;
    00603
    00604         /** Construction with constant value
    00605         */
    00606     explicit TinyVector(value_type const & initial)
    00607     : BaseType()
    00608     {
    00609         Loop::assignScalar(BaseType::begin(), initial);
    00610     }
    00611
    00612         /** Construction with explicit values.
    00613             Call only if SIZE == 2
    00614         */
    00615     TinyVector(value_type const & i1, value_type const & i2)
    00616     : BaseType()
    00617     {
    00618         BaseType::data_[0] = i1;
    00619         BaseType::data_[1] = i2;
    00620     }
    00621
    00622         /** Construction with explicit values.
    00623             Call only if SIZE == 3
    00624         */
    00625     TinyVector(value_type const & i1, value_type const & i2, value_type const & i3)
    00626     : BaseType()
    00627     {
    00628         BaseType::data_[0] = i1;
    00629         BaseType::data_[1] = i2;
    00630         BaseType::data_[2] = i3;
    00631     }
    00632
    00633         /** Construction with explicit values.
    00634             Call only if SIZE == 4
    00635         */
    00636     TinyVector(value_type const & i1, value_type const & i2,
    00637                value_type const & i3, value_type const & i4)
    00638     : BaseType()
    00639     {
    00640         BaseType::data_[0] = i1;
    00641         BaseType::data_[1] = i2;
    00642         BaseType::data_[2] = i3;
    00643         BaseType::data_[3] = i4;
    00644     }
    00645
    00646        /** Default constructor (initializes all components with zero)
    00647         */
    00648     TinyVector()
    00649     : BaseType()
    00650     {
    00651         Loop::assignScalar(BaseType::data_, NumericTraits<value_type>::zero());
    00652     }
    00653
    00654         /** Copy constructor.
    00655         */
    00656     TinyVector(TinyVector const & r)
    00657     : BaseType()
    00658     {
    00659         Loop::assign(BaseType::data_, r.data_);
    00660     }
    00661
    00662         /** Constructor from C array.
    00663         */
    00664     explicit TinyVector(const_pointer data)
    00665     : BaseType()
    00666     {
    00667         Loop::assign(BaseType::data_, data);
    00668     }
    00669
    00670         /** Copy assignment.
    00671         */
    00672     TinyVector & operator=(TinyVector const & r)
    00673     {
    00674         Loop::assign(BaseType::data_, r.data_);
    00675         return *this;
    00676     }
    00677
    00678         /** Copy with type conversion.
    00679         */
    00680     template <class U, class DATA, class DERIVED>
    00681     TinyVector(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r)
    00682     : BaseType()
    00683     {
    00684         Loop::assignCast(BaseType::data_, r.begin());
    00685     }
    00686
    00687         /** Copy assignment with type conversion.
    00688         */
    00689     template <class U, class DATA, class DERIVED>
    00690     TinyVector & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r)
    00691     {
    00692         Loop::assignCast(BaseType::data_, r.begin());
    00693         return *this;
    00694     }
    00695
    00696     explicit TinyVector(detail::DontInit)
    00697     : BaseType()
    00698     {}
    00699 };
    00700
    00701 /** \brief Wrapper for fixed size vectors.
    00702
    00703     This class wraps an array of size SIZE of the specified VALUETYPE.
    00704     Thus, the array can be accessed with an interface similar to
    00705     that of std::vector (except that there are no functions
    00706     that change the size of a TinyVectorView). The TinyVectorView
    00707     does <em>not</em> assume ownership of the given memory.
    00708
    00709     \ref TinyVectorOperators "Arithmetic operations"
    00710     on TinyVectorViews are defined as component-wise applications of these
    00711     operations. Addition and subtraction of two TinyVectorViews
    00712     (+=, -=, +, -, unary -), multiplication and division of an
    00713     TinyVectorViews with a double, and NumericTraits/PromoteTraits are defined,
    00714     so that TinyVectorView fulfills the requirements of \ref LinearAlgebra.
    00715
    00716     VIGRA algorithms typically use \ref vigra::VectorAccessor to access
    00717     TinyVectorViews as a whole, or specific components of them.
    00718
    00719     <b>See also:</b>
    00720     <ul>
    00721         <li> \ref vigra::TinyVectorBase
    00722         <li> \ref vigra::TinyVector
    00723         <li> \ref TinyVectorTraits
    00724         <li> \ref TinyVectorOperators
    00725     </ul>
    00726
    00727     <b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/tinyvector.hxx</a>"<br>
    00728     Namespace: vigra
    00729 **/
    00730 template <class T, int SIZE>
    00731 class TinyVectorView
    00732 : public TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> >
    00733 {
    00734     typedef TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> > BaseType;
    00735     typedef typename BaseType::Loop Loop;
    00736
    00737   public:
    00738
    00739     typedef typename BaseType::value_type value_type;
    00740     typedef typename BaseType::reference reference;
    00741     typedef typename BaseType::const_reference const_reference;
    00742     typedef typename BaseType::pointer pointer;
    00743     typedef typename BaseType::const_pointer const_pointer;
    00744     typedef typename BaseType::iterator iterator;
    00745     typedef typename BaseType::const_iterator const_iterator;
    00746     typedef typename BaseType::size_type size_type;
    00747     typedef typename BaseType::difference_type difference_type;
    00748     typedef typename BaseType::scalar_multiplier scalar_multiplier;
    00749     typedef typename BaseType::SquaredNormType SquaredNormType;
    00750     typedef typename BaseType::NormType NormType;
    00751
    00752         /** Default constructor
    00753             (pointer to wrapped data is NULL).
    00754         */
    00755     TinyVectorView()
    00756     : BaseType()
    00757     {
    00758         BaseType::data_ = 0;
    00759     }
    00760
    00761         /** Construct view for given data array
    00762         */
    00763     TinyVectorView(const_pointer data)
    00764     : BaseType()
    00765     {
    00766         BaseType::data_ = const_cast<pointer>(data);
    00767     }
    00768
    00769         /** Copy constructor (shallow copy).
    00770         */
    00771     TinyVectorView(TinyVectorView const & other)
    00772     : BaseType()
    00773     {
    00774         BaseType::data_ = const_cast<pointer>(other.data_);
    00775     }
    00776
    00777         /** Construct view from other TinyVector.
    00778         */
    00779     template <class DATA, class DERIVED>
    00780     TinyVectorView(TinyVectorBase<T, SIZE, DATA, DERIVED> const & other)
    00781     : BaseType()
    00782     {
    00783         BaseType::data_ = const_cast<pointer>(other.data());
    00784     }
    00785
    00786         /** Copy the data (not the pointer) of the rhs.
    00787         */
    00788    TinyVectorView & operator=(TinyVectorView const & r)
    00789     {
    00790         Loop::assign(BaseType::data_, r.begin());
    00791         return *this;
    00792     }
    00793
    00794         /** Copy the data of the rhs with cast.
    00795         */
    00796     template <class U, class DATA, class DERIVED>
    00797     TinyVectorView & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r)
    00798     {
    00799         Loop::assignCast(BaseType::data_, r.begin());
    00800         return *this;
    00801     }
    00802 };
    00803
    00804 /********************************************************/
    00805 /*                                                      */
    00806 /*                     TinyVector Comparison            */
    00807 /*                                                      */
    00808 /********************************************************/
    00809
    00810 /** \addtogroup TinyVectorOperators Functions for TinyVector
    00811
    00812     \brief <b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/tinyvector.hxx</a>
    00813
    00814     These functions fulfill the requirements of a Linear Space (vector space).
    00815     Return types are determined according to \ref TinyVectorTraits.
    00816
    00817     Namespace: vigra
    00818     <p>
    00819
    00820  */
    00821 //@{
    00822     /// component-wise equal
    00823 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
    00824 inline bool
    00825 operator==(TinyVectorBase<V1, SIZE, D1, D2> const & l,
    00826            TinyVectorBase<V2, SIZE, D3, D4> const & r)
    00827 {
    00828     return !(l != r);
    00829 }
    00830
    00831     /// component-wise not equal
    00832 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
    00833 inline bool
    00834 operator!=(TinyVectorBase<V1, SIZE, D1, D2> const & l,
    00835            TinyVectorBase<V2, SIZE, D3, D4> const & r)
    00836 {
    00837     typedef typename detail::LoopType<SIZE>::type ltype;
    00838     return ltype::notEqual(l.begin(), r.begin());
    00839 }
    00840
    00841 /********************************************************/
    00842 /*                                                      */
    00843 /*                     TinyVector Output                */
    00844 /*                                                      */
    00845 /********************************************************/
    00846
    00847     /// stream output
    00848 template <class V1, int SIZE, class DATA, class DERIVED>
    00849 std::ostream &
    00850 operator<<(std::ostream & out, TinyVectorBase<V1, SIZE, DATA, DERIVED> const & l)
    00851 {
    00852     out << "(";
    00853     int i;
    00854     for(i=0; i<SIZE-1; ++i)
    00855         out << l[i] << ", ";
    00856     out << l[i] << ")";
    00857     return out;
    00858 }
    00859 //@}
    00860
    00861 /********************************************************/
    00862 /*                                                      */
    00863 /*                      TinyVector-Traits               */
    00864 /*                                                      */
    00865 /********************************************************/
    00866
    00867 /** \page TinyVectorTraits Numeric and Promote Traits of TinyVector
    00868     The numeric and promote traits for TinyVectors follow
    00869     the general specifications for \ref NumericPromotionTraits.
    00870     They are implemented in terms of the traits of the basic types by
    00871     partial template specialization:
    00872
    00873     \code
    00874
    00875     template <class T, int SIZE>
    00876     struct NumericTraits<TinyVector<T, SIZE> >
    00877     {
    00878         typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
    00879         typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
    00880
    00881         typedef typename NumericTraits<T>::isIntegral isIntegral;
    00882         typedef VigraFalseType isScalar;
    00883         typedef typename NumericTraits<T>::isSigned isSigned;
    00884
    00885         // etc.
    00886     };
    00887
    00888     template <class T, int SIZE>
    00889     struct NormTraits<TinyVector<T, SIZE> >
    00890     {
    00891         typedef TinyVector<T, SIZE> Type;
    00892         typedef typename Type::SquaredNormType    SquaredNormType;
    00893         typedef typename Type::NormType           NormType;
    00894     };
    00895
    00896     template <class T1, class T2, SIZE>
    00897     struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
    00898     {
    00899         typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
    00900     };
    00901     \endcode
    00902
    00903     <b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/tinyvector.hxx</a>"<br>
    00904     Namespace: vigra
    00905
    00906     On compilers that don't support pertial template specialization (e.g.
    00907     MS VisualC++), the traits classes are explicitly specialized for
    00908     <TT>TinyVector<VALUETYPE, SIZE></TT> with
    00909     <TT>VALUETYPE = unsigned char | int | float | double</TT> and <TT>SIZE = 2 | 3 | 4</TT>.
    00910
    00911 */
    00912
    00913 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
    00914
    00915 template <class T, int SIZE>
    00916 struct NumericTraits<TinyVector<T, SIZE> >
    00917 {
    00918     typedef TinyVector<T, SIZE> Type;
    00919     typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
    00920     typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
    00921     typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
    00922     typedef T ValueType;
    00923
    00924     typedef typename NumericTraits<T>::isIntegral isIntegral;
    00925     typedef VigraFalseType isScalar;
    00926     typedef typename NumericTraits<T>::isSigned isSigned;
    00927     typedef VigraFalseType isOrdered;
    00928     typedef VigraFalseType isComplex;
    00929
    00930     static TinyVector<T, SIZE> zero() {
    00931         return TinyVector<T, SIZE>(NumericTraits<T>::zero());
    00932     }
    00933     static TinyVector<T, SIZE> one() {
    00934         return TinyVector<T, SIZE>(NumericTraits<T>::one());
    00935     }
    00936     static TinyVector<T, SIZE> nonZero() {
    00937         return TinyVector<T, SIZE>(NumericTraits<T>::nonZero());
    00938     }
    00939
    00940     template <class D1, class D2>
    00941     static Promote toPromote(TinyVectorBase<T, SIZE, D1, D2> const & v)
    00942     {
    00943         return Promote(v);
    00944     }
    00945
    00946     template <class D1, class D2>
    00947     static RealPromote toRealPromote(TinyVectorBase<T, SIZE, D1, D2> const & v)
    00948     {
    00949         return RealPromote(v);
    00950     }
    00951
    00952     template <class D1, class D2>
    00953     static TinyVector<T, SIZE>
    00954     fromPromote(TinyVectorBase<typename NumericTraits<T>::Promote, SIZE, D1, D2> const & v)
    00955     {
    00956         TinyVector<T, SIZE> res(detail::dontInit());
    00957         typedef typename detail::LoopType<SIZE>::type ltype;
    00958         ltype::fromPromote(res.begin(), v.begin());
    00959         return res;
    00960     }
    00961
    00962     template <class D1, class D2>
    00963     static TinyVector<T, SIZE>
    00964     fromRealPromote(TinyVectorBase<typename NumericTraits<T>::RealPromote, SIZE, D1, D2> const & v)
    00965     {
    00966         TinyVector<T, SIZE> res(detail::dontInit());
    00967         typedef typename detail::LoopType<SIZE>::type ltype;
    00968         ltype::fromRealPromote(res.begin(), v.begin());
    00969         return res;
    00970     }
    00971 };
    00972
    00973 template <class T, int SIZE>
    00974 struct NumericTraits<TinyVectorView<T, SIZE> >
    00975 : public NumericTraits<TinyVector<T, SIZE> >
    00976 {
    00977     typedef TinyVector<T, SIZE> Type;
    00978     typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
    00979     typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
    00980     typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
    00981     typedef T ValueType;
    00982
    00983     typedef typename NumericTraits<T>::isIntegral isIntegral;
    00984     typedef VigraFalseType isScalar;
    00985     typedef typename NumericTraits<T>::isSigned isSigned;
    00986     typedef VigraFalseType isOrdered;
    00987     typedef VigraFalseType isComplex;
    00988 };
    00989
    00990 template <class T, int SIZE>
    00991 struct NormTraits<TinyVector<T, SIZE> >
    00992 {
    00993     typedef TinyVector<T, SIZE> Type;
    00994     typedef typename Type::SquaredNormType    SquaredNormType;
    00995     typedef typename Type::NormType           NormType;
    00996 };
    00997
    00998 template <class T, int SIZE>
    00999 struct NormTraits<TinyVectorView<T, SIZE> >
    01000 {
    01001     typedef TinyVector<T, SIZE> Type;
    01002     typedef typename Type::SquaredNormType    SquaredNormType;
    01003     typedef typename Type::NormType           NormType;
    01004 };
    01005
    01006 template <class T1, class T2, int SIZE>
    01007 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
    01008 {
    01009     typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
    01010 };
    01011
    01012 template <class T1, class T2, int SIZE>
    01013 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVectorView<T2, SIZE> >
    01014 {
    01015     typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
    01016 };
    01017
    01018 template <class T1, class T2, int SIZE>
    01019 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVector<T2, SIZE> >
    01020 {
    01021     typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
    01022 };
    01023
    01024 template <class T1, class T2, int SIZE>
    01025 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVectorView<T2, SIZE> >
    01026 {
    01027     typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
    01028 };
    01029
    01030 template <class T, int SIZE>
    01031 struct PromoteTraits<TinyVector<T, SIZE>, double >
    01032 {
    01033     typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
    01034 };
    01035
    01036 template <class T, int SIZE>
    01037 struct PromoteTraits<double, TinyVector<T, SIZE> >
    01038 {
    01039     typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
    01040 };
    01041
    01042 template <class T, int SIZE>
    01043 struct PromoteTraits<TinyVectorView<T, SIZE>, double >
    01044 {
    01045     typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
    01046 };
    01047
    01048 template <class T, int SIZE>
    01049 struct PromoteTraits<double, TinyVectorView<T, SIZE> >
    01050 {
    01051     typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
    01052 };
    01053
    01054 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01055
    01056
    01057 #define TINYVECTOR_NUMTRAITS(T, SIZE) \
    01058 template<>\
    01059 struct NumericTraits<TinyVector<T, SIZE> >\
    01060 {\
    01061     typedef TinyVector<T, SIZE> Type;\
    01062     typedef TinyVector<NumericTraits<T>::Promote, SIZE> Promote;\
    01063     typedef TinyVector<NumericTraits<T>::RealPromote, SIZE> RealPromote;\
    01064     typedef TinyVector<NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;\
    01065     typedef T ValueType; \
    01066     typedef NumericTraits<T>::isIntegral isIntegral;\
    01067     typedef VigraFalseType isScalar;\
    01068     typedef NumericTraits<T>::isSigned isSigned; \
    01069     typedef VigraFalseType isOrdered;\
    01070     typedef VigraFalseType isComplex;\
    01071     \
    01072     static TinyVector<T, SIZE> zero() { \
    01073         return TinyVector<T, SIZE>(NumericTraits<T>::zero()); \
    01074     }\
    01075     static TinyVector<T, SIZE> one() { \
    01076         return TinyVector<T, SIZE>(NumericTraits<T>::one()); \
    01077     }\
    01078     static TinyVector<T, SIZE> nonZero() { \
    01079         return TinyVector<T, SIZE>(NumericTraits<T>::nonZero()); \
    01080     }\
    01081     \
    01082     static Promote toPromote(TinyVector<T, SIZE> const & v) { \
    01083         return Promote(v); \
    01084     }\
    01085     static RealPromote toRealPromote(TinyVector<T, SIZE> const & v) { \
    01086         return RealPromote(v); \
    01087     }\
    01088     static TinyVector<T, SIZE> fromPromote(Promote const & v) { \
    01089         TinyVector<T, SIZE> res;\
    01090         TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
    01091         Promote::const_iterator s = v.begin();\
    01092         for(; d != dend; ++d, ++s)\
    01093             *d = NumericTraits<T>::fromPromote(*s);\
    01094         return res;\
    01095     }\
    01096     static TinyVector<T, SIZE> fromRealPromote(RealPromote const & v) {\
    01097         TinyVector<T, SIZE> res;\
    01098         TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
    01099         RealPromote::const_iterator s = v.begin();\
    01100         for(; d != dend; ++d, ++s)\
    01101             *d = NumericTraits<T>::fromRealPromote(*s);\
    01102         return res;\
    01103     }\
    01104 }; \
    01105 template<>\
    01106 struct NormTraits<TinyVector<T, SIZE> >\
    01107 {\
    01108     typedef TinyVector<T, SIZE> Type;\
    01109     typedef Type::SquaredNormType           SquaredNormType; \
    01110     typedef Type::NormType NormType; \
    01111 };
    01112
    01113 #define TINYVECTOR_PROMTRAITS1(type1, SIZE) \
    01114 template<> \
    01115 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type1, SIZE> > \
    01116 { \
    01117     typedef TinyVector<PromoteTraits<type1, type1>::Promote, SIZE> Promote; \
    01118     static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
    01119         return static_cast<Promote>(v); } \
    01120 };
    01121
    01122 #define TINYVECTOR_PROMTRAITS2(type1, type2, SIZE) \
    01123 template<> \
    01124 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type2, SIZE> > \
    01125 { \
    01126     typedef TinyVector<PromoteTraits<type1, type2>::Promote, SIZE> Promote; \
    01127     static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
    01128         return static_cast<Promote>(v); } \
    01129     static Promote toPromote(TinyVector<type2, SIZE> const & v) { \
    01130        return static_cast<Promote>(v); } \
    01131 };
    01132
    01133 #define TINYVECTOR_TRAITS(SIZE) \
    01134 TINYVECTOR_NUMTRAITS(unsigned char, SIZE)\
    01135 TINYVECTOR_NUMTRAITS(int, SIZE)\
    01136 TINYVECTOR_NUMTRAITS(float, SIZE)\
    01137 TINYVECTOR_NUMTRAITS(double, SIZE)\
    01138 TINYVECTOR_PROMTRAITS1(unsigned char, SIZE)\
    01139 TINYVECTOR_PROMTRAITS1(int, SIZE)\
    01140 TINYVECTOR_PROMTRAITS1(float, SIZE)\
    01141 TINYVECTOR_PROMTRAITS1(double, SIZE)\
    01142 TINYVECTOR_PROMTRAITS2(float, unsigned char, SIZE)\
    01143 TINYVECTOR_PROMTRAITS2(unsigned char, float, SIZE)\
    01144 TINYVECTOR_PROMTRAITS2(int, unsigned char, SIZE)\
    01145 TINYVECTOR_PROMTRAITS2(unsigned char, int, SIZE)\
    01146 TINYVECTOR_PROMTRAITS2(int, float, SIZE)\
    01147 TINYVECTOR_PROMTRAITS2(float, int, SIZE)\
    01148 TINYVECTOR_PROMTRAITS2(double, unsigned char, SIZE)\
    01149 TINYVECTOR_PROMTRAITS2(unsigned char, double, SIZE)\
    01150 TINYVECTOR_PROMTRAITS2(int, double, SIZE)\
    01151 TINYVECTOR_PROMTRAITS2(double, int, SIZE)\
    01152 TINYVECTOR_PROMTRAITS2(double, float, SIZE)\
    01153 TINYVECTOR_PROMTRAITS2(float, double, SIZE)
    01154
    01155 TINYVECTOR_TRAITS(2)
    01156 TINYVECTOR_TRAITS(3)
    01157 TINYVECTOR_TRAITS(4)
    01158
    01159 #undef TINYVECTOR_NUMTRAITS
    01160 #undef TINYVECTOR_PROMTRAITS1
    01161 #undef TINYVECTOR_PROMTRAITS2
    01162 #undef TINYVECTOR_TRAITS
    01163
    01164 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
    01165
    01166
    01167 /********************************************************/
    01168 /*                                                      */
    01169 /*                      TinyVector-Arithmetic           */
    01170 /*                                                      */
    01171 /********************************************************/
    01172
    01173 /** \addtogroup TinyVectorOperators
    01174  */
    01175 //@{
    01176
    01177     /// component-wise addition
    01178 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
    01179 inline
    01180 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
    01181 operator+(TinyVectorBase<V1, SIZE, D1, D2> const & l,
    01182           TinyVectorBase<V2, SIZE, D3, D4> const & r)
    01183 {
    01184     return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) += r;
    01185 }
    01186
    01187     /// component-wise subtraction
    01188 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
    01189 inline
    01190 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
    01191 operator-(TinyVectorBase<V1, SIZE, D1, D2> const & l,
    01192           TinyVectorBase<V2, SIZE, D3, D4> const & r)
    01193 {
    01194     return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) -= r;
    01195 }
    01196
    01197     /// component-wise multiplication
    01198 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
    01199 inline
    01200 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
    01201 operator*(TinyVectorBase<V1, SIZE, D1, D2> const & l,
    01202           TinyVectorBase<V2, SIZE, D3, D4> const & r)
    01203 {
    01204     return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) *= r;
    01205 }
    01206
    01207     /// component-wise left scalar multiplication
    01208 template <class V, int SIZE, class D1, class D2>
    01209 inline
    01210 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
    01211 operator*(double v, TinyVectorBase<V, SIZE, D1, D2> const & r)
    01212 {
    01213     return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(r) *= v;
    01214 }
    01215
    01216     /// component-wise right scalar multiplication
    01217 template <class V, int SIZE, class D1, class D2>
    01218 inline
    01219 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
    01220 operator*(TinyVectorBase<V, SIZE, D1, D2> const & l, double v)
    01221 {
    01222     return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) *= v;
    01223 }
    01224
    01225     /// component-wise scalar division
    01226 template <class V, int SIZE, class D1, class D2>
    01227 inline
    01228 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
    01229 operator/(TinyVectorBase<V, SIZE, D1, D2> const & l, double v)
    01230 {
    01231     return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) /= v;
    01232 }
    01233
    01234
    01235     /** Unary negation (construct TinyVector with negative values)
    01236     */
    01237 template <class V, int SIZE, class D1, class D2>
    01238 inline
    01239 TinyVector<V, SIZE>
    01240 operator-(TinyVectorBase<V, SIZE, D1, D2> const & v)
    01241 {
    01242     TinyVector<V, SIZE> res(detail::dontInit());
    01243     typedef typename detail::LoopType<SIZE>::type ltype;
    01244     ltype::neg(res.begin(), v.begin());
    01245     return res;
    01246 }
    01247
    01248     /// component-wise absolute value
    01249 template <class V, int SIZE, class D1, class D2>
    01250 inline
    01251 TinyVector<V, SIZE>
    01252 abs(TinyVectorBase<V, SIZE, D1, D2> const & v)
    01253 {
    01254     TinyVector<V, SIZE> res(detail::dontInit());
    01255     typedef typename detail::LoopType<SIZE>::type ltype;
    01256     ltype::abs(res.begin(), v.begin());
    01257     return res;
    01258 }
    01259
    01260     /** Apply ceil() function to each vector component.
    01261     */
    01262 template <class V, int SIZE, class D1, class D2>
    01263 inline
    01264 TinyVector<V, SIZE>
    01265 ceil(TinyVectorBase<V, SIZE, D1, D2> const & v)
    01266 {
    01267     TinyVector<V, SIZE> res(detail::dontInit());
    01268     typedef typename detail::LoopType<SIZE>::type ltype;
    01269     ltype::ceil(res.begin(), v.begin());
    01270     return res;
    01271 }
    01272
    01273     /** Apply floor() function to each vector component.
    01274     */
    01275 template <class V, int SIZE, class D1, class D2>
    01276 inline
    01277 TinyVector<V, SIZE>
    01278 floor(TinyVectorBase<V, SIZE, D1, D2> const & v)
    01279 {
    01280     TinyVector<V, SIZE> res(detail::dontInit());
    01281     typedef typename detail::LoopType<SIZE>::type ltype;
    01282     ltype::floor(res.begin(), v.begin());
    01283     return res;
    01284 }
    01285
    01286     /// cross product
    01287 template <class V1, class D1, class D2, class V2, class D3, class D4>
    01288 inline
    01289 TinyVector<typename PromoteTraits<V1, V2>::Promote, 3>
    01290 cross(TinyVectorBase<V1, 3, D1, D2> const & r1,
    01291       TinyVectorBase<V2, 3, D3, D4> const & r2)
    01292 {
    01293     typedef TinyVector<typename PromoteTraits<V1, V2>::Promote, 3>
    01294             Res;
    01295     return  Res(r1[1]*r2[2] - r1[2]*r2[1],
    01296                 r1[2]*r2[0] - r1[0]*r2[2],
    01297                 r1[0]*r2[1] - r1[1]*r2[0]);
    01298 }
    01299
    01300     /// dot product
    01301 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
    01302 inline
    01303 typename PromoteTraits<V1, V2>::Promote
    01304 dot(TinyVectorBase<V1, SIZE, D1, D2> const & l,
    01305     TinyVectorBase<V2, SIZE, D3, D4> const & r)
    01306 {
    01307     typedef typename detail::LoopType<SIZE>::type ltype;
    01308     return ltype::dot(l.begin(), r.begin());
    01309 }
    01310
    01311
    01312     /// squared norm
    01313 template <class V1, int SIZE, class D1, class D2>
    01314 inline
    01315 typename TinyVectorBase<V1, SIZE, D1, D2>::SquaredNormType
    01316 squaredNorm(TinyVectorBase<V1, SIZE, D1, D2> const & t)
    01317 {
    01318     return t.squaredMagnitude();
    01319 }
    01320
    01321     /// squared norm
    01322 template <class V, int SIZE>
    01323 inline
    01324 typename TinyVector<V, SIZE>::SquaredNormType
    01325 squaredNorm(TinyVector<V, SIZE> const & t)
    01326 {
    01327     return t.squaredMagnitude();
    01328 }
    01329 //@}
    01330
    01331
    01332 } // namespace vigra
    01333
    01334 #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.5.0 (7 Dec 2006)