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

tinyvector.hxx
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#include "static_assert.hxx"
58
59#ifdef VIGRA_CHECK_BOUNDS
60#define VIGRA_ASSERT_INSIDE(diff) \
61 vigra_precondition(diff >= 0, "Index out of bounds");\
62 vigra_precondition(diff < SIZE, "Index out of bounds");
63#else
64#define VIGRA_ASSERT_INSIDE(diff)
65#endif
66
67 namespace vigra {
68
69// mask cl.exe shortcomings [begin]
70#if defined(_MSC_VER)
71#pragma warning( push )
72#pragma warning( disable : 4503 )
73#endif
74
75 using VIGRA_CSTD::abs;
76 using VIGRA_CSTD::ceil;
77 using VIGRA_CSTD::floor;
78 using VIGRA_CSTD::sqrt;
79
80
81 template <class V1, int SIZE, class D1, class D2>
82 class TinyVectorBase;
83
84 template <class V1, int SIZE, class D1, class D2>
85 inline
86 typename TinyVectorBase<V1, SIZE, D1, D2>::SquaredNormType
87 squaredNorm(TinyVectorBase<V1, SIZE, D1, D2> const & t);
88
89
90 namespace detail {
91
92#define VIGRA_EXEC_LOOP(NAME, OPER) \
93 template <class T1, class T2> \
94 static void NAME(T1 * left, T2 const * right) \
95 { \
96 for(int i=0; i<LEVEL; ++i) \
97 (left[i]) OPER (right[i]); \
98 }
99
100#define VIGRA_EXEC_LOOP_MINMAX(NAME, OPER) \
101 template <class T1, class T2> \
102 static void NAME(T1 * left, T2 const * right) \
103 { \
104 for(int i=0; i<LEVEL; ++i) \
105 if(left[i] OPER right[i]) \
106 left[i] = right[i]; \
107 }
108
109#define VIGRA_EXEC_LOOP_SCALAR(NAME, OPER) \
110 template <class T1, class T2> \
111 static void NAME(T1 * left, T2 right) \
112 { \
113 for(int i=0; i<LEVEL; ++i) \
114 (left[i]) = detail::RequiresExplicitCast<T1>::cast((left[i]) OPER (right)); \
115 }
116
117 template <int LEVEL>
118 struct ExecLoop
119{
120 template <class T1, class T2>
121 static void assignCast(T1 * left, T2 const * right)
122 {
123 for(int i=0; i<LEVEL; ++i)
124 left[i] = detail::RequiresExplicitCast<T1>::cast(right[i]);
125 }
126
127 template <class T1, class T2>
128 static void reverseAssign(T1 * left, T2 const * right)
129 {
130 for(int i=0; i<LEVEL; ++i)
131 left[i] = right[-i];
132 }
133
134 template <class T1, class T2>
135 static void assignScalar(T1 * left, T2 right)
136 {
137 for(int i=0; i<LEVEL; ++i)
138 left[i] = detail::RequiresExplicitCast<T1>::cast(right);
139 }
140
141 template <class T1, class T2>
142 static void power(T1 * left, T2 right)
143 {
144 for(int i=0; i<LEVEL; ++i)
145 left[i] = detail::RequiresExplicitCast<T1>::cast(pow(left, right));
146 }
147
148 VIGRA_EXEC_LOOP(assign, =)
149 VIGRA_EXEC_LOOP(add, +=)
150 VIGRA_EXEC_LOOP(sub, -=)
151 VIGRA_EXEC_LOOP(mul, *=)
152 VIGRA_EXEC_LOOP(div, /=)
153 VIGRA_EXEC_LOOP(mod, %=)
154 VIGRA_EXEC_LOOP(neg, = -)
155 VIGRA_EXEC_LOOP(abs, = vigra::abs)
156 VIGRA_EXEC_LOOP(floor, = vigra::floor)
157 VIGRA_EXEC_LOOP(ceil, = vigra::ceil)
158 VIGRA_EXEC_LOOP(round, = vigra::round)
159 VIGRA_EXEC_LOOP(sqrt, = vigra::sqrt)
160 VIGRA_EXEC_LOOP(fromPromote, = NumericTraits<T1>::fromPromote)
161 VIGRA_EXEC_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote)
162 VIGRA_EXEC_LOOP_SCALAR(addScalar, +)
163 VIGRA_EXEC_LOOP_SCALAR(subScalar, -)
164 VIGRA_EXEC_LOOP_SCALAR(mulScalar, *)
165 VIGRA_EXEC_LOOP_SCALAR(divScalar, /)
166
167 VIGRA_EXEC_LOOP_MINMAX(min, >)
168 VIGRA_EXEC_LOOP_MINMAX(max, <)
169
170 template <class T>
171 static T const & minimum(T const * p)
172 {
173 return *std::min_element(p, p+LEVEL);
174 }
175
176 template <class T>
177 static T const & maximum(T const * p)
178 {
179 return *std::max_element(p, p+LEVEL);
180 }
181
182 template <class T>
183 static bool all(T const * p, T const & zero)
184 {
185 for(int i=0; i<LEVEL; ++i)
186 if(p[i] == zero)
187 return false;
188 return true;
189 }
190
191 template <class T>
192 static bool any(T const * p, T const & zero)
193 {
194 for(int i=0; i<LEVEL; ++i)
195 if(p[i] != zero)
196 return true;
197 return false;
198 }
199
200 template <class T1, class T2>
201 static bool notEqual(T1 const * left, T2 const * right)
202 {
203 for(int i=0; i<LEVEL; ++i)
204 if(left[i] != right[i])
205 return true;
206 return false;
207 }
208
209 template <class T1, class T2>
210 static bool lexicographicLessThan(T1 const * left, T2 const * right)
211 {
212 for(int i=0; i<LEVEL; ++i)
213 {
214 if(left[i] < right[i])
215 return true;
216 if(right[i] < left[i])
217 return false;
218 }
219 return false;
220 }
221
222 template <class T>
223 static bool closeAtTolerance(T const * left, T const * right, T epsilon)
224 {
225 bool res = true;
226 for(int i=0; i<LEVEL; ++i)
227 {
228 res = res && vigra::closeAtTolerance(left[i], right[i], epsilon);
229 }
230 return res;
231 }
232
233 template <class T>
234 static typename NumericTraits<T>::Promote
235 dot(T const * d)
236 {
237 typename NumericTraits<T>::Promote res(*d * *d);
238 for(int i=1; i<LEVEL; ++i)
239 res += d[i] * d[i];
240 return res;
241 }
242
243 template <class T1, class T2>
244 static typename PromoteTraits<T1, T2>::Promote
245 dot(T1 const * left, T2 const * right)
246 {
247 typename PromoteTraits<T1, T2>::Promote res(*left * *right);
248 for(int i=1; i<LEVEL; ++i)
249 res += left[i] * right[i];
250 return res;
251 }
252
253 template <class T>
254 static typename NormTraits<T>::SquaredNormType
255 squaredNorm(T const * d)
256 {
257 typename NormTraits<T>::SquaredNormType res = vigra::squaredNorm(*d);
258 for(int i=1; i<LEVEL; ++i)
259 res += vigra::squaredNorm(d[i]);
260 return res;
261 }
262};
263
264 template <int LEVEL>
265 struct UnrollScalarResult
266{
267 template <class T>
268 static typename NumericTraits<T>::Promote
269 dot(T const * d)
270 {
271 return *d * *d + UnrollScalarResult<LEVEL-1>::dot(d+1);
272 }
273
274 template <class T1, class T2>
275 static typename PromoteTraits<T1, T2>::Promote
276 dot(T1 const * left, T2 const * right)
277 {
278 return *left * *right + UnrollScalarResult<LEVEL-1>::dot(left+1, right+1);
279 }
280
281 template <class T>
282 static typename NormTraits<T>::SquaredNormType
283 squaredNorm(T const * d)
284 {
285 return vigra::squaredNorm(*d) + UnrollScalarResult<LEVEL-1>::squaredNorm(d+1);
286 }
287
288 static std::ptrdiff_t
289 squaredNorm(std::ptrdiff_t const * d)
290 {
291 return (*d)*(*d) + UnrollScalarResult<LEVEL-1>::squaredNorm(d+1);
292 }
293
294 template <class T>
295 static T const & minimum(T const * p)
296 {
297 T const & m = UnrollScalarResult<LEVEL - 1>::minimum(p+1);
298 return *p < m
299 ? *p
300 : m;
301 }
302
303 template <class T>
304 static T const & maximum(T const * p)
305 {
306 T const & m = UnrollScalarResult<LEVEL - 1>::maximum(p+1);
307 return *p > m
308 ? *p
309 : m;
310 }
311
312 template <class T>
313 static bool all(T const * p, T const & zero)
314 {
315 return *p != zero && UnrollScalarResult<LEVEL - 1>::all(p+1, zero);
316 }
317
318 template <class T>
319 static bool any(T const * p, T const & zero)
320 {
321 return *p != zero || UnrollScalarResult<LEVEL - 1>::any(p+1, zero);
322 }
323};
324
325 template <>
326 struct UnrollScalarResult<1>
327{
328 template <class T>
329 static typename NumericTraits<T>::Promote
330 dot(T const * d)
331 {
332 return *d * *d ;
333 }
334
335 template <class T1, class T2>
336 static typename PromoteTraits<T1, T2>::Promote
337 dot(T1 const * left, T2 const * right)
338 {
339 return *left * *right;
340 }
341
342 template <class T>
343 static typename NormTraits<T>::SquaredNormType
344 squaredNorm(T const * d)
345 {
346 return vigra::squaredNorm(*d);
347 }
348
349 static std::ptrdiff_t
350 squaredNorm(std::ptrdiff_t const * d)
351 {
352 return (*d)*(*d);
353 }
354
355 template <class T>
356 static T const & minimum(T const * p)
357 {
358 return *p;
359 }
360
361 template <class T>
362 static T const & maximum(T const * p)
363 {
364 return *p;
365 }
366
367 template <class T>
368 static bool all(T const * p, T const & zero)
369 {
370 return *p != zero;
371 }
372
373 template <class T>
374 static bool any(T const * p, T const & zero)
375 {
376 return *p != zero;
377 }
378};
379
380#undef VIGRA_EXEC_LOOP
381#undef VIGRA_EXEC_LOOP_MINMAX
382#undef VIGRA_EXEC_LOOP_SCALAR
383
384#define VIGRA_UNROLL_LOOP(NAME, OPER) \
385 template <class T1, class T2> \
386 static void NAME(T1 * left, T2 const * right) \
387 { \
388 (*left) OPER (*right); \
389 UnrollLoop<LEVEL-1>::NAME(left+1, right+1); \
390 }
391
392#define VIGRA_UNROLL_LOOP_MINMAX(NAME, OPER) \
393 template <class T1, class T2> \
394 static void NAME(T1 * left, T2 const * right) \
395 { \
396 if(*left OPER *right) \
397 *left = *right; \
398 UnrollLoop<LEVEL-1>::NAME(left+1, right+1); \
399 }
400
401#define VIGRA_UNROLL_LOOP_SCALAR(NAME, OPER) \
402 template <class T1, class T2> \
403 static void NAME(T1 * left, T2 right) \
404 { \
405 (*left) = detail::RequiresExplicitCast<T1>::cast((*left) OPER (right)); \
406 UnrollLoop<LEVEL-1>::NAME(left+1, right); \
407 }
408
409
410 template <int LEVEL>
411 struct UnrollLoop
412{
413 template <class T1, class T2>
414 static void reverseAssign(T1 * left, T2 const * right)
415 {
416 *left = *right;
417 UnrollLoop<LEVEL-1>::reverseAssign(left+1, right-1);
418 }
419
420 template <class T1, class T2>
421 static void assignCast(T1 * left, T2 const * right)
422 {
423 *left = detail::RequiresExplicitCast<T1>::cast(*right);
424 UnrollLoop<LEVEL-1>::assignCast(left+1, right+1);
425 }
426
427 template <class T1, class T2>
428 static void assignScalar(T1 * left, T2 right)
429 {
430 *left = detail::RequiresExplicitCast<T1>::cast(right);
431 UnrollLoop<LEVEL-1>::assignScalar(left+1, right);
432 }
433
434 template <class T1, class T2>
435 static void power(T1 * left, T2 right)
436 {
437 *left = detail::RequiresExplicitCast<T1>::cast(pow(*left, right));
438 UnrollLoop<LEVEL-1>::power(left+1, right);
439 }
440
441 VIGRA_UNROLL_LOOP(assign, =)
442 VIGRA_UNROLL_LOOP(add, +=)
443 VIGRA_UNROLL_LOOP(sub, -=)
444 VIGRA_UNROLL_LOOP(mul, *=)
445 VIGRA_UNROLL_LOOP(div, /=)
446 VIGRA_UNROLL_LOOP(mod, %=)
447 VIGRA_UNROLL_LOOP(neg, = -)
448 VIGRA_UNROLL_LOOP(abs, = vigra::abs)
449 VIGRA_UNROLL_LOOP(floor, = vigra::floor)
450 VIGRA_UNROLL_LOOP(ceil, = vigra::ceil)
451 VIGRA_UNROLL_LOOP(round, = vigra::round)
452 VIGRA_UNROLL_LOOP(sqrt, = vigra::sqrt)
453 VIGRA_UNROLL_LOOP(fromPromote, = NumericTraits<T1>::fromPromote)
454 VIGRA_UNROLL_LOOP(fromRealPromote, = NumericTraits<T1>::fromRealPromote)
455 VIGRA_UNROLL_LOOP_SCALAR(addScalar, +)
456 VIGRA_UNROLL_LOOP_SCALAR(subScalar, -)
457 VIGRA_UNROLL_LOOP_SCALAR(mulScalar, *)
458 VIGRA_UNROLL_LOOP_SCALAR(divScalar, /)
459
460 VIGRA_UNROLL_LOOP_MINMAX(min, >)
461 VIGRA_UNROLL_LOOP_MINMAX(max, <)
462
463 template <class T>
464 static T const & minimum(T const * p)
465 {
466 return UnrollScalarResult<LEVEL>::minimum(p);
467 }
468
469 template <class T>
470 static T const & maximum(T const * p)
471 {
472 return UnrollScalarResult<LEVEL>::maximum(p);
473 }
474
475 template <class T>
476 static bool all(T const * p, T const & zero)
477 {
478 return UnrollScalarResult<LEVEL>::all(p, zero);
479 }
480
481 template <class T>
482 static bool any(T const * p, T const & zero)
483 {
484 return UnrollScalarResult<LEVEL>::any(p, zero);
485 }
486
487 template <class T1, class T2>
488 static bool notEqual(T1 const * left, T2 const * right)
489 {
490 return (*left != *right) || UnrollLoop<LEVEL - 1>::notEqual(left+1, right+1);
491 }
492
493 template <class T1, class T2>
494 static bool lexicographicLessThan(T1 const * left, T2 const * right)
495 {
496 if(*left < *right)
497 return true;
498 if(*right < *left)
499 return false;
500 return UnrollLoop<LEVEL - 1>::lexicographicLessThan(left+1, right+1);
501 }
502
503 template <class T>
504 static bool closeAtTolerance(T const * left, T const * right, T epsilon)
505 {
506 return vigra::closeAtTolerance(*left, *right, epsilon) &&
507 UnrollLoop<LEVEL - 1>::closeAtTolerance(left+1, right+1, epsilon);
508 }
509
510 template <class T>
511 static typename NumericTraits<T>::Promote
512 dot(T const * d)
513 {
514 return UnrollScalarResult<LEVEL>::dot(d);
515 }
516
517 template <class T1, class T2>
518 static typename PromoteTraits<T1, T2>::Promote
519 dot(T1 const * left, T2 const * right)
520 {
521 return UnrollScalarResult<LEVEL>::dot(left, right);
522 }
523
524 template <class T>
525 static typename NormTraits<T>::SquaredNormType
526 squaredNorm(T const * d)
527 {
528 return UnrollScalarResult<LEVEL>::squaredNorm(d);
529 }
530};
531
532#undef VIGRA_UNROLL_LOOP
533#undef VIGRA_UNROLL_LOOP_MINMAX
534#undef VIGRA_UNROLL_LOOP_SCALAR
535
536 template <>
537 struct UnrollLoop<0>
538{
539 template <class T1, class T2>
540 static void reverseAssign(T1, T2) {}
541 template <class T1, class T2>
542 static void assignCast(T1, T2) {}
543 template <class T1, class T2>
544 static void assign(T1, T2) {}
545 template <class T1, class T2>
546 static void assignScalar(T1, T2) {}
547 template <class T1, class T2>
548 static void power(T1, T2) {}
549 template <class T1, class T2>
550 static void add(T1, T2) {}
551 template <class T1, class T2>
552 static void addScalar(T1, T2) {}
553 template <class T1, class T2>
554 static void sub(T1, T2) {}
555 template <class T1, class T2>
556 static void subScalar(T1, T2) {}
557 template <class T1, class T2>
558 static void mul(T1, T2) {}
559 template <class T1, class T2>
560 static void mulScalar(T1, T2) {}
561 template <class T1, class T2>
562 static void div(T1, T2) {}
563 template <class T1, class T2>
564 static void mod(T1, T2) {}
565 template <class T1, class T2>
566 static void divScalar(T1, T2) {}
567 template <class T1, class T2>
568 static void fromPromote(T1, T2) {}
569 template <class T1, class T2>
570 static void fromRealPromote(T1, T2) {}
571 template <class T1, class T2>
572 static void neg(T1, T2) {}
573 template <class T1, class T2>
574 static void abs(T1, T2) {}
575 template <class T1, class T2>
576 static void floor(T1, T2) {}
577 template <class T1, class T2>
578 static void ceil(T1, T2) {}
579 template <class T1, class T2>
580 static void round(T1, T2) {}
581 template <class T1, class T2>
582 static void sqrt(T1, T2) {}
583 template <class T1, class T2>
584 static bool notEqual(T1, T2) { return false; }
585 template <class T1, class T2>
586 static bool lexicographicLessThan(T1, T2) { return false; }
587 template <class T1, class T2>
588 static void min(T1, T2) {}
589 template <class T1, class T2>
590 static void max(T1, T2) {}
591 template <class T>
592 static T minimum(T const *) { return NumericTraits<T>::max(); }
593 template <class T>
594 static T maximum(T const *) { return NumericTraits<T>::min(); }
595 template <class T>
596 static bool all(T const *, T const &) { return true; }
597 template <class T>
598 static bool any(T const *, T const &) { return false; }
599 template <class T>
600 static bool closeAtTolerance(T const *, T const *, T) { return true; }
601};
602
603 template <int SIZE>
604 struct LoopType
605{
606 static const int MaxUnrollSize = 5;
607 typedef typename IfBool<(SIZE <= MaxUnrollSize), UnrollLoop<SIZE>, ExecLoop<SIZE> >::type type;
608
609};
610
611 struct DontInit {};
612
613 inline DontInit dontInit() {return DontInit(); }
614
615} // namespace detail
616
617 template <class T, int SIZE>
618 class TinyVector;
619
620 template <class T, int SIZE>
621 class TinyVectorView;
622
623/********************************************************/
624/* */
625/* TinyVectorBase */
626/* */
627/********************************************************/
628
629/** \brief Base class for fixed size vectors.
630
631 This class contains functionality shared by
632 \ref TinyVector and \ref TinyVectorView, and enables these classes
633 to be freely mixed within expressions. It is typically not used directly.
634
635 <b>\#include</b> <vigra/tinyvector.hxx><br>
636 Namespace: vigra
637**/
638 template <class VALUETYPE, int SIZE, class DATA, class DERIVED>
639 class TinyVectorBase
640{
641 TinyVectorBase(TinyVectorBase const &); // do not use
642
643 TinyVectorBase & operator=(TinyVectorBase const & other); // do not use
644
645 protected:
646
647 typedef typename detail::LoopType<SIZE>::type Loop;
648
649 TinyVectorBase()
650 {}
651
652 public:
653 /** STL-compatible definition of valuetype
654 */
655 typedef VALUETYPE value_type;
656
657 /** reference (return of operator[]).
658 */
659 typedef VALUETYPE & reference;
660
661 /** const reference (return of operator[] const).
662 */
663 typedef VALUETYPE const & const_reference;
664
665 /** pointer (return of operator->).
666 */
667 typedef VALUETYPE * pointer;
668
669 /** const pointer (return of operator-> const).
670 */
671 typedef VALUETYPE const * const_pointer;
672
673 /** STL-compatible definition of iterator
674 */
675 typedef value_type * iterator;
676
677 /** STL-compatible definition of const iterator
678 */
679 typedef value_type const * const_iterator;
680
681 /** STL-compatible definition of size_type
682 */
683 typedef unsigned int size_type;
684
685 /** STL-compatible definition of difference_type
686 */
687 typedef std::ptrdiff_t difference_type;
688
689 /** the scalar type for the outer product
690 */
691 typedef double scalar_multiplier;
692
693 /** the vector's squared norm type
694 */
695 typedef typename NormTraits<VALUETYPE>::SquaredNormType SquaredNormType;
696
697 /** the vector's norm type
698 */
699 typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
700
701 /** the vector's size
702 */
703 enum { static_size = SIZE };
704
705 /** Initialize from another sequence (must have length SIZE!)
706 */
707 template <class Iterator>
708 void init(Iterator i, Iterator end)
709 {
710 vigra_precondition(end-i == SIZE,
711 "TinyVector::init(): Sequence has wrong size.");
712 Loop::assignCast(data_, i);
713 }
714
715 /** Initialize with constant value
716 */
717 void init(value_type initial)
718 {
719 Loop::assignScalar(data_, initial);
720 }
721
722 /** Component-wise add-assignment
723 */
724 template <class T1, class D1, class D2>
725 DERIVED & operator+=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
726 {
727 Loop::add(data_, r.begin());
728 return static_cast<DERIVED &>(*this);
729 }
730
731 /** Component-wise subtract-assignment
732 */
733 template <class T1, class D1, class D2>
734 DERIVED & operator-=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
735 {
736 Loop::sub(data_, r.begin());
737 return static_cast<DERIVED &>(*this);
738 }
739
740 /** Component-wise multiply-assignment
741 */
742 template <class T1, class D1, class D2>
743 DERIVED & operator*=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
744 {
745 Loop::mul(data_, r.begin());
746 return static_cast<DERIVED &>(*this);
747 }
748
749 /** Component-wise divide-assignment
750 */
751 template <class T1, class D1, class D2>
752 DERIVED & operator/=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
753 {
754 Loop::div(data_, r.begin());
755 return static_cast<DERIVED &>(*this);
756 }
757
758 /** Component-wise modulo-assignment
759 */
760 template <class T1, class D1, class D2>
761 DERIVED & operator%=(TinyVectorBase<T1, SIZE, D1, D2> const & r)
762 {
763 Loop::mod(data_, r.begin());
764 return static_cast<DERIVED &>(*this);
765 }
766
767 /** Component-wise scalar multiply-assignment
768 */
769 DERIVED & operator+=(double r)
770 {
771 Loop::addScalar(data_, r);
772 return static_cast<DERIVED &>(*this);
773 }
774
775 /** Component-wise scalar divide-assignment
776 */
777 DERIVED & operator-=(double r)
778 {
779 Loop::subScalar(data_, r);
780 return static_cast<DERIVED &>(*this);
781 }
782
783 /** Component-wise scalar multiply-assignment
784 */
785 DERIVED & operator*=(double r)
786 {
787 Loop::mulScalar(data_, r);
788 return static_cast<DERIVED &>(*this);
789 }
790
791 /** Component-wise scalar divide-assignment
792 */
793 DERIVED & operator/=(double r)
794 {
795 Loop::divScalar(data_, r);
796 return static_cast<DERIVED &>(*this);
797 }
798
799 /** Calculate magnitude (i.e. 2-norm / Euclidean norm / length).
800 * \see squaredMagnitude()
801 */
802 NormType magnitude() const
803 {
804 return sqrt(static_cast<typename
805 SquareRootTraits<SquaredNormType>::SquareRootArgument>(squaredMagnitude()));
806 }
807
808 /** Calculate squared magnitude (i.e. sum of squared elements).
809 */
810 SquaredNormType squaredMagnitude() const
811 {
812 return Loop::squaredNorm(data_);
813 }
814
815 /** Return the minimal element.
816 */
817 VALUETYPE const & minimum() const
818 {
819 return Loop::minimum(data_);
820 }
821
822 /** Return the maximal element.
823 */
824 VALUETYPE const & maximum() const
825 {
826 return Loop::maximum(data_);
827 }
828
829 /** Check that all elements of this vector are non-zero (or 'true' if T is bool).
830 */
831 bool all() const
832 {
833 return Loop::all(data_, VALUETYPE());
834 }
835
836 /** Check that at least one element of this vector is non-zero (or 'true' if T is bool).
837 */
838 bool any() const
839 {
840 return Loop::any(data_, VALUETYPE());
841 }
842
843 /** Access component by index.
844 */
845 reference operator[](difference_type i)
846 {
847 VIGRA_ASSERT_INSIDE(i);
848 return data_[i];
849 }
850
851 /** Get component by index.
852 */
853 const_reference operator[](difference_type i) const
854 {
855 VIGRA_ASSERT_INSIDE(i);
856 return data_[i];
857 }
858
859 /** Get random access iterator to begin of vector.
860 */
861 iterator begin() { return data_; }
862 /** Get random access iterator past-the-end of vector.
863 */
864 iterator end() { return data_ + SIZE; }
865
866 /** Get const random access iterator to begin of vector.
867 */
868 const_iterator begin() const { return data_; }
869
870 /** Get const random access iterator past-the-end of vector.
871 */
872 const_iterator end() const { return data_ + SIZE; }
873
874 /** Get const random access iterator to begin of vector.
875 */
876 const_iterator cbegin() const { return data_; }
877
878 /** Get const random access iterator past-the-end of vector.
879 */
880 const_iterator cend() const { return data_ + SIZE; }
881
882 /** Get a view to the subarray with length <tt>(TO-FROM)</tt> starting at <tt>FROM</tt>.
883 The bounds must fullfill <tt>0 <= FROM < TO <= SIZE</tt>, but this is only
884 checked when <tt>VIGRA_CHECK_BOUNDS</tt> is \#define'd.
885 */
886 template <int FROM, int TO>
887 TinyVectorView<VALUETYPE, TO-FROM> subarray() const
888 {
889#ifdef VIGRA_CHECK_BOUNDS
890 vigra_precondition(FROM >= 0, "Index out of bounds");
891 vigra_precondition(FROM < TO, "Index out of bounds");
892 vigra_precondition(TO <=SIZE, "Index out of bounds");
893#endif
894 return TinyVectorView<VALUETYPE, TO-FROM>(data_+FROM);
895 }
896
897 TinyVector<VALUETYPE, SIZE-1>
898 dropIndex(int m) const
899 {
900#ifdef VIGRA_CHECK_BOUNDS
901 vigra_precondition(0 <= m && m < SIZE, "Dimension out of bounds");
902#endif
903 TinyVector<VALUETYPE, SIZE-1> res(SkipInitialization);
904 for(int k=0; k<m; ++k)
905 res[k] = data_[k];
906 for(int k=m; k<SIZE-1; ++k)
907 res[k] = data_[k+1];
908 return res;
909 }
910
911 /** Size of TinyVector vector always equals the template parameter SIZE.
912 */
913 size_type size() const { return SIZE; }
914
915 pointer data() { return data_; }
916
917 const_pointer data() const { return data_; }
918
919 reference front()
920 {
921 return data_[0];
922 }
923
924 const_reference front() const
925 {
926 return data_[0];
927 }
928
929 reference back()
930 {
931 return data_[SIZE-1];
932 }
933
934 const_reference back() const
935 {
936 return data_[SIZE-1];
937 }
938
939 /** \brief Factory function for a unit vector for dimension \a k.
940 */
941 static TinyVector<VALUETYPE, SIZE> unitVector(int k)
942 {
943 VIGRA_ASSERT_INSIDE(k);
944 TinyVector<VALUETYPE, SIZE> ret;
945 ret[k] = 1;
946 return ret;
947 }
948
949 /** \brief Factory function for a linear sequence.
950
951 The result will be initialized as <tt>res[k] = start + k*step</tt>.
952 */
953 static TinyVector<VALUETYPE, SIZE> linearSequence(VALUETYPE start=VALUETYPE(), VALUETYPE step=VALUETYPE(1))
954 {
955 TinyVector<VALUETYPE, SIZE> ret(SkipInitialization);
956 for(int k=0; k<SIZE; ++k, start+=step)
957 ret[k] = start;
958 return ret;
959 }
960
961 protected:
962
963 DATA data_;
964};
965
966#ifndef DOXYGEN
967
968 template <int SIZE, int DESIRED_SIZE>
969 struct TinyVector_constructor_has_wrong_number_of_arguments
970: staticAssert::AssertBool<SIZE == DESIRED_SIZE>
971{};
972
973#endif /* DOXYGEN */
974
975 enum ReverseCopyTag { ReverseCopy };
976
977/** \brief Class for fixed size vectors.
978 \ingroup RangesAndPoints
979
980 This class contains an array of size SIZE of the specified VALUETYPE.
981 The interface conforms to STL vector, except that there are no functions
982 that change the size of a TinyVector.
983
984 \ref TinyVectorOperators "Arithmetic operations"
985 on TinyVectors are defined as component-wise applications of these
986 operations. Addition and subtraction of two TinyVectors
987 (+=, -=, +, -, unary -), multiplication and division of an
988 TinyVector with a double, and NumericTraits/PromoteTraits are defined,
989 so that TinyVector fulfills the requirements of \ref LinearAlgebraConcept "Linear Algebra".
990
991 VIGRA algorithms typically use \ref vigra::VectorAccessor to access
992 TinyVectors as a whole, or specific components of them.
993
994 See also:<br>
995 <UL style="list-style-image:url(documents/bullet.gif)">
996 <LI> \ref vigra::TinyVectorBase
997 <LI> \ref vigra::TinyVectorView
998 <LI> \ref TinyVectorTraits
999 <LI> \ref TinyVectorOperators
1000 </UL>
1001
1002 <b>\#include</b> <vigra/tinyvector.hxx><br>
1003 Namespace: vigra
1004**/
1005 template <class T, int SIZE>
1006 class TinyVector
1007: public TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> >
1008{
1009 typedef TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> > BaseType;
1010 typedef typename BaseType::Loop Loop;
1011
1012 public:
1013
1014 typedef typename BaseType::value_type value_type;
1015 typedef typename BaseType::reference reference;
1016 typedef typename BaseType::const_reference const_reference;
1017 typedef typename BaseType::pointer pointer;
1018 typedef typename BaseType::const_pointer const_pointer;
1019 typedef typename BaseType::iterator iterator;
1020 typedef typename BaseType::const_iterator const_iterator;
1021 typedef typename BaseType::size_type size_type;
1022 typedef typename BaseType::difference_type difference_type;
1023 typedef typename BaseType::scalar_multiplier scalar_multiplier;
1024 typedef typename BaseType::SquaredNormType SquaredNormType;
1025 typedef typename BaseType::NormType NormType;
1026
1027 /** Construction with constant value.
1028
1029 Initializes all vector elements with the given value.
1030 */
1031 explicit TinyVector(value_type const & initial)
1032 : BaseType()
1033 {
1034 Loop::assignScalar(BaseType::begin(), initial);
1035 }
1036
1037 /** Construction from lemon::Invalid.
1038
1039 Initializes all vector elements with -1.
1040 */
1041 TinyVector(lemon::Invalid const &)
1042 : BaseType()
1043 {
1044 Loop::assignScalar(BaseType::begin(), -1);
1045 }
1046
1047 /** Construction with Diff2D.
1048
1049 Use only when <tt>SIZE == 2</tt>.
1050 */
1051 explicit TinyVector(Diff2D const & initial)
1052 : BaseType()
1053 {
1054 BaseType::data_[0] = detail::RequiresExplicitCast<T>::cast(initial.x);
1055 BaseType::data_[1] = detail::RequiresExplicitCast<T>::cast(initial.y);
1056 }
1057
1058 /** Construction with explicit values.
1059 Call only if SIZE == 2
1060 */
1061 TinyVector(value_type const & i1, value_type const & i2)
1062 : BaseType()
1063 {
1064 VIGRA_STATIC_ASSERT((TinyVector_constructor_has_wrong_number_of_arguments<SIZE, 2>));
1065 BaseType::data_[0] = i1;
1066 BaseType::data_[1] = i2;
1067 }
1068
1069 /** Construction with explicit values.
1070 Call only if SIZE == 3
1071 */
1072 TinyVector(value_type const & i1, value_type const & i2, value_type const & i3)
1073 : BaseType()
1074 {
1075 VIGRA_STATIC_ASSERT((TinyVector_constructor_has_wrong_number_of_arguments<SIZE, 3>));
1076 BaseType::data_[0] = i1;
1077 BaseType::data_[1] = i2;
1078 BaseType::data_[2] = i3;
1079 }
1080
1081 /** Construction with explicit values.
1082 Call only if SIZE == 4
1083 */
1084 TinyVector(value_type const & i1, value_type const & i2,
1085 value_type const & i3, value_type const & i4)
1086 : BaseType()
1087 {
1088 VIGRA_STATIC_ASSERT((TinyVector_constructor_has_wrong_number_of_arguments<SIZE, 4>));
1089 BaseType::data_[0] = i1;
1090 BaseType::data_[1] = i2;
1091 BaseType::data_[2] = i3;
1092 BaseType::data_[3] = i4;
1093 }
1094
1095 /** Construction with explicit values.
1096 Call only if SIZE == 5
1097 */
1098 TinyVector(value_type const & i1, value_type const & i2,
1099 value_type const & i3, value_type const & i4,
1100 value_type const & i5)
1101 : BaseType()
1102 {
1103 VIGRA_STATIC_ASSERT((TinyVector_constructor_has_wrong_number_of_arguments<SIZE, 5>));
1104 BaseType::data_[0] = i1;
1105 BaseType::data_[1] = i2;
1106 BaseType::data_[2] = i3;
1107 BaseType::data_[3] = i4;
1108 BaseType::data_[4] = i5;
1109 }
1110
1111 /** Default constructor (initializes all elements with zero).
1112 */
1113 TinyVector()
1114 : BaseType()
1115 {
1116 Loop::assignScalar(BaseType::data_, value_type());
1117 }
1118
1119 /** Construct without initializing the vector elements.
1120 */
1121 explicit TinyVector(SkipInitializationTag)
1122 : BaseType()
1123 {}
1124
1125 explicit TinyVector(detail::DontInit)
1126 : BaseType()
1127 {}
1128
1129 /** Copy constructor.
1130 */
1131 TinyVector(TinyVector const & r)
1132 : BaseType()
1133 {
1134 Loop::assign(BaseType::data_, r.data_);
1135 }
1136
1137 /** Constructor from C array.
1138 */
1139 template <class U>
1140 explicit TinyVector(U const * data)
1141 : BaseType()
1142 {
1143 Loop::assign(BaseType::data_, data);
1144 }
1145
1146 /** Constructor by reverse copy from C array.
1147
1148 Usage:
1149 \code
1150 TinyVector<int, 3> v(1,2,3);
1151 TinyVector<int, 3> reversed(v.begin(), TinyVector<int, 3>::ReverseCopy);
1152 \endcode
1153 */
1154 explicit TinyVector(const_pointer data, ReverseCopyTag)
1155 : BaseType()
1156 {
1157 Loop::reverseAssign(BaseType::data_, data+SIZE-1);
1158 }
1159
1160 /** Copy with type conversion.
1161 */
1162 template <class U, class DATA, class DERIVED>
1163 TinyVector(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r)
1164 : BaseType()
1165 {
1166 Loop::assignCast(BaseType::data_, r.begin());
1167 }
1168
1169 /** Copy assignment.
1170 */
1171 TinyVector & operator=(TinyVector const & r)
1172 {
1173 Loop::assign(BaseType::data_, r.data_);
1174 return *this;
1175 }
1176
1177 /** Copy assignment with type conversion.
1178 */
1179 template <class U, class DATA, class DERIVED>
1180 TinyVector & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r)
1181 {
1182 Loop::assignCast(BaseType::data_, r.begin());
1183 return *this;
1184 }
1185
1186 /** Assignment from Diff2D.
1187
1188 Use only when <tt>SIZE == 2</tt>.
1189 */
1190 TinyVector & operator=(Diff2D const & r)
1191 {
1192 BaseType::data_[0] = detail::RequiresExplicitCast<T>::cast(r.x);
1193 BaseType::data_[1] = detail::RequiresExplicitCast<T>::cast(r.y);
1194 return *this;
1195 }
1196
1197 /** Assignment from scalar. Will set all entries to the given value.
1198 */
1199 TinyVector & operator=(value_type const & v)
1200 {
1201 Loop::assignScalar(BaseType::begin(), v);
1202 return *this;
1203 }
1204
1205 /** Copy from a TinyVector with a different number of elements.
1206
1207 Only the first <tt>min(SIZE, USIZE)</tt> elements are copied.
1208 */
1209 template <class U, int USIZE, class DATA, class DERIVED>
1210 TinyVector & copy(TinyVectorBase<U, USIZE, DATA, DERIVED> const & r)
1211 {
1212 static const int minSize = USIZE < SIZE
1213 ? USIZE
1214 : SIZE;
1215
1216 typedef typename detail::LoopType<minSize>::type MinLoop;
1217 MinLoop::assignCast(BaseType::data_, r.begin());
1218 return *this;
1219 }
1220};
1221
1222/** \brief Wrapper for fixed size vectors.
1223
1224 This class wraps an array of size SIZE of the specified VALUETYPE.
1225 Thus, the array can be accessed with an interface similar to
1226 that of std::vector (except that there are no functions
1227 that change the size of a TinyVectorView). The TinyVectorView
1228 does <em>not</em> assume ownership of the given memory.
1229
1230 \ref TinyVectorOperators "Arithmetic operations"
1231 on TinyVectorViews are defined as component-wise applications of these
1232 operations. Addition and subtraction of two TinyVectorViews
1233 (+=, -=, +, -, unary -), multiplication and division of an
1234 TinyVectorViews with a double, and NumericTraits/PromoteTraits are defined,
1235 so that TinyVectorView fulfills the requirements of \ref LinearAlgebraConcept "Linear Algebra".
1236
1237 VIGRA algorithms typically use \ref vigra::VectorAccessor to access
1238 TinyVectorViews as a whole, or specific components of them.
1239
1240 <b>See also:</b>
1241 <ul>
1242 <li> \ref vigra::TinyVectorBase
1243 <li> \ref vigra::TinyVector
1244 <li> \ref TinyVectorTraits
1245 <li> \ref TinyVectorOperators
1246 </ul>
1247
1248 <b>\#include</b> <vigra/tinyvector.hxx><br>
1249 Namespace: vigra
1250**/
1251 template <class T, int SIZE>
1252 class TinyVectorView
1253: public TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> >
1254{
1255 typedef TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> > BaseType;
1256 typedef typename BaseType::Loop Loop;
1257
1258 public:
1259
1260 typedef typename BaseType::value_type value_type;
1261 typedef typename BaseType::reference reference;
1262 typedef typename BaseType::const_reference const_reference;
1263 typedef typename BaseType::pointer pointer;
1264 typedef typename BaseType::const_pointer const_pointer;
1265 typedef typename BaseType::iterator iterator;
1266 typedef typename BaseType::const_iterator const_iterator;
1267 typedef typename BaseType::size_type size_type;
1268 typedef typename BaseType::difference_type difference_type;
1269 typedef typename BaseType::scalar_multiplier scalar_multiplier;
1270 typedef typename BaseType::SquaredNormType SquaredNormType;
1271 typedef typename BaseType::NormType NormType;
1272
1273 /** Default constructor
1274 (pointer to wrapped data is NULL).
1275 */
1276 TinyVectorView()
1277 : BaseType()
1278 {
1279 BaseType::data_ = 0;
1280 }
1281
1282 /** Construct view for given data array
1283 */
1284 TinyVectorView(const_pointer data)
1285 : BaseType()
1286 {
1287 BaseType::data_ = const_cast<pointer>(data);
1288 }
1289
1290 /** Copy constructor (shallow copy).
1291 */
1292 TinyVectorView(TinyVectorView const & other)
1293 : BaseType()
1294 {
1295 BaseType::data_ = const_cast<pointer>(other.data_);
1296 }
1297
1298 /** Construct view from other TinyVector.
1299 */
1300 template <class DATA, class DERIVED>
1301 TinyVectorView(TinyVectorBase<T, SIZE, DATA, DERIVED> const & other)
1302 : BaseType()
1303 {
1304 BaseType::data_ = const_cast<pointer>(other.data());
1305 }
1306
1307 /** Copy the data (not the pointer) of the rhs.
1308 */
1309 TinyVectorView & operator=(TinyVectorView const & r)
1310 {
1311 Loop::assign(BaseType::data_, r.begin());
1312 return *this;
1313 }
1314
1315 /** Copy the data of the rhs with cast.
1316 */
1317 template <class U, class DATA, class DERIVED>
1318 TinyVectorView & operator=(TinyVectorBase<U, SIZE, DATA, DERIVED> const & r)
1319 {
1320 Loop::assignCast(BaseType::data_, r.begin());
1321 return *this;
1322 }
1323};
1324
1325/********************************************************/
1326/* */
1327/* TinyVector Comparison */
1328/* */
1329/********************************************************/
1330
1331/** \addtogroup TinyVectorOperators Functions for TinyVector
1332
1333 \brief Implement basic arithmetic and equality for TinyVector.
1334
1335 These functions fulfill the requirements of a Linear Space (vector space).
1336 Return types are determined according to \ref TinyVectorTraits.
1337
1338 <b>\#include</b> <vigra/tinyvector.hxx><br>
1339 Namespace: vigra
1340*/
1341//@{
1342 /// component-wise equal
1343 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1344 inline bool
1345 operator==(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1346 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1347{
1348 return !(l != r);
1349}
1350
1351 /// component-wise not equal
1352 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1353 inline bool
1354 operator!=(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1355 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1356{
1357 typedef typename detail::LoopType<SIZE>::type ltype;
1358 return ltype::notEqual(l.begin(), r.begin());
1359}
1360
1361 /// lexicographical comparison
1362 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1363 inline bool
1364 operator<(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1365 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1366{
1367 typedef typename detail::LoopType<SIZE>::type ltype;
1368 return ltype::lexicographicLessThan(l.begin(), r.begin());
1369}
1370
1371
1372 /// pointwise less-than
1373 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1374 inline bool
1375 allLess(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1376 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1377{
1378 for(int k=0; k < SIZE; ++k)
1379 if (l[k] >= r[k])
1380 return false;
1381 return true;
1382}
1383
1384 /// pointwise greater-than
1385 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1386 inline bool
1387 allGreater(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1388 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1389{
1390 for(int k=0; k < SIZE; ++k)
1391 if(l[k] <= r[k])
1392 return false;
1393 return true;
1394}
1395
1396 /// pointwise less-equal
1397 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1398 inline bool
1399 allLessEqual(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1400 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1401{
1402 for(int k=0; k < SIZE; ++k)
1403 if (l[k] > r[k])
1404 return false;
1405 return true;
1406}
1407
1408 /// pointwise greater-equal
1409 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1410 inline bool
1411 allGreaterEqual(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1412 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1413{
1414 for(int k=0; k < SIZE; ++k)
1415 if (l[k] < r[k])
1416 return false;
1417 return true;
1418}
1419
1420 template <class V, int SIZE, class D1, class D2, class D3, class D4>
1421 bool
1422 closeAtTolerance(TinyVectorBase<V, SIZE, D1, D2> const & l,
1423 TinyVectorBase<V, SIZE, D3, D4> const & r,
1424 V epsilon = NumericTraits<V>::epsilon())
1425{
1426 typedef typename detail::LoopType<SIZE>::type ltype;
1427 return ltype::closeAtTolerance(l.begin(), r.begin(), epsilon);
1428}
1429
1430 template <class V, int SIZE>
1431 bool
1432 closeAtTolerance(TinyVector<V, SIZE> const & l,
1433 TinyVector<V, SIZE> const & r,
1434 V epsilon = NumericTraits<V>::epsilon())
1435{
1436 typedef typename detail::LoopType<SIZE>::type ltype;
1437 return ltype::closeAtTolerance(l.begin(), r.begin(), epsilon);
1438}
1439
1440/********************************************************/
1441/* */
1442/* TinyVector Output */
1443/* */
1444/********************************************************/
1445
1446 /// stream output
1447 template <class V1, int SIZE, class DATA, class DERIVED>
1448std::ostream &
1449 operator<<(std::ostream & out, TinyVectorBase<V1, SIZE, DATA, DERIVED> const & l)
1450{
1451 out << "(";
1452 int i;
1453 for(i=0; i<SIZE-1; ++i)
1454 out << l[i] << ", ";
1455 out << l[i] << ")";
1456 return out;
1457}
1458//@}
1459
1460/********************************************************/
1461/* */
1462/* TinyVector-Traits */
1463/* */
1464/********************************************************/
1465
1466/** \page TinyVectorTraits Numeric and Promote Traits of TinyVector
1467 The numeric and promote traits for TinyVectors follow
1468 the general specifications for \ref NumericPromotionTraits.
1469 They are implemented in terms of the traits of the basic types by
1470 partial template specialization:
1471
1472 \code
1473
1474 template <class T, int SIZE>
1475 struct NumericTraits<TinyVector<T, SIZE> >
1476 {
1477 typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
1478 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
1479
1480 typedef typename NumericTraits<T>::isIntegral isIntegral;
1481 typedef VigraFalseType isScalar;
1482 typedef typename NumericTraits<T>::isSigned isSigned;
1483
1484 // etc.
1485 };
1486
1487 template <class T, int SIZE>
1488 struct NormTraits<TinyVector<T, SIZE> >
1489 {
1490 typedef TinyVector<T, SIZE> Type;
1491 typedef typename Type::SquaredNormType SquaredNormType;
1492 typedef typename Type::NormType NormType;
1493 };
1494
1495 template <class T1, class T2, SIZE>
1496 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
1497 {
1498 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1499 };
1500 \endcode
1501
1502 <b>\#include</b> <vigra/tinyvector.hxx><br>
1503 Namespace: vigra
1504
1505 On compilers that don't support partial template specialization (e.g.
1506 MS VisualC++), the traits classes are explicitly specialized for
1507 <TT>TinyVector<VALUETYPE, SIZE></TT> with
1508 <TT>VALUETYPE = unsigned char | int | float | double</TT> and <TT>SIZE = 2 | 3 | 4</TT>.
1509
1510*/
1511
1512#if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
1513
1514 template <class T, int SIZE>
1515 struct NumericTraits<TinyVector<T, SIZE> >
1516{
1517 typedef TinyVector<T, SIZE> Type;
1518 typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
1519 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
1520 typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
1521 typedef T ValueType;
1522
1523 typedef typename NumericTraits<T>::isIntegral isIntegral;
1524 typedef VigraFalseType isScalar;
1525 typedef typename NumericTraits<T>::isSigned isSigned;
1526 typedef VigraTrueType isOrdered;
1527 typedef VigraFalseType isComplex;
1528
1529 static TinyVector<T, SIZE> zero()
1530 {
1531 return TinyVector<T, SIZE>(NumericTraits<T>::zero());
1532 }
1533 static TinyVector<T, SIZE> one()
1534 {
1535 return TinyVector<T, SIZE>(NumericTraits<T>::one());
1536 }
1537 static TinyVector<T, SIZE> nonZero()
1538 {
1539 return TinyVector<T, SIZE>(NumericTraits<T>::nonZero());
1540 }
1541
1542 static TinyVector<T, SIZE> min()
1543 {
1544 return TinyVector<T, SIZE>(NumericTraits<T>::min());
1545 }
1546 static TinyVector<T, SIZE> max()
1547 {
1548 return TinyVector<T, SIZE>(NumericTraits<T>::max());
1549 }
1550
1551 template <class D1, class D2>
1552 static Promote toPromote(TinyVectorBase<T, SIZE, D1, D2> const & v)
1553 {
1554 return Promote(v);
1555 }
1556
1557 template <class D1, class D2>
1558 static RealPromote toRealPromote(TinyVectorBase<T, SIZE, D1, D2> const & v)
1559 {
1560 return RealPromote(v);
1561 }
1562
1563 template <class D1, class D2>
1564 static TinyVector<T, SIZE>
1565 fromPromote(TinyVectorBase<typename NumericTraits<T>::Promote, SIZE, D1, D2> const & v)
1566 {
1567 TinyVector<T, SIZE> res(detail::dontInit());
1568 typedef typename detail::LoopType<SIZE>::type ltype;
1569 ltype::fromPromote(res.begin(), v.begin());
1570 return res;
1571 }
1572
1573 template <class D1, class D2>
1574 static TinyVector<T, SIZE>
1575 fromRealPromote(TinyVectorBase<typename NumericTraits<T>::RealPromote, SIZE, D1, D2> const & v)
1576 {
1577 TinyVector<T, SIZE> res(detail::dontInit());
1578 typedef typename detail::LoopType<SIZE>::type ltype;
1579 ltype::fromRealPromote(res.begin(), v.begin());
1580 return res;
1581 }
1582};
1583
1584 template <class T, int SIZE>
1585 struct NumericTraits<TinyVectorView<T, SIZE> >
1586: public NumericTraits<TinyVector<T, SIZE> >
1587{
1588 typedef TinyVector<T, SIZE> Type;
1589 typedef TinyVector<typename NumericTraits<T>::Promote, SIZE> Promote;
1590 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> RealPromote;
1591 typedef TinyVector<typename NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;
1592 typedef T ValueType;
1593
1594 typedef typename NumericTraits<T>::isIntegral isIntegral;
1595 typedef VigraFalseType isScalar;
1596 typedef typename NumericTraits<T>::isSigned isSigned;
1597 typedef VigraFalseType isOrdered;
1598 typedef VigraFalseType isComplex;
1599};
1600
1601 template <class T, int SIZE>
1602 struct NormTraits<TinyVector<T, SIZE> >
1603{
1604 typedef TinyVector<T, SIZE> Type;
1605 typedef typename Type::SquaredNormType SquaredNormType;
1606 typedef typename Type::NormType NormType;
1607};
1608
1609 template <class T, int SIZE>
1610 struct NormTraits<TinyVectorView<T, SIZE> >
1611{
1612 typedef TinyVector<T, SIZE> Type;
1613 typedef typename Type::SquaredNormType SquaredNormType;
1614 typedef typename Type::NormType NormType;
1615};
1616
1617 template <class T1, class T2, int SIZE>
1618 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
1619{
1620 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1621};
1622
1623 template <class T1, class T2, int SIZE>
1624 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVectorView<T2, SIZE> >
1625{
1626 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1627};
1628
1629 template <class T1, class T2, int SIZE>
1630 struct PromoteTraits<TinyVectorView<T1, SIZE>, TinyVector<T2, SIZE> >
1631{
1632 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1633};
1634
1635 template <class T1, class T2, int SIZE>
1636 struct PromoteTraits<TinyVector<T1, SIZE>, TinyVectorView<T2, SIZE> >
1637{
1638 typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> Promote;
1639};
1640
1641 template <class T, int SIZE>
1642 struct PromoteTraits<TinyVector<T, SIZE>, double >
1643{
1644 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
1645};
1646
1647 template <class T, int SIZE>
1648 struct PromoteTraits<double, TinyVector<T, SIZE> >
1649{
1650 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
1651};
1652
1653 template <class T, int SIZE>
1654 struct PromoteTraits<TinyVectorView<T, SIZE>, double >
1655{
1656 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
1657};
1658
1659 template <class T, int SIZE>
1660 struct PromoteTraits<double, TinyVectorView<T, SIZE> >
1661{
1662 typedef TinyVector<typename NumericTraits<T>::RealPromote, SIZE> Promote;
1663};
1664
1665 template<class T, int SIZE>
1666 struct CanSkipInitialization<TinyVectorView<T, SIZE> >
1667{
1668 typedef typename CanSkipInitialization<T>::type type;
1669 static const bool value = type::asBool;
1670};
1671
1672 template<class T, int SIZE>
1673 struct CanSkipInitialization<TinyVector<T, SIZE> >
1674{
1675 typedef typename CanSkipInitialization<T>::type type;
1676 static const bool value = type::asBool;
1677};
1678
1679
1680
1681#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1682
1683
1684#define TINYVECTOR_NUMTRAITS(T, SIZE) \
1685 template<>\
1686 struct NumericTraits<TinyVector<T, SIZE> >\
1687{\
1688 typedef TinyVector<T, SIZE> Type;\
1689 typedef TinyVector<NumericTraits<T>::Promote, SIZE> Promote;\
1690 typedef TinyVector<NumericTraits<T>::RealPromote, SIZE> RealPromote;\
1691 typedef TinyVector<NumericTraits<T>::ComplexPromote, SIZE> ComplexPromote;\
1692 typedef T ValueType; \
1693 typedef NumericTraits<T>::isIntegral isIntegral;\
1694 typedef VigraFalseType isScalar;\
1695 typedef NumericTraits<T>::isSigned isSigned; \
1696 typedef VigraFalseType isOrdered;\
1697 typedef VigraFalseType isComplex;\
1698 \
1699 static TinyVector<T, SIZE> zero() { \
1700 return TinyVector<T, SIZE>(NumericTraits<T>::zero()); \
1701 }\
1702 static TinyVector<T, SIZE> one() { \
1703 return TinyVector<T, SIZE>(NumericTraits<T>::one()); \
1704 }\
1705 static TinyVector<T, SIZE> nonZero() { \
1706 return TinyVector<T, SIZE>(NumericTraits<T>::nonZero()); \
1707 }\
1708 \
1709 static Promote toPromote(TinyVector<T, SIZE> const & v) { \
1710 return Promote(v); \
1711 }\
1712 static RealPromote toRealPromote(TinyVector<T, SIZE> const & v) { \
1713 return RealPromote(v); \
1714 }\
1715 static TinyVector<T, SIZE> fromPromote(Promote const & v) { \
1716 TinyVector<T, SIZE> res;\
1717 TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
1718 Promote::const_iterator s = v.begin();\
1719 for(; d != dend; ++d, ++s)\
1720 *d = NumericTraits<T>::fromPromote(*s);\
1721 return res;\
1722 }\
1723 static TinyVector<T, SIZE> fromRealPromote(RealPromote const & v) {\
1724 TinyVector<T, SIZE> res;\
1725 TinyVector<T, SIZE>::iterator d = res.begin(), dend = res.end();\
1726 RealPromote::const_iterator s = v.begin();\
1727 for(; d != dend; ++d, ++s)\
1728 *d = NumericTraits<T>::fromRealPromote(*s);\
1729 return res;\
1730 }\
1731}; \
1732 template<>\
1733 struct NormTraits<TinyVector<T, SIZE> >\
1734{\
1735 typedef TinyVector<T, SIZE> Type;\
1736 typedef Type::SquaredNormType SquaredNormType; \
1737 typedef Type::NormType NormType; \
1738};
1739
1740#define TINYVECTOR_PROMTRAITS1(type1, SIZE) \
1741 template<> \
1742 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type1, SIZE> > \
1743{ \
1744 typedef TinyVector<PromoteTraits<type1, type1>::Promote, SIZE> Promote; \
1745 static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
1746 return static_cast<Promote>(v); } \
1747};
1748
1749#define TINYVECTOR_PROMTRAITS2(type1, type2, SIZE) \
1750 template<> \
1751 struct PromoteTraits<TinyVector<type1, SIZE>, TinyVector<type2, SIZE> > \
1752{ \
1753 typedef TinyVector<PromoteTraits<type1, type2>::Promote, SIZE> Promote; \
1754 static Promote toPromote(TinyVector<type1, SIZE> const & v) { \
1755 return static_cast<Promote>(v); } \
1756 static Promote toPromote(TinyVector<type2, SIZE> const & v) { \
1757 return static_cast<Promote>(v); } \
1758};
1759
1760#define TINYVECTOR_TRAITS(SIZE) \
1761 TINYVECTOR_NUMTRAITS(unsigned char, SIZE)\
1762 TINYVECTOR_NUMTRAITS(int, SIZE)\
1763 TINYVECTOR_NUMTRAITS(float, SIZE)\
1764 TINYVECTOR_NUMTRAITS(double, SIZE)\
1765 TINYVECTOR_PROMTRAITS1(unsigned char, SIZE)\
1766 TINYVECTOR_PROMTRAITS1(int, SIZE)\
1767 TINYVECTOR_PROMTRAITS1(float, SIZE)\
1768 TINYVECTOR_PROMTRAITS1(double, SIZE)\
1769 TINYVECTOR_PROMTRAITS2(float, unsigned char, SIZE)\
1770 TINYVECTOR_PROMTRAITS2(unsigned char, float, SIZE)\
1771 TINYVECTOR_PROMTRAITS2(int, unsigned char, SIZE)\
1772 TINYVECTOR_PROMTRAITS2(unsigned char, int, SIZE)\
1773 TINYVECTOR_PROMTRAITS2(int, float, SIZE)\
1774 TINYVECTOR_PROMTRAITS2(float, int, SIZE)\
1775 TINYVECTOR_PROMTRAITS2(double, unsigned char, SIZE)\
1776 TINYVECTOR_PROMTRAITS2(unsigned char, double, SIZE)\
1777 TINYVECTOR_PROMTRAITS2(int, double, SIZE)\
1778 TINYVECTOR_PROMTRAITS2(double, int, SIZE)\
1779 TINYVECTOR_PROMTRAITS2(double, float, SIZE)\
1780 TINYVECTOR_PROMTRAITS2(float, double, SIZE)
1781
1782TINYVECTOR_TRAITS(2)
1783TINYVECTOR_TRAITS(3)
1784TINYVECTOR_TRAITS(4)
1785
1786#undef TINYVECTOR_NUMTRAITS
1787#undef TINYVECTOR_PROMTRAITS1
1788#undef TINYVECTOR_PROMTRAITS2
1789#undef TINYVECTOR_TRAITS
1790
1791#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
1792
1793
1794/********************************************************/
1795/* */
1796/* TinyVector-Arithmetic */
1797/* */
1798/********************************************************/
1799
1800/** \addtogroup TinyVectorOperators
1801 */
1802//@{
1803
1804 /// component-wise addition
1805 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1806 inline
1807 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1808 operator+(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1809 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1810{
1811 return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) += r;
1812}
1813
1814 /// component-wise subtraction
1815 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1816 inline
1817 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1818 operator-(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1819 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1820{
1821 return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) -= r;
1822}
1823
1824 /// component-wise multiplication
1825 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1826 inline
1827 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1828operator*(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1829 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1830{
1831 return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) *= r;
1832}
1833
1834 /// component-wise division
1835 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1836 inline
1837 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1838operator/(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1839 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1840{
1841 return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) /= r;
1842}
1843
1844 /// component-wise modulo
1845 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
1846 inline
1847 typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2, SIZE> >::Promote
1848 operator%(TinyVectorBase<V1, SIZE, D1, D2> const & l,
1849 TinyVectorBase<V2, SIZE, D3, D4> const & r)
1850{
1851 return typename PromoteTraits<TinyVector<V1, SIZE>, TinyVector<V2 , SIZE> >::Promote(l) %= r;
1852}
1853
1854 /// component-wise left scalar addition
1855 template <class V, int SIZE, class D1, class D2>
1856 inline
1857 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1858 operator+(double v, TinyVectorBase<V, SIZE, D1, D2> const & r)
1859{
1860 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(r) += v;
1861}
1862
1863 /// component-wise right scalar addition
1864 template <class V, int SIZE, class D1, class D2>
1865 inline
1866 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1867 operator+(TinyVectorBase<V, SIZE, D1, D2> const & l, double v)
1868{
1869 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) += v;
1870}
1871
1872 /// component-wise left scalar subtraction
1873 template <class V, int SIZE, class D1, class D2>
1874 inline
1875 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1876 operator-(double v, TinyVectorBase<V, SIZE, D1, D2> const & r)
1877{
1878 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(v) -= r;
1879}
1880
1881 /// component-wise right scalar subtraction
1882 template <class V, int SIZE, class D1, class D2>
1883 inline
1884 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1885 operator-(TinyVectorBase<V, SIZE, D1, D2> const & l, double v)
1886{
1887 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) -= v;
1888}
1889
1890 /// component-wise left scalar multiplication
1891 template <class V, int SIZE, class D1, class D2>
1892 inline
1893 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1894operator*(double v, TinyVectorBase<V, SIZE, D1, D2> const & r)
1895{
1896 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(r) *= v;
1897}
1898
1899 /// component-wise right scalar multiplication
1900 template <class V, int SIZE, class D1, class D2>
1901 inline
1902 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1903operator*(TinyVectorBase<V, SIZE, D1, D2> const & l, double v)
1904{
1905 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) *= v;
1906}
1907
1908 /// component-wise left scalar division
1909 template <class V, int SIZE, class D1, class D2>
1910 inline
1911 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1912operator/(double v, TinyVectorBase<V, SIZE, D1, D2> const & r)
1913{
1914 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(v) /= r;
1915}
1916
1917 /// component-wise right scalar division
1918 template <class V, int SIZE, class D1, class D2>
1919 inline
1920 typename NumericTraits<TinyVector<V, SIZE> >::RealPromote
1921operator/(TinyVectorBase<V, SIZE, D1, D2> const & l, double v)
1922{
1923 return typename NumericTraits<TinyVector<V, SIZE> >::RealPromote(l) /= v;
1924}
1925
1926 /// component-wise scalar division without type promotion
1927 template <class V, int SIZE, class D1, class D2>
1928 inline
1929TinyVector<V, SIZE>
1930 div(TinyVectorBase<V, SIZE, D1, D2> const & l, V v)
1931{
1932 TinyVector<V, SIZE> result(l);
1933 typedef typename detail::LoopType<SIZE>::type Loop;
1934 Loop::divScalar(result.data(), v);
1935 return result;
1936}
1937
1938
1939 /** Unary negation (construct TinyVector with negative values)
1940 */
1941 template <class V, int SIZE, class D1, class D2>
1942 inline
1943TinyVector<V, SIZE>
1944 operator-(TinyVectorBase<V, SIZE, D1, D2> const & v)
1945{
1946 TinyVector<V, SIZE> res(detail::dontInit());
1947 typedef typename detail::LoopType<SIZE>::type ltype;
1948 ltype::neg(res.begin(), v.begin());
1949 return res;
1950}
1951
1952 /// component-wise absolute value
1953 template <class V, int SIZE, class D1, class D2>
1954 inline
1955TinyVector<V, SIZE>
1956abs(TinyVectorBase<V, SIZE, D1, D2> const & v)
1957{
1958 TinyVector<V, SIZE> res(detail::dontInit());
1959 typedef typename detail::LoopType<SIZE>::type ltype;
1960 ltype::abs(res.begin(), v.begin());
1961 return res;
1962}
1963
1964 /** Apply ceil() function to each vector component.
1965 */
1966 template <class V, int SIZE, class D1, class D2>
1967 inline
1968TinyVector<V, SIZE>
1969 ceil(TinyVectorBase<V, SIZE, D1, D2> const & v)
1970{
1971 TinyVector<V, SIZE> res(detail::dontInit());
1972 typedef typename detail::LoopType<SIZE>::type ltype;
1973 ltype::ceil(res.begin(), v.begin());
1974 return res;
1975}
1976
1977 /** Apply floor() function to each vector component.
1978 */
1979 template <class V, int SIZE, class D1, class D2>
1980 inline
1981TinyVector<V, SIZE>
1982 floor(TinyVectorBase<V, SIZE, D1, D2> const & v)
1983{
1984 TinyVector<V, SIZE> res(detail::dontInit());
1985 typedef typename detail::LoopType<SIZE>::type ltype;
1986 ltype::floor(res.begin(), v.begin());
1987 return res;
1988}
1989
1990 /** Apply round() function to each vector component.
1991 */
1992 template <class V, int SIZE, class D1, class D2>
1993 inline
1994TinyVector<V, SIZE>
1995 round(TinyVectorBase<V, SIZE, D1, D2> const & v)
1996{
1997 TinyVector<V, SIZE> res(detail::dontInit());
1998 typedef typename detail::LoopType<SIZE>::type ltype;
1999 ltype::round(res.begin(), v.begin());
2000 return res;
2001}
2002
2003 /** Apply roundi() function to each vector component, i.e. return an integer vector.
2004 */
2005 template <class V, int SIZE, class D1, class D2>
2006 inline
2007TinyVector<std::ptrdiff_t, SIZE>
2008 roundi(TinyVectorBase<V, SIZE, D1, D2> const & v)
2009{
2010 TinyVector<V, SIZE> res(detail::dontInit());
2011 for(int k=0; k<SIZE; ++k)
2012 res[k] = roundi(v[k]);
2013 return res;
2014}
2015
2016 /** Apply sqrt() function to each vector component.
2017 */
2018 template <class V, int SIZE, class D1, class D2>
2019 inline
2020TinyVector<V, SIZE>
2021sqrt(TinyVectorBase<V, SIZE, D1, D2> const & v)
2022{
2023 TinyVector<V, SIZE> res(detail::dontInit());
2024 typedef typename detail::LoopType<SIZE>::type ltype;
2025 ltype::sqrt(res.begin(), v.begin());
2026 return res;
2027}
2028
2029 using std::pow;
2030
2031 /** Apply pow() function to each vector component.
2032 */
2033 template <class V, int SIZE, class D1, class D2, class E>
2034 inline
2035TinyVector<V, SIZE>
2036pow(TinyVectorBase<V, SIZE, D1, D2> const & v, E exponent)
2037{
2038 TinyVector<V, SIZE> res(v);
2039 typedef typename detail::LoopType<SIZE>::type ltype;
2040 ltype::power(res.begin(), exponent);
2041 return res;
2042}
2043
2044 /// cross product
2045 template <class V1, class D1, class D2, class V2, class D3, class D4>
2046 inline
2047TinyVector<typename PromoteTraits<V1, V2>::Promote, 3>
2048cross(TinyVectorBase<V1, 3, D1, D2> const & r1,
2049 TinyVectorBase<V2, 3, D3, D4> const & r2)
2050{
2051 typedef TinyVector<typename PromoteTraits<V1, V2>::Promote, 3>
2052 Res;
2053 return Res(r1[1]*r2[2] - r1[2]*r2[1],
2054 r1[2]*r2[0] - r1[0]*r2[2],
2055 r1[0]*r2[1] - r1[1]*r2[0]);
2056}
2057
2058 /// dot product
2059 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
2060 inline
2061 typename PromoteTraits<V1, V2>::Promote
2062dot(TinyVectorBase<V1, SIZE, D1, D2> const & l,
2063 TinyVectorBase<V2, SIZE, D3, D4> const & r)
2064{
2065 typedef typename detail::LoopType<SIZE>::type ltype;
2066 return ltype::dot(l.begin(), r.begin());
2067}
2068
2069 /// sum of the vector's elements
2070 template <class V, int SIZE, class D1, class D2>
2071 inline
2072 typename NumericTraits<V>::Promote
2073 sum(TinyVectorBase<V, SIZE, D1, D2> const & l)
2074{
2075 typename NumericTraits<V>::Promote res = l[0];
2076 for(int k=1; k<SIZE; ++k)
2077 res += l[k];
2078 return res;
2079}
2080
2081 /// cumulative sum of the vector's elements
2082 template <class V, int SIZE, class D1, class D2>
2083 inline
2084TinyVector<typename NumericTraits<V>::Promote, SIZE>
2085 cumsum(TinyVectorBase<V, SIZE, D1, D2> const & l)
2086{
2087 TinyVector<typename NumericTraits<V>::Promote, SIZE> res(l);
2088 for(int k=1; k<SIZE; ++k)
2089 res[k] += res[k-1];
2090 return res;
2091}
2092
2093 /// product of the vector's elements
2094 template <class V, int SIZE, class D1, class D2>
2095 inline
2096 typename NumericTraits<V>::Promote
2097 prod(TinyVectorBase<V, SIZE, D1, D2> const & l)
2098{
2099 typename NumericTraits<V>::Promote res = l[0];
2100 for(int k=1; k<SIZE; ++k)
2101 res *= l[k];
2102 return res;
2103}
2104
2105 /// cumulative product of the vector's elements
2106 template <class V, int SIZE, class D1, class D2>
2107 inline
2108TinyVector<typename NumericTraits<V>::Promote, SIZE>
2109 cumprod(TinyVectorBase<V, SIZE, D1, D2> const & l)
2110{
2111 TinyVector<typename NumericTraits<V>::Promote, SIZE> res(l);
2112 for(int k=1; k<SIZE; ++k)
2113 res[k] *= res[k-1];
2114 return res;
2115}
2116
2117 using std::min;
2118
2119 /// element-wise minimum
2120 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
2121 inline
2122TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE>
2123min(TinyVectorBase<V1, SIZE, D1, D2> const & l,
2124 TinyVectorBase<V2, SIZE, D3, D4> const & r)
2125{
2126 typedef typename detail::LoopType<SIZE>::type ltype;
2127 TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE> res(l);
2128 ltype::min(res.begin(), r.begin());
2129 return res;
2130}
2131
2132// we also have to overload min for like-typed argument to prevent match of std::min()
2133 template <class V1, int SIZE, class D1, class D2>
2134 inline
2135TinyVector<V1, SIZE>
2136min(TinyVectorBase<V1, SIZE, D1, D2> const & l,
2137 TinyVectorBase<V1, SIZE, D1, D2> const & r)
2138{
2139 typedef typename detail::LoopType<SIZE>::type ltype;
2140 TinyVector<V1, SIZE> res(l);
2141 ltype::min(res.begin(), r.begin());
2142 return res;
2143}
2144
2145 template <class V1, int SIZE>
2146 inline
2147TinyVector<V1, SIZE>
2148min(TinyVector<V1, SIZE> const & l,
2149 TinyVector<V1, SIZE> const & r)
2150{
2151 typedef typename detail::LoopType<SIZE>::type ltype;
2152 TinyVector<V1, SIZE> res(l);
2153 ltype::min(res.begin(), r.begin());
2154 return res;
2155}
2156
2157 /// minimum element
2158 template <class V, int SIZE, class D1, class D2>
2159 inline
2160V const &
2161min(TinyVectorBase<V, SIZE, D1, D2> const & l)
2162{
2163 return l.minimum();
2164}
2165
2166 using std::max;
2167
2168 /// element-wise maximum
2169 template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
2170 inline
2171TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE>
2172max(TinyVectorBase<V1, SIZE, D1, D2> const & l,
2173 TinyVectorBase<V2, SIZE, D3, D4> const & r)
2174{
2175 typedef typename detail::LoopType<SIZE>::type ltype;
2176 TinyVector<typename PromoteTraits<V1, V2>::Promote, SIZE> res(l);
2177 ltype::max(res.begin(), r.begin());
2178 return res;
2179}
2180
2181// we also have to overload max for like-typed argument to prevent match of std::max()
2182 template <class V1, int SIZE, class D1, class D2>
2183 inline
2184TinyVector<V1, SIZE>
2185max(TinyVectorBase<V1, SIZE, D1, D2> const & l,
2186 TinyVectorBase<V1, SIZE, D1, D2> const & r)
2187{
2188 typedef typename detail::LoopType<SIZE>::type ltype;
2189 TinyVector<V1, SIZE> res(l);
2190 ltype::max(res.begin(), r.begin());
2191 return res;
2192}
2193
2194 template <class V1, int SIZE>
2195 inline
2196TinyVector<V1, SIZE>
2197max(TinyVector<V1, SIZE> const & l,
2198 TinyVector<V1, SIZE> const & r)
2199{
2200 typedef typename detail::LoopType<SIZE>::type ltype;
2201 TinyVector<V1, SIZE> res(l);
2202 ltype::max(res.begin(), r.begin());
2203 return res;
2204}
2205
2206 /// maximum element
2207 template <class V, int SIZE, class D1, class D2>
2208 inline
2209V const &
2210max(TinyVectorBase<V, SIZE, D1, D2> const & l)
2211{
2212 return l.maximum();
2213}
2214
2215 /// squared norm
2216 template <class V1, int SIZE, class D1, class D2>
2217 inline
2218 typename TinyVectorBase<V1, SIZE, D1, D2>::SquaredNormType
2219 squaredNorm(TinyVectorBase<V1, SIZE, D1, D2> const & t)
2220{
2221 return t.squaredMagnitude();
2222}
2223
2224 /// squared norm
2225 template <class V, int SIZE>
2226 inline
2227 typename TinyVector<V, SIZE>::SquaredNormType
2228 squaredNorm(TinyVector<V, SIZE> const & t)
2229{
2230 return t.squaredMagnitude();
2231}
2232
2233 using std::reverse;
2234
2235 /// reversed copy
2236 template <class V, int SIZE>
2237 inline
2238TinyVector<V, SIZE>
2239reverse(TinyVector<V, SIZE> const & t)
2240{
2241 return TinyVector<V, SIZE>(t.begin(), ReverseCopy);
2242}
2243
2244 /** \brief transposed copy
2245
2246 Elements are arranged such that <tt>res[k] = t[permutation[k]]</tt>.
2247 */
2248 template <class V, int SIZE, class T>
2249 inline
2250TinyVector<V, SIZE>
2251transpose(TinyVector<V, SIZE> const & t, TinyVector<T, SIZE> const & permutation)
2252{
2253 TinyVector<V, SIZE> res(SkipInitialization);
2254 for(int k=0; k<SIZE; ++k)
2255 {
2256 VIGRA_ASSERT_INSIDE(permutation[k]);
2257 res[k] = t[permutation[k]];
2258 }
2259 return res;
2260}
2261
2262 /** \brief Clip negative values.
2263
2264 All elements smaller than 0 are set to zero.
2265 */
2266 template<class V,int SIZE>
2267 inline
2268 TinyVector<V, SIZE> clipLower(TinyVector<V, SIZE> const & t){
2269 return clipLower(t, V(0));
2270}
2271
2272 /** \brief Clip values below a threshold.
2273
2274 All elements smaller than \a val are set to \a val.
2275 */
2276 template<class V,int SIZE>
2277 inline
2278 TinyVector<V, SIZE> clipLower(TinyVector<V, SIZE> const & t,const V val){
2279 TinyVector<V, SIZE> res(SkipInitialization);
2280 for(int k=0; k<SIZE; ++k){
2281 res[k]=t[k]< val ? val : t[k];
2282 }
2283 return res;
2284}
2285
2286 /** \brief Clip values above a threshold.
2287
2288 All elements bigger than \a val are set to \a val.
2289 */
2290 template<class V,int SIZE>
2291 inline
2292 TinyVector<V, SIZE> clipUpper(TinyVector<V, SIZE> const & t,const V val){
2293 TinyVector<V, SIZE> res(SkipInitialization);
2294 for(int k=0; k<SIZE; ++k){
2295 res[k]=t[k]> val ? val : t[k];
2296 }
2297 return res;
2298}
2299
2300 /** \brief Clip values to an interval.
2301
2302 All elements less than \a valLower are set to \a valLower, all elements
2303 bigger than \a valUpper are set to \a valUpper.
2304 */
2305 template<class V,int SIZE>
2306 inline
2307 TinyVector<V, SIZE> clip(TinyVector<V, SIZE> const & t,const V valLower, const V valUpper){
2308 TinyVector<V, SIZE> res(SkipInitialization);
2309 for(int k=0; k<SIZE; ++k){
2310 res[k] = (t[k] < valLower)
2311 ? valLower
2312 : (t[k] > valUpper)
2313 ? valUpper
2314 : t[k];
2315 }
2316 return res;
2317}
2318
2319 /** \brief Clip values to a vector of intervals.
2320
2321 All elements less than \a valLower are set to \a valLower, all elements
2322 bigger than \a valUpper are set to \a valUpper.
2323 */
2324 template<class V,int SIZE>
2325 inline
2326 TinyVector<V, SIZE> clip(TinyVector<V, SIZE> const & t,
2327 TinyVector<V, SIZE> const & valLower,
2328 TinyVector<V, SIZE> const & valUpper)
2329{
2330 TinyVector<V, SIZE> res(SkipInitialization);
2331 for(int k=0; k<SIZE; ++k){
2332 res[k] = (t[k] < valLower[k])
2333 ? valLower[k]
2334 : (t[k] > valUpper[k])
2335 ? valUpper[k]
2336 : t[k];
2337 }
2338 return res;
2339}
2340
2341 /** \brief Round up values to the nearest power of 2.
2342 Implemented only for UInt32
2343 */
2344 template<int SIZE>
2345 inline TinyVector<UInt32,SIZE> ceilPower2(vigra::TinyVector<UInt32,SIZE> const & t)
2346{
2347 TinyVector<UInt32,SIZE> res(SkipInitialization);
2348 for( size_t k = 0; k < SIZE; k++)
2349 res[k] = ceilPower2(t[k]);
2350 return res;
2351}
2352
2353 /** \brief Round down values to the nearest power of 2.
2354 Implemented only for UInt32
2355 */
2356 template<int SIZE>
2357 inline TinyVector<UInt32,SIZE> floorPower2(vigra::TinyVector<UInt32,SIZE> const & t)
2358{
2359 TinyVector<UInt32, SIZE> res(SkipInitialization);
2360 for( size_t k = 0; k < SIZE; k++)
2361 res[k] = floorPower2(t[k]);
2362 return res;
2363}
2364
2365 template<class V,int SIZE>
2366 inline
2367 bool isZero(TinyVector<V, SIZE> const & t){
2368 for(int k=0; k<SIZE; ++k){
2369 if(t[k]!=static_cast<V>(0))
2370 return false;
2371 }
2372 return true;
2373}
2374
2375 template<class V,int SIZE>
2376 inline typename NumericTraits<V>::RealPromote
2377mean(TinyVector<V, SIZE> const & t){
2378 const V sumVal = sum(t);
2379 return static_cast< typename NumericTraits<V>::RealPromote>(sumVal)/SIZE;
2380}
2381
2382
2383 template<class V,int SIZE>
2384 inline typename NumericTraits<V>::RealPromote
2385sizeDividedSquaredNorm(TinyVector<V, SIZE> const & t){
2386 return squaredNorm(t)/SIZE;
2387}
2388
2389 template<class V,int SIZE>
2390 inline typename NumericTraits<V>::RealPromote
2391sizeDividedNorm(TinyVector<V, SIZE> const & t){
2392 return norm(t)/SIZE;
2393}
2394
2395
2396
2397//@}
2398
2399// mask cl.exe shortcomings [end]
2400#if defined(_MSC_VER)
2401#pragma warning( pop )
2402#endif
2403
2404} // namespace vigra
2405#undef VIGRA_ASSERT_INSIDE
2406#endif // VIGRA_TINYVECTOR_HXX
vigra::Diff2D
Two dimensional difference vector.
Definition diff2d.hxx:186
vigra::Diff2D::y
int y
Definition diff2d.hxx:392
vigra::Diff2D::x
int x
Definition diff2d.hxx:385
vigra::RGBValue
Class for a single RGB value.
Definition rgbvalue.hxx:128
vigra::RGBValue::squaredMagnitude
SquaredNormType squaredMagnitude() const
Definition rgbvalue.hxx:313
vigra::TinyVectorBase
Base class for fixed size vectors.
Definition tinyvector.hxx:640
vigra::TinyVectorBase::magnitude
NormType magnitude() const
Definition tinyvector.hxx:802
vigra::TinyVectorBase::operator%=
DERIVED & operator%=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition tinyvector.hxx:761
vigra::TinyVectorBase::begin
const_iterator begin() const
Definition tinyvector.hxx:868
vigra::TinyVectorBase::unitVector
static TinyVector< VALUETYPE, SIZE > unitVector(int k)
Factory function for a unit vector for dimension k.
Definition tinyvector.hxx:941
vigra::TinyVectorBase::cbegin
const_iterator cbegin() const
Definition tinyvector.hxx:876
vigra::TinyVectorBase::NormType
SquareRootTraits< SquaredNormType >::SquareRootResult NormType
Definition tinyvector.hxx:699
vigra::TinyVectorBase::operator/=
DERIVED & operator/=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition tinyvector.hxx:752
vigra::TinyVectorBase::iterator
value_type * iterator
Definition tinyvector.hxx:675
vigra::TinyVectorBase::const_reference
VALUETYPE const & const_reference
Definition tinyvector.hxx:663
vigra::TinyVectorBase::reference
VALUETYPE & reference
Definition tinyvector.hxx:659
vigra::TinyVectorBase::init
void init(Iterator i, Iterator end)
Definition tinyvector.hxx:708
vigra::TinyVectorBase::size
size_type size() const
Definition tinyvector.hxx:913
vigra::TinyVectorBase::operator*=
DERIVED & operator*=(double r)
Definition tinyvector.hxx:785
vigra::TinyVectorBase::operator+=
DERIVED & operator+=(double r)
Definition tinyvector.hxx:769
vigra::TinyVectorBase::SquaredNormType
NormTraits< VALUETYPE >::SquaredNormType SquaredNormType
Definition tinyvector.hxx:695
vigra::TinyVectorBase::subarray
TinyVectorView< VALUETYPE, TO-FROM > subarray() const
Definition tinyvector.hxx:887
vigra::TinyVectorBase::minimum
VALUETYPE const & minimum() const
Definition tinyvector.hxx:817
vigra::TinyVectorBase::operator/=
DERIVED & operator/=(double r)
Definition tinyvector.hxx:793
vigra::TinyVectorBase::all
bool all() const
Definition tinyvector.hxx:831
vigra::TinyVectorBase::maximum
VALUETYPE const & maximum() const
Definition tinyvector.hxx:824
vigra::TinyVectorBase::operator*=
DERIVED & operator*=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition tinyvector.hxx:743
vigra::TinyVectorBase::const_iterator
value_type const * const_iterator
Definition tinyvector.hxx:679
vigra::TinyVectorBase::cend
const_iterator cend() const
Definition tinyvector.hxx:880
vigra::TinyVectorBase::operator[]
reference operator[](difference_type i)
Definition tinyvector.hxx:845
vigra::TinyVectorBase::const_pointer
VALUETYPE const * const_pointer
Definition tinyvector.hxx:671
vigra::TinyVectorBase::operator-=
DERIVED & operator-=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition tinyvector.hxx:734
vigra::TinyVectorBase::pointer
VALUETYPE * pointer
Definition tinyvector.hxx:667
vigra::TinyVectorBase::end
iterator end()
Definition tinyvector.hxx:864
vigra::TinyVectorBase::end
const_iterator end() const
Definition tinyvector.hxx:872
vigra::TinyVectorBase::operator+=
DERIVED & operator+=(TinyVectorBase< T1, SIZE, D1, D2 > const &r)
Definition tinyvector.hxx:725
vigra::TinyVectorBase::difference_type
std::ptrdiff_t difference_type
Definition tinyvector.hxx:687
vigra::TinyVectorBase::begin
iterator begin()
Definition tinyvector.hxx:861
vigra::TinyVectorBase::value_type
VALUETYPE value_type
Definition tinyvector.hxx:655
vigra::TinyVectorBase::init
void init(value_type initial)
Definition tinyvector.hxx:717
vigra::TinyVectorBase::size_type
unsigned int size_type
Definition tinyvector.hxx:683
vigra::TinyVectorBase::scalar_multiplier
double scalar_multiplier
Definition tinyvector.hxx:691
vigra::TinyVectorBase::operator[]
const_reference operator[](difference_type i) const
Definition tinyvector.hxx:853
vigra::TinyVectorBase::operator-=
DERIVED & operator-=(double r)
Definition tinyvector.hxx:777
vigra::TinyVectorBase::squaredMagnitude
SquaredNormType squaredMagnitude() const
Definition tinyvector.hxx:810
vigra::TinyVectorBase::linearSequence
static TinyVector< VALUETYPE, SIZE > linearSequence(VALUETYPE start=VALUETYPE(), VALUETYPE step=VALUETYPE(1))
Factory function for a linear sequence.
Definition tinyvector.hxx:953
vigra::TinyVectorBase::any
bool any() const
Definition tinyvector.hxx:838
vigra::TinyVectorView
Wrapper for fixed size vectors.
Definition tinyvector.hxx:1254
vigra::TinyVectorView::operator=
TinyVectorView & operator=(TinyVectorBase< U, SIZE, DATA, DERIVED > const &r)
Definition tinyvector.hxx:1318
vigra::TinyVectorView::operator=
TinyVectorView & operator=(TinyVectorView const &r)
Definition tinyvector.hxx:1309
vigra::TinyVectorView::TinyVectorView
TinyVectorView(const_pointer data)
Definition tinyvector.hxx:1284
vigra::TinyVectorView::TinyVectorView
TinyVectorView(TinyVectorBase< T, SIZE, DATA, DERIVED > const &other)
Definition tinyvector.hxx:1301
vigra::TinyVectorView::TinyVectorView
TinyVectorView()
Definition tinyvector.hxx:1276
vigra::TinyVectorView::TinyVectorView
TinyVectorView(TinyVectorView const &other)
Definition tinyvector.hxx:1292
vigra::TinyVector
Class for fixed size vectors.
Definition tinyvector.hxx:1008
vigra::TinyVector::TinyVector
TinyVector(lemon::Invalid const &)
Definition tinyvector.hxx:1041
vigra::TinyVector::TinyVector
TinyVector(value_type const &initial)
Definition tinyvector.hxx:1031
vigra::TinyVector::operator=
TinyVector & operator=(Diff2D const &r)
Definition tinyvector.hxx:1190
vigra::TinyVector::operator=
TinyVector & operator=(TinyVectorBase< U, SIZE, DATA, DERIVED > const &r)
Definition tinyvector.hxx:1180
vigra::TinyVector::operator=
TinyVector & operator=(TinyVector const &r)
Definition tinyvector.hxx:1171
vigra::TinyVector::TinyVector
TinyVector(SkipInitializationTag)
Definition tinyvector.hxx:1121
vigra::TinyVector::TinyVector
TinyVector(TinyVector const &r)
Definition tinyvector.hxx:1131
vigra::TinyVector::operator=
TinyVector & operator=(value_type const &v)
Definition tinyvector.hxx:1199
vigra::TinyVector::copy
TinyVector & copy(TinyVectorBase< U, USIZE, DATA, DERIVED > const &r)
Definition tinyvector.hxx:1210
vigra::TinyVector::TinyVector
TinyVector(U const *data)
Definition tinyvector.hxx:1140
vigra::TinyVector::TinyVector
TinyVector(value_type const &i1, value_type const &i2)
Definition tinyvector.hxx:1061
vigra::TinyVector::TinyVector
TinyVector(value_type const &i1, value_type const &i2, value_type const &i3)
Definition tinyvector.hxx:1072
vigra::TinyVector::TinyVector
TinyVector(value_type const &i1, value_type const &i2, value_type const &i3, value_type const &i4, value_type const &i5)
Definition tinyvector.hxx:1098
vigra::TinyVector::TinyVector
TinyVector(Diff2D const &initial)
Definition tinyvector.hxx:1051
vigra::TinyVector::TinyVector
TinyVector(const_pointer data, ReverseCopyTag)
Definition tinyvector.hxx:1154
vigra::TinyVector::TinyVector
TinyVector()
Definition tinyvector.hxx:1113
vigra::TinyVector::TinyVector
TinyVector(value_type const &i1, value_type const &i2, value_type const &i3, value_type const &i4)
Definition tinyvector.hxx:1084
vigra::TinyVector::TinyVector
TinyVector(TinyVectorBase< U, SIZE, DATA, DERIVED > const &r)
Definition tinyvector.hxx:1163
vigra::linalg::dot
NormTraits< T >::SquaredNormType dot(const MultiArrayView< 2, T, C1 > &x, const MultiArrayView< 2, T, C2 > &y)
Definition matrix.hxx:1342
vigra
vigra::floor
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition fixedpoint.hxx:667
vigra::allGreater
bool allGreater(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise greater-than
Definition tinyvector.hxx:1387
vigra::sub
void sub(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
subtraction with enforced result type.
Definition fixedpoint.hxx:583
vigra::allGreaterEqual
bool allGreaterEqual(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise greater-equal
Definition tinyvector.hxx:1411
vigra::round
int round(FixedPoint< IntBits, FracBits > v)
rounding to the nearest integer.
Definition fixedpoint.hxx:683
vigra::cumprod
TinyVector< typename NumericTraits< V >::Promote, SIZE > cumprod(TinyVectorBase< V, SIZE, D1, D2 > const &l)
cumulative product of the vector's elements
Definition tinyvector.hxx:2109
vigra::power
V power(const V &x)
Exponentiation to a positive integer power by squaring.
Definition mathutil.hxx:427
vigra::allLessEqual
bool allLessEqual(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise less-equal
Definition tinyvector.hxx:1399
vigra::operator+
Diff2D operator+(Diff2D const &a, Diff2D const &b)
Definition diff2d.hxx:739
vigra::mul
void mul(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
multiplication with enforced result type.
Definition fixedpoint.hxx:605
vigra::add
void add(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
addition with enforced result type.
Definition fixedpoint.hxx:561
vigra::norm
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude)
Definition fftw3.hxx:1037
vigra::clipUpper
TinyVector< V, SIZE > clipUpper(TinyVector< V, SIZE > const &t, const V val)
Clip values above a threshold.
Definition tinyvector.hxx:2292
vigra::cumsum
TinyVector< typename NumericTraits< V >::Promote, SIZE > cumsum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
cumulative sum of the vector's elements
Definition tinyvector.hxx:2085
vigra::roundi
Int32 roundi(FixedPoint16< IntBits, OverflowHandling > v)
rounding to the nearest integer.
Definition fixedpoint.hxx:1775
vigra::ceilPower2
UInt32 ceilPower2(UInt32 x)
Round up to the nearest power of 2.
Definition mathutil.hxx:294
vigra::sum
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition tinyvector.hxx:2073
vigra::floorPower2
UInt32 floorPower2(UInt32 x)
Round down to the nearest power of 2.
Definition mathutil.hxx:317
vigra::operator%
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:1848
vigra::prod
NumericTraits< V >::Promote prod(TinyVectorBase< V, SIZE, D1, D2 > const &l)
product of the vector's elements
Definition tinyvector.hxx:2097
vigra::clipLower
TinyVector< V, SIZE > clipLower(TinyVector< V, SIZE > const &t)
Clip negative values.
Definition tinyvector.hxx:2268
vigra::clip
TinyVector< V, SIZE > clip(TinyVector< V, SIZE > const &t, const V valLower, const V valUpper)
Clip values to an interval.
Definition tinyvector.hxx:2307
vigra::squaredNorm
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude)
Definition fftw3.hxx:1044
vigra::allLess
bool allLess(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise less-than
Definition tinyvector.hxx:1375
vigra::closeAtTolerance
bool closeAtTolerance(T1 l, T2 r, typename PromoteTraits< T1, T2 >::Promote epsilon)
Tolerance based floating-point equality.
Definition mathutil.hxx:1638
vigra::operator<
bool operator<(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less than
Definition fixedpoint.hxx:512
vigra::div
FixedPoint16< IntBits3, OverflowHandling > & div(FixedPoint16< IntBits1, OverflowHandling > l, FixedPoint16< IntBits2, OverflowHandling > r, FixedPoint16< IntBits3, OverflowHandling > &result)
division with enforced result type.
Definition fixedpoint.hxx:1616
vigra::operator==
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition fftw3.hxx:825
vigra::ceil
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition fixedpoint.hxx:675
vigra::operator!=
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition fftw3.hxx:841
vigra::operator-
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition diff2d.hxx:711

© 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.11.1