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

details vigra/tinyvector.hxx VIGRA

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

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

html generated using doxygen and Python
VIGRA 1.4.0 (21 Dec 2005)