File indexing completed on 2025-12-15 10:30:40
0001 #ifndef ATOOLS_Math_Vec4_H
0002 #define ATOOLS_Math_Vec4_H
0003
0004 #include "ATOOLS/Math/MathTools.H"
0005
0006 namespace ATOOLS {
0007 template<typename Scalar> class Vec4;
0008 template<typename Scalar> class Vec3;
0009
0010 template<typename Scalar>
0011 class Vec4 {
0012 Scalar m_x[4];
0013 template <typename Scalar2> friend class Vec4;
0014 public:
0015 inline Vec4() {
0016 m_x[0]=m_x[1]=m_x[2]=m_x[3]=Scalar(0.0);
0017 }
0018 template<typename Scalar2>
0019 inline Vec4(const Vec4<Scalar2> & vec) {
0020 m_x[0] = vec[0]; m_x[1] = vec[1];
0021 m_x[2] = vec[2]; m_x[3] = vec[3];
0022 }
0023
0024
0025
0026 inline Vec4(const Scalar& x0, const Scalar& x1,
0027 const Scalar& x2, const Scalar& x3) {
0028 m_x[0] = x0; m_x[1] = x1; m_x[2] = x2; m_x[3] = x3;
0029 }
0030
0031
0032
0033 inline Vec4(const Scalar& E, const Vec3<Scalar>& xn) {
0034 m_x[0] = E;
0035 m_x[1] = xn[1];
0036 m_x[2] = xn[2];
0037 m_x[3] = xn[3];
0038 }
0039
0040 inline Scalar& operator[] (int i) {
0041 return m_x[i];
0042 }
0043
0044 inline const Scalar operator[] (int i) const {
0045 return m_x[i];
0046 }
0047
0048 inline Vec4<Scalar>& operator+=(const Vec4<Scalar>& v) {
0049 m_x[0] += v[0];
0050 m_x[1] += v[1];
0051 m_x[2] += v[2];
0052 m_x[3] += v[3];
0053 return *this;
0054 }
0055
0056 inline Vec4<Scalar>& operator-=(const Vec4<Scalar>& v) {
0057 m_x[0] -= v[0];
0058 m_x[1] -= v[1];
0059 m_x[2] -= v[2];
0060 m_x[3] -= v[3];
0061 return *this;
0062 }
0063
0064 inline Vec4<Scalar>& operator*= (const Scalar& scal) {
0065 m_x[0] *= scal;
0066 m_x[1] *= scal;
0067 m_x[2] *= scal;
0068 m_x[3] *= scal;
0069 return *this;
0070 }
0071
0072 inline Vec4<Scalar> operator-() const {
0073 return Vec4<Scalar>(-m_x[0],-m_x[1],-m_x[2],-m_x[3]);
0074 }
0075
0076 template<typename Scalar2> inline PROMOTE(Scalar,Scalar2)
0077 operator*(const Vec4<Scalar2>& v2) const {
0078 return m_x[0]*v2[0]-m_x[1]*v2[1]-m_x[2]*v2[2]-m_x[3]*v2[3];
0079 }
0080
0081 template<typename Scalar2> inline Vec4<PROMOTE(Scalar,Scalar2)>
0082 operator+ (const Vec4<Scalar2>& v2) const {
0083 return Vec4<PROMOTE(Scalar,Scalar2)>
0084 (m_x[0]+v2[0],m_x[1]+v2[1],m_x[2]+v2[2],m_x[3]+v2[3]);
0085 }
0086
0087 template<typename Scalar2> inline Vec4<PROMOTE(Scalar,Scalar2)>
0088 operator- (const Vec4<Scalar2>& v2) const {
0089 return Vec4<PROMOTE(Scalar,Scalar2)>
0090 (m_x[0]-v2[0],m_x[1]-v2[1],m_x[2]-v2[2],m_x[3]-v2[3]);
0091 }
0092
0093 template<typename Scalar2> inline Vec4<PROMOTE(Scalar,Scalar2)>
0094 operator* (const Scalar2& s) const {
0095 return Vec4<PROMOTE(Scalar,Scalar2)>
0096 (s*m_x[0],s*m_x[1],s*m_x[2],s*m_x[3]);
0097 }
0098
0099 template<typename Scalar2> inline Vec4<PROMOTE(Scalar,Scalar2)>
0100 operator/ (const Scalar2& scal) const {
0101 return (*this)*(1./scal);
0102 }
0103
0104
0105 inline bool Nan() const {
0106 for(short unsigned int i(0);i<4;++i)
0107 if (ATOOLS::IsNan<Scalar>(m_x[i])) return true;
0108 return false;
0109 }
0110 inline bool IsZero() const {
0111 for(short unsigned int i(0);i<4;++i)
0112 if (!ATOOLS::IsZero<Scalar>(m_x[i])) return false;
0113 return true;
0114 }
0115
0116
0117 Scalar Abs2() const { return (m_x[0]+m_x[3])*(m_x[0]-m_x[3])-m_x[1]*m_x[1]-m_x[2]*m_x[2]; }
0118 Scalar RelAbs2() const {
0119 const auto abs2 = Abs2();
0120 return (abs2 == 0) ? 0 : abs2/(m_x[0]*m_x[0]);
0121 }
0122 Scalar Abs() const { return sqrt(Abs2()); }
0123 double Mass() const {
0124 return sqrt(ATOOLS::Abs<Scalar>(Abs2()));
0125 }
0126 Scalar P() const { return PSpat(); }
0127
0128 Scalar PPerp2() const { return m_x[1]*m_x[1]+m_x[2]*m_x[2]; }
0129 Scalar PPerp() const { return sqrt(PPerp2()); }
0130 Scalar MPerp2() const { return (m_x[0]+m_x[3])*(m_x[0]-m_x[3]); }
0131 Scalar MPerp() const { return sqrt(MPerp2()); }
0132 Scalar MPerp2(const Vec4<Scalar> &ref) const {
0133 return Abs2()+PPerp2(ref);
0134 }
0135 Scalar MPerp(const Vec4<Scalar> &ref) const {
0136 return sqrt(MPerp2(ref));
0137 }
0138 Scalar EPerp2() const {
0139 return m_x[0]*m_x[0]*PPerp2()/PSpat2();
0140 }
0141 Scalar EPerp() const { return sqrt(EPerp2()); }
0142 Scalar PPlus() const { return m_x[0]+m_x[3]; }
0143 Scalar PMinus() const { return m_x[0]-m_x[3]; }
0144 Scalar E() const { return m_x[0]; }
0145
0146 Scalar PSpat2() const {
0147 return m_x[1]*m_x[1]+m_x[2]*m_x[2]+m_x[3]*m_x[3];
0148 }
0149 Scalar PSpat() const { return sqrt(PSpat2()); }
0150 Scalar Y() const { return 0.5*log(PPlus()/PMinus()); }
0151
0152 inline Vec4<Scalar> Perp() const {
0153 return Vec4<Scalar>(0.,m_x[1],m_x[2],0.);
0154 }
0155 inline Vec4<Scalar> Long() const {
0156 return Vec4<Scalar>(m_x[0],0.,0.,m_x[3]);
0157 }
0158 inline Vec4<Scalar> Plus() const {
0159 Scalar pplus=0.5*PPlus();
0160 return Vec4<Scalar>(pplus,0.0,0.0,pplus);
0161 }
0162 inline Vec4<Scalar> Minus() const {
0163 Scalar pminus=0.5*PMinus();
0164 return Vec4<Scalar>(pminus,0.0,0.0,-pminus);
0165 }
0166
0167 Scalar PPerp2(const Vec4<Scalar>& ref) const {
0168 Scalar ppref = PPerp(ref);
0169 return ppref*ppref;
0170 }
0171 Scalar PPerp(const Vec4<Scalar>& ref) const {
0172 Vec3<Scalar> perp=1./ATOOLS::Max(Vec3<Scalar>(ref).Abs(),1.e-12)*
0173 Vec3<Scalar>(ref);
0174 perp=Vec3<Scalar>(*this)-perp*(perp*Vec3<Scalar>(*this));
0175 return perp.Abs();
0176 }
0177
0178
0179
0180 Scalar CosPhi() const;
0181 Scalar SinPhi() const;
0182 Scalar Phi() const;
0183 Scalar CosTheta() const;
0184 Scalar SinTheta() const;
0185 Scalar Theta() const;
0186 Scalar Eta() const;
0187 Scalar CosTheta(const Vec4<Scalar>& ref) const;
0188 Scalar Theta(const Vec4<Scalar>& ref) const;
0189 Scalar Eta(const Vec4<Scalar>& ref) const;
0190 Scalar CosDPhi(const Vec4<Scalar>& ref) const;
0191 Scalar DPhi(const Vec4<Scalar>& ref) const;
0192 Scalar DEta(const Vec4<Scalar>& ref) const;
0193 Scalar DY(const Vec4<Scalar>& ref) const;
0194 Scalar DR(const Vec4<Scalar>& ref) const;
0195 Scalar DR2(const Vec4<Scalar>& ref) const;
0196 Scalar DRy(const Vec4<Scalar>& ref) const;
0197 Scalar DR2y(const Vec4<Scalar>& ref) const;
0198 Scalar SmallOMCT(const Vec4<Scalar>& ref) const;
0199 Scalar SmallMLDP(const Vec4<Scalar>& ref) const;
0200
0201
0202 const static Vec4<Scalar> XVEC;
0203 const static Vec4<Scalar> YVEC;
0204 const static Vec4<Scalar> ZVEC;
0205 };
0206
0207 template<typename Scalar,typename Scal2> inline Vec4<PROMOTE(Scalar,Scal2)>
0208 operator* (const Scal2& s, const Vec4<Scalar>& v) {
0209 return Vec4<PROMOTE(Scalar,Scal2)>(v*s);
0210 }
0211
0212 template<typename S1,typename S2,typename S3> inline
0213 Vec4<PROMOTE(S1,PROMOTE(S2,S3))>
0214 cross(const Vec4<S1>&q, const Vec4<S2>&r, const Vec4<S3>&s)
0215 {
0216 PROMOTE(S1,PROMOTE(S2,S3)) r0s1mr1s0(r[0]*s[1]-r[1]*s[0]),
0217 r0s2mr2s0(r[0]*s[2]-r[2]*s[0]), r0s3mr3s0(r[0]*s[3]-r[3]*s[0]),
0218 r1s2mr2s1(r[1]*s[2]-r[2]*s[1]), r1s3mr3s1(r[1]*s[3]-r[3]*s[1]),
0219 r2s3mr3s2(r[2]*s[3]-r[3]*s[2]);
0220 return Vec4<PROMOTE(S1,PROMOTE(S2,S3))>
0221 (-q[1]*r2s3mr3s2+q[2]*r1s3mr3s1-q[3]*r1s2mr2s1,
0222 -q[0]*r2s3mr3s2+q[2]*r0s3mr3s0-q[3]*r0s2mr2s0,
0223 +q[0]*r1s3mr3s1-q[1]*r0s3mr3s0+q[3]*r0s1mr1s0,
0224 -q[0]*r1s2mr2s1+q[1]*r0s2mr2s0-q[2]*r0s1mr1s0);
0225 }
0226
0227 template<typename Scalar> inline
0228 double CosPhi(const Vec4<Scalar> &pi,const Vec4<Scalar> &pj,
0229 const Vec4<Scalar> &pk,const Vec4<Scalar> &pl)
0230 {
0231 Scalar sij((pi+pj).Abs2()), sik((pi+pk).Abs2()), sil((pi+pl).Abs2());
0232 Scalar sjk((pj+pk).Abs2()), sjl((pj+pl).Abs2()), skl((pk+pl).Abs2());
0233 Scalar si(pi.Abs2()), sj(pj.Abs2()), sk(pk.Abs2()), sl(pl.Abs2());
0234 Scalar cp(skl*(sik*sjl+sil*sjk)-sk*sil*sjl-sl*sik*sjk-sij*skl*skl+sij*sk*sl);
0235 return cp/sqrt((2.0*skl*sik*sil-sk*sil*sil-sl*sik*sik-si*skl*skl+si*sk*sl)*
0236 (2.0*skl*sjk*sjl-sk*sjl*sjl-sl*sjk*sjk-sj*skl*skl+sj*sk*sl));
0237 }
0238
0239 template<typename Scalar>
0240 std::ostream& operator<<(std::ostream& s, const Vec4<Scalar>& vec) {
0241 return s<<'('<<vec[0]<<','<<vec[1]<<','<<vec[2]<<','<<vec[3]<<')';
0242 }
0243
0244 }
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296 #endif