1 /***************************************************************************
5 * Author: Brian Lasiuk, Thomas Ullrich, April 1998
6 ***************************************************************************
10 * Remarks: Since not all compilers support member templates
11 * we have to specialize the templated member on these
12 * platforms. If member templates are not supported the
13 * ST_NO_MEMBER_TEMPLATES flag has to be set. tu.
15 ***************************************************************************
18 * Revision 1.1.1.1 2007/04/25 15:38:41 panos
19 * Importing the HBT code dir
21 * Revision 1.1.1.1 2007/03/07 10:14:49 mchojnacki
22 * First version on CVS
24 * Revision 1.15 2005/09/22 20:09:20 fisyak
25 * Make AliFmLorentzVector persistent
27 * Revision 1.14 2005/07/19 22:27:11 perev
30 * Revision 1.13 2005/07/06 18:49:57 fisyak
31 * Replace AliFmHelixD, AliFmLorentzVectorD,AliFmLorentzVectorF,AliFmMatrixD,AliFmMatrixF,AliFmPhysicalHelixD,AliFmThreeVectorD,AliFmThreeVectorF by templated version
33 * Revision 1.12 2005/03/28 06:03:41 perev
36 * Revision 1.11 2004/12/02 20:07:32 fine
37 * define the valid method for both flavor of AliFmThreeVector
39 * Revision 1.10 2003/10/30 20:06:46 perev
40 * Check of quality added
42 * Revision 1.9 2003/09/02 17:59:35 perev
43 * gcc 3.2 updates + WarnOff
45 * Revision 1.8 2002/06/21 17:47:37 genevb
48 * Revision 1.7 2000/01/04 19:56:05 ullrich
49 * Added cpp macro for CINT.
51 * Revision 1.6 1999/12/21 15:14:31 ullrich
52 * Modified to cope with new compiler version on Sun (CC5.0).
54 * Revision 1.5 1999/10/15 15:46:54 ullrich
55 * Changed output format in operator<<
57 * Revision 1.4 1999/06/04 18:00:05 ullrich
58 * Added new constructor which takes C-style array as argument.
59 * New operators operator() and operator[] which can be used
62 * Revision 1.3 1999/02/17 11:42:19 ullrich
63 * Removed specialization for 'long double'.
65 * Revision 1.2 1999/02/14 23:11:48 fisyak
68 * Revision 1.1 1999/01/30 03:59:05 fisyak
69 * Root Version of AliFmarClassLibrary
71 * Revision 1.1 1999/01/23 00:28:04 ullrich
74 **************************************************************************/
76 //// General class for a three-vector
78 #ifndef ST_THREE_VECTOR_HH
79 #define ST_THREE_VECTOR_HH
90 #if defined (__SUNPRO_CC) && __SUNPRO_CC < 0x500
93 #ifndef ST_NO_EXCEPTIONS
95 # if !defined(ST_NO_NAMESPACES)
96 using std::out_of_range;
105 class TRootIOCtor;//nic nie rozumiem
109 template<class T> class AliFmThreeVector {
111 AliFmThreeVector(T = 0, T = 0, T = 0);
112 // ROOT_VERSION(5,03,01)
113 #if ROOT_VERSION_CODE >= 328449
114 AliFmThreeVector(TRootIOCtor*) : mX1(0), mX2(0), mX3(0) {}
116 virtual ~AliFmThreeVector();
118 #ifndef ST_NO_MEMBER_TEMPLATES
119 template<class X> AliFmThreeVector(const AliFmThreeVector<X>&);
120 template<class X> AliFmThreeVector(const X*);
121 template<class X> AliFmThreeVector<T>& operator=(const AliFmThreeVector<X>&);
122 // AliFmThreeVector(const AliFmThreeVector<T>&); use default
123 // AliFmThreeVector<T>& operator=(const AliFmThreeVector<T>&); use default
125 AliFmThreeVector(const AliFmThreeVector<float>&);
126 AliFmThreeVector(const AliFmThreeVector<double>&);
128 AliFmThreeVector(const float*);
129 AliFmThreeVector(const double*);
131 AliFmThreeVector<T>& operator=(const AliFmThreeVector<float>&);
132 AliFmThreeVector<T>& operator=(const AliFmThreeVector<double>&);
142 void SetMagnitude(T);
155 T PseudoRapidity() const;
156 T operator() (size_t) const;
157 T operator[] (size_t) const;
159 T& operator() (size_t);
160 T& operator[] (size_t);
162 T MassHypothesis(T mass) const;
164 AliFmThreeVector<T> Unit() const;
165 AliFmThreeVector<T> Orthogonal() const;
171 AliFmThreeVector<T> operator- ();
172 AliFmThreeVector<T> operator+ ();
173 AliFmThreeVector<T>& operator*= (double);
174 AliFmThreeVector<T>& operator/= (double);
175 AliFmThreeVector<T> PseudoProduct(double,double,double) const;
177 #ifndef ST_NO_MEMBER_TEMPLATES
178 template<class X> T Angle(const AliFmThreeVector<X>&) const;
179 template<class X> AliFmThreeVector<T> Cross(const AliFmThreeVector<X>&) const;
180 template<class X> T Dot (const AliFmThreeVector<X>&) const;
181 template<class X> AliFmThreeVector<T> PseudoProduct(const AliFmThreeVector<X>&) const;
183 template<class X> bool operator == (const AliFmThreeVector<X>& v) const;
184 template<class X> bool operator != (const AliFmThreeVector<X>& v) const;
186 template<class X> AliFmThreeVector<T>& operator+= (const AliFmThreeVector<X>&);
187 template<class X> AliFmThreeVector<T>& operator-= (const AliFmThreeVector<X>&);
189 T Angle(const AliFmThreeVector<float>&) const;
190 AliFmThreeVector<T> Cross(const AliFmThreeVector<float>&) const;
191 T Dot (const AliFmThreeVector<float>&) const;
192 AliFmThreeVector<T> PseudoProduct(const AliFmThreeVector<float>&) const;
194 T Angle(const AliFmThreeVector<double>&) const;
195 T Dot (const AliFmThreeVector<double>&) const;
196 AliFmThreeVector<T> Cross(const AliFmThreeVector<double>&) const;
197 AliFmThreeVector<T> PseudoProduct(const AliFmThreeVector<double>&) const;
199 bool operator == (const AliFmThreeVector<float>& v) const;
200 bool operator != (const AliFmThreeVector<float>& v) const;
201 AliFmThreeVector<T>& operator+= (const AliFmThreeVector<float>&);
202 AliFmThreeVector<T>& operator-= (const AliFmThreeVector<float>&);
204 bool operator == (const AliFmThreeVector<double>& v) const;
205 bool operator != (const AliFmThreeVector<double>& v) const;
206 AliFmThreeVector<T>& operator+= (const AliFmThreeVector<double>&);
207 AliFmThreeVector<T>& operator-= (const AliFmThreeVector<double>&);
209 int valid(double world = 1.e+5) const;
210 int bad(double world = 1.e+5) const;
212 T mX1, mX2, mX3; // Three vector components
214 ClassDef(AliFmThreeVector,3)
215 #endif /* __ROOT__ */
220 // Implementation of member functions
223 inline AliFmThreeVector<T>::AliFmThreeVector(T x, T y, T z)
224 : mX1(x), mX2(y), mX3(z) {/* nop */}
226 inline AliFmThreeVector<T>::~AliFmThreeVector() {/* nop */}
229 inline void AliFmThreeVector<T>::SetX(T x) {mX1 = x;}
232 inline void AliFmThreeVector<T>::SetY(T y) {mX2 = y;}
235 inline void AliFmThreeVector<T>::SetZ(T z) {mX3 = z;}
238 void AliFmThreeVector<T>::SetPhi(T angle)
240 double r = Magnitude();
243 mX1 = r*sin(th)*cos(angle);
244 mX2 = r*sin(th)*sin(angle);
248 void AliFmThreeVector<T>::SetTheta(T angle)
250 double r = Magnitude();
253 mX1 = r*sin(angle)*cos(ph);
254 mX2 = r*sin(angle)*sin(ph);
259 void AliFmThreeVector<T>::SetMagnitude(T r)
264 mX1 = r*sin(th)*cos(ph);
265 mX2 = r*sin(th)*sin(ph);
270 void AliFmThreeVector<T>::SetMag(T mag)
276 inline T AliFmThreeVector<T>::x() const {return mX1;}
279 inline T AliFmThreeVector<T>::y() const {return mX2;}
282 inline T AliFmThreeVector<T>::z() const {return mX3;}
285 inline T AliFmThreeVector<T>::Theta() const
287 return acos(CosTheta());
291 inline T AliFmThreeVector<T>::CosTheta() const
293 return mX3/(Mag()+1e-20);
297 inline T AliFmThreeVector<T>::Phi() const
299 return atan2(mX2,mX1);
303 inline T AliFmThreeVector<T>::PseudoRapidity() const
306 // change code to more optimal:
308 // return 0.5*::log( (m+z())/(m-z()) );
309 double tmp = tan(Theta()/2.); if (tmp <=0.) return 1e20;
314 inline AliFmThreeVector<T> AliFmThreeVector<T>::Unit() const
316 double tmp = Mag(); if (tmp<=0.) tmp = 1e-20;
321 T AliFmThreeVector<T>::MassHypothesis(T mass) const
323 return ::sqrt((*this)*(*this) + mass*mass);
327 AliFmThreeVector<T> AliFmThreeVector<T>::Orthogonal() const
329 // Direct copy from CLHEP--it is probably better to
330 // use your own dot/cross product code...
331 double x = (mX1 < 0.0) ? -mX1 : mX1;
332 double y = (mX2 < 0.0) ? -mX2 : mX2;
333 double z = (mX3 < 0.0) ? -mX3 : mX3;
336 return x < z ? AliFmThreeVector<T>(0,mX3,-mX2) : AliFmThreeVector<T>(mX2,-mX1,0);
338 return mX2 < mX3 ? AliFmThreeVector<T>(-mX3,0,mX1) : AliFmThreeVector<T>(mX2,-mX1,0);
342 void AliFmThreeVector<T>::RotateX(T angle)
344 // may in the future make use of the AliFmRotation class!
345 double yPrime = cos(angle)*mX2 - sin(angle)*mX3;
346 double zPrime = sin(angle)*mX2 + cos(angle)*mX3;
353 void AliFmThreeVector<T>::RotateY(T angle)
355 // may in the future make use of the AliFmRotation class!
356 double zPrime = cos(angle)*mX3 - sin(angle)*mX1;
357 double xPrime = sin(angle)*mX3 + cos(angle)*mX1;
364 void AliFmThreeVector<T>::RotateZ(T angle)
366 // may in the future make use of the AliFmRotation class!
367 double xPrime = cos(angle)*mX1 - sin(angle)*mX2;
368 double yPrime = sin(angle)*mX1 + cos(angle)*mX2;
375 inline T AliFmThreeVector<T>::Perp() const
377 return ::sqrt(mX1*mX1+mX2*mX2);
381 inline T AliFmThreeVector<T>::Perp2() const
383 return mX1*mX1+mX2*mX2;
387 inline T AliFmThreeVector<T>::Magnitude() const
393 inline T AliFmThreeVector<T>::Mag() const
395 return ::sqrt(mX1*mX1+mX2*mX2+mX3*mX3);
399 inline T AliFmThreeVector<T>::Mag2() const
401 return mX1*mX1+mX2*mX2+mX3*mX3;
405 inline T AliFmThreeVector<T>::operator() (size_t i) const
407 if (0 <=i && i <= 2) return (&mX1)[i];
408 #ifndef ST_NO_EXCEPTIONS
409 throw out_of_range("AliFmThreeVector<T>::operator(): bad index");
411 cerr << "AliFmThreeVector<T>::operator(): bad index" << endl;
417 inline T& AliFmThreeVector<T>::operator() (size_t i)
419 if (0 <=i && i <= 2) return (&mX1)[i];
420 #ifndef ST_NO_EXCEPTIONS
421 throw out_of_range("AliFmThreeVector<T>::operator(): bad index");
423 cerr << "AliFmThreeVector<T>::operator(): bad index" << endl;
429 inline T AliFmThreeVector<T>::operator[] (size_t i) const
431 if (0 <=i && i <= 2) return (&mX1)[i];
432 #ifndef ST_NO_EXCEPTIONS
433 throw out_of_range("AliFmThreeVector<T>::operator[]: bad index");
435 cerr << "AliFmThreeVector<T>::operator[]: bad index" << endl;
441 inline T &AliFmThreeVector<T>::operator[] (size_t i)
443 if (0 <=i && i <= 2) return (&mX1)[i];
444 #ifndef ST_NO_EXCEPTIONS
445 throw out_of_range("AliFmThreeVector<T>::operator[]: bad index");
447 cerr << "AliFmThreeVector<T>::operator[]: bad index" << endl;
453 inline AliFmThreeVector<T>& AliFmThreeVector<T>::operator*= (double c)
455 mX1 *= c; mX2 *= c; mX3 *= c;
460 inline AliFmThreeVector<T>& AliFmThreeVector<T>::operator/= (double c)
462 mX1 /= c; mX2 /= c; mX3 /= c;
467 inline AliFmThreeVector<T>
468 AliFmThreeVector<T>::PseudoProduct(double x,double y,double z) const
470 return AliFmThreeVector<T>(mX1*x,mX2*y,mX3*z);
474 AliFmThreeVector<T> AliFmThreeVector<T>::operator- ()
476 return AliFmThreeVector<T>(-mX1, -mX2, -mX3);
480 AliFmThreeVector<T> AliFmThreeVector<T>::operator+ ()
485 #ifndef ST_NO_MEMBER_TEMPLATES
490 inline AliFmThreeVector<T>::AliFmThreeVector(const AliFmThreeVector<X>& v)
491 : mX1(v.x()), mX2(v.y()), mX3(v.z()) {/* nop */}
495 inline AliFmThreeVector<T>::AliFmThreeVector(const X *a)
504 inline AliFmThreeVector<T>&
505 AliFmThreeVector<T>::operator=(const AliFmThreeVector<X>& v)
507 mX1 = v.x(); mX2 = v.y(); mX3 = v.z();
513 inline bool AliFmThreeVector<T>::operator== (const AliFmThreeVector<X>& v) const
515 return mX1 == v.x() && mX2 == v.y() && mX3 == v.z();
520 inline bool AliFmThreeVector<T>::operator!= (const AliFmThreeVector<X>& v) const
522 return !(*this == v);
527 inline AliFmThreeVector<T>&
528 AliFmThreeVector<T>::operator+= (const AliFmThreeVector<X>& v)
530 mX1 += v.x(); mX2 += v.y(); mX3 += v.z();
536 inline AliFmThreeVector<T>&
537 AliFmThreeVector<T>::operator-= (const AliFmThreeVector<X>& v)
539 mX1 -= v.x(); mX2 -= v.y(); mX3 -= v.z();
545 inline T AliFmThreeVector<T>::Dot(const AliFmThreeVector<X>& v) const
547 return mX1*v.x() + mX2*v.y() + mX3*v.z();
552 inline AliFmThreeVector<T>
553 AliFmThreeVector<T>::Cross(const AliFmThreeVector<X>& v) const
555 return AliFmThreeVector<T>(mX2*v.z() - mX3*v.y(),
556 mX3*v.x() - mX1*v.z(),
557 mX1*v.y() - mX2*v.x());
562 inline T AliFmThreeVector<T>::Angle(const AliFmThreeVector<X>& vec) const
564 double norm = this->Mag2()*vec.Mag2();
566 return norm > 0 ? acos(this->Dot(vec)/(::sqrt(norm))) : 0;
571 inline AliFmThreeVector<T>
572 AliFmThreeVector<T>::PseudoProduct(const AliFmThreeVector<X>& v) const
574 return this->PseudoProduct(v.x(),v.y(),v.z());
581 inline AliFmThreeVector<T>::AliFmThreeVector(const AliFmThreeVector<float>& v)
582 : mX1(v.x()), mX2(v.y()), mX3(v.z()) {/* nop */}
585 inline AliFmThreeVector<T>::AliFmThreeVector(const AliFmThreeVector<double>& v)
586 : mX1(v.x()), mX2(v.y()), mX3(v.z()) {/* nop */}
589 inline AliFmThreeVector<T>::AliFmThreeVector(const float *a)
597 inline AliFmThreeVector<T>::AliFmThreeVector(const double *a)
605 inline AliFmThreeVector<T>&
606 AliFmThreeVector<T>::operator=(const AliFmThreeVector<float>& v)
608 mX1 = v.x(); mX2 = v.y(); mX3 = v.z();
613 inline AliFmThreeVector<T>&
614 AliFmThreeVector<T>::operator=(const AliFmThreeVector<double>& v)
616 mX1 = v.x(); mX2 = v.y(); mX3 = v.z();
622 AliFmThreeVector<T>::operator== (const AliFmThreeVector<float>& v) const
624 return mX1 == v.x() && mX2 == v.y() && mX3 == v.z();
629 AliFmThreeVector<T>::operator== (const AliFmThreeVector<double>& v) const
631 return mX1 == v.x() && mX2 == v.y() && mX3 == v.z();
636 AliFmThreeVector<T>::operator!= (const AliFmThreeVector<float>& v) const
638 return !(*this == v);
643 AliFmThreeVector<T>::operator!= (const AliFmThreeVector<double>& v) const
645 return !(*this == v);
649 inline AliFmThreeVector<T>&
650 AliFmThreeVector<T>::operator+= (const AliFmThreeVector<float>& v)
652 mX1 += v.x(); mX2 += v.y(); mX3 += v.z();
657 inline AliFmThreeVector<T>&
658 AliFmThreeVector<T>::operator+= (const AliFmThreeVector<double>& v)
660 mX1 += v.x(); mX2 += v.y(); mX3 += v.z();
665 inline AliFmThreeVector<T>&
666 AliFmThreeVector<T>::operator-= (const AliFmThreeVector<float>& v)
668 mX1 -= v.x(); mX2 -= v.y(); mX3 -= v.z();
673 inline AliFmThreeVector<T>&
674 AliFmThreeVector<T>::operator-= (const AliFmThreeVector<double>& v)
676 mX1 -= v.x(); mX2 -= v.y(); mX3 -= v.z();
681 inline T AliFmThreeVector<T>::Dot(const AliFmThreeVector<float>& v) const
683 return mX1*v.x() + mX2*v.y() + mX3*v.z();
687 inline T AliFmThreeVector<T>::Dot(const AliFmThreeVector<double>& v) const
689 return mX1*v.x() + mX2*v.y() + mX3*v.z();
693 inline AliFmThreeVector<T>
694 AliFmThreeVector<T>::Cross(const AliFmThreeVector<float>& v) const
696 return AliFmThreeVector<T>(mX2*v.z() - mX3*v.y(),
697 mX3*v.x() - mX1*v.z(),
698 mX1*v.y() - mX2*v.x());
702 inline AliFmThreeVector<T>
703 AliFmThreeVector<T>::Cross(const AliFmThreeVector<double>& v) const
705 return AliFmThreeVector<T>(mX2*v.z() - mX3*v.y(),
706 mX3*v.x() - mX1*v.z(),
707 mX1*v.y() - mX2*v.x());
711 inline T AliFmThreeVector<T>::Angle(const AliFmThreeVector<float>& v) const
713 double tmp = Mag()*v.Mag(); if (tmp <=0) tmp = 1e-20;
714 return acos(this->Dot(v)/tmp);
718 inline T AliFmThreeVector<T>::Angle(const AliFmThreeVector<double>& v) const
720 double tmp = Mag()*v.Mag(); if (tmp <=0) tmp = 1e-20;
721 return acos(this->Dot(v)/tmp);
725 inline AliFmThreeVector<T>
726 AliFmThreeVector<T>::PseudoProduct(const AliFmThreeVector<float>& v) const
728 return this->PseudoProduct(v.x(),v.y(),v.z());
732 inline AliFmThreeVector<T>
733 AliFmThreeVector<T>::PseudoProduct(const AliFmThreeVector<double>& v) const
735 return this->PseudoProduct(v.x(),v.y(),v.z());
737 #endif // ST_NO_MEMBER_TEMPLATES
740 AliFmThreeVector<T>::valid(double world) const {return !bad(world);}
744 AliFmThreeVector<T>::bad(double world) const
746 for (int i=0;i<3;i++) {
747 if (!finite((&mX1)[i]) ) return 10+i;
748 if ( fabs ((&mX1)[i])>world) return 20+i;
752 #endif /*! __CINT__ */
754 template<> float abs(const AliFmThreeVector<float>& v);
755 template<> double abs(const AliFmThreeVector<double>& v);
756 template<> AliFmThreeVector<double> cross_product(const AliFmThreeVector<double>& v1, const AliFmThreeVector<double>& v2);
757 template<> AliFmThreeVector<float> cross_product(const AliFmThreeVector<float>& v1, const AliFmThreeVector<float>& v2);
758 template<> AliFmThreeVector<double> cross_product(const AliFmThreeVector<float>& v1, const AliFmThreeVector<double>& v2);
759 template<> AliFmThreeVector<double> cross_product(const AliFmThreeVector<double>& v1, const AliFmThreeVector<float>& v2);
760 template<> AliFmThreeVector<double> operator+ (const AliFmThreeVector<double>& v1, const AliFmThreeVector<double>& v2);
761 template<> AliFmThreeVector<float> operator+ (const AliFmThreeVector<float>& v1, const AliFmThreeVector<float>& v2);
762 template<> AliFmThreeVector<double> operator+ (const AliFmThreeVector<double>& v1, const AliFmThreeVector<float>& v2);
763 template<> AliFmThreeVector<double> operator+ (const AliFmThreeVector<float>& v1, const AliFmThreeVector<double>& v2);
764 template<> AliFmThreeVector<double> operator- (const AliFmThreeVector<double>& v1, const AliFmThreeVector<double>& v2);
765 template<> AliFmThreeVector<float> operator- (const AliFmThreeVector<float>& v1, const AliFmThreeVector<float>& v2);
766 template<> AliFmThreeVector<double> operator- (const AliFmThreeVector<double>& v1, const AliFmThreeVector<float>& v2);
767 template<> AliFmThreeVector<double> operator- (const AliFmThreeVector<float>& v1, const AliFmThreeVector<double>& v2);
768 template<> AliFmThreeVector<double> operator* (const AliFmThreeVector<double>& v1, const AliFmThreeVector<double>& v2);
769 template<> AliFmThreeVector<float> operator* (const AliFmThreeVector<float>& v1, const AliFmThreeVector<float>& v2);
770 template<> AliFmThreeVector<double> operator* (const AliFmThreeVector<double>& v1, const AliFmThreeVector<float>& v2);
771 template<> AliFmThreeVector<double> operator* (const AliFmThreeVector<float>& v1, const AliFmThreeVector<double>& v2);
772 template<> AliFmThreeVector<double> operator* (const double v1, const AliFmThreeVector<float>& v2);
773 template<> AliFmThreeVector<double> operator* (const AliFmThreeVector<float>& v1, const double v2);
774 template<> AliFmThreeVector<double> operator* (const double v1, const AliFmThreeVector<double>& v2);
775 template<> AliFmThreeVector<double> operator* (const AliFmThreeVector<double>& v1, const double v2);
776 template<> AliFmThreeVector<double> operator/ (const AliFmThreeVector<double>& v1, const AliFmThreeVector<double>& v2);
777 template<> AliFmThreeVector<float> operator/ (const AliFmThreeVector<float>& v1, const AliFmThreeVector<float>& v2);
778 template<> AliFmThreeVector<double> operator/ (const AliFmThreeVector<double>& v1, const AliFmThreeVector<float>& v2);
779 template<> AliFmThreeVector<double> operator/ (const AliFmThreeVector<float>& v1, const AliFmThreeVector<double>& v2);
780 template<> AliFmThreeVector<double> operator/ (const double v1, const AliFmThreeVector<double>& v2);
781 template<> AliFmThreeVector<float> operator/ (const double v1, const AliFmThreeVector<float>& v2);
782 template<> AliFmThreeVector<double> operator/ (const AliFmThreeVector<double>& v1, const double v2);
783 template<> AliFmThreeVector<double> operator/ (const AliFmThreeVector<float>& v1, const double v2);
784 template<> istream& operator>>(istream& is,const AliFmThreeVector<double>& v);
785 template<> istream& operator>>(istream& is,const AliFmThreeVector<float>& v);
786 template<> ostream& operator<<(ostream& os,const AliFmThreeVector<double>& v);
787 template<> ostream& operator<<(ostream& os,const AliFmThreeVector<float>& v);
790 // Non-member functions
793 inline T abs(const AliFmThreeVector<T>& v) {return v.Mag();}
795 template<class T, class X>
796 inline AliFmThreeVector<T>
797 cross_product(const AliFmThreeVector<T>& v1, const AliFmThreeVector<X>& v2)
804 // Non-member operators
806 template<class T, class X>
807 inline AliFmThreeVector<T>
808 operator+ (const AliFmThreeVector<T>& v1, const AliFmThreeVector<X>& v2)
810 return AliFmThreeVector<T>(v1) += v2;
813 template<class T, class X>
814 inline AliFmThreeVector<T>
815 operator- (const AliFmThreeVector<T>& v1, const AliFmThreeVector<X>& v2)
817 return AliFmThreeVector<T>(v1) -= v2;
820 template<class T, class X>
821 inline T operator* (const AliFmThreeVector<T>& v1, const AliFmThreeVector<X>& v2)
823 return AliFmThreeVector<T>(v1).Dot(v2);
827 inline AliFmThreeVector<T> operator* (const AliFmThreeVector<T>& v, double c)
829 return AliFmThreeVector<T>(v) *= c;
833 inline AliFmThreeVector<T> operator* (double c, const AliFmThreeVector<T>& v)
835 return AliFmThreeVector<T>(v) *= c;
838 template<class T, class X>
839 inline AliFmThreeVector<T> operator/ (const AliFmThreeVector<T>& v, X c)
841 return AliFmThreeVector<T>(v) /= c;
845 ostream& operator<<(ostream& os, const AliFmThreeVector<T>& v)
847 return os << v.x() << '\t' << v.y() << '\t' << v.z();
851 istream& operator>>(istream& is, AliFmThreeVector<T>& v)
860 #endif /* ! __CINT__ */