diff --git a/Helicity/LorentzTensor.h b/Helicity/LorentzTensor.h --- a/Helicity/LorentzTensor.h +++ b/Helicity/LorentzTensor.h @@ -1,537 +1,572 @@ // -*- C++ -*- // // LorentzTensor.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 2003-2019 Peter Richardson, Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_LorentzTensor_H #define ThePEG_LorentzTensor_H // This is the declaration of the LorentzTensor class. #include "ThePEG/Config/PhysicalQtyComplex.h" #include "ThePEG/Config/ThePEG.h" #include "LorentzPolarizationVector.h" namespace ThePEG { namespace Helicity { // compiler magic needs these pre-declarations to make friend templates work template<typename Value> class LorentzTensor; /** * The LorentzTensor class is designed to implement the storage of a * complex tensor to be used to representation the wavefunction of a * spin-2 particle. * * At the moment it only implements the storage of the tensor * components but it is envisaged that it will be extended to include * boost methods etc. * * @author Peter Richardson * */ template<typename Value> class LorentzTensor { public: /** @name Standard constructors and destructors. */ //@{ /** * Default zero constructor. */ LorentzTensor() = default; /** * Constructor specifyign all components. */ LorentzTensor(complex<Value> xx, complex<Value> xy, complex<Value> xz, complex<Value> xt, complex<Value> yx, complex<Value> yy, complex<Value> yz, complex<Value> yt, complex<Value> zx, complex<Value> zy, complex<Value> zz, complex<Value> zt, complex<Value> tx, complex<Value> ty, complex<Value> tz, complex<Value> tt) : _tensor{{ {{xx,xy,xz,xt}}, {{yx,yy,yz,yt}}, {{zx,zy,zz,zt}}, {{tx,ty,tz,tt}} }} {} /** * Constructor in terms of two polarization vectors. */ LorentzTensor(const LorentzPolarizationVector & p, const LorentzPolarizationVector & q) { setXX(p.x() * q.x()); setYX(p.y() * q.x()); setZX(p.z() * q.x()); setTX(p.t() * q.x()); setXY(p.x() * q.y()); setYY(p.y() * q.y()); setZY(p.z() * q.y()); setTY(p.t() * q.y()); setXZ(p.x() * q.z()); setYZ(p.y() * q.z()); setZZ(p.z() * q.z()); setTZ(p.t() * q.z()); setXT(p.x() * q.t()); setYT(p.y() * q.t()); setZT(p.z() * q.t()); setTT(p.t() * q.t()); } //@} /** @name Access individual components. */ //@{ /** * Get x,x component. */ complex<Value> xx() const {return _tensor[0][0];} /** * Get y,x component. */ complex<Value> yx() const {return _tensor[1][0];} /** * Get z,x component. */ complex<Value> zx() const {return _tensor[2][0];} /** * Get t,x component. */ complex<Value> tx() const {return _tensor[3][0];} /** * Get x,y component. */ complex<Value> xy() const {return _tensor[0][1];} /** * Get y,y component. */ complex<Value> yy() const {return _tensor[1][1];} /** * Get z,y component. */ complex<Value> zy() const {return _tensor[2][1];} /** * Get t,y component. */ complex<Value> ty() const {return _tensor[3][1];} /** * Get x,z component. */ complex<Value> xz() const {return _tensor[0][2];} /** * Get y,z component. */ complex<Value> yz() const {return _tensor[1][2];} /** * Get z,z component. */ complex<Value> zz() const {return _tensor[2][2];} /** * Get t,z component. */ complex<Value> tz() const {return _tensor[3][2];} /** * Get x,t component. */ complex<Value> xt() const {return _tensor[0][3];} /** * Get y,t component. */ complex<Value> yt() const {return _tensor[1][3];} /** * Get z,t component. */ complex<Value> zt() const {return _tensor[2][3];} /** * Get t,t component. */ complex<Value> tt() const {return _tensor[3][3];} /** * Set x,x component. */ void setXX(complex<Value> a) {_tensor[0][0]=a;} /** * Set y,x component. */ void setYX(complex<Value> a) {_tensor[1][0]=a;} /** * Set z,x component. */ void setZX(complex<Value> a) {_tensor[2][0]=a;} /** * Set t,x component. */ void setTX(complex<Value> a) {_tensor[3][0]=a;} /** * Set x,y component. */ void setXY(complex<Value> a) {_tensor[0][1]=a;} /** * Set y,y component. */ void setYY(complex<Value> a) {_tensor[1][1]=a;} /** * Set z,y component. */ void setZY(complex<Value> a) {_tensor[2][1]=a;} /** * Set t,y component. */ void setTY(complex<Value> a) {_tensor[3][1]=a;} /** * Set x,z component. */ void setXZ(complex<Value> a) {_tensor[0][2]=a;} /** * Set y,z component. */ void setYZ(complex<Value> a) {_tensor[1][2]=a;} /** * Set z,z component. */ void setZZ(complex<Value> a) {_tensor[2][2]=a;} /** * Set t,z component. */ void setTZ(complex<Value> a) {_tensor[3][2]=a;} /** * Set x,t component. */ void setXT(complex<Value> a) {_tensor[0][3]=a;} /** * Set y,t component. */ void setYT(complex<Value> a) {_tensor[1][3]=a;} /** * Set z,t component. */ void setZT(complex<Value> a) {_tensor[2][3]=a;} /** * Set t,t component. */ void setTT(complex<Value> a) {_tensor[3][3]=a;} /** * Get components by indices. */ complex<Value> operator () (int i, int j) const { assert( i>=0 && i<=3 && j>=0 && j<=3); return _tensor[i][j]; } /** * Set components by indices. */ complex<Value> & operator () (int i, int j) { assert( i>=0 && i<=3 && j>=0 && j<=3); return _tensor[i][j]; } //@} /** @name Transformations. */ //@{ /** * Standard Lorentz boost specifying the components of the beta vector. */ LorentzTensor & boost(double,double,double); /** * Standard Lorentz boost specifying the beta vector. */ LorentzTensor<Value> & boost(const Boost & b) { return boost(b.x(), b.y(), b.z()); } /** * General Lorentz transformation */ LorentzTensor & transform(const SpinOneLorentzRotation & r){ unsigned int ix,iy,ixa,iya; LorentzTensor<Value> output; complex<Value> temp; for(ix=0;ix<4;++ix) { for(iy=0;iy<4;++iy) { temp=complex<Value>(); for(ixa=0;ixa<4;++ixa) { for(iya=0;iya<4;++iya) temp+=r(ix,ixa)*r(iy,iya)*(*this)(ixa,iya); } output(ix,iy)=temp; } } *this=output; return *this; } /** * Return the complex conjugate. */ LorentzTensor<Value> conjugate() { return LorentzTensor<Value>(conj(xx()), conj(xy()), conj(xz()), conj(xt()), conj(yx()), conj(yy()), conj(yz()), conj(yt()), conj(zx()), conj(zy()), conj(zz()), conj(zt()), conj(tx()), conj(ty()), conj(tz()), conj(tt())); } //@} /** @name Arithmetic operators. */ //@{ /** * Scaling with a complex number */ LorentzTensor<Value> operator*=(Complex a) { for(int ix=0;ix<4;++ix) for(int iy=0;iy<4;++iy) _tensor[ix][iy]*=a; return *this; } /** * Scalar product with other tensor */ template <typename T, typename U> friend auto operator*(const LorentzTensor<T> & t, const LorentzTensor<U> & u) -> decltype(t.xx()*u.xx()) ; /** * Addition. */ LorentzTensor<Value> operator+(const LorentzTensor<Value> & in) const { return LorentzTensor<Value>(xx()+in.xx(),xy()+in.xy(),xz()+in.xz(),xt()+in.xt(), yx()+in.yx(),yy()+in.yy(),yz()+in.yz(),yt()+in.yt(), zx()+in.zx(),zy()+in.zy(),zz()+in.zz(),zt()+in.zt(), tx()+in.tx(),ty()+in.ty(),tz()+in.tz(),tt()+in.tt()); } /** * Subtraction. */ LorentzTensor<Value> operator-(const LorentzTensor<Value> & in) const { return LorentzTensor<Value>(xx()-in.xx(),xy()-in.xy(),xz()-in.xz(),xt()-in.xt(), yx()-in.yx(),yy()-in.yy(),yz()-in.yz(),yt()-in.yt(), zx()-in.zx(),zy()-in.zy(),zz()-in.zz(),zt()-in.zt(), tx()-in.tx(),ty()-in.ty(),tz()-in.tz(),tt()-in.tt()); } /** * Trace */ complex<Value> trace() const { return _tensor[3][3]-_tensor[0][0]-_tensor[1][1]-_tensor[2][2]; } + + /** + * Inner product with another tensor + */ + template<typename ValueB> + auto innerProduct(const LorentzTensor<ValueB> & ten) const { + LorentzTensor<decltype(ten.xx().real()*this->xx().real())> output; + for(unsigned int ix=0;ix<3;++ix) { + for(unsigned int iy=0;iy<3;++iy) { + output(ix,iy) = _tensor[ix][3]*ten(3,iy); + for(unsigned int iz=0;iz<3;++iz) { + output(ix,iy) -= _tensor[ix][iz]*ten(iz,iy); + } + } + } + return output; + } + + /** + * Outer product with another tensor + */ + template<typename ValueB> + auto outerProduct(const LorentzTensor<ValueB> & ten) const { + LorentzTensor<decltype(ten.xx().real()*this->xx().real())> output; + for(unsigned int ix=0;ix<3;++ix) { + for(unsigned int iy=0;iy<3;++iy) { + output(ix,iy) = _tensor[3][ix]*ten(iy,3); + for(unsigned int iz=0;iz<3;++iz) { + output(ix,iy) -= _tensor[iz][ix]*ten(iy,iz); + } + } + } + return output; + } + //@} /** * Various dot products */ //@{ /** * First index dot product with polarization vector */ template<typename ValueB> auto preDot (const LorentzVector<complex<ValueB> > & vec) const -> LorentzVector<decltype(vec.x()*this->xx())> { LorentzVector<decltype(vec.x()*this->xx())> output; output.setX(vec.t()*_tensor[3][0]-vec.x()*_tensor[0][0]- vec.y()*_tensor[1][0]-vec.z()*_tensor[2][0]); output.setY(vec.t()*_tensor[3][1]-vec.x()*_tensor[0][1]- vec.y()*_tensor[1][1]-vec.z()*_tensor[2][1]); output.setZ(vec.t()*_tensor[3][2]-vec.x()*_tensor[0][2]- vec.y()*_tensor[1][2]-vec.z()*_tensor[2][2]); output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[0][3]- vec.y()*_tensor[1][3]-vec.z()*_tensor[2][3]); return output; } /** * Second index dot product with polarization vector */ template<typename ValueB> auto postDot(const LorentzVector<complex<ValueB> > & vec) const -> LorentzVector<decltype(vec.x()*this->xx())> { LorentzVector<decltype(vec.x()*this->xx())> output; output.setX(vec.t()*_tensor[0][3]-vec.x()*_tensor[0][0]- vec.y()*_tensor[0][1]-vec.z()*_tensor[0][2]); output.setY(vec.t()*_tensor[1][3]-vec.x()*_tensor[1][0]- vec.y()*_tensor[1][1]-vec.z()*_tensor[1][2]); output.setZ(vec.t()*_tensor[2][3]-vec.x()*_tensor[2][0]- vec.y()*_tensor[2][1]-vec.z()*_tensor[2][2]); output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[3][0]- vec.y()*_tensor[3][1]-vec.z()*_tensor[3][2]); return output; } /** * First index dot product with momentum */ auto preDot (const Lorentz5Momentum & vec) const -> LorentzVector<decltype(vec.x()*this->xx())> { LorentzVector<decltype(vec.x()*this->xx())> output; output.setX(vec.t()*_tensor[3][0]-vec.x()*_tensor[0][0]- vec.y()*_tensor[1][0]-vec.z()*_tensor[2][0]); output.setY(vec.t()*_tensor[3][1]-vec.x()*_tensor[0][1]- vec.y()*_tensor[1][1]-vec.z()*_tensor[2][1]); output.setZ(vec.t()*_tensor[3][2]-vec.x()*_tensor[0][2]- vec.y()*_tensor[1][2]-vec.z()*_tensor[2][2]); output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[0][3]- vec.y()*_tensor[1][3]-vec.z()*_tensor[2][3]); return output; } /** * Second index dot product with momentum */ auto postDot(const Lorentz5Momentum & vec) const -> LorentzVector<decltype(vec.x()*this->xx())> { LorentzVector<decltype(vec.x()*this->xx())> output; output.setX(vec.t()*_tensor[0][3]-vec.x()*_tensor[0][0]- vec.y()*_tensor[0][1]-vec.z()*_tensor[0][2]); output.setY(vec.t()*_tensor[1][3]-vec.x()*_tensor[1][0]- vec.y()*_tensor[1][1]-vec.z()*_tensor[1][2]); output.setZ(vec.t()*_tensor[2][3]-vec.x()*_tensor[2][0]- vec.y()*_tensor[2][1]-vec.z()*_tensor[2][2]); output.setT(vec.t()*_tensor[3][3]-vec.x()*_tensor[3][0]- vec.y()*_tensor[3][1]-vec.z()*_tensor[3][2]); return output; } //@} private: /** * The components. */ std::array<std::array<complex<Value>,4>,4> _tensor; }; /** * Multiplication by a complex number. */ template<typename T, typename U> inline auto operator*(complex<U> a, const LorentzTensor<T> & t) -> LorentzTensor<decltype(a.real()*t.xx().real())> { return {a*t.xx(), a*t.xy(), a*t.xz(), a*t.xt(), a*t.yx(), a*t.yy(), a*t.yz(), a*t.yt(), a*t.zx(), a*t.zy(), a*t.zz(), a*t.zt(), a*t.tx(), a*t.ty(), a*t.tz(), a*t.tt()}; } /** * Multiplication by a complex number. */ template<typename T, typename U> inline auto operator*(const LorentzTensor<T> & t,complex<U> a) -> LorentzTensor<decltype(a.real()*t.xx().real())> { return {a*t.xx(), a*t.xy(), a*t.xz(), a*t.xt(), a*t.yx(), a*t.yy(), a*t.yz(), a*t.yt(), a*t.zx(), a*t.zy(), a*t.zz(), a*t.zt(), a*t.tx(), a*t.ty(), a*t.tz(), a*t.tt()}; } /** * Multiply a LorentzVector by a LorentzTensor. */ template<typename T, typename U> inline auto operator*(const LorentzVector<U> & v, const LorentzTensor<T> & t) -> LorentzVector<decltype(v.t()*t(3,0))> { LorentzVector<decltype(v.t()*t(3,0))> outvec; outvec.setX( v.t()*t(3,0)-v.x()*t(0,0) -v.y()*t(1,0)-v.z()*t(2,0)); outvec.setY( v.t()*t(3,1)-v.x()*t(0,1) -v.y()*t(1,1)-v.z()*t(2,1)); outvec.setZ( v.t()*t(3,2)-v.x()*t(0,2) -v.y()*t(1,2)-v.z()*t(2,2)); outvec.setT( v.t()*t(3,3)-v.x()*t(0,3) -v.y()*t(1,3)-v.z()*t(2,3)); return outvec; } /** * Multiply a LorentzTensor by a LorentzVector. */ template<typename T, typename U> inline auto operator*(const LorentzTensor<T> & t, const LorentzVector<U> & v) -> LorentzVector<decltype(v.t()*t(0,3))> { LorentzVector<decltype(v.t()*t(0,3))> outvec; outvec.setX( v.t()*t(0,3)-v.x()*t(0,0) -v.y()*t(0,1)-v.z()*t(0,2)); outvec.setY( v.t()*t(1,3)-v.x()*t(1,0) -v.y()*t(1,1)-v.z()*t(1,2)); outvec.setZ( v.t()*t(2,3)-v.x()*t(2,0) -v.y()*t(2,1)-v.z()*t(2,2)); outvec.setT( v.t()*t(3,3)-v.x()*t(3,0) -v.y()*t(3,1)-v.z()*t(3,2)); return outvec; } /** * Multiply a LorentzTensor by a LorentzTensor */ template <typename T, typename U> inline auto operator*(const LorentzTensor<T> & t, const LorentzTensor<U> & u) -> decltype(t.xx()*u.xx()) { using RetT = decltype(t.xx()*u.xx()); RetT output=RetT(),temp; for(unsigned int ix=0;ix<4;++ix) { temp = t._tensor[ix][3]*u._tensor[ix][3]; for(unsigned int iy=0;iy<3;++iy) { - temp+= t._tensor[ix][iy]*u._tensor[ix][iy]; + temp -= t._tensor[ix][iy]*u._tensor[ix][iy]; } if(ix<3) output-=temp; else output+=temp; } return output; } } } #ifndef ThePEG_TEMPLATES_IN_CC_FILE #include "LorentzTensor.tcc" #endif #endif diff --git a/Helicity/epsilon.h b/Helicity/epsilon.h --- a/Helicity/epsilon.h +++ b/Helicity/epsilon.h @@ -1,134 +1,165 @@ // -*- C++ -*- // // epsilon.h is a part of ThePEG - Toolkit for HEP Event Generation // Copyright (C) 2003-2019 Peter Richardson, Leif Lonnblad // // ThePEG is licenced under version 3 of the GPL, see COPYING for details. // Please respect the MCnet academic guidelines, see GUIDELINES for details. // #ifndef ThePEG_epsilon_H #define ThePEG_epsilon_H // // This is the declaration of the epsilon class. #include "ThePEG/Vectors/LorentzVector.h" #include "LorentzTensor.h" namespace ThePEG { namespace Helicity { /** \ingroup Helicity * \author Peter Richardson * * This class is designed to combine 5-momenta and polarization * vectors together with the result being the product with the * eps function. The class is purely static and contains no data. * * @see LorentzPolarizationVector * @see Lorentz5Vector */ /** * Return the product * \f$\epsilon^{\alpha\beta\gamma\delta}v_{1\alpha}v_{2\beta}v_{3\gamma}v_{4\delta}\f$. * @param a The first vector \f$v_{1\alpha}\f$. * @param b The second vector \f$v_{2\beta}\f$. * @param c The third vector \f$v_{3\gamma}\f$. * @param d The fourth vector \f$v_{4\delta}\f$. * @return The product * \f$\epsilon^{\alpha\beta\gamma\delta}v_{1\alpha}v_{2\beta}v_{3\gamma}v_{4\delta}\f$ */ template <typename A, typename B, typename C, typename D> auto epsilon(const LorentzVector<A> & a, const LorentzVector<B> & b, const LorentzVector<C> & c, const LorentzVector<D> & d) -> decltype(a.x()*b.y()*c.z()*d.t()) { auto diffxy = a.x() * b.y() - a.y() * b.x(); auto diffxz = a.x() * b.z() - a.z() * b.x(); auto diffxt = a.x() * b.t() - a.t() * b.x(); auto diffyz = a.y() * b.z() - a.z() * b.y(); auto diffyt = a.y() * b.t() - a.t() * b.y(); auto diffzt = a.z() * b.t() - a.t() * b.z(); auto diff2xy = c.x() * d.y() - c.y() * d.x(); auto diff2xz = c.x() * d.z() - c.z() * d.x(); auto diff2xt = c.x() * d.t() - c.t() * d.x(); auto diff2yz = c.y() * d.z() - c.z() * d.y(); auto diff2yt = c.y() * d.t() - c.t() * d.y(); auto diff2zt = c.z() * d.t() - c.t() * d.z(); return diff2yz*diffxt + diff2zt*diffxy - diff2yt*diffxz - diff2xz*diffyt + diff2xt*diffyz + diff2xy*diffzt; } /** * Return the product * \f$\epsilon^{\mu\alpha\beta\gamma}v_{1\alpha}v_{2\beta}v_{3\gamma}\f$. * @param a The first vector \f$v_{1\alpha}\f$. * @param b The second vector \f$v_{2\beta}\f$. * @param c The third vector \f$v_{3\gamma}\f$. * @return The product * \f$\epsilon^{\mu\alpha\beta\gamma}v_{1\alpha}v_{2\beta}v_{3\gamma}\f$. */ template <typename A, typename B, typename C> auto epsilon(const LorentzVector<A> & a, const LorentzVector<B> & b, const LorentzVector<C> & c) -> LorentzVector<decltype(a.x()*b.y()*c.z())> { auto diffxy = a.x() * b.y() - a.y() * b.x(); auto diffxz = a.x() * b.z() - a.z() * b.x(); auto diffxt = a.x() * b.t() - a.t() * b.x(); auto diffyz = a.y() * b.z() - a.z() * b.y(); auto diffyt = a.y() * b.t() - a.t() * b.y(); auto diffzt = a.z() * b.t() - a.t() * b.z(); using ResultType = LorentzVector<decltype(a.x()*b.x()*c.x())>; ResultType result; result.setX( c.z() * diffyt - c.t() * diffyz - c.y() * diffzt); result.setY( c.t() * diffxz - c.z() * diffxt + c.x() * diffzt); result.setZ(-c.t() * diffxy + c.y() * diffxt - c.x() * diffyt); result.setT(-c.z() * diffxy + c.y() * diffxz - c.x() * diffyz); return result; } /** * Return the product * \f$\epsilon^{\mu\nu\alpha\beta}v_{1\alpha}v_{2\beta}\f$. * @param a The first vector \f$v_{1\alpha}\f$. * @param b The second vector \f$v_{2\beta}\f$. - * @return The product + * @return The product * \f$\epsilon^{\mu\nu\alpha\beta\gamma}v_{1\alpha}v_{2\beta}\f$. */ template <typename A, typename B> - auto epsilon(const LorentzVector<A> & a, - const LorentzVector<B> & b) - -> LorentzTensor<decltype(real(a.x()*b.y()))> + auto epsilon(const LorentzVector<complex<A> > & a, + const LorentzVector<complex<B> > & b) + -> LorentzTensor<decltype(a.x().real()*b.y().real())> { auto diffxy = a.x() * b.y() - a.y() * b.x(); auto diffxz = a.x() * b.z() - a.z() * b.x(); auto diffxt = a.x() * b.t() - a.t() * b.x(); auto diffyz = a.y() * b.z() - a.z() * b.y(); auto diffyt = a.y() * b.t() - a.t() * b.y(); auto diffzt = a.z() * b.t() - a.t() * b.z(); - complex<decltype(real(a.x()*b.x()))> zero(ZERO); + complex<decltype(a.x().real()*b.x().real())> zero(ZERO); - using ResultType = LorentzTensor<decltype(real(a.x()*b.x()))>; + using ResultType = LorentzTensor<decltype(a.x().real()*b.x().real())>; ResultType result; result.setTT( zero ); result.setTX( diffyz); result.setTY(-diffxz); result.setTZ( diffxy); result.setXT(-diffyz); result.setXX( zero ); result.setXY( diffzt); result.setXZ(-diffyt); result.setYT( diffxz); result.setYX(-diffzt); result.setYY( zero ); result.setYZ( diffxt); result.setZT(-diffxy); result.setZX( diffyt); result.setZY(-diffxt); result.setZZ( zero ); - + return result; } + /** + * Return the product + * \f$\epsilon^{\mu\nu\alpha\beta}v_{1\alpha}v_{2\beta}\f$. + * @param a The first vector \f$v_{1\alpha}\f$. + * @param b The second vector \f$v_{2\beta}\f$. + * @return The product + * \f$\epsilon^{\mu\nu\alpha\beta\gamma}v_{1\alpha}v_{2\beta}\f$. + */ + template <typename A, typename B> + auto epsilon(const LorentzVector<A> & a, + const LorentzVector<B> & b) + -> LorentzTensor<decltype(a.x()*b.y())> + { + auto diffxy = a.x() * b.y() - a.y() * b.x(); + auto diffxz = a.x() * b.z() - a.z() * b.x(); + auto diffxt = a.x() * b.t() - a.t() * b.x(); + auto diffyz = a.y() * b.z() - a.z() * b.y(); + auto diffyt = a.y() * b.t() - a.t() * b.y(); + auto diffzt = a.z() * b.t() - a.t() * b.z(); + complex<decltype(a.x()*b.x())> zero(ZERO); + + using ResultType = LorentzTensor<decltype(a.x()*b.x())>; + ResultType result; + result.setTT( zero ); result.setTX( diffyz); result.setTY(-diffxz); result.setTZ( diffxy); + result.setXT(-diffyz); result.setXX( zero ); result.setXY( diffzt); result.setXZ(-diffyt); + result.setYT( diffxz); result.setYX(-diffzt); result.setYY( zero ); result.setYZ( diffxt); + result.setZT(-diffxy); result.setZX( diffyt); result.setZY(-diffxt); result.setZZ( zero ); + + return result; + } + } } #endif /* ThePEG_epsilon_H */