MVE - Multi-View Environment mve-devel
Loading...
Searching...
No Matches
vector.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015, Simon Fuhrmann
3 * TU Darmstadt - Graphics, Capture and Massively Parallel Computing
4 * All rights reserved.
5 *
6 * This software may be modified and distributed under the terms
7 * of the BSD 3-Clause license. See the LICENSE.txt file for details.
8 */
9
10#ifndef MATH_VECTOR_HEADER
11#define MATH_VECTOR_HEADER
12
13#include <algorithm>
14#include <functional>
15#include <stdexcept>
16#include <numeric>
17#include <cmath>
18#include <ostream>
19
20#include "math/defines.h"
21#include "math/algo.h"
22
24
25/*
26 * Vector type definitions for convenience.
27 */
28template <typename T, int N> class Vector;
81
85template <typename T, int N>
86class Vector
87{
88public:
89 typedef T ValueType;
90
91 static int constexpr dim = N;
92
93 /* ------------------------ Constructors ---------------------- */
94
96 Vector (void);
98 explicit Vector (T const* values);
100 explicit Vector (T const& value);
102 Vector (T const& v1, T const& v2);
104 Vector (T const& v1, T const& v2, T const& v3);
106 Vector (T const& v1, T const& v2, T const& v3, T const& v4);
107
109 Vector (Vector<T,N-1> const& other, T const& v1);
110
112 Vector (Vector<T,N> const& other);
114 template <typename O>
115 Vector (Vector<O,N> const& other);
116
118 template <typename O>
119 explicit Vector (O const* values);
120
121 /* ------------------------- Management ----------------------- */
122
124 Vector<T,N>& fill (T const& value);
125
127 Vector<T,N>& copy (T const* values, int num = N);
128
130 T minimum (void) const;
131
133 T maximum (void) const;
134
136 T sum (void) const;
137
139 T abs_sum (void) const;
140
142 T product (void) const;
143
144 // TODO: central projection (4D -> 3D)
145
146 /* ---------------------- Unary operators --------------------- */
147
149 T norm (void) const;
151 T square_norm (void) const;
152
157
162
166 Vector<T,N> negated (void) const;
167
176
178 template <typename F>
181 template <typename F>
182 Vector<T,N> applied_for_each (F functor) const;
183
184 // TODO: component-wise max, min, mean?
185
186 /* --------------------- Binary operators --------------------- */
187
189 T dot (Vector<T,N> const& other) const;
190
192 Vector<T,N> cross (Vector<T,N> const& other) const;
193
195 Vector<T,N> cw_mult (Vector<T,N> const& other) const;
196
198 Vector<T,N> cw_div (Vector<T,N> const& other) const;
199
201 bool is_similar (Vector<T,N> const& other, T const& epsilon) const;
202
203 /* --------------------- Value iterators ---------------------- */
204
205 T* begin (void);
206 T const* begin (void) const;
207 T* end (void);
208 T const* end (void) const;
209
210 /* --------------------- Object operators --------------------- */
211
213 T* operator* (void);
215 T const* operator* (void) const;
216
218 T& operator[] (int index);
220 T const& operator[] (int index) const;
221
223 T& operator() (int index);
225 T const& operator() (int index) const;
226
228 bool operator== (Vector<T,N> const& rhs) const;
230 bool operator!= (Vector<T,N> const& rhs) const;
231
233 Vector<T,N>& operator= (Vector<T,N> const& rhs);
235 template <typename O>
236 Vector<T,N>& operator= (Vector<O,N> const& rhs);
237
239 Vector<T,N> operator- (void) const;
240
242 Vector<T,N>& operator-= (Vector<T,N> const& rhs);
244 Vector<T,N> operator- (Vector<T,N> const& rhs) const;
246 Vector<T,N>& operator+= (Vector<T,N> const& rhs);
248 Vector<T,N> operator+ (Vector<T,N> const& rhs) const;
249
251 Vector<T,N>& operator-= (T const& rhs);
253 Vector<T,N> operator- (T const& rhs) const;
255 Vector<T,N>& operator+= (T const& rhs);
257 Vector<T,N> operator+ (T const& rhs) const;
259 Vector<T,N>& operator*= (T const& rhs);
261 Vector<T,N> operator* (T const& rhs) const;
263 Vector<T,N>& operator/= (T const& rhs);
265 Vector<T,N> operator/ (T const& rhs) const;
266
267protected:
268 T v[N];
269};
270
272
273/* ------------------------ Implementation ------------------------ */
274
275#include <cmath>
276#include <algorithm>
277#include <stdexcept>
278#include <numeric>
279
281
282template <typename T, int N>
283int constexpr Vector<T,N>::dim;
284
285template <typename T, int N>
286inline
288{
289}
290
291template <typename T, int N>
292inline
293Vector<T,N>::Vector (T const* values)
294{
295 std::copy(values, values + N, v);
296}
297
298template <typename T, int N>
299inline
300Vector<T,N>::Vector (T const& value)
301{
302 fill(value);
303}
304
305template <typename T, int N>
306inline
307Vector<T,N>::Vector (T const& v1, T const& v2)
308{
309 v[0] = v1; v[1] = v2;
310}
311
312template <typename T, int N>
313inline
314Vector<T,N>::Vector (T const& v1, T const& v2, T const& v3)
315{
316 v[0] = v1; v[1] = v2; v[2] = v3;
317}
318
319template <typename T, int N>
320inline
321Vector<T,N>::Vector (T const& v1, T const& v2, T const& v3, T const& v4)
322{
323 v[0] = v1; v[1] = v2; v[2] = v3; v[3] = v4;
324}
325
326template <typename T, int N>
327inline
328Vector<T,N>::Vector (Vector<T,N-1> const& other, T const& v1)
329{
330 std::copy(*other, *other + N-1, v);
331 v[N-1] = v1;
332}
333
334template <typename T, int N>
335inline
337{
338 std::copy(*other, *other + N, v);
339}
340
341template <typename T, int N>
342template <typename O>
343inline
345{
346 std::copy(*other, *other + N, v);
347}
348
349template <typename T, int N>
350template <typename O>
351inline
352Vector<T,N>::Vector (O const* values)
353{
354 std::copy(values, values + N, v);
355}
356
357/* ------------------------- Vector helpers ----------------------- */
358
360template <typename T, int N>
361inline Vector<T,N>
362cross_product (Vector<T,N> const& /*v1*/, Vector<T,N> const& /*v2*/)
363{
364 throw std::invalid_argument("Only defined for 3-vectors");
365}
366
368template <typename T>
369inline Vector<T,3>
371{
372 return Vector<T,3>(v1[1] * v2[2] - v1[2] * v2[1],
373 v1[2] * v2[0] - v1[0] * v2[2],
374 v1[0] * v2[1] - v1[1] * v2[0]);
375}
376
377/* ---------------------------- Management ------------------------ */
378
379template <typename T, int N>
380inline Vector<T,N>&
381Vector<T,N>::fill (T const& value)
382{
383 std::fill(v, v + N, value);
384 return *this;
385}
386
387template <typename T, int N>
388inline Vector<T,N>&
389Vector<T,N>::copy (T const* values, int num)
390{
391 std::copy(values, values + num, this->v);
392 return *this;
393}
394
395template <typename T, int N>
396inline T
398{
399 return *std::min_element(v, v + N);
400}
401
402template <typename T, int N>
403inline T
405{
406 return *std::max_element(v, v + N);
407}
408
409template <typename T, int N>
410inline T
412{
413 return std::accumulate(v, v + N, T(0), std::plus<T>());
414}
415
416template <typename T, int N>
417inline T
419{
420 return std::accumulate(v, v + N, T(0), &algo::accum_absolute_sum<T>);
421}
422
423template <typename T, int N>
424inline T
426{
427 return std::accumulate(v, v + N, T(1), std::multiplies<T>());
428}
429
430/* ------------------------- Unary operators ---------------------- */
431
432template <typename T, int N>
433inline T
435{
436 return std::sqrt(square_norm());
437}
438
439template <typename T, int N>
440inline T
442{
443 return std::accumulate(v, v + N, T(0), &algo::accum_squared_sum<T>);
444}
445
446template <typename T, int N>
447inline Vector<T,N>&
449{
450 std::for_each(v, v + N, algo::foreach_divide_by_const<T>(norm()));
451 return *this;
452}
453
454template <typename T, int N>
455inline Vector<T,N>
457{
458 return Vector<T,N>(*this).normalize();
459}
460
461template <typename T, int N>
462inline Vector<T,N>&
464{
465 std::for_each(v, v + N, &algo::foreach_absolute_value<T>);
466 return *this;
467}
468
469template <typename T, int N>
470inline Vector<T,N>
472{
473 return Vector<T,N>(*this).abs_value();
474}
475
476template <typename T, int N>
477inline Vector<T,N>&
479{
480 std::for_each(v, v + N, &algo::foreach_negate_value<T>);
481 return *this;
482}
483
484template <typename T, int N>
485inline Vector<T,N>
487{
488 return Vector<T,N>(*this).negate();
489}
490
491template <typename T, int N>
492inline Vector<T,N>&
494{
495 std::sort(v, v + N, std::less<T>());
496 return *this;
497}
498
499template <typename T, int N>
500inline Vector<T,N>&
502{
503 std::sort(v, v + N, std::greater<T>());
504 return *this;
505}
506
507template <typename T, int N>
508inline Vector<T,N>
510{
511 return Vector<T,N>(*this).sort_asc();
512}
513
514template <typename T, int N>
515inline Vector<T,N>
517{
518 return Vector<T,N>(*this).sort_desc();
519}
520
521template <typename T, int N>
522template <typename F>
523inline Vector<T,N>&
525{
526 std::for_each(v, v + N, functor);
527 return *this;
528}
529
530template <typename T, int N>
531template <typename F>
532inline Vector<T,N>
534{
535 return Vector<T,N>(*this).apply_for_each(functor);
536}
537
538/* ------------------------ Binary operators ---------------------- */
539
540template <typename T, int N>
541inline T
542Vector<T,N>::dot (Vector<T,N> const& other) const
543{
544 return std::inner_product(v, v + N, *other, T(0));
545}
546
547template <typename T, int N>
548inline Vector<T,N>
549Vector<T,N>::cross (Vector<T,N> const& other) const
550{
551 return cross_product(*this, other);
552}
553
554template <typename T, int N>
555inline Vector<T,N>
557{
558 Vector<T,N> ret;
559 std::transform(v, v + N, other.v, ret.v, std::multiplies<T>());
560 return ret;
561}
562
563template <typename T, int N>
564inline Vector<T,N>
566{
567 Vector<T,N> ret;
568 std::transform(v, v + N, other.v, ret.v, std::divides<T>());
569 return ret;
570}
571
572template <typename T, int N>
573inline bool
574Vector<T,N>::is_similar (Vector<T,N> const& other, T const& eps) const
575{
576 return std::equal(v, v + N, *other, algo::predicate_epsilon_equal<T>(eps));
577}
578
579/* ------------------------ Value iterators ----------------------- */
580
581template <typename T, int N>
582inline T*
584{
585 return v;
586}
587
588template <typename T, int N>
589inline T const*
591{
592 return v;
593}
594
595template <typename T, int N>
596inline T*
598{
599 return v + N;
600}
601
602template <typename T, int N>
603inline T const*
605{
606 return v + N;
607}
608
609/* ------------------------ Object operators ---------------------- */
610
611template <typename T, int N>
612inline T*
614{
615 return v;
616}
617
618template <typename T, int N>
619inline T const*
621{
622 return v;
623}
624
625template <typename T, int N>
626inline T&
628{
629 return v[index];
630}
631
632template <typename T, int N>
633inline T const&
635{
636 return v[index];
637}
638
639template <typename T, int N>
640inline T&
642{
643 return v[index];
644}
645
646template <typename T, int N>
647inline T const&
649{
650 return v[index];
651}
652
653template <typename T, int N>
654inline bool
656{
657 return std::equal(v, v + N, *rhs);
658}
659
660template <typename T, int N>
661inline bool
663{
664 return !std::equal(v, v + N, *rhs);
665}
666
667template <typename T, int N>
668inline Vector<T,N>&
670{
671 std::copy(*rhs, *rhs + N, v);
672 return *this;
673}
674
675template <typename T, int N>
676template <typename O>
677inline Vector<T,N>&
679{
680 std::copy(*rhs, *rhs + N, v);
681 return *this;
682}
683
684template <typename T, int N>
685inline Vector<T,N>
687{
688 return negated();
689}
690
691template <typename T, int N>
692inline Vector<T,N>&
694{
695 std::transform(v, v + N, *rhs, v, std::minus<T>());
696 return *this;
697}
698
699template <typename T, int N>
700inline Vector<T,N>
702{
703 return Vector<T,N>(*this) -= rhs;
704}
705
706template <typename T, int N>
707inline Vector<T,N>&
709{
710 std::transform(v, v + N, *rhs, v, std::plus<T>());
711 return *this;
712}
713
714template <typename T, int N>
715inline Vector<T,N>
717{
718 return Vector<T,N>(*this) += rhs;
719}
720
721template <typename T, int N>
722inline Vector<T,N>&
724{
725 std::for_each(v, v + N, algo::foreach_substraction_with_const<T>(rhs));
726 return *this;
727}
728
729template <typename T, int N>
730inline Vector<T,N>
731Vector<T,N>::operator- (T const& rhs) const
732{
733 return Vector<T,N>(*this) -= rhs;
734}
735
736template <typename T, int N>
737inline Vector<T,N>&
739{
740 std::for_each(v, v + N, algo::foreach_addition_with_const<T>(rhs));
741 return *this;
742}
743
744template <typename T, int N>
745inline Vector<T,N>
746Vector<T,N>::operator+ (T const& rhs) const
747{
748 return Vector<T,N>(*this) += rhs;
749}
750
751template <typename T, int N>
752inline Vector<T,N>&
754{
755 std::for_each(v, v + N, algo::foreach_multiply_with_const<T>(rhs));
756 return *this;
757}
758
759template <typename T, int N>
760inline Vector<T,N>
761Vector<T,N>::operator* (T const& rhs) const
762{
763 return Vector<T,N>(*this) *= rhs;
764}
765
766template <typename T, int N>
767inline Vector<T,N>&
769{
770 std::for_each(v, v + N, algo::foreach_divide_by_const<T>(rhs));
771 return *this;
772}
773
774template <typename T, int N>
775inline Vector<T,N>
776Vector<T,N>::operator/ (T const& rhs) const
777{
778 return Vector<T,N>(*this) /= rhs;
779}
780
781/* ------------------------- Vector tools ------------------------- */
782
784template <typename T, int N>
785inline Vector<T,N>
786operator* (T const& s, Vector<T,N> const& v)
787{
788 return v * s;
789}
790
792template <typename T, int N>
793inline Vector<T,N>
794operator+ (T const& s, Vector<T,N> const& v)
795{
796 return v + s;
797}
798
800template <typename T, int N>
801inline Vector<T,N>
802operator- (T const& s, Vector<T,N> const& v)
803{
804 return -v + s;
805}
806
808template <typename T, int N>
809inline bool
811{
812 return std::any_of(v.begin(), v.end(),
813 [](T const& value) { return std::isnan(value); });
814}
815
817
818/* --------------------- Ouput stream adapter --------------------- */
819
820#include <ostream>
821
823
825template <typename T, int N>
826inline std::ostream&
827operator<< (std::ostream& os, Vector<T,N> const& v)
828{
829 for (int i = 0; i < N - 1; ++i)
830 os << v[i] << " ";
831 os << v[N-1];
832 return os;
833}
834
836
837#endif /* MATH_VECTOR_HEADER */
Vector class for arbitrary dimensions and types.
Definition vector.h:87
Vector< T, N > cw_mult(Vector< T, N > const &other) const
Component-wise multiplication with another vector.
Definition vector.h:556
T abs_sum(void) const
Returns the sum of the absolute values of all elements.
Definition vector.h:418
T square_norm(void) const
Computes the squared norm of the vector (much cheaper).
Definition vector.h:441
Vector< T, N > cross(Vector< T, N > const &other) const
Cross product between this and another vector.
Definition vector.h:549
T sum(void) const
Returns the sum of all elements.
Definition vector.h:411
T minimum(void) const
Returns the smallest element in the vector.
Definition vector.h:397
T product(void) const
Returns the product of all elements.
Definition vector.h:425
Vector< T, N > applied_for_each(F functor) const
Applies a for-each functor to a copy of the vector.
Definition vector.h:533
Vector(T const *values)
Ctor taking a pointer to initialize values.
Definition vector.h:293
Vector< T, N > cw_div(Vector< T, N > const &other) const
Component-wise division with another vector.
Definition vector.h:565
T norm(void) const
Computes the norm (length) of the vector.
Definition vector.h:434
T dot(Vector< T, N > const &other) const
Dot (or scalar) product between self and another vector.
Definition vector.h:542
Vector(T const &v1, T const &v2)
Ctor that initializes the first two elements.
Definition vector.h:307
Vector< T, N > & abs_value(void)
Component-wise absolute-value on self, returns self.
Definition vector.h:463
Vector< T, N > & sort_desc(void)
Sorts the elements of the vector into descending order.
Definition vector.h:501
Vector< T, N > sorted_asc(void) const
Returns a sorted vector into ascending order.
Definition vector.h:509
Vector< T, N > & fill(T const &value)
Fills all vector elements with the given value.
Definition vector.h:381
Vector(T const &v1, T const &v2, T const &v3)
Ctor that initializes the first three elements.
Definition vector.h:314
Vector(O const *values)
Ctor taking a pointer from different type to initialize values.
Definition vector.h:352
Vector< T, N > sorted_desc(void) const
Returns a sorted vector into descending order.
Definition vector.h:516
Vector(Vector< T, N > const &other)
Copy ctor from vector of same type.
Definition vector.h:336
Vector(Vector< T, N-1 > const &other, T const &v1)
Ctor that takes a smaller vector and one element.
Definition vector.h:328
T maximum(void) const
Returns the largest element in the vector.
Definition vector.h:404
Vector(void)
Default ctor.
Definition vector.h:287
Vector< T, N > & normalize(void)
Normalizes self and returns reference to self.
Definition vector.h:448
Vector(T const &v1, T const &v2, T const &v3, T const &v4)
Ctor that initializes the first four elements.
Definition vector.h:321
Vector< T, N > & apply_for_each(F functor)
Applies a for-each functor to all values.
Definition vector.h:524
T * end(void)
Definition vector.h:597
T const * end(void) const
Definition vector.h:604
Vector(T const &value)
Ctor that initializes ALL elements.
Definition vector.h:300
Vector< T, N > normalized(void) const
Returns a normalized copy of self.
Definition vector.h:456
T const * begin(void) const
Definition vector.h:590
Vector< T, N > & copy(T const *values, int num=N)
Copies values from the given pointer.
Definition vector.h:389
bool is_similar(Vector< T, N > const &other, T const &epsilon) const
Component-wise similarity using epsilon checks.
Definition vector.h:574
Vector< T, N > & negate(void)
Component-wise negation on self, returns self.
Definition vector.h:478
Vector< T, N > abs_valued(void) const
Returns a component-wise absolute-value copy of self.
Definition vector.h:471
Vector< T, N > & sort_asc(void)
Sorts the elements of the vector into ascending order.
Definition vector.h:493
Vector(Vector< O, N > const &other)
Copy ctor from vector of different type.
Definition vector.h:344
T * begin(void)
Definition vector.h:583
Vector< T, N > negated(void) const
Returns a component-wise negation on copy of self.
Definition vector.h:486
#define MATH_NAMESPACE_BEGIN
Definition defines.h:15
#define MATH_NAMESPACE_END
Definition defines.h:16
Vector< T, N > cross_product(Vector< T, N > const &, Vector< T, N > const &)
Cross product template for partial specialization.
Definition vector.h:362
bool isnan(Vector< T, N > const &v)
Tests if any of the vector values is NaN.
Definition vector.h:810
for-each functor: adds a constant value to operand.
Definition algo.h:241
for-each functor: divides operand by constant divisor.
Definition algo.h:232
for-each functor: multiplies operand with constant factor.
Definition algo.h:223
for-each functor: substracts a constant value to operand.
Definition algo.h:250
Epsilon comparator predicate.
Definition algo.h:136