Free Electron
Vector.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __math_Vector_h__
8 #define __math_Vector_h__
9 
10 namespace fe
11 {
12 
13 /**************************************************************************//**
14  @brief Dense vector - size fixed by template
15 
16  @ingroup math
17 *//***************************************************************************/
18 template<int N, class T>
19 class Vector
20 {
21  public:
22  Vector(void);
23  Vector(const Vector<N,T> &other);
24  template<typename U>
25  Vector(const Vector<N,U> &other);
26  template<typename U>
27  Vector(const Vector<N+1,U> &other);
28  template<typename U>
29  Vector(const Vector<N+2,U> &other);
30  template<typename U>
31  Vector(const Vector<N-1,U> &other);
32  template<typename U>
33  Vector(const Vector<N-2,U> &other);
34  Vector(const T *array);
35 
36 // Vector(T x,T y,T z=(T)0,T w=(T)0,T v=(T)0,T u=(T)0);
37  Vector(T x,T y,T z,T w,T v,T u);
38  Vector(T x,T y,T z,T w,T v);
39  Vector(T x,T y,T z,T w);
40  Vector(T x,T y,T z);
41  Vector(T x,T y);
42  Vector(T x);
43 
44 // Vector(const T &all);
45 
46 const T& operator[](unsigned int index) const;
47  T& operator[](unsigned int index);
48 
49  T *raw(void);
50 const T *raw(void) const;
51 
52  // like raw, but only valid if used on the call
53 const T *temp(void) const;
54 
55  Vector<N,T> &operator=(const T *array);
56  Vector<N,T> &operator=(const Vector<N,T> &other);
57  template<typename U>
58  Vector<N,T> &operator=(const Vector<N,U> &other);
59  Vector<N,T> &operator=(const Vector<N+1,T> &other);
60  template<typename U>
61  Vector<N,T> &operator=(const Vector<N+1,U> &other);
62  template<typename U>
63  Vector<N,T> &operator=(const Vector<N+2,U> &other);
64  template<typename U>
65  Vector<N,T> &operator=(const Vector<N-1,U> &other);
66  template<typename U>
67  Vector<N,T> &operator=(const Vector<N-2,U> &other);
68 
69  bool operator==(const Vector<N,T> &other) const;
70  bool operator!=(const Vector<N,T> &other) const;
71 
72  public:
73  T m_data[N];
74 };
75 
76 /// @internal
77 template<typename T>
78 inline
79 BWORD checkValid(const T& a_value)
80 {
81  return TRUE;
82 }
83 
84 /// @internal
85 template<typename T>
86 inline
87 void confirmValid(const T& a_value)
88 {
89 }
90 
91 /// @internal
92 inline
93 BWORD checkValid(const F32& a_value)
94 {
95  return !FE_INVALID_SCALAR(a_value);
96 }
97 
98 /// @internal
99 inline
100 void confirmValid(const F32& a_value)
101 {
102  if(!checkValid(a_value))
103  feX(e_corrupt,"confirmValid(F32)","scalar invalid");
104 }
105 
106 /// @internal
107 inline
108 BWORD checkValid(const F64& a_value)
109 {
110  return !FE_INVALID_SCALAR(a_value);
111 }
112 
113 /// @internal
114 inline
115 void confirmValid(const F64& a_value)
116 {
117  if(!checkValid(a_value))
118  feX(e_corrupt,"confirmValid(F64)","scalar invalid");
119 }
120 
121 /// @internal
122 template<int N,typename T>
123 inline
124 BWORD checkValid(const Vector<N,T>& a_vector)
125 {
126  return TRUE;
127 }
128 
129 /// @internal
130 template<int N,typename T>
131 inline
132 void confirmValid(const Vector<N,T>& a_vector)
133 {
134 }
135 
136 /// @internal
137 template<int N>
138 inline
139 BWORD checkValid(const Vector<N,F32>& a_vector)
140 {
141  const F32* data=a_vector.raw();
142  if(N>0 && FE_INVALID_SCALAR(data[0]))
143  return FALSE;
144  if(N>1 && FE_INVALID_SCALAR(data[1]))
145  return FALSE;
146  if(N>2 && FE_INVALID_SCALAR(data[2]))
147  return FALSE;
148  if(N>3 && FE_INVALID_SCALAR(data[3]))
149  return FALSE;
150  if(N>4 && FE_INVALID_SCALAR(data[4]))
151  return FALSE;
152  if(N>5 && FE_INVALID_SCALAR(data[5]))
153  return FALSE;
154  return TRUE;
155 }
156 
157 /// @internal
158 template<int N>
159 inline
160 void confirmValid(const Vector<N,F32>& a_vector)
161 {
162  const F32* data=a_vector.raw();
163  if(N>0 && FE_INVALID_SCALAR(data[0]))
164  feX(e_corrupt,"confirmValid(Vector<N,F32>)","vector element 0 invalid");
165  if(N>1 && FE_INVALID_SCALAR(data[1]))
166  feX(e_corrupt,"confirmValid(Vector<N,F32>)","vector element 1 invalid");
167  if(N>2 && FE_INVALID_SCALAR(data[2]))
168  feX(e_corrupt,"confirmValid(Vector<N,F32>)","vector element 2 invalid");
169  if(N>3 && FE_INVALID_SCALAR(data[3]))
170  feX(e_corrupt,"confirmValid(Vector<N,F32>)","vector element 3 invalid");
171  if(N>4 && FE_INVALID_SCALAR(data[4]))
172  feX(e_corrupt,"confirmValid(Vector<N,F32>)","vector element 4 invalid");
173  if(N>5 && FE_INVALID_SCALAR(data[5]))
174  feX(e_corrupt,"confirmValid(Vector<N,F32>)","vector element 5 invalid");
175 }
176 
177 /// @internal
178 template<int N>
179 inline
180 BWORD checkValid(const Vector<N,F64>& a_vector)
181 {
182  const F64* data=a_vector.raw();
183  if(N>0 && FE_INVALID_SCALAR(data[0]))
184  return FALSE;
185  if(N>1 && FE_INVALID_SCALAR(data[1]))
186  return FALSE;
187  if(N>2 && FE_INVALID_SCALAR(data[2]))
188  return FALSE;
189  if(N>3 && FE_INVALID_SCALAR(data[3]))
190  return FALSE;
191  if(N>4 && FE_INVALID_SCALAR(data[4]))
192  return FALSE;
193  if(N>5 && FE_INVALID_SCALAR(data[5]))
194  return FALSE;
195  return TRUE;
196 }
197 
198 /// @internal
199 template<int N>
200 inline
201 void confirmValid(const Vector<N,F64>& a_vector)
202 {
203  const F64* data=a_vector.raw();
204  if(N>0 && FE_INVALID_SCALAR(data[0]))
205  feX(e_corrupt,"confirmValid(Vector<N,F64>)","vector element 0 invalid");
206  if(N>1 && FE_INVALID_SCALAR(data[1]))
207  feX(e_corrupt,"confirmValid(Vector<N,F64>)","vector element 1 invalid");
208  if(N>2 && FE_INVALID_SCALAR(data[2]))
209  feX(e_corrupt,"confirmValid(Vector<N,F64>)","vector element 2 invalid");
210  if(N>3 && FE_INVALID_SCALAR(data[3]))
211  feX(e_corrupt,"confirmValid(Vector<N,F64>)","vector element 3 invalid");
212  if(N>4 && FE_INVALID_SCALAR(data[4]))
213  feX(e_corrupt,"confirmValid(Vector<N,F64>)","vector element 4 invalid");
214  if(N>5 && FE_INVALID_SCALAR(data[5]))
215  feX(e_corrupt,"confirmValid(Vector<N,F64>)","vector element 5 invalid");
216 }
217 
218 /// @internal
219 template<typename T>
220 inline
221 void maybeConfirmValid(const T& a_value)
222 {
223 #if FE_VEC_CHECK_VALID
224  confirmValid(a_value);
225 #endif
226 }
227 
228 template<int N, class T>
229 inline Vector<N,T>::Vector(void)
230 {
231  for(unsigned int i = 0; i < N; i++)
232  {
233  m_data[i] = T(0);
234  }
235  maybeConfirmValid(*this);
236 }
237 
238 template<int N, class T>
239 inline Vector<N,T>::Vector(const Vector<N,T> &other)
240 {
241  for(unsigned int i = 0; i < N; i++)
242  {
243  m_data[i] = other[i];
244  }
245  maybeConfirmValid(*this);
246 }
247 
248 template<int N, class T>
249 template<typename U>
250 inline Vector<N,T>::Vector(const Vector<N,U> &other)
251 {
252  for(unsigned int i = 0; i < N; i++)
253  {
254  m_data[i] = (T)other[i];
255  }
256  maybeConfirmValid(*this);
257 }
258 
259 template<int N, class T>
260 template<typename U>
261 inline Vector<N,T>::Vector(const Vector<N+1,U> &other)
262 {
263  for(unsigned int i = 0; i < N; i++)
264  {
265  m_data[i] = other[i];
266  }
267  maybeConfirmValid(*this);
268 }
269 
270 template<int N, class T>
271 template<typename U>
272 inline Vector<N,T>::Vector(const Vector<N+2,U> &other)
273 {
274  for(unsigned int i = 0; i < N; i++)
275  {
276  m_data[i] = other[i];
277  }
278  maybeConfirmValid(*this);
279 }
280 
281 template<int N, class T>
282 template<typename U>
283 inline Vector<N,T>::Vector(const Vector<N-1,U> &other)
284 {
285  for(unsigned int i = 0; i < N-1; i++)
286  {
287  m_data[i] = other[i];
288  }
289  if(N>1)
290  {
291  m_data[N-1]=T(0);
292  }
293  maybeConfirmValid(*this);
294 }
295 
296 template<int N, class T>
297 template<typename U>
298 inline Vector<N,T>::Vector(const Vector<N-2,U> &other)
299 {
300  for(unsigned int i = 0; i < N-2; i++)
301  {
302  m_data[i] = other[i];
303  }
304  if(N>1)
305  {
306  m_data[N-1]=T(0);
307  if(N>2)
308  {
309  m_data[N-2]=T(0);
310  }
311  }
312  maybeConfirmValid(*this);
313 }
314 
315 template<int N, class T>
316 inline Vector<N,T>::Vector(const T *array)
317 {
318  operator=(array);
319 }
320 
321 #if FALSE
322 template<int N,class T>
323 inline Vector<N,T>::Vector(T x, T y, T z, T w, T v, T u)
324 {
325  m_data[0] = x;
326  if(N >=2) m_data[1] = y;
327  if(N >=3) m_data[2] = z;
328  if(N >=4) m_data[3] = w;
329  if(N >=5) m_data[4] = v;
330  if(N >=6) m_data[5] = u;
331 
332  maybeConfirmValid(*this);
333 }
334 #else
335 template<int N,class T>
336 inline Vector<N,T>::Vector(T x, T y, T z, T w, T v, T u)
337 {
338  m_data[0] = x;
339  m_data[1] = y;
340  m_data[2] = z;
341  m_data[3] = w;
342  m_data[4] = v;
343  m_data[5] = u;
344  for(I32 n=6;n<N;n++) m_data[n]=T(0);
345 
346  maybeConfirmValid(*this);
347 }
348 template<int N,class T>
349 inline Vector<N,T>::Vector(T x, T y, T z, T w, T v)
350 {
351  m_data[0] = x;
352  m_data[1] = y;
353  m_data[2] = z;
354  m_data[3] = w;
355  m_data[4] = v;
356  for(I32 n=5;n<N;n++) m_data[n]=T(0);
357 
358  maybeConfirmValid(*this);
359 }
360 template<int N,class T>
361 inline Vector<N,T>::Vector(T x, T y, T z, T w)
362 {
363  m_data[0] = x;
364  m_data[1] = y;
365  m_data[2] = z;
366  m_data[3] = w;
367  for(I32 n=4;n<N;n++) m_data[n]=T(0);
368 
369  maybeConfirmValid(*this);
370 }
371 template<int N,class T>
372 inline Vector<N,T>::Vector(T x, T y, T z)
373 {
374  m_data[0] = x;
375  m_data[1] = y;
376  m_data[2] = z;
377  for(I32 n=3;n<N;n++) m_data[n]=T(0);
378 
379  maybeConfirmValid(*this);
380 }
381 template<int N,class T>
382 inline Vector<N,T>::Vector(T x, T y)
383 {
384  m_data[0] = x;
385  m_data[1] = y;
386  for(I32 n=2;n<N;n++) m_data[n]=T(0);
387 
388  maybeConfirmValid(*this);
389 }
390 template<int N,class T>
391 inline Vector<N,T>::Vector(T x)
392 {
393  m_data[0] = x;
394  for(I32 n=1;n<N;n++) m_data[n]=T(0);
395 
396  maybeConfirmValid(*this);
397 }
398 #endif
399 
400 #if FALSE
401 template<int N,class T>
402 inline Vector<N,T>::Vector(const T &all)
403 {
404  for(unsigned int i = 0; i < N; i++)
405  {
406  m_data[i] = all;
407  }
408 }
409 #endif
410 
411 template<int N, class T>
412 inline const T& Vector<N,T>::operator[](unsigned int index) const
413 {
414 #if FE_BOUNDSCHECK
415  if(index >= N) { feX(e_invalidRange); }
416 #endif
417  return m_data[index];
418 }
419 
420 template<int N, class T>
421 inline T &Vector<N,T>::operator[](unsigned int index)
422 {
423 #if FE_BOUNDSCHECK
424  if(index >= N) { feX(e_invalidRange); }
425 #endif
426  return m_data[index];
427 }
428 
429 template<int N, class T>
430 inline T *Vector<N,T>::raw(void)
431 {
432  return m_data;
433 }
434 
435 template<int N, class T>
436 inline const T *Vector<N,T>::raw(void) const
437 {
438  return m_data;
439 }
440 
441 template<int N, class T>
442 inline const T *Vector<N,T>::temp(void) const
443 {
444  maybeConfirmValid(*this);
445  return m_data;
446 }
447 
448 template<int N, class T>
449 inline bool Vector<N,T>::operator==(const Vector<N,T> &other) const
450 {
451  maybeConfirmValid(*this);
452  maybeConfirmValid(other);
453  if((void*)this != (void*)&other)
454  {
455  for(unsigned int i = 0; i < N; i++)
456  {
457  if(m_data[i] != other[i]) { return false; }
458  }
459  }
460  return true;
461 }
462 
463 template<int N, class T>
464 inline bool Vector<N,T>::operator!=(const Vector<N,T> &other) const
465 {
466  return !operator==(other);
467 }
468 
469 template<int N, class T>
470 inline Vector<N,T> &Vector<N,T>::operator=(const Vector<N,T> &other)
471 {
472  maybeConfirmValid(other);
473  if((void*)this != (void*)&other)
474  {
475  for(unsigned int i = 0; i < N; i++)
476  {
477  m_data[i] = other[i];
478  }
479  }
480  maybeConfirmValid(*this);
481  return *this;
482 }
483 
484 template<int N, class T>
485 template<typename U>
486 inline Vector<N,T> &Vector<N,T>::operator=(const Vector<N,U> &other)
487 {
488  maybeConfirmValid(other);
489  if((void*)this != (void*)&other)
490  {
491  for(unsigned int i = 0; i < N; i++)
492  {
493  m_data[i] = (T)other[i];
494  }
495  }
496  maybeConfirmValid(*this);
497  return *this;
498 }
499 
500 template<int N, class T>
502 {
503  maybeConfirmValid(other);
504  for(unsigned int i = 0; i < N; i++)
505  {
506  m_data[i] = other[i];
507  }
508  maybeConfirmValid(*this);
509  return *this;
510 }
511 
512 template<int N, class T>
513 template<typename U>
515 {
516  maybeConfirmValid(other);
517  for(unsigned int i = 0; i < N; i++)
518  {
519  m_data[i] = (T)other[i];
520  }
521  maybeConfirmValid(*this);
522  return *this;
523 }
524 
525 template<int N, class T>
526 template<typename U>
528 {
529  maybeConfirmValid(other);
530  for(unsigned int i = 0; i < N; i++)
531  {
532  m_data[i] = (T)other[i];
533  }
534  maybeConfirmValid(*this);
535  return *this;
536 }
537 
538 template<int N, class T>
539 template<typename U>
541 {
542  maybeConfirmValid(other);
543  for(unsigned int i = 0; i < N-1; i++)
544  {
545  m_data[i] = (T)other[i];
546  }
547  if(N>1)
548  {
549  m_data[N-1]=T(0);
550  }
551  maybeConfirmValid(*this);
552  return *this;
553 }
554 
555 template<int N, class T>
556 template<typename U>
558 {
559  maybeConfirmValid(other);
560  for(unsigned int i = 0; i < N-2; i++)
561  {
562  m_data[i] = (T)other[i];
563  }
564  if(N>1)
565  {
566  m_data[N-1]=T(0);
567  if(N>2)
568  {
569  m_data[N-2]=T(0);
570  }
571  }
572  maybeConfirmValid(*this);
573  return *this;
574 }
575 
576 template<int N, class T>
577 inline Vector<N,T> &Vector<N,T>::operator=(const T *array)
578 {
579  for(unsigned int i = 0; i < N; i++)
580  {
581  maybeConfirmValid(array[i]);
582  m_data[i] = array[i];
583  }
584  maybeConfirmValid(*this);
585  return *this;
586 }
587 
588 /* non member operations */
589 
590 /** Set all the elements to zero
591  @relates Vector
592  */
593 template<int N, class T>
594 inline Vector<N,T>& set(Vector<N,T> &lhs)
595 {
596  for(unsigned int i = 0; i < N; i++)
597  {
598  lhs[i] = T(0);
599  }
600  maybeConfirmValid(lhs);
601  return lhs;
602 }
603 
604 /** Set all the elements to the given value
605  @relates Vector
606  */
607 template<int N, class T, class U>
608 inline Vector<N,T>& setAll(Vector<N,T> &lhs,const U value)
609 {
610  maybeConfirmValid(value);
611  for(unsigned int i = 0; i < N; i++)
612  {
613  lhs[i] = value;
614  }
615  maybeConfirmValid(lhs);
616  return lhs;
617 }
618 
619 /** Set the value at the index
620  @relates Vector
621  */
622 template<int N, class T,class U>
623 inline Vector<N,T> &setAt(Vector<N,T> &lhs, U32 index,const U value)
624 {
625  maybeConfirmValid(value);
626  lhs[index]=value;
627  maybeConfirmValid(lhs);
628  return lhs;
629 }
630 
631 /** Return the number of elements
632  @relates Vector
633  */
634 template<int N, class T>
635 inline U32 size(const Vector<N,T> &lhs)
636 {
637  maybeConfirmValid(lhs);
638  return N;
639 }
640 
641 /** In place add operator
642  @relates Vector
643  */
644 template<int N, class T>
646 {
647  maybeConfirmValid(rhs);
648  for(unsigned int i = 0; i < N; i++)
649  {
650  lhs[i] += rhs[i];
651  }
652  maybeConfirmValid(lhs);
653  return lhs;
654 }
655 
656 /** In place add operator
657  @relates Vector
658  */
659 template<int M, int N, class T>
661 {
662  maybeConfirmValid(rhs);
663  const unsigned int limit=(M<N)? M: N;
664  for(unsigned int i = 0; i < limit; i++)
665  {
666  lhs[i] += rhs[i];
667  }
668  maybeConfirmValid(lhs);
669  return lhs;
670 }
671 
672 /** In place subtract operator
673  @relates Vector
674  */
675 template<int N, class T>
677 {
678  maybeConfirmValid(rhs);
679  for(unsigned int i = 0; i < N; i++)
680  {
681  lhs[i] -= rhs[i];
682  }
683  maybeConfirmValid(lhs);
684  return lhs;
685 }
686 
687 /** In place subtract operator
688  @relates Vector
689  */
690 template<int M, int N, class T>
692 {
693  maybeConfirmValid(rhs);
694  const int limit=(M<N)? M: N;
695  for(unsigned int i = 0; i < limit; i++)
696  {
697  lhs[i] -= rhs[i];
698  }
699  maybeConfirmValid(lhs);
700  return lhs;
701 }
702 
703 /** Negate operation
704  @relates Vector
705  */
706 template<int N, class T>
708 {
709  maybeConfirmValid(rhs);
710  Vector<N,T> v;
711  for(unsigned int i = 0; i < N; i++)
712  {
713  v[i] = -rhs[i];
714  }
715  return v;
716 }
717 
718 /** In place piecewise multiply operator
719  @relates Vector
720  */
721 template<int N, class T>
723 {
724  maybeConfirmValid(rhs);
725  for(unsigned int i = 0; i < N; i++)
726  {
727  lhs[i] = lhs[i] * rhs[i];
728  }
729  maybeConfirmValid(lhs);
730  return lhs;
731 }
732 
733 /** In place piecewise multiply operator
734  @relates Vector
735  */
736 template<int M, int N, class T>
738 {
739  maybeConfirmValid(rhs);
740  const int limit=(M<N)? M: N;
741  for(unsigned int i = 0; i < limit; i++)
742  {
743  lhs[i] *= rhs[i];
744  }
745  maybeConfirmValid(lhs);
746  return lhs;
747 }
748 
749 /** In place piecewise scale operator
750  @relates Vector
751  */
752 template<int N, class T,class U>
753 inline Vector<N,T> &operator*=(Vector<N,T> &lhs, U scale)
754 {
755  maybeConfirmValid(scale);
756  for(unsigned int i = 0; i < N; i++)
757  {
758  lhs[i] *= scale;
759  }
760  maybeConfirmValid(lhs);
761  return lhs;
762 }
763 
764 /** Dot (inner) product
765  @relates Vector
766  */
767 template<int N, class T>
768 inline T dot(const Vector<N,T> &lhs, const Vector<N,T> &rhs)
769 {
770  maybeConfirmValid(lhs);
771  maybeConfirmValid(rhs);
772  T t = (T)0;
773  for(unsigned int i = 0; i < N; i++)
774  {
775  t += lhs[i] * rhs[i];
776  }
778  return t;
779 }
780 
781 /** Frobenius norm operation
782  @relates Vector
783  */
784 template<int N, class T>
785 inline T magnitude(const Vector<N,T> &rhs)
786 {
787  return sqrt(magnitudeSquared(rhs));
788 }
789 
790 /** Square of the length
791  @relates Vector
792  */
793 template<int N, class T>
794 inline T magnitudeSquared(const Vector<N,T> &rhs)
795 {
796  maybeConfirmValid(rhs);
797  T mag = 0.0;
798  for(unsigned int i = 0; i < N; i++)
799  {
800  mag += (T)rhs[i] * (T)rhs[i];
801  }
802  maybeConfirmValid(mag);
803  return mag;
804 }
805 
806 /** Return vector scaled to unit length
807  @relates Vector
808  */
809 template<int N, class T>
810 inline Vector<N,T> unit(const Vector<N,T> &vec)
811 {
812  maybeConfirmValid(vec);
813  T mag=magnitude(vec);
814  if(mag==T(0))
815  {
816  feX("unit(Vector<N,T>)","attempt to normalize zero magnitude vector");
817  }
818  T inv=T(1)/mag;
819  Vector<N,T> v;
820  for(U32 i=0;i<N;i++)
821  {
822  v[i]=inv*vec[i];
823  }
825  return v;
826 }
827 
828 /** Return vector scaled to unit length with zero check
829  @relates Vector
830  */
831 template<int N, class T>
832 inline Vector<N,T> unitSafe(const Vector<N,T> &vec)
833 {
834  maybeConfirmValid(vec);
835  T mag=magnitude(vec);
836  if(mag>T(0))
837  {
838  T inv=T(1)/mag;
839  Vector<N,T> v;
840  for(U32 i=0;i<N;i++)
841  {
842  v[i]=inv*vec[i];
843  }
845  return v;
846  }
847  return vec;
848 }
849 
850 /** In place normalize operator
851  @relates Vector
852  */
853 template<int N, class T>
855 {
856  maybeConfirmValid(vec);
857  T mag=magnitude(vec);
858  if(mag==T(0))
859  {
860  feX("Vector<N,T>::normal",
861  "attempt to normalize zero magnitude vector");
862  }
863  T inv=T(1)/mag;
864  for(U32 i=0;i<N;i++)
865  {
866  vec[i]*=inv;
867  }
868  maybeConfirmValid(vec);
869  return vec;
870 }
871 
872 /** In place normalize operator with zero length check
873  @relates Vector
874  */
875 template<int N, class T>
877 {
878  maybeConfirmValid(vec);
879  T mag=magnitude(vec);
880  if(mag>T(0))
881  {
882  T inv=T(1)/mag;
883  for(U32 i=0;i<N;i++)
884  {
885  vec[i]*=inv;
886  }
887  maybeConfirmValid(vec);
888  }
889  return vec;
890 }
891 
892 /** Print to a string
893  @relates Vector
894  */
895 template<int N, class T>
896 inline String print(const Vector<N,T> &vec)
897 {
898  maybeConfirmValid(vec);
899  String s = "";
900  for(unsigned int i = 0; i < N; i++)
901  {
902  s.cat(print(vec[i]));
903  if(i < N-1)
904  {
905  s.cat(" ");
906  }
907  }
908  return s;
909 }
910 
911 /** add operation
912  @relates Vector
913  */
914 template<int N, class T>
915 inline Vector<N,T> operator+(const Vector<N,T> &lhs, const Vector<N,T> &rhs)
916 {
917  maybeConfirmValid(lhs);
918  maybeConfirmValid(rhs);
919  Vector<N,T> v;
920  for(unsigned int i = 0; i < N; i++)
921  {
922  v[i] = lhs[i] + rhs[i];
923  }
925  return v;
926 }
927 
928 /** add operation
929  @relates Vector
930  */
931 template<int N, int M, class T>
932 inline Vector<N,T> operator+(const Vector<N,T> &lhs, const Vector<M,T> &rhs)
933 {
934  maybeConfirmValid(lhs);
935  maybeConfirmValid(rhs);
936  Vector<N,T> v;
937  for(unsigned int i = 0; i < N; i++)
938  {
939  if(i >= M)
940  {
941  v[i] = lhs[i];
942  }
943  else
944  {
945  v[i] = lhs[i] + rhs[i];
946  }
947  }
949  return v;
950 }
951 
952 
953 /** subtract operation
954  @relates Vector
955  */
956 template<int N, class T>
957 inline Vector<N,T> operator-(const Vector<N,T> &lhs, const Vector<N,T> &rhs)
958 {
959  maybeConfirmValid(lhs);
960  maybeConfirmValid(rhs);
961  Vector<N,T> v;
962  for(unsigned int i = 0; i < N; i++)
963  {
964  v[i] = lhs[i] - rhs[i];
965  }
967  return v;
968 }
969 
970 /** subtract operation
971  @relates Vector
972  */
973 template<int N, int M, class T>
974 inline Vector<N,T> operator-(const Vector<N,T> &lhs, const Vector<M,T> &rhs)
975 {
976  maybeConfirmValid(lhs);
977  maybeConfirmValid(rhs);
978  Vector<N,T> v;
979  for(unsigned int i = 0; i < N; i++)
980  {
981  if(i >= M)
982  {
983  v[i] = lhs[i];
984  }
985  else
986  {
987  v[i] = lhs[i] - rhs[i];
988  }
989  }
991  return v;
992 }
993 
994 /** equality test
995  @relates Vector
996  */
997 template<int N, class T>
998 inline bool operator==(const Vector<N,T> &lhs, const Vector<N,T> &rhs)
999 {
1000  maybeConfirmValid(lhs);
1001  maybeConfirmValid(rhs);
1002  for(unsigned int i = 0; i < N; i++)
1003  {
1004  if(rhs[i] != lhs[i])
1005  {
1006  return false;
1007  }
1008  }
1009  return true;
1010 }
1011 
1012 /** Equivalence test within the given tolerance @em margin
1013  @relates Vector
1014  */
1015 template<int N, class T,class U>
1016 inline bool equivalent(const Vector<N,T> &lhs, const Vector<N,T> &rhs, U margin)
1017 {
1018  maybeConfirmValid(lhs);
1019  maybeConfirmValid(rhs);
1020  maybeConfirmValid(margin);
1021  for(unsigned int i = 0; i < N; i++)
1022  {
1023  if(FE_INVALID_SCALAR(lhs[i]) ||
1024  FE_INVALID_SCALAR(rhs[i]) ||
1025  fabs(rhs[i] - lhs[i]) > margin)
1026  {
1027  return false;
1028  }
1029  }
1030  return true;
1031 }
1032 
1033 /** Piecewise multiply operation
1034  @relates Vector
1035  */
1036 template<int N, class T>
1037 inline Vector<N,T> operator*(const Vector<N,T> &lhs, const Vector<N,T> &rhs)
1038 {
1039  maybeConfirmValid(lhs);
1040  maybeConfirmValid(rhs);
1041  Vector<N,T> v;
1042  for(unsigned int i = 0; i < N; i++)
1043  {
1044  v[i] = lhs[i] * rhs[i];
1045  }
1046  maybeConfirmValid(v);
1047  return v;
1048 }
1049 
1050 /** Scale operation
1051  @relates Vector
1052  */
1053 template<int N, class T,class U>
1054 inline Vector<N,T> operator*(const U lhs, const Vector<N,T> &rhs)
1055 {
1056  maybeConfirmValid(lhs);
1057  maybeConfirmValid(rhs);
1058  Vector<N,T> v;
1059  for(unsigned int i = 0; i < N; i++)
1060  {
1061  v[i] = rhs[i] * lhs;
1062  }
1063  maybeConfirmValid(v);
1064  return v;
1065 }
1066 
1067 /** @brief Scale operation
1068 
1069  @relates Vector
1070  */
1071 template<int N, class T,class U>
1072 inline Vector<N,T> operator*(const Vector<N,T> &lhs, const U &rhs)
1073 {
1074  maybeConfirmValid(lhs);
1075  maybeConfirmValid(rhs);
1076  Vector<N,T> v;
1077  for(unsigned int i = 0; i < N; i++)
1078  {
1079  v[i] = lhs[i] * rhs;
1080  }
1081  maybeConfirmValid(v);
1082  return v;
1083 }
1084 
1085 /** @brief Inverse Scale operation
1086 
1087  @relates Vector
1088  */
1089 template<int N, class T,class U>
1090 inline Vector<N,T> operator/(const Vector<N,T> &lhs, const U &rhs)
1091 {
1092  maybeConfirmValid(lhs);
1093  maybeConfirmValid(rhs);
1094  if(rhs==0.0f)
1095  feX(e_unsolvable,"operator/(Vector<N,T>,T)","divide by zero");
1096  return lhs*(1.0f/rhs);
1097 }
1098 
1099 /** @brief Add with scaling
1100 
1101  lhs = lhs + rhs * scalar
1102 
1103  @relates Vector
1104  */
1105 template<int N, class T,class U>
1106 inline Vector<N,T> &addScaled(Vector<N,T> &lhs,U scalar,
1107  const Vector<N,T> &rhs)
1108 {
1109  maybeConfirmValid(rhs);
1110  maybeConfirmValid(scalar);
1111  for(unsigned int i = 0; i < N; i++)
1112  {
1113  lhs[i]+=scalar*rhs[i];
1114  }
1115  maybeConfirmValid(lhs);
1116  return lhs;
1117 }
1118 
1119 /** @brief Scale then add
1120 
1121  lhs = lhs * scalar + rhs
1122 
1123  @relates Vector
1124  */
1125 template<int N, class T,class U>
1126 inline Vector<N,T> &scaleAndAdd(Vector<N,T> &lhs,U scalar,
1127  const Vector<N,T> &rhs)
1128 {
1129  maybeConfirmValid(rhs);
1130  maybeConfirmValid(scalar);
1131  for(unsigned int i = 0; i < N; i++)
1132  {
1133  lhs[i]=lhs[i]*scalar+rhs[i];
1134  }
1135  maybeConfirmValid(lhs);
1136  return lhs;
1137 }
1138 
1139 } /* namespace */
1140 
1141 #endif /* __math_Vector_h__ */
1142 
Vector< N, T > operator+(const Vector< N, T > &lhs, const Vector< N, T > &rhs)
add operation
Definition: Vector.h:915
Vector< N, T > & normalize(Vector< N, T > &vec)
In place normalize operator.
Definition: Vector.h:854
bool equivalent(const Vector< N, T > &lhs, const Vector< N, T > &rhs, U margin)
Equivalence test within the given tolerance margin.
Definition: Vector.h:1016
bool operator==(const Vector< N, T > &lhs, const Vector< N, T > &rhs)
equality test
Definition: Vector.h:998
Vector< N, T > operator-(const Vector< N, T > &lhs, const Vector< M, T > &rhs)
subtract operation
Definition: Vector.h:974
Vector< N, T > unitSafe(const Vector< N, T > &vec)
Return vector scaled to unit length with zero check.
Definition: Vector.h:832
Vector< N, T > & operator-=(Vector< N, T > &lhs, const Vector< M, T > &rhs)
In place subtract operator.
Definition: Vector.h:691
Vector< N, T > & operator*=(Vector< N, T > &lhs, const Vector< M, T > &rhs)
In place piecewise multiply operator.
Definition: Vector.h:737
Vector< N, T > & scaleAndAdd(Vector< N, T > &lhs, U scalar, const Vector< N, T > &rhs)
Scale then add.
Definition: Vector.h:1126
Vector< N, T > & operator+=(Vector< N, T > &lhs, const Vector< M, T > &rhs)
In place add operator.
Definition: Vector.h:660
Vector< N, T > & operator+=(Vector< N, T > &lhs, const Vector< N, T > &rhs)
In place add operator.
Definition: Vector.h:645
void confirmValid(const T &a_value)
Definition: Vector.h:87
Vector< N, T > operator*(const Vector< N, T > &lhs, const U &rhs)
Scale operation.
Definition: Vector.h:1072
kernel
Definition: namespace.dox:3
String print(const Vector< N, T > &vec)
Print to a string.
Definition: Vector.h:896
BWORD checkValid(const T &a_value)
Definition: Vector.h:79
Vector< N, T > operator/(const Vector< N, T > &lhs, const U &rhs)
Inverse Scale operation.
Definition: Vector.h:1090
void maybeConfirmValid(const T &a_value)
Definition: Vector.h:221
Vector< N, T > & operator*=(Vector< N, T > &lhs, U scale)
In place piecewise scale operator.
Definition: Vector.h:753
Vector< N, T > operator*(const Vector< N, T > &lhs, const Vector< N, T > &rhs)
Piecewise multiply operation.
Definition: Vector.h:1037
Vector< N, T > operator-(const Vector< N, T > &rhs)
Negate operation.
Definition: Vector.h:707
Vector< N, T > & operator*=(Vector< N, T > &lhs, const Vector< N, T > &rhs)
In place piecewise multiply operator.
Definition: Vector.h:722
Dense vector - size fixed by template.
Definition: Vector.h:19
Vector< N, T > operator*(const U lhs, const Vector< N, T > &rhs)
Scale operation.
Definition: Vector.h:1054
T dot(const Vector< N, T > &lhs, const Vector< N, T > &rhs)
Dot (inner) product.
Definition: Vector.h:768
Vector< N, T > unit(const Vector< N, T > &vec)
Return vector scaled to unit length.
Definition: Vector.h:810
String & cat(const char *operand)
Append the current String with the given text.
Definition: String.cc:545
Vector< N, T > & addScaled(Vector< N, T > &lhs, U scalar, const Vector< N, T > &rhs)
Add with scaling.
Definition: Vector.h:1106
Automatically reference-counted string container.
Definition: String.h:128
Vector< N, T > operator+(const Vector< N, T > &lhs, const Vector< M, T > &rhs)
add operation
Definition: Vector.h:932
Vector< N, T > & setAll(Vector< N, T > &lhs, const U value)
Set all the elements to the given value.
Definition: Vector.h:608
Vector< N, T > & setAt(Vector< N, T > &lhs, U32 index, const U value)
Set the value at the index.
Definition: Vector.h:623
T magnitude(const Vector< N, T > &rhs)
Frobenius norm operation.
Definition: Vector.h:785
U32 size(const Vector< N, T > &lhs)
Return the number of elements.
Definition: Vector.h:635
T magnitudeSquared(const Vector< N, T > &rhs)
Square of the length.
Definition: Vector.h:794
Vector< N, T > & normalizeSafe(Vector< N, T > &vec)
In place normalize operator with zero length check.
Definition: Vector.h:876
Vector< N, T > & operator-=(Vector< N, T > &lhs, const Vector< N, T > &rhs)
In place subtract operator.
Definition: Vector.h:676
Vector< N, T > operator-(const Vector< N, T > &lhs, const Vector< N, T > &rhs)
subtract operation
Definition: Vector.h:957