Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
SVector.icc
Go to the documentation of this file.
1 // @(#)root/smatrix:$Id$
2 // Authors: T. Glebe, L. Moneta 2005
3 
4 #ifndef ROOT_Math_SVector_icc
5 #define ROOT_Math_SVector_icc
6 // ********************************************************************
7 //
8 // source:
9 //
10 // type: source code
11 //
12 // created: 21. Mar 2001
13 //
14 // author: Thorsten Glebe
15 // HERA-B Collaboration
16 // Max-Planck-Institut fuer Kernphysik
17 // Saupfercheckweg 1
18 // 69117 Heidelberg
19 // Germany
20 // E-mail: T.Glebe@mpi-hd.mpg.de
21 //
22 // Description: A fixed size Vector class
23 //
24 // changes:
25 // 21 Mar 2001 (TG) creation
26 // 26 Mar 2001 (TG) added place_at()
27 // 06 Apr 2001 (TG) CTORS added
28 // 07 Apr 2001 (TG) CTORS added
29 // 22 Aug 2001 (TG) CTOR(T*,len) added
30 // 14 Jan 2002 (TG) added operator==(), operator!=(), operator>(), operator<()
31 //
32 // ********************************************************************
33 
34 #ifndef ROOT_Math_SVector
35 #error "Do not use SVector.icc directly. #include \"Math/SVector.h\" instead."
36 #endif // ROOT_Math_SVector
37 
38 #include <iostream>
39 #include <assert.h>
40 #include <algorithm>
41 
42 #include "Math/StaticCheck.h"
43 
44 namespace ROOT {
45 
46 namespace Math {
47 
48 
49 //==============================================================================
50 // Constructors
51 //==============================================================================
52 template <class T, unsigned int D>
53 SVector<T,D>::SVector() {
54  for(unsigned int i=0; i<D; ++i)
55  fArray[i] = 0;
56 }
57 
58 template <class T, unsigned int D>
59 template <class A>
60 SVector<T,D>::SVector(const VecExpr<A,T,D>& rhs) {
61  operator=(rhs);
62 }
63 
64 template <class T, unsigned int D>
65 SVector<T,D>::SVector(const SVector<T,D>& rhs) {
66  for(unsigned int i=0; i<D; ++i)
67  fArray[i] = rhs.fArray[i];
68 }
69 
70 
71 
72 //==============================================================================
73 // New Constructors from STL interfaces
74 //==============================================================================
75 
76 #ifdef LATER
77 template <class T, unsigned int D>
78 template <class InputIterator>
79 SVector<T,D>::SVector(InputIterator begin, InputIterator end) {
80  assert(begin + D == end);
81  std::copy(begin, end, fArray);
82 }
83 
84 template <class T, unsigned int D>
85 template <class InputIterator>
86 SVector<T,D>::SVector(InputIterator begin, unsigned int size) {
87  assert( size <= D);
88  std::copy(begin, begin+size, fArray);
89 }
90 
91 #else
92 
93 template <class T, unsigned int D>
94 #ifdef NDEBUG
95 SVector<T,D>::SVector(const T* a, unsigned int) {
96 #else
97 SVector<T,D>::SVector(const T* a, unsigned int len) {
98 #endif
99  assert(len == D);
100  for(unsigned int i=0; i<D; ++i)
101  fArray[i] = a[i];
102 }
103 
104 template <class T, unsigned int D>
105 SVector<T,D>::SVector(const_iterator ibegin, const_iterator iend) {
106  assert(ibegin + D == iend);
107  std::copy(ibegin, iend, fArray);
108 }
109 
110 
111 #endif
112 
113 
114 template <class T, unsigned int D>
115 SVector<T,D>::SVector(const T& a1) {
116  STATIC_CHECK( D == 1,SVector_dimension_not_right);
117  fArray[0] = a1;
118 }
119 
120 template <class T, unsigned int D>
121 SVector<T,D>::SVector(const T& a1, const T& a2) {
122  STATIC_CHECK( D == 2,SVector_dimension_not_right);
123  fArray[0] = a1; fArray[1] = a2;
124 }
125 
126 template <class T, unsigned int D>
127 SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3) {
128  STATIC_CHECK( D == 3,SVector_dimension_not_right);
129  fArray[0] = a1; fArray[1] = a2; fArray[2] = a3;
130 }
131 
132 template <class T, unsigned int D>
133 SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4) {
134  STATIC_CHECK( D == 4,SVector_dimension_not_right);
135  fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4;
136 }
137 
138 template <class T, unsigned int D>
139 SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4,
140  const T& a5) {
141  STATIC_CHECK( D == 5,SVector_dimension_not_right);
142  fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4;
143  fArray[4] = a5;
144 }
145 
146 template <class T, unsigned int D>
147 SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4,
148  const T& a5, const T& a6) {
149  STATIC_CHECK( D == 6,SVector_dimension_not_right);
150  fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4;
151  fArray[4] = a5; fArray[5] = a6;
152 }
153 
154 template <class T, unsigned int D>
155 SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4,
156  const T& a5, const T& a6, const T& a7) {
157  STATIC_CHECK( D == 7,SVector_dimension_not_right);
158  fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4;
159  fArray[4] = a5; fArray[5] = a6; fArray[6] = a7;
160 }
161 
162 template <class T, unsigned int D>
163 SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4,
164  const T& a5, const T& a6, const T& a7, const T& a8) {
165  STATIC_CHECK( D == 8,SVector_dimension_not_right);
166  fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4;
167  fArray[4] = a5; fArray[5] = a6; fArray[6] = a7; fArray[7] = a8;
168 }
169 
170 template <class T, unsigned int D>
171 SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4,
172  const T& a5, const T& a6, const T& a7, const T& a8,
173  const T& a9) {
174  STATIC_CHECK( D == 9,SVector_dimension_not_right);
175  fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4;
176  fArray[4] = a5; fArray[5] = a6; fArray[6] = a7; fArray[7] = a8;
177  fArray[8] = a9;
178 }
179 
180 template <class T, unsigned int D>
181 SVector<T,D>::SVector(const T& a1, const T& a2, const T& a3, const T& a4,
182  const T& a5, const T& a6, const T& a7, const T& a8,
183  const T& a9, const T& a10) {
184  STATIC_CHECK( D == 10,SVector_dimension_not_right);
185  fArray[0] = a1; fArray[1] = a2; fArray[2] = a3; fArray[3] = a4;
186  fArray[4] = a5; fArray[5] = a6; fArray[6] = a7; fArray[7] = a8;
187  fArray[8] = a9; fArray[9] = a10;
188 }
189 
190 //==============================================================================
191 // operator=
192 //==============================================================================
193 template <class T, unsigned int D>
194 SVector<T,D>& SVector<T,D>::operator=(const T& a1) {
195  // operator = for size 1 vectors
196  STATIC_CHECK( D == 1,SVector_dimension_not_right);
197  fArray[0] = a1;
198  return *this;
199 }
200 
201 template <class T, unsigned int D>
202 SVector<T,D>& SVector<T,D>::operator=(const SVector<T,D>& rhs) {
203  for(unsigned int i=0; i<D; ++i)
204  fArray[i] = rhs.fArray[i];
205  return *this;
206 }
207 
208 template <class T, unsigned int D>
209 template <class A>
210 SVector<T,D>& SVector<T,D>::operator=(const VecExpr<A,T,D>& rhs) {
211  if (! rhs.IsInUse(fArray) ) {
212  for(unsigned int i=0; i<D; ++i) {
213  fArray[i] = rhs.apply(i);
214  }
215  }
216  else {
217  // otherwise we need to create a temporary object
218  T tmp[D];
219  for(unsigned int i=0; i<D; ++i) {
220  tmp[i] = rhs.apply(i);
221  }
222  for(unsigned int i=0; i<D; ++i) {
223  fArray[i] = tmp[i];
224  }
225  }
226  return *this;
227 }
228 
229 //==============================================================================
230 // operator==
231 //==============================================================================
232 template <class T, unsigned int D>
233 bool SVector<T,D>::operator==(const T& rhs) const {
234  bool rc = true;
235  for(unsigned int i=0; i<D; ++i) {
236  rc = rc && (fArray[i] == rhs);
237  }
238  return rc;
239 }
240 
241 template <class T, unsigned int D>
242 bool SVector<T,D>::operator==(const SVector<T,D>& rhs) const {
243  bool rc = true;
244  for(unsigned int i=0; i<D; ++i) {
245  rc = rc && (fArray[i] == rhs.apply(i));
246  }
247  return rc;
248 }
249 
250 template <class T, unsigned int D>
251 template <class A>
252 bool SVector<T,D>::operator==(const VecExpr<A,T,D>& rhs) const {
253  bool rc = true;
254  for(unsigned int i=0; i<D; ++i) {
255  rc = rc && (fArray[i] == rhs.apply(i));
256  }
257  return rc;
258 }
259 
260 //==============================================================================
261 // operator!=
262 //==============================================================================
263 template <class T, unsigned int D>
264 inline bool SVector<T,D>::operator!=(const T& rhs) const {
265  return !operator==(rhs);
266 }
267 
268 template <class T, unsigned int D>
269 inline bool SVector<T,D>::operator!=(const SVector<T,D>& rhs) const {
270  return !operator==(rhs);
271 }
272 
273 template <class T, unsigned int D>
274 template <class A>
275 inline bool SVector<T,D>::operator!=(const VecExpr<A,T,D>& rhs) const {
276  return !operator==(rhs);
277 }
278 
279 //==============================================================================
280 // operator>
281 //==============================================================================
282 template <class T, unsigned int D>
283 bool SVector<T,D>::operator>(const T& rhs) const {
284  bool rc = true;
285  for(unsigned int i=0; i<D; ++i) {
286  rc = rc && (fArray[i] > rhs);
287  }
288  return rc;
289 }
290 
291 template <class T, unsigned int D>
292 bool SVector<T,D>::operator>(const SVector<T,D>& rhs) const {
293  bool rc = true;
294  for(unsigned int i=0; i<D; ++i) {
295  rc = rc && (fArray[i] > rhs.apply(i));
296  }
297  return rc;
298 }
299 
300 template <class T, unsigned int D>
301 template <class A>
302 bool SVector<T,D>::operator>(const VecExpr<A,T,D>& rhs) const {
303  bool rc = true;
304  for(unsigned int i=0; i<D; ++i) {
305  rc = rc && (fArray[i] > rhs.apply(i));
306  }
307  return rc;
308 }
309 
310 //==============================================================================
311 // operator<
312 //==============================================================================
313 template <class T, unsigned int D>
314 bool SVector<T,D>::operator<(const T& rhs) const {
315  bool rc = true;
316  for(unsigned int i=0; i<D; ++i) {
317  rc = rc && (fArray[i] < rhs);
318  }
319  return rc;
320 }
321 
322 template <class T, unsigned int D>
323 bool SVector<T,D>::operator<(const SVector<T,D>& rhs) const {
324  bool rc = true;
325  for(unsigned int i=0; i<D; ++i) {
326  rc = rc && (fArray[i] < rhs.apply(i));
327  }
328  return rc;
329 }
330 
331 template <class T, unsigned int D>
332 template <class A>
333 bool SVector<T,D>::operator<(const VecExpr<A,T,D>& rhs) const {
334  bool rc = true;
335  for(unsigned int i=0; i<D; ++i) {
336  rc = rc && (fArray[i] < rhs.apply(i));
337  }
338  return rc;
339 }
340 
341 //==============================================================================
342 // operator+=
343 //==============================================================================
344 #ifdef NEW_IMPL
345 template <class T, unsigned int D>
346 template<class A>
347 SVector<T,D>& SVector<T,D>::operator+=(const A& rhs) {
348  return operator=(*this + rhs);
349 }
350 
351 template <class T, unsigned int D>
352 template<class A>
353 SVector<T,D>& SVector<T,D>::operator-=(const A& rhs) {
354  // self subtraction
355  return operator=(*this - rhs);
356 }
357 
358 template <class T, unsigned int D>
359 template<class A>
360 SVector<T,D>& SVector<T,D>::operator*=(const A& rhs) {
361  // self multiplication
362  return operator=(*this * rhs);
363 }
364 
365 template <class T, unsigned int D>
366 template<class A>
367 SVector<T,D>& SVector<T,D>::operator/=(const A& rhs) {
368  // self division
369  return operator=(*this / rhs);
370 }
371 #endif
372 
373 template <class T, unsigned int D>
374 SVector<T,D>& SVector<T,D>::operator+=(const T& rhs) {
375  for(unsigned int i=0; i<D; ++i) {
376  fArray[i] += rhs;
377  }
378  return *this;
379 }
380 
381 template <class T, unsigned int D>
382 SVector<T,D>& SVector<T,D>::operator+=(const SVector<T,D>& rhs) {
383  for(unsigned int i=0; i<D; ++i) {
384  fArray[i] += rhs.apply(i);
385  }
386  return *this;
387 }
388 
389 
390 template <class T, unsigned int D>
391 template <class A>
392 SVector<T,D>& SVector<T,D>::operator+=(const VecExpr<A,T,D>& rhs) {
393  for(unsigned int i=0; i<D; ++i) {
394  fArray[i] += rhs.apply(i);
395  }
396  return *this;
397 }
398 
399 //==============================================================================
400 // operator-=
401 //==============================================================================
402 template <class T, unsigned int D>
403 SVector<T,D>& SVector<T,D>::operator-=(const T& rhs) {
404  for(unsigned int i=0; i<D; ++i) {
405  fArray[i] -= rhs;
406  }
407  return *this;
408 }
409 
410 template <class T, unsigned int D>
411 SVector<T,D>& SVector<T,D>::operator-=(const SVector<T,D>& rhs) {
412  for(unsigned int i=0; i<D; ++i) {
413  fArray[i] -= rhs.apply(i);
414  }
415  return *this;
416 }
417 
418 template <class T, unsigned int D>
419 template <class A>
420 SVector<T,D>& SVector<T,D>::operator-=(const VecExpr<A,T,D>& rhs) {
421  for(unsigned int i=0; i<D; ++i) {
422  fArray[i] -= rhs.apply(i);
423  }
424  return *this;
425 }
426 
427 //==============================================================================
428 // operator*= (only scalar values)
429 //==============================================================================
430 template <class T, unsigned int D>
431 SVector<T,D>& SVector<T,D>::operator*=(const T& rhs) {
432  for(unsigned int i=0; i<D; ++i) {
433  fArray[i] *= rhs;
434  }
435  return *this;
436 }
437 #ifdef OLD_IMPL
438 template <class T, unsigned int D>
439 template <class A>
440 SVector<T,D>& SVector<T,D>::operator*=(const VecExpr<A,T,D>& rhs) {
441  for(unsigned int i=0; i<D; ++i) {
442  fArray[i] *= rhs.apply(i);
443  }
444  return *this;
445 }
446 
447 //==============================================================================
448 // operator/=
449 //==============================================================================
450 template <class T, unsigned int D>
451 SVector<T,D>& SVector<T,D>::operator/=(const SVector<T,D>& rhs) {
452  for(unsigned int i=0; i<D; ++i) {
453  fArray[i] /= rhs.apply(i);
454  }
455  return *this;
456 }
457 
458 template <class T, unsigned int D>
459 template <class A>
460 SVector<T,D>& SVector<T,D>::operator/=(const VecExpr<A,T,D>& rhs) {
461  for(unsigned int i=0; i<D; ++i) {
462  fArray[i] /= rhs.apply(i);
463  }
464  return *this;
465 }
466 #endif
467 template <class T, unsigned int D>
468 SVector<T,D>& SVector<T,D>::operator/=(const T& rhs) {
469  for(unsigned int i=0; i<D; ++i) {
470  fArray[i] /= rhs;
471  }
472  return *this;
473 }
474 
475 
476 //==============================================================================
477 // unit
478 //==============================================================================
479 template <class T, unsigned int D>
480 SVector<T,D>& SVector<T,D>::Unit() {
481  const T len = Mag(*this);
482  for(unsigned int i=0; i<D; ++i) {
483  fArray[i] /= len;
484  }
485  return *this;
486 }
487 
488 //==============================================================================
489 // place_at
490 //==============================================================================
491 template <class T, unsigned int D>
492 template <unsigned int D2>
493 SVector<T,D>& SVector<T,D>::Place_at(const SVector<T,D2>& rhs, unsigned int row) {
494 
495  assert(row+D2 <= D);
496  // Sassert(end <= D);
497 
498  for(unsigned int i=row, j=0; j<D2; ++i,++j)
499  fArray[i] = rhs.apply(j);
500 
501  return *this;
502 }
503 
504 
505 //==============================================================================
506 // place_at
507 //==============================================================================
508 template <class T, unsigned int D>
509 template <class A, unsigned int D2>
510 SVector<T,D>& SVector<T,D>::Place_at(const VecExpr<A,T,D2>& rhs, unsigned int row) {
511 
512  assert(row+D2 <= D);
513 
514  for(unsigned int i=row, j=0; j<D2; ++i,++j)
515  fArray[i] = rhs.apply(j);
516 
517  return *this;
518 }
519 
520 //==============================================================================
521 // print
522 //==============================================================================
523 template <class T, unsigned int D>
524 std::ostream& SVector<T,D>::Print(std::ostream& os) const {
525  const std::ios_base::fmtflags prevFmt = os.setf(std::ios::right,std::ios::adjustfield);
526  // os.setf(ios::fixed);
527 
528  for (unsigned int i = 0; i < D; ++i ) {
529  os << fArray[i];
530  if (i != D-1) os << ", ";
531  }
532  if (prevFmt != os.flags() ) os.setf(prevFmt, std::ios::adjustfield);
533  return os;
534 }
535 
536 //==============================================================================
537 // Access functions
538 //==============================================================================
539 template <class T, unsigned int D>
540 inline T SVector<T,D>::apply(unsigned int i) const { return fArray[i]; }
541 
542 template <class T, unsigned int D>
543 inline const T* SVector<T,D>::Array() const { return fArray; }
544 
545 template <class T, unsigned int D>
546 inline T* SVector<T,D>::Array() { return fArray; }
547 
548 
549 //==============================================================================
550 // STL interface
551 //==============================================================================
552 template <class T, unsigned int D>
553 inline T* SVector<T,D>::begin() { return fArray; }
554 
555 template <class T, unsigned int D>
556 inline const T* SVector<T,D>::begin() const { return fArray; }
557 
558 template <class T, unsigned int D>
559 inline T* SVector<T,D>::end() { return fArray + Dim(); }
560 
561 template <class T, unsigned int D>
562 inline const T* SVector<T,D>::end() const { return fArray + Dim(); }
563 
564 template <class T, unsigned int D>
565 template <class InputIterator>
566 void SVector<T,D>::SetElements(InputIterator ibegin, InputIterator iend) {
567  // iterator size must match vector size
568  assert( ibegin + D == iend);
569  std::copy(ibegin, iend, fArray);
570 }
571 
572 template <class T, unsigned int D>
573 template <class InputIterator>
574 void SVector<T,D>::SetElements(InputIterator ibegin, unsigned int size) {
575  // size <= vector size
576  assert( size <= D);
577  std::copy(ibegin, ibegin+size, fArray);
578 }
579 
580 
581 //==============================================================================
582 // Operators
583 //==============================================================================
584 template <class T, unsigned int D>
585 inline const T& SVector<T,D>::operator[](unsigned int i) const { return fArray[i]; }
586 
587 template <class T, unsigned int D>
588 inline const T& SVector<T,D>::operator()(unsigned int i) const { return fArray[i]; }
589 
590 template <class T, unsigned int D>
591 inline T& SVector<T,D>::operator[](unsigned int i) { return fArray[i]; }
592 
593 template <class T, unsigned int D>
594 inline T& SVector<T,D>::operator()(unsigned int i) { return fArray[i]; }
595 //==============================================================================
596 // Element access with At()
597 //==============================================================================
598 template <class T, unsigned int D>
599 inline const T& SVector<T,D>::At(unsigned int i) const {
600  assert(i < D);
601  return fArray[i];
602 }
603 
604 template <class T, unsigned int D>
605 inline T& SVector<T,D>::At(unsigned int i) {
606  assert(i < D);
607  return fArray[i];
608 }
609 
610 //==============================================================================
611 // SubVector
612 //==============================================================================
613 template <class T, unsigned int D>
614 template <class SubVector>
615 SubVector SVector<T,D>::Sub(unsigned int row) const {
616 
617  STATIC_CHECK( SubVector::kSize <= D,SVector_dimension_too_small);
618 
619  assert(row + SubVector::kSize <= D);
620 
621  SubVector tmp;
622  // need to use std::copy ??
623  for(unsigned int i=0; i < SubVector::kSize; ++i) {
624  tmp[i] = fArray[i+row];
625  }
626  return tmp;
627 }
628 
629 // check if the given passed pointer is teh same contained in the vector
630 template <class T, unsigned int D>
631 bool SVector<T,D>::IsInUse( const T * p) const {
632  return p == fArray;
633 }
634 
635 
636 //==============================================================================
637 // operator<<
638 //==============================================================================
639 template <class T, unsigned int D>
640 inline std::ostream& operator<<(std::ostream& os, const SVector<T,D>& rhs) {
641  return rhs.Print(os);
642 }
643 
644 
645 
646 
647 } // namespace Math
648 
649 } // namespace ROOT
650 
651 
652 #endif