VectorND.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2008-2015 Imperial College London
5  * Copyright 2008-2015 Daniel Rueckert, Julia Schnabel
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_VectorND_H
21 #define MIRTK_VectorND_H
22 
23 #include "mirtk/Math.h"
24 #include "mirtk/Point.h"
25 #include "mirtk/Vector3.h"
26 
27 
28 namespace mirtk {
29 
30 
31 /// Represents a n-D vector of fixed dimensions
32 ///
33 /// Must be a primitive type which can be treated as an array of n
34 /// values of type T such that sizeof(VectorND<n, T>) == n * sizeof(T).
35 /// Thus, this primitive vector type may not have any other data members
36 /// besides the n vector components. This is required especially
37 /// when VectorND is used as voxel type of an image and further an
38 /// externally allocated continuous block of n * sizeof(T) bytes used
39 /// internally by the image instance which only reinterprets the memory
40 /// as consecutive VectorND<n, T> instances, i.e.,
41 ///
42 /// \code
43 /// const int X = 256;
44 /// const int Y = 256;
45 /// const int Z = 128;
46 /// const int num = X * Y * Z;
47 /// const int dim = 9;
48 /// double *data = new double[dim * num];
49 /// GenericImage<VectorND<dim, double> > image(X, Y, Z, data);
50 /// \endcode
51 template <int N, typename T>
52 struct VectorND
53 {
54  typedef T ComponentType;
55 
56  // ---------------------------------------------------------------------------
57  // Attributes
58 
59  /// Vector components
60  T _v[N];
61 
62  // ---------------------------------------------------------------------------
63  // Construction/Destruction
64 
65  /// Construct from scalar
66  VectorND(T = T(0));
67 
68  /// Construct from C array
69  explicit VectorND(const T[N]);
70 
71  /// Construct from variable size vector type
72  explicit VectorND(const Vector &);
73 
74  /// Copy constructor
75  template <typename T2>
76  VectorND(const VectorND<N, T2> &);
77 
78  // ---------------------------------------------------------------------------
79  // Accessors
80 
81  /// Number of vector components
82  static int Rows() { return N; }
83 
84  /// Set/get vector component at index
85  T &operator ()(int);
86 
87  /// Get vector component at index
88  T operator ()(int) const;
89 
90  /// Cast to C array pointer
91  operator T *();
92 
93  /// Cast to C array pointer
94  operator const T *() const;
95 
96  // ---------------------------------------------------------------------------
97  // Vector/integral-valued scalar operators
98 
99  /// Assign integral valued scalar
100  VectorND &operator =(int);
101 
102  /// Add integral valued scalar
103  VectorND &operator +=(int);
104 
105  /// Subtract integral valued scalar
106  VectorND &operator -=(int);
107 
108  /// Multiply by integral valued scalar
109  VectorND &operator *=(int);
110 
111  /// Divide by integral valued scalar
112  VectorND &operator /=(int);
113 
114  /// Add integral valued scalar to vector
115  VectorND operator +(int) const;
116 
117  /// Subtract integral valued scalar to vector
118  VectorND operator -(int) const;
119 
120  /// Multiply vector by integral valued scalar
121  VectorND operator *(int) const;
122 
123  /// Divide vector by integral valued scalar
124  VectorND operator /(int) const;
125 
126  // ---------------------------------------------------------------------------
127  // Vector/real-valued scalar operators
128 
129  /// Assign real valued scalar
130  VectorND &operator =(double);
131 
132  /// Add real valued scalar
133  VectorND &operator +=(double);
134 
135  /// Subtract real valued scalar
136  VectorND &operator -=(double);
137 
138  /// Multiply by real valued scalar
139  VectorND &operator *=(double);
140 
141  /// Divide by real valued scalar
142  VectorND &operator /=(double);
143 
144  /// Add real valued scalar to vector
145  VectorND operator +(double) const;
146 
147  /// Subtract real valued scalar to vector
148  VectorND operator -(double) const;
149 
150  /// Multiply vector by real valued scalar
151  VectorND operator *(double) const;
152 
153  /// Divide vector by real valued scalar
154  VectorND operator /(double) const;
155 
156  // ---------------------------------------------------------------------------
157  // Vector/vector operators
158 
159  /// Unary negation operator
160  VectorND operator -() const;
161 
162  /// Assignment from other vector
163  template <typename T2> VectorND &operator =(const VectorND<N, T2> &);
164 
165  /// Addition of other vector
166  template <typename T2> VectorND &operator +=(const VectorND<N, T2> &);
167 
168  /// Subtraction of other vector
169  template <typename T2> VectorND &operator -=(const VectorND<N, T2> &);
170 
171  /// Element-wise multiplication with other vector
172  template <typename T2> VectorND &operator *=(const VectorND<N, T2> &);
173 
174  /// Element-wise division by other vector
175  template <typename T2> VectorND &operator /=(const VectorND<N, T2> &);
176 
177  /// Addition of two vectors
178  template <typename T2> VectorND operator +(const VectorND<N, T2> &) const;
179 
180  /// Subtraction of two vectors
181  template <typename T2> VectorND operator -(const VectorND<N, T2> &) const;
182 
183  /// Element-wise multiplication of two vectors
184  template <typename T2> VectorND operator *(const VectorND<N, T2> &) const;
185 
186  /// Element-wise division of two vectors
187  template <typename T2> VectorND operator /(const VectorND<N, T2> &) const;
188 
189  // ---------------------------------------------------------------------------
190  // Vector/integral-valued scalar comparison
191 
192  /// Element-wise equality comparison with inegral-valued scalar
193  bool operator ==(int) const;
194 
195  /// Element-wise inequality comparison with inegral-valued scalar
196  bool operator !=(int) const;
197 
198  /// Element-wise less than comparison to inegral-valued scalar
199  bool operator <(int) const;
200 
201  /// Element-wise greater than comparison to inegral-valued scalar
202  bool operator >(int) const;
203 
204  /// Element-wise less or equal than comparison to inegral-valued scalar
205  bool operator <=(int) const;
206 
207  /// Element-wise greater or equal than comparison to inegral-valued scalar
208  bool operator >=(int) const;
209 
210  // ---------------------------------------------------------------------------
211  // Vector/real-valued scalar comparison
212 
213  /// Element-wise equality comparison with real-valued scalar
214  bool operator ==(double) const;
215 
216  /// Element-wise inequality comparison with real-valued scalar
217  bool operator !=(double) const;
218 
219  /// Element-wise less than comparison to real-valued scalar
220  bool operator <(double) const;
221 
222  /// Element-wise greater than comparison to real-valued scalar
223  bool operator >(double) const;
224 
225  /// Element-wise less or equal than comparison to real-valued scalar
226  bool operator <=(double) const;
227 
228  /// Element-wise greater or equal than comparison to real-valued scalar
229  bool operator >=(double) const;
230 
231  // ---------------------------------------------------------------------------
232  // Vector/vector comparison
233 
234  /// Operator for testing equality of two vectors
235  template <typename T2> bool operator ==(const VectorND<N, T2> &) const;
236 
237  /// Operator for testing non-equality of two vector
238  template <typename T2> bool operator !=(const VectorND<N, T2> &) const;
239 
240  /// Operator for ordering vectors
241  template <typename T2> bool operator <(const VectorND<N, T2> &) const;
242 
243  /// Operator for ordering vectors
244  template <typename T2> bool operator >(const VectorND<N, T2> &) const;
245 
246  /// Operator for ordering vectors
247  template <typename T2> bool operator <=(const VectorND<N, T2> &) const;
248 
249  /// Operator for ordering vectors
250  template <typename T2> bool operator >=(const VectorND<N, T2> &) const;
251 
252  // ---------------------------------------------------------------------------
253  // Other vector functions
254 
255  /// Compute squared length of vector
256  double SquaredLength() const;
257 
258  /// Compute length of vector
259  double Length() const;
260 
261  /// Normalize vector to length one
262  void Normalize();
263 
264  /// Dot-product with other vector
265  double DotProduct(const VectorND &) const;
266 
267 };
268 
269 ////////////////////////////////////////////////////////////////////////////////
270 // Inline definitions
271 ////////////////////////////////////////////////////////////////////////////////
272 
273 // =============================================================================
274 // Construction/Destruction
275 // =============================================================================
276 
277 // -----------------------------------------------------------------------------
278 template <int N, typename T>
280 {
281  for (int i = 0; i < N; ++i) {
282  _v[i] = s;
283  }
284 }
285 
286 // -----------------------------------------------------------------------------
287 template <int N, typename T>
288 inline VectorND<N, T>::VectorND(const T v[N])
289 {
290  for (int i = 0; i < N; ++i) {
291  _v[i] = v[i];
292  }
293 }
294 
295 // -----------------------------------------------------------------------------
296 template <int N, typename T>
298 {
299  if (v.Rows() != N) {
300  Throw(ERR_InvalidArgument, __FUNCTION__, "Vector must have ", N, " components");
301  }
302  for (int i = 0; i < N; ++i) {
303  _v[i] = static_cast<T>(v(i));
304  }
305 }
306 
307 // -----------------------------------------------------------------------------
308 template <int N, typename T1> template <typename T2>
310 {
311  for (int i = 0; i < N; ++i) {
312  _v[i] = static_cast<T1>(v._v[i]);
313  }
314 }
315 
316 // =============================================================================
317 // Accessors
318 // =============================================================================
319 
320 // -----------------------------------------------------------------------------
321 template <int N, typename T>
323 {
324  return _v[i];
325 }
326 
327 // -----------------------------------------------------------------------------
328 template <int N, typename T>
329 inline T VectorND<N, T>::operator ()(int i) const
330 {
331  return _v[i];
332 }
333 
334 // -----------------------------------------------------------------------------
335 template <int N, typename T>
337 {
338  return _v;
339 }
340 
341 // -----------------------------------------------------------------------------
342 template <int N, typename T>
343 inline VectorND<N, T>::operator const T *() const
344 {
345  return _v;
346 }
347 
348 // =============================================================================
349 // Vector/integral-valued scalar operators
350 // =============================================================================
351 
352 // -----------------------------------------------------------------------------
353 template <int N, typename T>
355 {
356  for (int i = 0; i < N; ++i) {
357  _v[i] = static_cast<T>(s);
358  }
359  return *this;
360 }
361 
362 // -----------------------------------------------------------------------------
363 template <int N, typename T>
365 {
366  for (int i = 0; i < N; ++i) {
367  _v[i] = static_cast<T>(static_cast<double>(_v[i]) + static_cast<double>(s));
368  }
369  return *this;
370 }
371 
372 // -----------------------------------------------------------------------------
373 template <int N, typename T>
375 {
376  for (int i = 0; i < N; ++i) {
377  _v[i] = static_cast<T>(static_cast<double>(_v[i]) - static_cast<double>(s));
378  }
379  return *this;
380 }
381 
382 // -----------------------------------------------------------------------------
383 template <int N, typename T>
385 {
386  for (int i = 0; i < N; ++i) {
387  _v[i] = static_cast<T>(static_cast<double>(_v[i]) * static_cast<double>(s));
388  }
389  return *this;
390 }
391 
392 // -----------------------------------------------------------------------------
393 template <int N, typename T>
395 {
396  for (int i = 0; i < N; ++i) {
397  _v[i] = static_cast<T>(static_cast<double>(_v[i]) / static_cast<double>(s));
398  }
399  return *this;
400 }
401 
402 // -----------------------------------------------------------------------------
403 template <int N, typename T>
405 {
406  VectorND<N, T> r(*this);
407  r += s;
408  return r;
409 }
410 
411 // -----------------------------------------------------------------------------
412 template <int N, typename T>
414 {
415  VectorND<N, T> r(*this);
416  r -= s;
417  return r;
418 }
419 
420 // -----------------------------------------------------------------------------
421 template <int N, typename T>
423 {
424  VectorND<N, T> r(*this);
425  r *= s;
426  return r;
427 }
428 
429 // -----------------------------------------------------------------------------
430 template <int N, typename T>
432 {
433  VectorND<N, T> r(*this);
434  r /= s;
435  return r;
436 }
437 
438 // -----------------------------------------------------------------------------
439 template <int N, typename T>
440 inline VectorND<N, T> operator +(int s, const VectorND<N, T> &v)
441 {
442  return v + s;
443 }
444 
445 // -----------------------------------------------------------------------------
446 template <int N, typename T>
447 inline VectorND<N, T> operator -(int s, const VectorND<N, T> &v)
448 {
449  return v - s;
450 }
451 
452 // -----------------------------------------------------------------------------
453 template <int N, typename T>
454 inline VectorND<N, T> operator *(int s, const VectorND<N, T> &v)
455 {
456  return v * s;
457 }
458 
459 // =============================================================================
460 // Vector/real-valued scalar operators
461 // =============================================================================
462 
463 // -----------------------------------------------------------------------------
464 template <int N, typename T>
466 {
467  for (int i = 0; i < N; ++i) {
468  _v[i] = static_cast<T>(s);
469  }
470  return *this;
471 }
472 
473 // -----------------------------------------------------------------------------
474 template <int N, typename T>
476 {
477  for (int i = 0; i < N; ++i) {
478  _v[i] = static_cast<T>(static_cast<double>(_v[i]) + s);
479  }
480  return *this;
481 }
482 
483 // -----------------------------------------------------------------------------
484 template <int N, typename T>
486 {
487  for (int i = 0; i < N; ++i) {
488  _v[i] = static_cast<T>(static_cast<double>(_v[i]) - s);
489  }
490  return *this;
491 }
492 
493 // -----------------------------------------------------------------------------
494 template <int N, typename T>
496 {
497  for (int i = 0; i < N; ++i) {
498  _v[i] = static_cast<T>(static_cast<double>(_v[i]) * s);
499  }
500  return *this;
501 }
502 
503 // -----------------------------------------------------------------------------
504 template <int N, typename T>
506 {
507  for (int i = 0; i < N; ++i) {
508  _v[i] = static_cast<T>(static_cast<double>(_v[i]) / s);
509  }
510  return *this;
511 }
512 
513 // -----------------------------------------------------------------------------
514 template <int N, typename T>
516 {
517  VectorND<N, T> r(*this);
518  r += s;
519  return r;
520 }
521 
522 // -----------------------------------------------------------------------------
523 template <int N, typename T>
525 {
526  VectorND<N, T> r(*this);
527  r -= s;
528  return r;
529 }
530 
531 // -----------------------------------------------------------------------------
532 template <int N, typename T>
534 {
535  VectorND<N, T> r(*this);
536  r *= s;
537  return r;
538 }
539 
540 // -----------------------------------------------------------------------------
541 template <int N, typename T>
543 {
544  VectorND<N, T> r(*this);
545  r /= s;
546  return r;
547 }
548 
549 // -----------------------------------------------------------------------------
550 template <int N, typename T>
551 inline VectorND<N, T> operator +(double s, const VectorND<N, T> &v)
552 {
553  return v + s;
554 }
555 
556 // -----------------------------------------------------------------------------
557 template <int N, typename T>
558 inline VectorND<N, T> operator -(double s, const VectorND<N, T> &v)
559 {
560  return v - s;
561 }
562 
563 // -----------------------------------------------------------------------------
564 template <int N, typename T>
565 inline VectorND<N, T> operator *(double s, const VectorND<N, T> &v)
566 {
567  return v * s;
568 }
569 
570 // =============================================================================
571 // Vector/vector operators
572 // =============================================================================
573 
574 // -----------------------------------------------------------------------------
575 template <int N, typename T>
577 {
578  VectorND<N, T> v(*this);
579  for (int i = 0; i < N; ++i) {
580  v._v[i] = -v._v[i];
581  }
582  return v;
583 }
584 
585 // -----------------------------------------------------------------------------
586 template <int N, typename T1> template <typename T2>
588 {
589  for (int i = 0; i < N; ++i) {
590  v._v[i] = static_cast<T1>(v._v[i]);
591  }
592  return *this;
593 }
594 
595 // -----------------------------------------------------------------------------
596 template <int N, typename T1> template <typename T2>
598 {
599  for (int i = 0; i < N; ++i) {
600  _v[i] = static_cast<T1>(static_cast<double>(_v[i]) + static_cast<double>(v._v[i]));
601  }
602  return *this;
603 }
604 
605 // -----------------------------------------------------------------------------
606 template <int N, typename T1> template <typename T2>
608 {
609  for (int i = 0; i < N; ++i) {
610  _v[i] = static_cast<T1>(static_cast<double>(_v[i]) - static_cast<double>(v._v[i]));
611  }
612  return *this;
613 }
614 
615 // -----------------------------------------------------------------------------
616 template <int N, typename T1> template <typename T2>
618 {
619  for (int i = 0; i < N; ++i) {
620  _v[i] = static_cast<T1>(static_cast<double>(_v[i]) * static_cast<double>(v._v[i]));
621  }
622  return *this;
623 }
624 
625 // -----------------------------------------------------------------------------
626 template <int N, typename T1> template <typename T2>
628 {
629  for (int i = 0; i < N; ++i) {
630  _v[i] = static_cast<T1>(static_cast<double>(_v[i]) / static_cast<double>(v._v[i]));
631  }
632  return *this;
633 }
634 
635 // -----------------------------------------------------------------------------
636 template <int N, typename T1> template <typename T2>
638 {
639  VectorND<N, T1> r(*this);
640  r += v;
641  return r;
642 }
643 
644 // -----------------------------------------------------------------------------
645 template <int N, typename T1> template <typename T2>
647 {
648  VectorND<N, T1> r(*this);
649  r -= v;
650  return r;
651 }
652 
653 // -----------------------------------------------------------------------------
654 template <int N, typename T1> template <typename T2>
656 {
657  VectorND<N, T1> r(*this);
658  r *= v;
659  return r;
660 }
661 
662 // -----------------------------------------------------------------------------
663 template <int N, typename T1> template <typename T2>
665 {
666  VectorND<N, T1> r(*this);
667  r /= v;
668  return r;
669 }
670 
671 // =============================================================================
672 // Vector/real-valued scalar comparison
673 // =============================================================================
674 
675 // -----------------------------------------------------------------------------
676 template <int N, typename T>
677 inline bool VectorND<N, T>::operator ==(double s) const
678 {
679  for (int i = 0; i < N; ++i) {
680  if (!AreEqual(static_cast<double>(_v[i]), s)) return false;
681  }
682 }
683 
684 // -----------------------------------------------------------------------------
685 template <int N, typename T>
686 inline bool VectorND<N, T>::operator !=(double s) const
687 {
688  return !(*this == s);
689 }
690 
691 // -----------------------------------------------------------------------------
692 template <int N, typename T>
693 inline bool VectorND<N, T>::operator <(double s) const
694 {
695  for (int i = 0; i < N; ++i) {
696  if (!(static_cast<double>(_v[i]) < s)) return false;
697  }
698  return true;
699 }
700 
701 // -----------------------------------------------------------------------------
702 template <int N, typename T>
703 inline bool VectorND<N, T>::operator >(double s) const
704 {
705  for (int i = 0; i < N; ++i) {
706  if (!(static_cast<double>(_v[i]) > s)) return false;
707  }
708  return true;
709 }
710 
711 // -----------------------------------------------------------------------------
712 template <int N, typename T>
713 inline bool VectorND<N, T>::operator <=(double s) const
714 {
715  return !(*this > s);
716 }
717 
718 // -----------------------------------------------------------------------------
719 template <int N, typename T>
720 inline bool VectorND<N, T>::operator >=(double s) const
721 {
722  return !(*this < s);
723 }
724 
725 // =============================================================================
726 // Vector/integral-valued scalar comparison
727 // =============================================================================
728 
729 // -----------------------------------------------------------------------------
730 template <int N, typename T>
731 inline bool VectorND<N, T>::operator ==(int s) const
732 {
733  return (*this == static_cast<double>(s));
734 }
735 
736 // -----------------------------------------------------------------------------
737 template <int N, typename T>
738 inline bool VectorND<N, T>::operator !=(int s) const
739 {
740  return !(*this == s);
741 }
742 
743 // -----------------------------------------------------------------------------
744 template <int N, typename T>
745 inline bool VectorND<N, T>::operator <(int s) const
746 {
747  return (*this < static_cast<double>(s));
748 }
749 
750 // -----------------------------------------------------------------------------
751 template <int N, typename T>
752 inline bool VectorND<N, T>::operator >(int s) const
753 {
754  return (*this > static_cast<double>(s));
755 }
756 
757 // -----------------------------------------------------------------------------
758 template <int N, typename T>
759 inline bool VectorND<N, T>::operator <=(int s) const
760 {
761  return !(*this > s);
762 }
763 
764 // -----------------------------------------------------------------------------
765 template <int N, typename T>
766 inline bool VectorND<N, T>::operator >=(int s) const
767 {
768  return !(*this < s);
769 }
770 
771 // =============================================================================
772 // Vector/vector comparison
773 // =============================================================================
774 
775 // -----------------------------------------------------------------------------
776 template <int N, typename T1> template <typename T2>
778 {
779  for (int i = 0; i < N; ++i) {
780  if (!AreEqual(static_cast<double>(_v[i]), static_cast<double>(v._v[i]))) return false;
781  }
782  return true;
783 }
784 
785 // -----------------------------------------------------------------------------
786 template <int N, typename T1> template <typename T2>
788 {
789  return !(*this == v);
790 }
791 
792 // -----------------------------------------------------------------------------
793 template <int N, typename T1> template <typename T2>
794 inline bool VectorND<N, T1>::operator <(const VectorND<N, T2> &v) const
795 {
796  for (int i = N - 1; i >= 0; --i) {
797  if (static_cast<double>(_v[i]) < static_cast<double>(v._v[i])) return true;
798  if (!AreEqual(static_cast<double>(_v[i]), static_cast<double>(v._v[i]))) break;
799  }
800  return false;
801 }
802 
803 // -----------------------------------------------------------------------------
804 template <int N, typename T1> template <typename T2>
805 inline bool VectorND<N, T1>::operator >(const VectorND<N, T2> &v) const
806 {
807  return !(*this == v) && !(*this < v);
808 }
809 
810 // -----------------------------------------------------------------------------
811 template <int N, typename T1> template <typename T2>
813 {
814  return (*this < v) || (*this == v);
815 }
816 
817 // -----------------------------------------------------------------------------
818 template <int N, typename T1> template <typename T2>
820 {
821  return (*this > v) || (*this == v);
822 }
823 
824 // =============================================================================
825 // Vector functions
826 // =============================================================================
827 
828 // -----------------------------------------------------------------------------
829 template <int N, typename T>
830 inline double VectorND<N, T>::DotProduct(const VectorND<N, T> &v) const
831 {
832  double dp = 0.;
833  for (int i = 0; i < N; ++i) {
834  dp += static_cast<double>(_v[i]) * static_cast<double>(v._v[i]);
835  }
836  return dp;
837 }
838 
839 // -----------------------------------------------------------------------------
840 template <int N, typename T>
841 inline double VectorND<N, T>::SquaredLength() const
842 {
843  return DotProduct(*this);
844 }
845 
846 // -----------------------------------------------------------------------------
847 template <int N, typename T>
848 inline double VectorND<N, T>::Length() const
849 {
850  return sqrt(SquaredLength());
851 }
852 
853 // -----------------------------------------------------------------------------
854 template <int N, typename T>
856 {
857  const double length = Length();
858  if (!IsZero(length)) (*this) /= length;
859 }
860 
861 // =============================================================================
862 // Indexed element access
863 // =============================================================================
864 
865 // -----------------------------------------------------------------------------
866 template <int N, class T>
867 inline T get(const VectorND<N, T> &v, int n)
868 {
869  return v(n);
870 }
871 
872 // -----------------------------------------------------------------------------
873 template <int N, class T>
874 inline void put(VectorND<N, T> &v, int n, const T &value)
875 {
876  v(n) = value;
877 }
878 
879 // =============================================================================
880 // Element-wise <cmath> functions
881 // =============================================================================
882 
883 // -----------------------------------------------------------------------------
884 template <int N, typename T>
885 VectorND<N, T> pow(const VectorND<N, T> &v, int e)
886 {
887  VectorND<N, T> w;
888  for (int i = 0; i < N; ++i) {
889  w._v[i] = pow(v._v[i], e);
890  }
891  return w;
892 }
893 
894 // -----------------------------------------------------------------------------
895 template <int N, typename T>
896 VectorND<N, T> pow(const VectorND<N, T> &v, double e)
897 {
898  VectorND<N, T> w;
899  for (int i = 0; i < N; ++i) {
900  w._v[i] = pow(v._v[i], e);
901  }
902  return w;
903 }
904 
905 // -----------------------------------------------------------------------------
906 template <int N, typename T>
907 VectorND<N, T> sqrt(const VectorND<N, T> &v)
908 {
909  VectorND<N, T> w;
910  for (int i = 0; i < N; ++i) {
911  w._v[i] = sqrt(v._v[i]);
912  }
913  return w;
914 }
915 
916 
917 } // namespace mirtk
918 
919 #endif // MIRTK_VectorND_H
bool operator>=(int) const
Element-wise greater or equal than comparison to inegral-valued scalar.
Definition: VectorND.h:766
VectorND & operator+=(int)
Add integral valued scalar.
Definition: VectorND.h:364
double SquaredLength() const
Compute squared length of vector.
Definition: VectorND.h:841
MIRTKCU_API bool IsZero(double a, double tol=1e-12)
Determine equality of a floating point number with zero.
Definition: Math.h:131
bool operator==(int) const
Element-wise equality comparison with inegral-valued scalar.
Definition: VectorND.h:731
double DotProduct(const VectorND &) const
Dot-product with other vector.
Definition: VectorND.h:830
Definition: IOConfig.h:41
VectorND & operator=(int)
Assign integral valued scalar.
Definition: VectorND.h:354
int Rows() const
Returns number of rows.
Definition: Vector.h:438
T _v[N]
Vector components.
Definition: VectorND.h:60
VectorND operator*(int) const
Multiply vector by integral valued scalar.
Definition: VectorND.h:422
T & operator()(int)
Set/get vector component at index.
Definition: VectorND.h:322
VectorND operator-() const
Unary negation operator.
Definition: VectorND.h:576
VectorND operator+(int) const
Add integral valued scalar to vector.
Definition: VectorND.h:404
bool operator<=(int) const
Element-wise less or equal than comparison to inegral-valued scalar.
Definition: VectorND.h:759
VectorND operator/(int) const
Divide vector by integral valued scalar.
Definition: VectorND.h:431
bool operator>(int) const
Element-wise greater than comparison to inegral-valued scalar.
Definition: VectorND.h:752
VectorND & operator-=(int)
Subtract integral valued scalar.
Definition: VectorND.h:374
VectorND & operator/=(int)
Divide by integral valued scalar.
Definition: VectorND.h:394
bool operator!=(int) const
Element-wise inequality comparison with inegral-valued scalar.
Definition: VectorND.h:738
static int Rows()
Number of vector components.
Definition: VectorND.h:82
void Throw(ErrorType err, const char *func, Args... args)
Definition: Exception.h:74
MIRTKCU_API bool AreEqual(double a, double b, double tol=1e-12)
Determine equality of two floating point numbers.
Definition: Math.h:115
bool operator<(int) const
Element-wise less than comparison to inegral-valued scalar.
Definition: VectorND.h:745
double Length() const
Compute length of vector.
Definition: VectorND.h:848
void Normalize()
Normalize vector to length one.
Definition: VectorND.h:855
VectorND & operator*=(int)
Multiply by integral valued scalar.
Definition: VectorND.h:384
VectorND(T=T(0))
Construct from scalar.
Definition: VectorND.h:279