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

tinyvector.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 
37 #ifndef VIGRA_TINYVECTOR_HXX
38 #define VIGRA_TINYVECTOR_HXX
39 
40 namespace lemon {
41 
42 struct Invalid;
43 
44 } // namespace lemon
45 
46 #include <cmath> // abs(double)
47 #include <cstdlib> // abs(int)
48 #include <iosfwd> // ostream
49 #include <algorithm>
50 #include "config.hxx"
51 #include "error.hxx"
52 #include "metaprogramming.hxx"
53 #include "numerictraits.hxx"
54 #include "memory.hxx"
55 #include "mathutil.hxx"
56 #include "diff2d.hxx"
57 
58 #ifdef VIGRA_CHECK_BOUNDS
59 #define VIGRA_ASSERT_INSIDE(diff) \
60  vigra_precondition(diff >= 0, "Index out of bounds");\
61  vigra_precondition(diff < SIZE, "Index out of bounds");
62 #else
63 #define VIGRA_ASSERT_INSIDE(diff)
64 #endif
65 
66 namespace vigra {
67 
68 // mask cl.exe shortcomings [begin]
69 #if defined(_MSC_VER)
70 #pragma warning( push )
71 #pragma warning( disable : 4503 )
72 #endif
73 
74 using VIGRA_CSTD::abs;
75 using VIGRA_CSTD::ceil;
76 using VIGRA_CSTD::floor;
77 using VIGRA_CSTD::sqrt;
78 
79 
80 template <class V1, int SIZE, class D1, class D2>
82 
83 template <class V1, int SIZE, class D1, class D2>
84 inline
87 
88 
89 namespace detail {
90 
91 #define VIGRA_EXEC_LOOP(NAME, OPER) \
92  template <class T1, class T2> \
93  static void NAME(T1 * left, T2 const * right) \
94  { \
95  for(int i=0; i<LEVEL; ++i) \
96  (left[i]) OPER (right[i]); \
97  }
98 
99 #define VIGRA_EXEC_LOOP_MINMAX(NAME, OPER) \
100  template <class T1, class T2> \
101  static void NAME(T1 * left, T2 const * right) \
102  { \
103  for(int i=0; i<LEVEL; ++i) \
104  if(left[i] OPER right[i]) \
105  left[i] = right[i]; \
106  }
107 
108 #define VIGRA_EXEC_LOOP_SCALAR(NAME, OPER) \
109  template <class T1, class T2> \
110  static void NAME(T1 * left, T2 right) \
111  { \
112  for(int i=0; i<LEVEL; ++i) \
113  (left[i]) = detail::RequiresExplicitCast<T1>::cast((left[i]) OPER (right)); \
114  }
115 
116 template <int LEVEL>
117 struct ExecLoop
118 {
119  template <class T1, class T2>
120  static void assignCast(T1 * left, T2 const * right)
121  {
122  for(int i=0; i<LEVEL; ++i)
123  left[i] = detail::RequiresExplicitCast<T1>::cast(right[i]);
124  }
125 
126  template <class T1, class T2>
127  static void reverseAssign(T1 * left, T2 const * right)
128  {
129  for(int i=0; i<LEVEL; ++i)
130  left[i] = right[-i];
131  }
132 
133  template <class T1, class T2>
134  static void assignScalar(T1 * left, T2 right)
135  {
136  for(int i=0; i<LEVEL; ++i)
137  left[i] = detail::RequiresExplicitCast<T1>::cast(right);
138  }
139 
140  template <class T1, class T2>
141  static void power(T1 * left, T2 right)
142  {
143  for(int i=0; i<LEVEL; ++i)
144  left[i] = detail::RequiresExplicitCast<T1>::cast(pow(left, right));
145  }
146 
147  VIGRA_EXEC_LOOP(assign, =)
148  VIGRA_EXEC_LOOP(add, +=)
149  VIGRA_EXEC_LOOP(sub, -=)
150  VIGRA_EXEC_LOOP(mul, *=)
151  VIGRA_EXEC_LOOP(div, /=)
152  VIGRA_EXEC_LOOP(mod, %=)
153  VIGRA_EXEC_LOOP(neg, = -)
154  VIGRA_EXEC_LOOP(abs, = vigra::abs)
155  VIGRA_EXEC_LOOP(floor, = vigra::floor)
156  VIGRA_EXEC_LOOP(ceil, = vigra::ceil)
157  VIGRA_EXEC_LOOP(round, = vigra::round)
158  VIGRA_EXEC_LOOP(sqrt, = vigra::sqrt)
159  VIGRA_EXEC_LOOP(fromPromote, = NumericTraits<T1>::fromPromote)
160  VIGRA_EXEC_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote)
161  VIGRA_EXEC_LOOP_SCALAR(mulScalar, *)
162  VIGRA_EXEC_LOOP_SCALAR(divScalar, /)
163 
164  VIGRA_EXEC_LOOP_MINMAX(min, >)
165  VIGRA_EXEC_LOOP_MINMAX(max, <)
166 
167  template <class T>
168  static T const & minimum(T const * p)
169  {
170  return *std::min_element(p, p+LEVEL);
171  }
172 
173  template <class T>
174  static T const & maximum(T const * p)
175  {
176  return *std::max_element(p, p+LEVEL);
177  }
178 
179  template <class T>
180  static bool all(T const * p, T const & zero)
181  {
182  for(int i=0; i<LEVEL; ++i)
183  if(p[i] == zero)
184  return false;
185  return true;
186  }
187 
188  template <class T>
189  static bool any(T const * p, T const & zero)
190  {
191  for(int i=0; i<LEVEL; ++i)
192  if(p[i] != zero)
193  return true;
194  return false;
195  }
196 
197  template <class T1, class T2>
198  static bool notEqual(T1 const * left, T2 const * right)
199  {
200  for(int i=0; i<LEVEL; ++i)
201  if(left[i] != right[i])
202  return true;
203  return false;
204  }
205 
206  template <class T1, class T2>
207  static bool less(T1 const * left, T2 const * right)
208  {
209  for(int i=0; i<LEVEL; ++i)
210  {
211  if(left[i] < right[i])
212  return true;
213  if(right[i] < left[i])
214  return false;
215  }
216  return false;
217  }
218 
219  template <class T>
220  static bool closeAtTolerance(T const * left, T const * right, T epsilon)
221  {
222  bool res = true;
223  for(int i=0; i<LEVEL; ++i)
224  {
225  res = res && vigra::closeAtTolerance(left[i], right[i], epsilon);
226  }
227  return res;
228  }
229 
230  template <class T>
231  static typename NumericTraits<T>::Promote
232  dot(T const * d)
233  {
234  typename NumericTraits<T>::Promote res(*d * *d);
235  for(int i=1; i<LEVEL; ++i)
236  res += d[i] * d[i];
237  return res;
238  }
239 
240  template <class T1, class T2>
241  static typename PromoteTraits<T1, T2>::Promote
242  dot(T1 const * left, T2 const * right)
243  {
244  typename PromoteTraits<T1, T2>::Promote res(*left * *right);
245  for(int i=1; i<LEVEL; ++i)
246  res += left[i] * right[i];
247  return res;
248  }
249 
250  template <class T>
251  static typename NormTraits<T>::SquaredNormType
252  squaredNorm(T const * d)
253  {
254  typename NormTraits<T>::SquaredNormType res = vigra::squaredNorm(*d);
255  for(int i=1; i<LEVEL; ++i)
256  res += vigra::squaredNorm(d[i]);
257  return res;
258  }
259 };
260 
261 template <int LEVEL>
262 struct UnrollScalarResult
263 {
264  template <class T>
265  static typename NumericTraits<T>::Promote
266  dot(T const * d)
267  {
268  return *d * *d + UnrollScalarResult<LEVEL-1>::dot(d+1);
269  }
270 
271  template <class T1, class T2>
272  static typename PromoteTraits<T1, T2>::Promote
273  dot(T1 const * left, T2 const * right)
274  {
275  return *left * *right + UnrollScalarResult<LEVEL-1>::dot(left+1, right+1);
276  }
277 
278  template <class T>
279  static typename NormTraits<T>::SquaredNormType
280  squaredNorm(T const * d)
281  {
283  }
284 
285  static std::ptrdiff_t
286  squaredNorm(std::ptrdiff_t const * d)
287  {
288  return (*d)*(*d) + UnrollScalarResult<LEVEL-1>::squaredNorm(d+1);
289  }
290 
291  template <class T>
292  static T const & minimum(T const * p)
293  {
294  T const & m = UnrollScalarResult<LEVEL - 1>::minimum(p+1);
295  return *p < m
296  ? *p
297  : m;
298  }
299 
300  template <class T>
301  static T const & maximum(T const * p)
302  {
303  T const & m = UnrollScalarResult<LEVEL - 1>::maximum(p+1);
304  return *p > m
305  ? *p
306  : m;
307  }
308 
309  template <class T>
310  static bool all(T const * p, T const & zero)
311  {
312  return *p != zero && UnrollScalarResult<LEVEL - 1>::all(p+1, zero);
313  }
314 
315  template <class T>
316  static bool any(T const * p, T const & zero)
317  {
318  return *p != zero || UnrollScalarResult<LEVEL - 1>::any(p+1, zero);
319  }
320 };
321 
322 template <>
323 struct UnrollScalarResult<1>
324 {
325  template <class T>
326  static typename NumericTraits<T>::Promote
327  dot(T const * d)
328  {
329  return *d * *d ;
330  }
331 
332  template <class T1, class T2>
333  static typename PromoteTraits<T1, T2>::Promote
334  dot(T1 const * left, T2 const * right)
335  {
336  return *left * *right;
337  }
338 
339  template <class T>
340  static typename NormTraits<T>::SquaredNormType
341  squaredNorm(T const * d)
342  {
343  return vigra::squaredNorm(*d);
344  }
345 
346  static std::ptrdiff_t
347  squaredNorm(std::ptrdiff_t const * d)
348  {
349  return (*d)*(*d);
350  }
351 
352  template <class T>
353  static T const & minimum(T const * p)
354  {
355  return *p;
356  }
357 
358  template <class T>
359  static T const & maximum(T const * p)
360  {
361  return *p;
362  }
363 
364  template <class T>
365  static bool all(T const * p, T const & zero)
366  {
367  return *p != zero;
368  }
369 
370  template <class T>
371  static bool any(T const * p, T const & zero)
372  {
373  return *p != zero;
374  }
375 };
376 
377 #undef VIGRA_EXEC_LOOP
378 #undef VIGRA_EXEC_LOOP_MINMAX
379 #undef VIGRA_EXEC_LOOP_SCALAR
380 
381 #define VIGRA_UNROLL_LOOP(NAME, OPER) \
382  template <class T1, class T2> \
383  static void NAME(T1 * left, T2 const * right) \
384  { \
385  (*left) OPER (*right); \
386  UnrollLoop<LEVEL-1>::NAME(left+1, right+1); \
387  }
388 
389 #define VIGRA_UNROLL_LOOP_MINMAX(NAME, OPER) \
390  template <class T1, class T2> \
391  static void NAME(T1 * left, T2 const * right) \
392  { \
393  if(*left OPER *right) \
394  *left = *right; \
395  UnrollLoop<LEVEL-1>::NAME(left+1, right+1); \
396  }
397 
398 #define VIGRA_UNROLL_LOOP_SCALAR(NAME, OPER) \
399  template <class T1, class T2> \
400  static void NAME(T1 * left, T2 right) \
401  { \
402  (*left) = detail::RequiresExplicitCast<T1>::cast((*left) OPER (right)); \
403  UnrollLoop<LEVEL-1>::NAME(left+1, right); \
404  }
405 
406 
407 template <int LEVEL>
408 struct UnrollLoop
409 {
410  template <class T1, class T2>
411  static void reverseAssign(T1 * left, T2 const * right)
412  {
413  *left = *right;
414  UnrollLoop<LEVEL-1>::reverseAssign(left+1, right-1);
415  }
416 
417  template <class T1, class T2>
418  static void assignCast(T1 * left, T2 const * right)
419  {
420  *left = detail::RequiresExplicitCast<T1>::cast(*right);
421  UnrollLoop<LEVEL-1>::assignCast(left+1, right+1);
422  }
423 
424  template <class T1, class T2>
425  static void assignScalar(T1 * left, T2 right)
426  {
427  *left = detail::RequiresExplicitCast<T1>::cast(right);
428  UnrollLoop<LEVEL-1>::assignScalar(left+1, right);
429  }
430 
431  template <class T1, class T2>
432  static void power(T1 * left, T2 right)
433  {
434  *left = detail::RequiresExplicitCast<T1>::cast(pow(*left, right));
435  UnrollLoop<LEVEL-1>::power(left+1, right);
436  }
437 
438  VIGRA_UNROLL_LOOP(assign, =)
439  VIGRA_UNROLL_LOOP(add, +=)
440  VIGRA_UNROLL_LOOP(sub, -=)
441  VIGRA_UNROLL_LOOP(mul, *=)
442  VIGRA_UNROLL_LOOP(div, /=)
443  VIGRA_UNROLL_LOOP(mod, %=)
444  VIGRA_UNROLL_LOOP(neg, = -)
445  VIGRA_UNROLL_LOOP(abs, = vigra::abs)
446  VIGRA_UNROLL_LOOP(floor, = vigra::floor)
447  VIGRA_UNROLL_LOOP(ceil, = vigra::ceil)
448  VIGRA_UNROLL_LOOP(round, = vigra::round)
449  VIGRA_UNROLL_LOOP(sqrt, = vigra::sqrt)
450  VIGRA_UNROLL_LOOP(fromPromote, = NumericTraits<T1>::fromPromote)
451  VIGRA_UNROLL_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote)
452  VIGRA_UNROLL_LOOP_SCALAR(mulScalar, *)
453  VIGRA_UNROLL_LOOP_SCALAR(divScalar, /)
454 
455  VIGRA_UNROLL_LOOP_MINMAX(min, >)
456  VIGRA_UNROLL_LOOP_MINMAX(max, <)
457 
458  template <class T>
459  static T const & minimum(T const * p)
460  {
461  return UnrollScalarResult<LEVEL>::minimum(p);
462  }
463 
464  template <class T>
465  static T const & maximum(T const * p)
466  {
467  return UnrollScalarResult<LEVEL>::maximum(p);
468  }
469 
470  template <class T>
471  static bool all(T const * p, T const & zero)
472  {
473  return UnrollScalarResult<LEVEL>::all(p, zero);
474  }
475 
476  template <class T>
477  static bool any(T const * p, T const & zero)
478  {
479  return UnrollScalarResult<LEVEL>::any(p, zero);
480  }
481 
482  template <class T1, class T2>
483  static bool notEqual(T1 const * left, T2 const * right)
484  {
485  return (*left != *right) || UnrollLoop<LEVEL - 1>::notEqual(left+1, right+1);
486  }
487 
488  template <class T1, class T2>
489  static bool less(T1 const * left, T2 const * right)
490  {
491  if(*left < *right)
492  return true;
493  if(*right < *left)
494  return false;
495  return UnrollLoop<LEVEL - 1>::less(left+1, right+1);
496  }
497 
498  template <class T>
499  static bool closeAtTolerance(T const * left, T const * right, T epsilon)
500  {
501  return vigra::closeAtTolerance(*left, *right, epsilon) &&
502  UnrollLoop<LEVEL - 1>::closeAtTolerance(left+1, right+1, epsilon);
503  }
504 
505  template <class T>
506  static typename NumericTraits<T>::Promote
507  dot(T const * d)
508  {
510  }
511 
512  template <class T1, class T2>
513  static typename PromoteTraits<T1, T2>::Promote
514  dot(T1 const * left, T2 const * right)
515  {
516  return UnrollScalarResult<LEVEL>::dot(left, right);
517  }
518 
519  template <class T>
520  static typename NormTraits<T>::SquaredNormType
521  squaredNorm(T const * d)
522  {
524  }
525 };
526 
527 #undef VIGRA_UNROLL_LOOP
528 #undef VIGRA_UNROLL_LOOP_MINMAX
529 #undef VIGRA_UNROLL_LOOP_SCALAR
530 
531 template <>
532 struct UnrollLoop<0>
533 {
534  template <class T1, class T2>
535  static void reverseAssign(T1, T2) {}
536  template <class T1, class T2>
537  static void assignCast(T1, T2) {}
538  template <class T1, class T2>
539  static void assign(T1, T2) {}
540  template <class T1, class T2>
541  static void assignScalar(T1, T2) {}
542  template <class T1, class T2>
543  static void power(T1, T2) {}
544  template <class T1, class T2>
545  static void add(T1, T2) {}
546  template <class T1, class T2>
547  static void sub(T1, T2) {}
548  template <class T1, class T2>
549  static void mul(T1, T2) {}
550  template <class T1, class T2>
551  static void mulScalar(T1, T2) {}
552  template <class T1, class T2>
553  static void div(T1, T2) {}
554  template <class T1, class T2>
555  static void mod(T1, T2) {}
556  template <class T1, class T2>
557  static void divScalar(T1, T2) {}
558  template <class T1, class T2>
559  static void fromPromote(T1, T2) {}
560  template <class T1, class T2>
561  static void fromRealPromote(T1, T2) {}
562  template <class T1, class T2>
563  static void neg(T1, T2) {}
564  template <class T1, class T2>
565  static void abs(T1, T2) {}
566  template <class T1, class T2>
567  static void floor(T1, T2) {}
568  template <class T1, class T2>
569  static void ceil(T1, T2) {}
570  template <class T1, class T2>
571  static void round(T1, T2) {}
572  template <class T1, class T2>
573  static void sqrt(T1, T2) {}
574  template <class T1, class T2>
575  static bool notEqual(T1, T2) { return false; }
576  template <class T1, class T2>
577  static bool less(T1, T2) { return false; }
578  template <class T1, class T2>
579  static void min(T1, T2) {}
580  template <class T1, class T2>
581  static void max(T1, T2) {}
582  template <class T>
583  static T minimum(T const *) { return NumericTraits<T>::max(); }
584  template <class T>
585  static T maximum(T const *) { return NumericTraits<T>::min(); }
586  template <class T>
587  static bool all(T const *, T const &) { return true; }
588  template <class T>
589  static bool any(T const *, T const &) { return false; }
590  template <class T>
591  static bool closeAtTolerance(T const *, T const *, T) { return true; }
592 };
593 
594 template <int SIZE>
595 struct LoopType
596 {
597  static const int MaxUnrollSize = 5;
598  typedef typename IfBool<(SIZE <= MaxUnrollSize), UnrollLoop<SIZE>, ExecLoop<SIZE> >::type type;
599 
600 };
601 
602 struct DontInit {};
603 
604 inline DontInit dontInit() {return DontInit(); }
605 
606 } // namespace detail
607 
608 template <class T, int SIZE>
609 class TinyVector;
610 
611 template <class T, int SIZE>
613 
614 /********************************************************/
615 /* */
616 /* TinyVectorBase */
617 /* */
618 /********************************************************/
619 
620 /** \brief Base class for fixed size vectors.
621 
622  This class contains functionality shared by
623  \ref TinyVector and \ref TinyVectorView, and enables these classes
624  to be freely mixed within expressions. It is typically not used directly.
625 
626  <b>\#include</b> <vigra/tinyvector.hxx><br>
627  Namespace: vigra
628 **/
629 template <class VALUETYPE, int SIZE, class DATA, class DERIVED>
630 class TinyVectorBase
631 {
632  TinyVectorBase(TinyVectorBase const &); // do not use
633 
634  TinyVectorBase & operator=(TinyVectorBase const & other); // do not use
635 
636  protected:
637 
638  typedef typename detail::LoopType<SIZE>::type Loop;
639 
641  {}
642 
643  public:
644  /** STL-compatible definition of valuetype
645  */
646  typedef VALUETYPE value_type;
647 
648  /** reference (return of operator[]).
649  */
650  typedef VALUETYPE & reference;
651 
652  /** const reference (return of operator[] const).
653  */
654  typedef VALUETYPE const & const_reference;
655 
656  /** pointer (return of operator->).
657  */
658  typedef VALUETYPE * pointer;
659 
660  /** const pointer (return of operator-> const).
661  */
662  typedef VALUETYPE const * const_pointer;
663 
664  /** STL-compatible definition of iterator
665  */
666  typedef value_type * iterator;
667 
668  /** STL-compatible definition of const iterator
669  */
670  typedef value_type const * const_iterator;
671 
672  /** STL-compatible definition of size_type
673  */
674  typedef unsigned int size_type;
675 
676  /** STL-compatible definition of difference_type
677  */
678  typedef std::ptrdiff_t difference_type;
679 
680  /** the scalar type for the outer product
681  */
682  typedef double scalar_multiplier;
683 
684  /** the vector's squared norm type
685  */
686  typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
687 
688  /** the vector's norm type
689  */
690  typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
691 
692  /** the vector's size
693  */
694  enum { static_size = SIZE };
695 
696  /** Initialize from another sequence (must have length SIZE!)
697  */
698  template <class Iterator>
699  void init(Iterator i, Iterator end)
700  {
701  vigra_precondition(end-i == SIZE,
702  "TinyVector::init(): Sequence has wrong size.");
703  Loop::assignCast(data_, i);
704  }
705 
706  /** Initialize with constant value
707  */
708  void init(value_type initial)
709  {
710  Loop::assignScalar(data_, initial);
711  }
712 
713  /** Component-wise add-assignment
714  */
715  template <class T1, class D1, class D2>
717  {
718  Loop::add(data_, r.begin());
719  return static_cast<DERIVED &>(*this);
720  }
721 
722  /** Component-wise subtract-assignment
723  */
724  template <class T1, class D1, class D2>
726  {
727  Loop::sub(data_, r.begin());
728  return static_cast<DERIVED &>(*this);
729  }
730 
731  /** Component-wise multiply-assignment
732  */
733  template <class T1, class D1, class D2>
735  {
736  Loop::mul(data_, r.begin());
737  return static_cast<DERIVED &>(*this);
738  }
739 
740  /** Component-wise divide-assignment
741  */
742  template <class T1, class D1, class D2>
744  {
745  Loop::div(data_, r.begin());
746  return static_cast<DERIVED &>(*this);
747  }
748 
749  /** Component-wise modulo-assignment
750  */
751  template <class T1, class D1, class D2>
753  {
754  Loop::mod(data_, r.begin());
755  return static_cast<DERIVED &>(*this);
756  }
757 
758  /** Component-wise scalar multiply-assignment
759  */
760  DERIVED & operator*=(double r)
761  {
762  Loop::mulScalar(data_, r);
763  return static_cast<DERIVED &>(*this);
764  }
765 
766  /** Component-wise scalar divide-assignment
767  */
768  DERIVED & operator/=(double r)
769  {
770  Loop::divScalar(data_, r);
771  return static_cast<DERIVED &>(*this);
772  }
773 
774  /** Calculate magnitude.
775  */
776  NormType magnitude() const
777  {
778  return sqrt(static_cast<typename
779  SquareRootTraits<SquaredNormType>::SquareRootArgument>(squaredMagnitude()));
780  }
781 
782  /** Calculate squared magnitude.
783  */
784  SquaredNormType squaredMagnitude() const
785  {
786  return Loop::squaredNorm(data_);
787  }
788 
789  /** Return the minimal element.
790  */
791  VALUETYPE const & minimum() const
792  {
793  return Loop::minimum(data_);
794  }
795 
796  /** Return the maximal element.
797  */
798  VALUETYPE const & maximum() const
799  {
800  return Loop::maximum(data_);
801  }
802 
803  /** Check that all elements of this vector are non-zero (or 'true' if T is bool).
804  */
805  bool all() const
806  {
807  return Loop::all(data_, VALUETYPE());
808  }
809 
810  /** Check that at least one element of this vector is non-zero (or 'true' if T is bool).
811  */
812  bool any() const
813  {
814  return Loop::any(data_, VALUETYPE());
815  }
816 
817  /** Access component by index.
818  */
819  reference operator[](difference_type i)
820  {
821  VIGRA_ASSERT_INSIDE(i);
822  return data_[i];
823  }
824 
825  /** Get component by index.
826  */
827  const_reference operator[](difference_type i) const
828  {
829  VIGRA_ASSERT_INSIDE(i);
830  return data_[i];
831  }
832 
833  /** Get random access iterator to begin of vector.
834  */
835  iterator begin() { return data_; }
836  /** Get random access iterator past-the-end of vector.
837  */
838  iterator end() { return data_ + SIZE; }
839 
840  /** Get const random access iterator to begin of vector.
841  */
842  const_iterator begin() const { return data_; }
843 
844  /** Get const random access iterator past-the-end of vector.
845  */
846  const_iterator end() const { return data_ + SIZE; }
847 
848  /** Get a view to the subarray with length <tt>(TO-FROM)</tt> starting at <tt>FROM</tt>.
849  The bounds must fullfill <tt>0 <= FROM < TO <= SIZE</tt>, but this is only
850  checked when <tt>VIGRA_CHECK_BOUNDS</tt> is \#define'd.
851  */
852  template <int FROM, int TO>
853  TinyVectorView<VALUETYPE, TO-FROM> subarray() const
854  {
855 #ifdef VIGRA_CHECK_BOUNDS
856  vigra_precondition(FROM >= 0, "Index out of bounds");
857  vigra_precondition(FROM < TO, "Index out of bounds");
858  vigra_precondition(TO <=SIZE, "Index out of bounds");
859 #endif
860  return TinyVectorView<VALUETYPE, TO-FROM>(data_+FROM);
861  }
862 
863  /** Size of TinyVector vector always equals the template parameter SIZE.
864  */
865  size_type size() const { return SIZE; }
866 
867  pointer data() { return data_; }
868 
869  const_pointer data() const { return data_; }
870 
871  static TinyVector<VALUETYPE, SIZE> unitVector(int k)
872  {
873  VIGRA_ASSERT_INSIDE(k);
875  ret[k] = 1;
876  return ret;
877  }
878 
879  protected:
880 
881  DATA data_;
882 };
883 
884 /** \brief Class for fixed size vectors.
885  \ingroup RangesAndPoints
886 
887  This class contains an array of size SIZE of the specified VALUETYPE.
888  The interface conforms to STL vector, except that there are no functions
889  that change the size of a TinyVector.
890 
891  \ref TinyVectorOperators "Arithmetic operations"
892  on TinyVectors are defined as component-wise applications of these
893  operations. Addition and subtraction of two TinyVectors
894  (+=, -=, +, -, unary -), multiplication and division of an
895  TinyVector with a double, and NumericTraits/PromoteTraits are defined,
896  so that TinyVector fulfills the requirements of \ref LinearAlgebraConcept "Linear Algebra".
897 
898  VIGRA algorithms typically use \ref vigra::VectorAccessor to access
899  TinyVectors as a whole, or specific components of them.
900 
901  See also:<br>
902  <UL style="list-style-image:url(documents/bullet.gif)">
903  <LI> \ref vigra::TinyVectorBase
904  <LI> \ref vigra::TinyVectorView
905  <LI> \ref TinyVectorTraits
906  <LI> \ref TinyVectorOperators
907  </UL>
908 
909  <b>\#include</b> <vigra/tinyvector.hxx><br>
910  Namespace: vigra
911 **/
912 template <class T, int SIZE>
913 class TinyVector
914 : public TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> >
915 {
917  typedef typename BaseType::Loop Loop;
918 
919  public:
920 
921  typedef typename BaseType::value_type value_type;
922  typedef typename BaseType::reference reference;
923  typedef typename BaseType::const_reference const_reference;
924  typedef typename BaseType::pointer pointer;
925  typedef typename BaseType::const_pointer const_pointer;
926  typedef typename BaseType::iterator iterator;
927  typedef typename BaseType::const_iterator const_iterator;
928  typedef typename BaseType::size_type size_type;
929  typedef typename BaseType::difference_type difference_type;
930  typedef typename BaseType::scalar_multiplier scalar_multiplier;
931  typedef typename BaseType::SquaredNormType SquaredNormType;
932  typedef typename BaseType::NormType NormType;
933 
934  enum ReverseCopyTag { ReverseCopy };
935 
936  /** Construction with constant value.
937 
938  Initializes all vector elements with the given value.
939  */
940  explicit TinyVector(value_type const & initial)
941  : BaseType()
942  {
943  Loop::assignScalar(BaseType::begin(), initial);
944  }
945 
946  /** Construction from lemon::Invalid.
947 
948  Initializes all vector elements with -1.
949  */
950  TinyVector(lemon::Invalid const &)
951  : BaseType()
952  {
953  Loop::assignScalar(BaseType::begin(), -1);
954  }
955 
956  /** Construction with Diff2D.
957 
958  Use only when <tt>SIZE == 2</tt>.
959  */
960  explicit TinyVector(Diff2D const & initial)
961  : BaseType()
962  {
963  BaseType::data_[0] = detail::RequiresExplicitCast<T>::cast(initial.x);
964  BaseType::data_[1] = detail::RequiresExplicitCast<T>::cast(initial.y);
965  }
966 
967  /** Construction with explicit values.
968  Call only if SIZE == 2
969  */
970  TinyVector(value_type const & i1, value_type const & i2)
971  : BaseType()
972  {
973  BaseType::data_[0] = i1;
974  BaseType::data_[1] = i2;
975  }
976 
977  /** Construction with explicit values.
978  Call only if SIZE == 3
979  */
980  TinyVector(value_type const & i1, value_type const & i2, value_type const & i3)
981  : BaseType()
982  {
983  BaseType::data_[0] = i1;
984  BaseType::data_[1] = i2;
985  BaseType::data_[2] = i3;
986  }
987 
988  /** Construction with explicit values.
989  Call only if SIZE == 4
990  */
991  TinyVector(value_type const & i1, value_type const & i2,
992  value_type const & i3, value_type const & i4)
993  : BaseType()
994  {
995  BaseType::data_[0] = i1;
996  BaseType::data_[1] = i2;
997  BaseType::data_[2] = i3;
998  BaseType::data_[3] = i4;
999  }
1000 
1001  /** Construction with explicit values.
1002  Call only if SIZE == 5
1003  */
1004  TinyVector(value_type const & i1, value_type const & i2,
1005  value_type const & i3, value_type const & i4,
1006  value_type const & i5)
1007  : BaseType()
1008  {
1009  BaseType::data_[0] = i1;
1010  BaseType::data_[1] = i2;
1011  BaseType::data_[2] = i3;
1012  BaseType::data_[3] = i4;
1013  BaseType::data_[4] = i5;
1014  }
1015 
1016  /** Default constructor (initializes all elements with zero).
1017  */
1019  : BaseType()
1020  {
1021  Loop::assignScalar(BaseType::data_, value_type());
1022  }
1023 
1024  /** Construct without initializing the vector elements.
1025  */
1026  explicit TinyVector(SkipInitializationTag)
1027  : BaseType()
1028  {}
1029 
1030  explicit TinyVector(detail::DontInit)
1031  : BaseType()
1032  {}
1033 
1034  /** Copy constructor.
1035  */
1037  : BaseType()
1038  {
1039  Loop::assign(BaseType::data_, r.data_);
1040  }
1041 
1042  /** Constructor from C array.
1043  */
1044  template <class U>
1045  explicit TinyVector(U const * data)
1046  : BaseType()
1047  {
1048  Loop::assign(BaseType::data_, data);
1049  }
1050 
1051  /** Constructor by reverse copy from C array.
1052 
1053  Usage:
1054  \code
1055  TinyVector<int, 3> v(1,2,3);
1056  TinyVector<int, 3> reversed(v.begin(), TinyVector<int, 3>::ReverseCopy);
1057  \endcode
1058  */
1059  explicit TinyVector(const_pointer data, ReverseCopyTag)
1060  : BaseType()
1061  {
1062  Loop::reverseAssign(BaseType::data_, data+SIZE-1);
1063  }
1064 
1065  /** Copy with type conversion.
1066  */
1067  template <class U, class DATA, class DERIVED>
1069  : BaseType()
1070  {
1071  Loop::assignCast(BaseType::data_, r.begin());
1072  }
1073 
1074  /** Copy assignment.
1075  */
1077  {
1078  Loop::assign(BaseType::data_, r.data_);
1079  return *this;
1080  }
1081 
1082  /** Copy assignment with type conversion.
1083  */
1084  template <class U, class DATA, class DERIVED>
1086  {
1087  Loop::assignCast(BaseType::data_, r.begin());
1088  return *this;
1089  }
1090 
1091  /** Assignment from Diff2D.
1092 
1093  Use only when <tt>SIZE == 2</tt>.
1094  */
1096  {
1097  BaseType::data_[0] = detail::RequiresExplicitCast<T>::cast(r.x);
1098  BaseType::data_[1] = detail::RequiresExplicitCast<T>::cast(r.y);
1099  return *this;
1100  }
1101 
1102  /** Assignment from scalar. Will set all entries to the given value.
1103  */
1104  TinyVector & operator=(value_type const & v)
1105  {
1106  Loop::assignScalar(BaseType::begin(), v);
1107  return *this;
1108  }
1109 
1110  /** Copy from a TinyVector with a different number of elements.
1111 
1112  Only the first <tt>min(SIZE, USIZE)</tt> elements are copied.
1113  */
1114  template <class U, int USIZE, class DATA, class DERIVED>
1116  {
1117  static const int minSize = USIZE < SIZE
1118  ? USIZE
1119  : SIZE;
1120 
1121  typedef typename detail::LoopType<minSize>::type MinLoop;
1122  MinLoop::assignCast(BaseType::data_, r.begin());
1123  return *this;
1124  }
1125 };
1126 
1127 /** \brief Wrapper for fixed size vectors.
1128 
1129  This class wraps an array of size SIZE of the specified VALUETYPE.
1130  Thus, the array can be accessed with an interface similar to
1131  that of std::vector (except that there are no functions
1132  that change the size of a TinyVectorView). The TinyVectorView
1133  does <em>not</em> assume ownership of the given memory.
1134 
1135  \ref TinyVectorOperators "Arithmetic operations"
1136  on TinyVectorViews are defined as component-wise applications of these
1137  operations. Addition and subtraction of two TinyVectorViews
1138  (+=, -=, +, -, unary -), multiplication and division of an
1139  TinyVectorViews with a double, and NumericTraits/PromoteTraits are defined,
1140  so that TinyVectorView fulfills the requirements of \ref LinearAlgebraConcept "Linear Algebra".
1141 
1142  VIGRA algorithms typically use \ref vigra::VectorAccessor to access
1143  TinyVectorViews as a whole, or specific components of them.
1144 
1145  <b>See also:</b>
1146  <ul>
1147  <li> \ref vigra::TinyVectorBase
1148  <li> \ref vigra::TinyVector
1149  <li> \ref TinyVectorTraits
1150  <li> \ref TinyVectorOperators
1151  </ul>
1152 
1153  <b>\#include</b> <vigra/tinyvector.hxx><br>
1154  Namespace: vigra
1155 **/
1156 template <class T, int SIZE>
1157 class TinyVectorView
1158 : public TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> >
1159 {
1161  typedef typename BaseType::Loop Loop;
1162 
1163  public:
1164 
1165  typedef typename BaseType::value_type value_type;
1166  typedef typename BaseType::reference reference;
1167  typedef typename BaseType::const_reference const_reference;
1168  typedef typename BaseType::pointer pointer;
1169  typedef typename BaseType::const_pointer const_pointer;
1170  typedef typename BaseType::iterator iterator;
1171  typedef typename BaseType::const_iterator const_iterator;
1172  typedef typename BaseType::size_type size_type;
1173  typedef typename BaseType::difference_type difference_type;
1174  typedef typename BaseType::scalar_multiplier scalar_multiplier;
1175  typedef typename BaseType::SquaredNormType SquaredNormType;
1176  typedef typename BaseType::NormType NormType;
1177 
1178  /** Default constructor
1179  (pointer to wrapped data is NULL).
1180  */
1182  : BaseType()
1183  {
1184  BaseType::data_ = 0;
1185  }
1186 
1187  /** Construct view for given data array
1188  */
1189  TinyVectorView(const_pointer data)
1190  : BaseType()
1191  {
1192  BaseType::data_ = const_cast<pointer>(data);
1193  }
1194 
1195  /** Copy constructor (shallow copy).
1196  */
1198  : BaseType()
1199  {
1200  BaseType::data_ = const_cast<pointer>(other.data_);
1201  }
1202 
1203  /** Construct view from other TinyVector.
1204  */
1205  template <class DATA, class DERIVED>
1207  : BaseType()
1208  {
1209  BaseType::data_ = const_cast<pointer>(other.data());
1210  }
1211 
1212  /** Copy the data (not the pointer) of the rhs.
1213  */
1215  {
1216  Loop::assign(BaseType::data_, r.begin());
1217  return *this;
1218  }
1219 
1220  /** Copy the data of the rhs with cast.
1221  */
1222  template <class U, class DATA, class DERIVED>
1224  {
1225  Loop::assignCast(BaseType::data_, r.begin());
1226  return *this;
1227  }
1228 };
1229 
1230 /********************************************************/
1231 /* */
1232 /* TinyVector Comparison */
1233 /* */
1234 /********************************************************/
1235 
1236 /** \addtogroup TinyVectorOperators Functions for TinyVector
1237 
1238  \brief Implement basic arithmetic and equality for TinyVector.
1239 
1240  These functions fulfill the requirements of a Linear Space (vector space).
1241  Return types are determined according to \ref TinyVectorTraits.
1242 
1243  <b>\#include</b> <vigra/tinyvector.hxx><br>
1244  Namespace: vigra
1245 */
1246 //@{
1247  /// component-wise equal
1248 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1249 inline bool
1252 {
1253  return !(l != r);
1254 }
1255 
1256  /// component-wise not equal
1257 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1258 inline bool
1261 {
1262  typedef typename detail::LoopType<SIZE>::type ltype;
1263  return ltype::notEqual(l.begin(), r.begin());
1264 }
1265 
1266  /// lexicographical comparison
1267 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1268 inline bool
1269 operator<(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1271 {
1272  typedef typename detail::LoopType<SIZE>::type ltype;
1273  return ltype::less(l.begin(), r.begin());
1274 }
1275 
1276 template <class V, int SIZE, class D1, class D2, class D3, class D4>
1277 bool
1278 closeAtTolerance(TinyVectorBase<V, SIZE, D1, D2> const & l,
1280  V epsilon = NumericTraits<V>::epsilon())
1281 {
1282  typedef typename detail::LoopType<SIZE>::type ltype;
1283  return ltype::closeAtTolerance(l.begin(), r.begin(), epsilon);
1284 }
1285 
1286 template <class V, int SIZE>
1287 bool
1288 closeAtTolerance(TinyVector<V, SIZE> const & l,
1289  TinyVector<V, SIZE> const & r,
1290  V epsilon = NumericTraits<V>::epsilon())
1291 {
1292  typedef typename detail::LoopType<SIZE>::type ltype;
1293  return ltype::closeAtTolerance(l.begin(), r.begin(), epsilon);
1294 }
1295 
1296 /********************************************************/
1297 /* */
1298 /* TinyVector Output */
1299 /* */
1300 /********************************************************/
1301 
1302  /// stream output
1303 template <class V1, int SIZE, class DATA, class DERIVED>
1304 std::ostream &
1305 operator<<(std::ostream & out, TinyVectorBase<V1, SIZE, DATA, DERIVED> const & l)
1306 {
1307  out << "(";
1308  int i;
1309  for(i=0; i<SIZE-1; ++i)
1310  out << l[i] << ", ";
1311  out << l[i] << ")";
1312  return out;
1313 }
1314 //@}
1315 
1316 /********************************************************/
1317 /* */
1318 /* TinyVector-Traits */
1319 /* */
1320 /********************************************************/
1321 
1322 /** \page TinyVectorTraits Numeric and Promote Traits of TinyVector
1323  The numeric and promote traits for TinyVectors follow
1324  the general specifications for \ref NumericPromotionTraits.
1325  They are implemented in terms of the traits of the basic types by
1326  partial template specialization:
1327 
1328  \code
1329 
1330  template <class T, int SIZE>
1331  struct NumericTraits<TinyVector<T, SIZE> >
1332  {
1333  typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
1334  typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
1335 
1336  typedef typename NumericTraits<T>::isIntegral isIntegral;
1337  typedef VigraFalseType isScalar;
1338  typedef typename NumericTraits<T>::isSigned isSigned;
1339 
1340  // etc.
1341  };
1342 
1343  template <class T, int SIZE>
1344  struct NormTraits<TinyVector<T, SIZE> >
1345  {
1346  typedef TinyVector<T, SIZE> Type;
1347  typedef typename Type::SquaredNormType SquaredNormType;
1348  typedef typename Type::NormType NormType;
1349  };
1350 
1351  template <class T1, class T2, SIZE>
1352  struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
1353  {
1354  typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1355  };
1356  \endcode
1357 
1358  <b>\#include</b> <vigra/tinyvector.hxx><br>
1359  Namespace: vigra
1360 
1361  On compilers that don't support partial template specialization (e.g.
1362  MS VisualC++), the traits classes are explicitly specialized for
1363  <TT>TinyVector<VALUETYPE, SIZE></TT> with
1364  <TT>VALUETYPE = unsigned char | int | float | double</TT> and <TT>SIZE = 2 | 3 | 4</TT>.
1365 
1366 */
1367 
1368 #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
1369 
1370 template <class T, int SIZE>
1371 struct NumericTraits<TinyVector<T, SIZE> >
1372 {
1373  typedef TinyVector<T, SIZE> Type;
1374  typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
1375  typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
1376  typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
1377  typedef T ValueType;
1378 
1379  typedef typename NumericTraits<T>::isIntegral isIntegral;
1380  typedef VigraFalseType isScalar;
1381  typedef typename NumericTraits<T>::isSigned isSigned;
1382  typedef VigraTrueType isOrdered;
1383  typedef VigraFalseType isComplex;
1384 
1385  static TinyVector<T, SIZE> zero()
1386  {
1387  return TinyVector<T, SIZE>(NumericTraits<T>::zero());
1388  }
1389  static TinyVector<T, SIZE> one()
1390  {
1391  return TinyVector<T, SIZE>(NumericTraits<T>::one());
1392  }
1393  static TinyVector<T, SIZE> nonZero()
1394  {
1395  return TinyVector<T, SIZE>(NumericTraits<T>::nonZero());
1396  }
1397 
1398  static TinyVector<T, SIZE> min()
1399  {
1401  }
1402  static TinyVector<T, SIZE> max()
1403  {
1405  }
1406 
1407  template <class D1, class D2>
1408  static Promote toPromote(TinyVectorBase<T, SIZE, D1, D2> const & v)
1409  {
1410  return Promote(v);
1411  }
1412 
1413  template <class D1, class D2>
1414  static RealPromote toRealPromote(TinyVectorBase<T, SIZE, D1, D2> const & v)
1415  {
1416  return RealPromote(v);
1417  }
1418 
1419  template <class D1, class D2>
1420  static TinyVector<T, SIZE>
1421  fromPromote(TinyVectorBase<typename NumericTraits<T>::Promote, SIZE, D1, D2> const & v)
1422  {
1423  TinyVector<T, SIZE> res(detail::dontInit());
1424  typedef typename detail::LoopType<SIZE>::type ltype;
1425  ltype::fromPromote(res.begin(), v.begin());
1426  return res;
1427  }
1428 
1429  template <class D1, class D2>
1430  static TinyVector<T, SIZE>
1431  fromRealPromote(TinyVectorBase<typename NumericTraits<T>::RealPromote, SIZE, D1, D2> const & v)
1432  {
1433  TinyVector<T, SIZE> res(detail::dontInit());
1434  typedef typename detail::LoopType<SIZE>::type ltype;
1435  ltype::fromRealPromote(res.begin(), v.begin());
1436  return res;
1437  }
1438 };
1439 
1440 template <class T, int SIZE>
1441 struct NumericTraits<TinyVectorView<T, SIZE> >
1442 : public NumericTraits<TinyVector<T, SIZE> >
1443 {
1444  typedef TinyVector<T, SIZE> Type;
1445  typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
1446  typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
1447  typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
1448  typedef T ValueType;
1449 
1450  typedef typename NumericTraits<T>::isIntegral isIntegral;
1451  typedef VigraFalseType isScalar;
1452  typedef typename NumericTraits<T>::isSigned isSigned;
1453  typedef VigraFalseType isOrdered;
1454  typedef VigraFalseType isComplex;
1455 };
1456 
1457 template <class T, int SIZE>
1458 struct NormTraits<TinyVector<T, SIZE> >
1459 {
1460  typedef TinyVector<T, SIZE> Type;
1461  typedef typename Type::SquaredNormType SquaredNormType;
1462  typedef typename Type::NormType NormType;
1463 };
1464 
1465 template <class T, int SIZE>
1466 struct NormTraits<TinyVectorView<T, SIZE> >
1467 {
1468  typedef TinyVector<T, SIZE> Type;
1469  typedef typename Type::SquaredNormType SquaredNormType;
1470  typedef typename Type::NormType NormType;
1471 };
1472 
1473 template <class T1, class T2, int SIZE>
1474 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
1475 {
1477 };
1478 
1479 template <class T1, class T2, int SIZE>
1480 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVectorView<T2, SIZE> >
1481 {
1483 };
1484 
1485 template <class T1, class T2, int SIZE>
1486 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVector<T2, SIZE> >
1487 {
1489 };
1490 
1491 template <class T1, class T2, int SIZE>
1492 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVectorView<T2, SIZE> >
1493 {
1495 };
1496 
1497 template <class T, int SIZE>
1498 struct PromoteTraits<TinyVector<T, SIZE>, double >
1499 {
1501 };
1502 
1503 template <class T, int SIZE>
1504 struct PromoteTraits<double, TinyVector<T, SIZE> >
1505 {
1507 };
1508 
1509 template <class T, int SIZE>
1510 struct PromoteTraits<TinyVectorView<T, SIZE>, double >
1511 {
1513 };
1514 
1515 template <class T, int SIZE>
1516 struct PromoteTraits<double, TinyVectorView<T, SIZE> >
1517 {
1519 };
1520 
1521 template<class T, int SIZE>
1522 struct CanSkipInitialization<TinyVectorView<T, SIZE> >
1523 {
1524  typedef typename CanSkipInitialization<T>::type type;
1525  static const bool value = type::asBool;
1526 };
1527 
1528 template<class T, int SIZE>
1529 struct CanSkipInitialization<TinyVector<T, SIZE> >
1530 {
1531  typedef typename CanSkipInitialization<T>::type type;
1532  static const bool value = type::asBool;
1533 };
1534 
1535 
1536 
1537 #else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1538 
1539 
1540 #define TINYVECTOR_NUMTRAITS(T, SIZE) \
1541 template<>\
1542 struct NumericTraits<TinyVector<T, SIZE> >\
1543 {\
1544  typedef TinyVector<T, SIZE> Type;\
1545  typedef TinyVector<NumericTraits<T>::Promote, SIZE> Promote;\
1546  typedef TinyVector<NumericTraits<T>::RealPromote, SIZE> RealPromote;\
1547  typedef TinyVector<NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;\
1548  typedef T ValueType; \
1549  typedef NumericTraits<T>::isIntegral isIntegral;\
1550  typedef VigraFalseType isScalar;\
1551  typedef NumericTraits<T>::isSigned isSigned; \
1552  typedef VigraFalseType isOrdered;\
1553  typedef VigraFalseType isComplex;\
1554  \
1555  static TinyVector<T, SIZE> zero() { \
1556  return TinyVector<T, SIZE>(NumericTraits<T>::zero()); \
1557  }\
1558  static TinyVector<T, SIZE> one() { \
1559  return TinyVector<T, SIZE>(NumericTraits<T>::one()); \
1560  }\
1561  static TinyVector<T, SIZE> nonZero() { \
1562  return TinyVector<T, SIZE>(NumericTraits<T>::nonZero()); \
1563  }\
1564  \
1565  static Promote toPromote(TinyVector<T, SIZE> const & v) { \
1566  return Promote(v); \
1567  }\
1568  static RealPromote toRealPromote(TinyVector<T, SIZE> const & v) { \
1569  return RealPromote(v); \
1570  }\
1571  static TinyVector<T, SIZE> fromPromote(Promote const & v) { \
1572  TinyVector<T, SIZE> res;\
1573  TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
1574  Promote::const_iterator s = v.begin();\
1575  for(; d != dend; ++d, ++s)\
1576  *d = NumericTraits<T>::fromPromote(*s);\
1577  return res;\
1578  }\
1579  static TinyVector<T, SIZE> fromRealPromote(RealPromote const & v) {\
1580  TinyVector<T, SIZE> res;\
1581  TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
1582  RealPromote::const_iterator s = v.begin();\
1583  for(; d != dend; ++d, ++s)\
1584  *d = NumericTraits<T>::fromRealPromote(*s);\
1585  return res;\
1586  }\
1587 }; \
1588 template<>\
1589 struct NormTraits<TinyVector<T, SIZE> >\
1590 {\
1591  typedef TinyVector<T, SIZE> Type;\
1592  typedef Type::SquaredNormType SquaredNormType; \
1593  typedef Type::NormType NormType; \
1594 };
1595 
1596 #define TINYVECTOR_PROMTRAITS1(type1, SIZE) \
1597 template<> \
1598 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type1, SIZE> > \
1599 { \
1600  typedef TinyVector<PromoteTraits<type1, type1>::Promote, SIZE> Promote; \
1601  static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
1602  return static_cast<Promote>(v); } \
1603 };
1604 
1605 #define TINYVECTOR_PROMTRAITS2(type1, type2, SIZE) \
1606 template<> \
1607 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type2, SIZE> > \
1608 { \
1609  typedef TinyVector<PromoteTraits<type1, type2>::Promote, SIZE> Promote; \
1610  static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
1611  return static_cast<Promote>(v); } \
1612  static Promote toPromote(TinyVector<type2, SIZE> const & v) { \
1613  return static_cast<Promote>(v); } \
1614 };
1615 
1616 #define TINYVECTOR_TRAITS(SIZE) \
1617 TINYVECTOR_NUMTRAITS(unsigned char, SIZE)\
1618 TINYVECTOR_NUMTRAITS(int, SIZE)\
1619 TINYVECTOR_NUMTRAITS(float, SIZE)\
1620 TINYVECTOR_NUMTRAITS(double, SIZE)\
1621 TINYVECTOR_PROMTRAITS1(unsigned char, SIZE)\
1622 TINYVECTOR_PROMTRAITS1(int, SIZE)\
1623 TINYVECTOR_PROMTRAITS1(float, SIZE)\
1624 TINYVECTOR_PROMTRAITS1(double, SIZE)\
1625 TINYVECTOR_PROMTRAITS2(float, unsigned char, SIZE)\
1626 TINYVECTOR_PROMTRAITS2(unsigned char, float, SIZE)\
1627 TINYVECTOR_PROMTRAITS2(int, unsigned char, SIZE)\
1628 TINYVECTOR_PROMTRAITS2(unsigned char, int, SIZE)\
1629 TINYVECTOR_PROMTRAITS2(int, float, SIZE)\
1630 TINYVECTOR_PROMTRAITS2(float, int, SIZE)\
1631 TINYVECTOR_PROMTRAITS2(double, unsigned char, SIZE)\
1632 TINYVECTOR_PROMTRAITS2(unsigned char, double, SIZE)\
1633 TINYVECTOR_PROMTRAITS2(int, double, SIZE)\
1634 TINYVECTOR_PROMTRAITS2(double, int, SIZE)\
1635 TINYVECTOR_PROMTRAITS2(double, float, SIZE)\
1636 TINYVECTOR_PROMTRAITS2(float, double, SIZE)
1637 
1638 TINYVECTOR_TRAITS(2)
1639 TINYVECTOR_TRAITS(3)
1640 TINYVECTOR_TRAITS(4)
1641 
1642 #undef TINYVECTOR_NUMTRAITS
1643 #undef TINYVECTOR_PROMTRAITS1
1644 #undef TINYVECTOR_PROMTRAITS2
1645 #undef TINYVECTOR_TRAITS
1646 
1647 #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1648 
1649 
1650 /********************************************************/
1651 /* */
1652 /* TinyVector-Arithmetic */
1653 /* */
1654 /********************************************************/
1655 
1656 /** \addtogroup TinyVectorOperators
1657  */
1658 //@{
1659 
1660  /// component-wise addition
1661 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1662 inline
1663 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1666 {
1667  return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) += r;
1668 }
1669 
1670  /// component-wise subtraction
1671 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1672 inline
1673 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1676 {
1677  return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) -= r;
1678 }
1679 
1680  /// component-wise multiplication
1681 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1682 inline
1683 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1686 {
1687  return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) *= r;
1688 }
1689 
1690  /// component-wise division
1691 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1692 inline
1693 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1696 {
1697  return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) /= r;
1698 }
1699 
1700  /// component-wise modulo
1701 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1702 inline
1703 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1706 {
1707  return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) %= r;
1708 }
1709 
1710  /// component-wise left scalar multiplication
1711 template <class V, int SIZE, class D1, class D2>
1712 inline
1713 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1715 {
1716  return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(r) *= v;
1717 }
1718 
1719  /// component-wise right scalar multiplication
1720 template <class V, int SIZE, class D1, class D2>
1721 inline
1722 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1724 {
1725  return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) *= v;
1726 }
1727 
1728  /// component-wise scalar division
1729 template <class V, int SIZE, class D1, class D2>
1730 inline
1731 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1733 {
1734  return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) /= v;
1735 }
1736 
1737  /// component-wise scalar division without type promotion
1738 template <class V, int SIZE, class D1, class D2>
1739 inline
1742 {
1743  TinyVector<V, SIZE> result(l);
1744  typedef typename detail::LoopType<SIZE>::type Loop;
1745  Loop::divScalar(result.data(), v);
1746  return result;
1747 }
1748 
1749 
1750  /** Unary negation (construct TinyVector with negative values)
1751  */
1752 template <class V, int SIZE, class D1, class D2>
1753 inline
1756 {
1757  TinyVector<V, SIZE> res(detail::dontInit());
1758  typedef typename detail::LoopType<SIZE>::type ltype;
1759  ltype::neg(res.begin(), v.begin());
1760  return res;
1761 }
1762 
1763  /// component-wise absolute value
1764 template <class V, int SIZE, class D1, class D2>
1765 inline
1768 {
1769  TinyVector<V, SIZE> res(detail::dontInit());
1770  typedef typename detail::LoopType<SIZE>::type ltype;
1771  ltype::abs(res.begin(), v.begin());
1772  return res;
1773 }
1774 
1775  /** Apply ceil() function to each vector component.
1776  */
1777 template <class V, int SIZE, class D1, class D2>
1778 inline
1781 {
1782  TinyVector<V, SIZE> res(detail::dontInit());
1783  typedef typename detail::LoopType<SIZE>::type ltype;
1784  ltype::ceil(res.begin(), v.begin());
1785  return res;
1786 }
1787 
1788  /** Apply floor() function to each vector component.
1789  */
1790 template <class V, int SIZE, class D1, class D2>
1791 inline
1794 {
1795  TinyVector<V, SIZE> res(detail::dontInit());
1796  typedef typename detail::LoopType<SIZE>::type ltype;
1797  ltype::floor(res.begin(), v.begin());
1798  return res;
1799 }
1800 
1801  /** Apply round() function to each vector component.
1802  */
1803 template <class V, int SIZE, class D1, class D2>
1804 inline
1807 {
1808  TinyVector<V, SIZE> res(detail::dontInit());
1809  typedef typename detail::LoopType<SIZE>::type ltype;
1810  ltype::round(res.begin(), v.begin());
1811  return res;
1812 }
1813 
1814  /** Apply sqrt() function to each vector component.
1815  */
1816 template <class V, int SIZE, class D1, class D2>
1817 inline
1820 {
1821  TinyVector<V, SIZE> res(detail::dontInit());
1822  typedef typename detail::LoopType<SIZE>::type ltype;
1823  ltype::sqrt(res.begin(), v.begin());
1824  return res;
1825 }
1826 
1827 using std::pow;
1828 
1829  /** Apply pow() function to each vector component.
1830  */
1831 template <class V, int SIZE, class D1, class D2, class E>
1832 inline
1834 pow(TinyVectorBase<V, SIZE, D1, D2> const & v, E exponent)
1835 {
1836  TinyVector<V, SIZE> res(v);
1837  typedef typename detail::LoopType<SIZE>::type ltype;
1838  ltype::power(res.begin(), exponent);
1839  return res;
1840 }
1841 
1842  /// cross product
1843 template <class V1, class D1, class D2, class V2, class D3, class D4>
1844 inline
1847  TinyVectorBase<V2, 3, D3, D4> const & r2)
1848 {
1850  Res;
1851  return Res(r1[1]*r2[2] - r1[2]*r2[1],
1852  r1[2]*r2[0] - r1[0]*r2[2],
1853  r1[0]*r2[1] - r1[1]*r2[0]);
1854 }
1855 
1856  /// dot product
1857 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1858 inline
1859 typename PromoteTraits<V1, V2>::Promote
1862 {
1863  typedef typename detail::LoopType<SIZE>::type ltype;
1864  return ltype::dot(l.begin(), r.begin());
1865 }
1866 
1867  /// sum of the vector's elements
1868 template <class V, int SIZE, class D1, class D2>
1869 inline
1870 typename NumericTraits<V>::Promote
1872 {
1873  typename NumericTraits<V>::Promote res = l[0];
1874  for(int k=1; k<SIZE; ++k)
1875  res += l[k];
1876  return res;
1877 }
1878 
1879  /// cumulative sum of the vector's elements
1880 template <class V, int SIZE, class D1, class D2>
1881 inline
1884 {
1885  TinyVector<typename NumericTraits<V>::Promote, SIZE> res(l);
1886  for(int k=1; k<SIZE; ++k)
1887  res[k] += res[k-1];
1888  return res;
1889 }
1890 
1891  /// product of the vector's elements
1892 template <class V, int SIZE, class D1, class D2>
1893 inline
1894 typename NumericTraits<V>::Promote
1896 {
1897  typename NumericTraits<V>::Promote res = l[0];
1898  for(int k=1; k<SIZE; ++k)
1899  res *= l[k];
1900  return res;
1901 }
1902 
1903  /// cumulative product of the vector's elements
1904 template <class V, int SIZE, class D1, class D2>
1905 inline
1906 TinyVector<typename NumericTraits<V>::Promote, SIZE>
1908 {
1909  TinyVector<typename NumericTraits<V>::Promote, SIZE> res(l);
1910  for(int k=1; k<SIZE; ++k)
1911  res[k] *= res[k-1];
1912  return res;
1913 }
1914 
1915 using std::min;
1916 
1917  /// element-wise minimum
1918 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1919 inline
1923 {
1924  typedef typename detail::LoopType<SIZE>::type ltype;
1925  TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE> res(l);
1926  ltype::min(res.begin(), r.begin());
1927  return res;
1928 }
1929 
1930 // we also have to overload min for like-typed argument to prevent match of std::min()
1931 template <class V1, int SIZE, class D1, class D2>
1932 inline
1936 {
1937  typedef typename detail::LoopType<SIZE>::type ltype;
1938  TinyVector<V1, SIZE> res(l);
1939  ltype::min(res.begin(), r.begin());
1940  return res;
1941 }
1942 
1943 template <class V1, int SIZE>
1944 inline
1946 min(TinyVector<V1, SIZE> const & l,
1947  TinyVector<V1, SIZE> const & r)
1948 {
1949  typedef typename detail::LoopType<SIZE>::type ltype;
1950  TinyVector<V1, SIZE> res(l);
1951  ltype::min(res.begin(), r.begin());
1952  return res;
1953 }
1954 
1955  /// minimum element
1956 template <class V, int SIZE, class D1, class D2>
1957 inline
1958 V const &
1960 {
1961  return l.minimum();
1962 }
1963 
1964 using std::max;
1965 
1966  /// element-wise maximum
1967 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1968 inline
1969 TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE>
1972 {
1973  typedef typename detail::LoopType<SIZE>::type ltype;
1974  TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE> res(l);
1975  ltype::max(res.begin(), r.begin());
1976  return res;
1977 }
1978 
1979 // we also have to overload max for like-typed argument to prevent match of std::max()
1980 template <class V1, int SIZE, class D1, class D2>
1981 inline
1985 {
1986  typedef typename detail::LoopType<SIZE>::type ltype;
1987  TinyVector<V1, SIZE> res(l);
1988  ltype::max(res.begin(), r.begin());
1989  return res;
1990 }
1991 
1992 template <class V1, int SIZE>
1993 inline
1995 max(TinyVector<V1, SIZE> const & l,
1996  TinyVector<V1, SIZE> const & r)
1997 {
1998  typedef typename detail::LoopType<SIZE>::type ltype;
1999  TinyVector<V1, SIZE> res(l);
2000  ltype::max(res.begin(), r.begin());
2001  return res;
2002 }
2003 
2004  /// maximum element
2005 template <class V, int SIZE, class D1, class D2>
2006 inline
2007 V const &
2009 {
2010  return l.maximum();
2011 }
2012 
2013  /// squared norm
2014 template <class V1, int SIZE, class D1, class D2>
2015 inline
2018 {
2019  return t.squaredMagnitude();
2020 }
2021 
2022  /// squared norm
2023 template <class V, int SIZE>
2024 inline
2025 typename TinyVector<V, SIZE>::SquaredNormType
2027 {
2028  return t.squaredMagnitude();
2029 }
2030 
2031 using std::reverse;
2032 
2033  /// reversed copy
2034 template <class V, int SIZE>
2035 inline
2038 {
2040 }
2041 
2042 //@}
2043 
2044 // mask cl.exe shortcomings [end]
2045 #if defined(_MSC_VER)
2046 #pragma warning( pop )
2047 #endif
2048 
2049 } // namespace vigra
2050 #undef VIGRA_ASSERT_INSIDE
2051 #endif // VIGRA_TINYVECTOR_HXX
NormType magnitude() const
Definition: tinyvector.hxx:776
const_reference operator[](difference_type i) const
Definition: tinyvector.hxx:827
DERIVED & operator/=(double r)
Definition: tinyvector.hxx:768
TinyVector< V, SIZE > operator-(TinyVectorBase< V, SIZE, D1, D2 > const &v)
Definition: tinyvector.hxx:1755
TinyVectorView & operator=(TinyVectorView const &r)
Definition: tinyvector.hxx:1214
bool all() const
Definition: tinyvector.hxx:805
TinyVector(value_type const &initial)
Definition: tinyvector.hxx:940
int y
Definition: diff2d.hxx:392
VALUETYPE * pointer
Definition: tinyvector.hxx:658
value_type const * const_iterator
Definition: tinyvector.hxx:670
double scalar_multiplier
Definition: tinyvector.hxx:682
VALUETYPE const * const_pointer
Definition: tinyvector.hxx:662
TinyVector(TinyVector const &r)
Definition: tinyvector.hxx:1036
TinyVector< V, SIZE > round(TinyVectorBase< V, SIZE, D1, D2 > const &v)
Definition: tinyvector.hxx:1806
DERIVED & operator+=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition: tinyvector.hxx:716
TinyVector(TinyVectorBase< U, SIZE, DATA, DERIVED > const &r)
Definition: tinyvector.hxx:1068
void sub(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
subtraction with enforced result type.
Definition: fixedpoint.hxx:583
TinyVector< V, SIZE > div(TinyVectorBase< V, SIZE, D1, D2 > const &l, V v)
component-wise scalar division without type promotion
Definition: tinyvector.hxx:1741
TinyVector(value_type const &i1, value_type const &i2, value_type const &i3, value_type const &i4, value_type const &i5)
Definition: tinyvector.hxx:1004
int x
Definition: diff2d.hxx:385
bool operator!=(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
component-wise not equal
Definition: tinyvector.hxx:1259
V power(const V &x)
Exponentiation to a positive integer power by squaring.
Definition: mathutil.hxx:389
const_iterator begin() const
Definition: tinyvector.hxx:842
const_iterator end() const
Definition: tinyvector.hxx:846
iterator end()
Definition: tinyvector.hxx:838
Two dimensional difference vector.
Definition: diff2d.hxx:185
NumericTraits< TinyVector< V, SIZE > >::RealPromote operator*(TinyVectorBase< V, SIZE, D1, D2 > const &l, double v)
component-wise right scalar multiplication
Definition: tinyvector.hxx:1723
void add(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
addition with enforced result type.
Definition: fixedpoint.hxx:561
TinyVector< V, SIZE > ceil(TinyVectorBase< V, SIZE, D1, D2 > const &v)
Definition: tinyvector.hxx:1780
SquaredNormType squaredMagnitude() const
Definition: tinyvector.hxx:784
TinyVector(Diff2D const &initial)
Definition: tinyvector.hxx:960
Definition: accessor.hxx:43
TinyVector(const_pointer data, ReverseCopyTag)
Definition: tinyvector.hxx:1059
DERIVED & operator/=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition: tinyvector.hxx:743
TinyVector< V, SIZE > sqrt(TinyVectorBase< V, SIZE, D1, D2 > const &v)
Definition: tinyvector.hxx:1819
TinyVector & copy(TinyVectorBase< U, USIZE, DATA, DERIVED > const &r)
Definition: tinyvector.hxx:1115
value_type * iterator
Definition: tinyvector.hxx:666
PromoteTraits< TinyVector< V1, SIZE >, TinyVector< V2, SIZE > >::Promote operator+(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
component-wise addition
Definition: tinyvector.hxx:1664
DERIVED & operator*=(double r)
Definition: tinyvector.hxx:760
Definition: graphs.hxx:226
DERIVED & operator-=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition: tinyvector.hxx:725
TinyVector & operator=(TinyVector const &r)
Definition: tinyvector.hxx:1076
TinyVector()
Definition: tinyvector.hxx:1018
VALUETYPE value_type
Definition: tinyvector.hxx:646
void mul(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
multiplication with enforced result type.
Definition: fixedpoint.hxx:605
NumericTraits< V >::Promote prod(TinyVectorBase< V, SIZE, D1, D2 > const &l)
product of the vector&#39;s elements
Definition: tinyvector.hxx:1895
TinyVectorView(TinyVectorBase< T, SIZE, DATA, DERIVED > const &other)
Definition: tinyvector.hxx:1206
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector&#39;s elements
Definition: tinyvector.hxx:1871
TinyVector(value_type const &i1, value_type const &i2, value_type const &i3, value_type const &i4)
Definition: tinyvector.hxx:991
TinyVectorView()
Definition: tinyvector.hxx:1181
void init(value_type initial)
Definition: tinyvector.hxx:708
NumericTraits< TinyVector< V, SIZE > >::RealPromote operator/(TinyVectorBase< V, SIZE, D1, D2 > const &l, double v)
component-wise scalar division
Definition: tinyvector.hxx:1732
VALUETYPE & reference
Definition: tinyvector.hxx:650
iterator begin()
Definition: tinyvector.hxx:835
size_type size() const
Definition: tinyvector.hxx:865
TinyVector< V, SIZE > pow(TinyVectorBase< V, SIZE, D1, D2 > const &v, E exponent)
Definition: tinyvector.hxx:1834
VALUETYPE const & const_reference
Definition: tinyvector.hxx:654
TinyVector & operator=(value_type const &v)
Definition: tinyvector.hxx:1104
TinyVector< V, SIZE >::SquaredNormType squaredNorm(TinyVector< V, SIZE > const &t)
squared norm
Definition: tinyvector.hxx:2026
TinyVector(value_type const &i1, value_type const &i2, value_type const &i3)
Definition: tinyvector.hxx:980
TinyVector(SkipInitializationTag)
Definition: tinyvector.hxx:1026
TinyVectorView & operator=(TinyVectorBase< U, SIZE, DATA, DERIVED > const &r)
Definition: tinyvector.hxx:1223
V const & max(TinyVectorBase< V, SIZE, D1, D2 > const &l)
maximum element
Definition: tinyvector.hxx:2008
TinyVector< typename NumericTraits< V >::Promote, SIZE > cumsum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
cumulative sum of the vector&#39;s elements
Definition: tinyvector.hxx:1883
Wrapper for fixed size vectors.
Definition: tinyvector.hxx:612
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
unsigned int size_type
Definition: tinyvector.hxx:674
TinyVectorView< VALUETYPE, TO-FROM > subarray() const
Definition: tinyvector.hxx:853
TinyVectorView(TinyVectorView const &other)
Definition: tinyvector.hxx:1197
Base class for fixed size vectors.
Definition: tinyvector.hxx:81
TinyVector< V, SIZE > floor(TinyVectorBase< V, SIZE, D1, D2 > const &v)
Definition: tinyvector.hxx:1793
TinyVector(U const *data)
Definition: tinyvector.hxx:1045
SquareRootTraits< SquaredNormType >::SquareRootResult NormType
Definition: tinyvector.hxx:690
VALUETYPE const & maximum() const
Definition: tinyvector.hxx:798
std::ptrdiff_t difference_type
Definition: tinyvector.hxx:678
TinyVector< typename PromoteTraits< V1, V2 >::Promote, 3 > cross(TinyVectorBase< V1, 3, D1, D2 > const &r1, TinyVectorBase< V2, 3, D3, D4 > const &r2)
cross product
Definition: tinyvector.hxx:1846
bool any() const
Definition: tinyvector.hxx:812
TinyVector(value_type const &i1, value_type const &i2)
Definition: tinyvector.hxx:970
TinyVector< V, SIZE > reverse(TinyVector< V, SIZE > const &t)
reversed copy
Definition: tinyvector.hxx:2037
TinyVectorView(const_pointer data)
Definition: tinyvector.hxx:1189
TinyVector & operator=(TinyVectorBase< U, SIZE, DATA, DERIVED > const &r)
Definition: tinyvector.hxx:1085
TinyVector< typename NumericTraits< V >::Promote, SIZE > cumprod(TinyVectorBase< V, SIZE, D1, D2 > const &l)
cumulative product of the vector&#39;s elements
Definition: tinyvector.hxx:1907
VALUETYPE const & minimum() const
Definition: tinyvector.hxx:791
DERIVED & operator%=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition: tinyvector.hxx:752
void init(Iterator i, Iterator end)
Definition: tinyvector.hxx:699
TinyVector< V, SIZE > abs(TinyVectorBase< V, SIZE, D1, D2 > const &v)
component-wise absolute value
Definition: tinyvector.hxx:1767
NormTraits< VALUETYPE >::SquaredNormType SquaredNormType
Definition: tinyvector.hxx:686
DERIVED & operator*=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition: tinyvector.hxx:734
TinyVector & operator=(Diff2D const &r)
Definition: tinyvector.hxx:1095
reference operator[](difference_type i)
Definition: tinyvector.hxx:819
PromoteTraits< TinyVector< V1, SIZE >, TinyVector< V2, SIZE > >::Promote operator%(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
component-wise modulo
Definition: tinyvector.hxx:1704
TinyVector(lemon::Invalid const &)
Definition: tinyvector.hxx:950
V const & min(TinyVectorBase< V, SIZE, D1, D2 > const &l)
minimum element
Definition: tinyvector.hxx:1959
bool operator==(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
component-wise equal
Definition: tinyvector.hxx:1250
PromoteTraits< V1, V2 >::Promote dot(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
dot product
Definition: tinyvector.hxx:1860

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

html generated using doxygen and Python
vigra 1.10.0