File indexing completed on 2025-04-19 09:09:51
0001 #ifndef ATOOLS_Math_Tensor_Contractions_H
0002 #define ATOOLS_Math_Tensor_Contractions_H
0003
0004
0005
0006
0007
0008
0009
0010 template<typename Scalar>
0011 Scalar
0012 ATOOLS::Contraction(const Lorentz_Ten2<Scalar>& t) {
0013
0014 return t.at(0,0)-t.at(1,1)-t.at(2,2)-t.at(3,3);
0015 }
0016
0017 template<typename Scalar>
0018 Vec4<Scalar>
0019 ATOOLS::Contraction(const Lorentz_Ten3<Scalar>& ten, int i, int j) {
0020 Lorentz_Ten3<Scalar> t;
0021
0022 if (((i==2) && (j==3)) || ((j==2) && (i==3)))
0023 t = ten;
0024
0025 else if (((i==1) && (j==3)) || ((j==1) && (i==3)))
0026 t = ten.Transpose(1,2);
0027
0028 else if (((i==1) && (j==2)) || ((j==1) && (i==2)))
0029 t = ten.Transpose(1,3);
0030 else
0031 return Vec4<Scalar>(0.,0.,0.,0.);
0032 return Vec4<Scalar>(t.at(0,0,0)-t.at(0,1,1)-t.at(0,2,2)-t.at(0,3,3),
0033 t.at(1,0,0)-t.at(1,1,1)-t.at(1,2,2)-t.at(1,3,3),
0034 t.at(2,0,0)-t.at(2,1,1)-t.at(2,2,2)-t.at(2,3,3),
0035 t.at(3,0,0)-t.at(3,1,1)-t.at(3,2,2)-t.at(3,3,3));
0036 }
0037
0038 template<typename Scalar>
0039 Lorentz_Ten2<Scalar>
0040 ATOOLS::Contraction(const Lorentz_Ten4<Scalar>& ten, int i, int j) {
0041 Lorentz_Ten4<Scalar> t;
0042
0043 if (((i==3) && (j==4)) || ((i==4) && (j==3)))
0044 t = ten;
0045
0046 else if (((i==2) && (j==4)) || ((i==4) && (j==2)))
0047 t = ten.Transpose(2,3);
0048
0049 else if (((i==1) && (j==4)) || ((i==4) && (j==1)))
0050 {t = ten.Transpose(1,2); t = t.Transpose(2,3);}
0051
0052 else if (((i==2) && (j==3)) || ((i==3) && (j==2)))
0053 t = ten.Transpose(2,4);
0054
0055 else if (((i==1) && (j==3)) || ((i==3) && (j==1)))
0056 {t = ten.Transpose(1,2); t = t.Transpose(2,4);}
0057
0058 else if (((i==1) && (j==2)) || ((i==2) && (j==1)))
0059 {t = ten.Transpose(1,3); t = t.Transpose(2,4);}
0060 else
0061 return Lorentz_Ten2<Scalar>();
0062 return Lorentz_Ten2<Scalar>(t.at(0,0,0,0)-t.at(0,0,1,1)-t.at(0,0,2,2)-t.at(0,0,3,3),
0063 t.at(1,0,0,0)-t.at(1,0,1,1)-t.at(1,0,2,2)-t.at(1,0,3,3),
0064 t.at(2,0,0,0)-t.at(2,0,1,1)-t.at(2,0,2,2)-t.at(2,0,3,3),
0065 t.at(3,0,0,0)-t.at(3,0,1,1)-t.at(3,0,2,2)-t.at(3,0,3,3),
0066 t.at(0,1,0,0)-t.at(0,1,1,1)-t.at(0,1,2,2)-t.at(0,1,3,3),
0067 t.at(1,1,0,0)-t.at(1,1,1,1)-t.at(1,1,2,2)-t.at(1,1,3,3),
0068 t.at(2,1,0,0)-t.at(2,1,1,1)-t.at(2,1,2,2)-t.at(2,1,3,3),
0069 t.at(3,1,0,0)-t.at(3,1,1,1)-t.at(3,1,2,2)-t.at(3,1,3,3),
0070 t.at(0,2,0,0)-t.at(0,2,1,1)-t.at(0,2,2,2)-t.at(0,2,3,3),
0071 t.at(1,2,0,0)-t.at(1,2,1,1)-t.at(1,2,2,2)-t.at(1,2,3,3),
0072 t.at(2,2,0,0)-t.at(2,2,1,1)-t.at(2,2,2,2)-t.at(2,2,3,3),
0073 t.at(3,2,0,0)-t.at(3,2,1,1)-t.at(3,2,2,2)-t.at(3,2,3,3),
0074 t.at(0,3,0,0)-t.at(0,3,1,1)-t.at(0,3,2,2)-t.at(0,3,3,3),
0075 t.at(1,3,0,0)-t.at(1,3,1,1)-t.at(1,3,2,2)-t.at(1,3,3,3),
0076 t.at(2,3,0,0)-t.at(2,3,1,1)-t.at(2,3,2,2)-t.at(2,3,3,3),
0077 t.at(3,3,0,0)-t.at(3,3,1,1)-t.at(3,3,2,2)-t.at(3,3,3,3));
0078 }
0079
0080 template<typename Scalar>
0081 Scalar
0082 ATOOLS::Contraction(const Lorentz_Ten4<Scalar>& ten, int i, int j, int k, int l) {
0083 Lorentz_Ten4<Scalar> t;
0084
0085 if (((((i==1) && (j==2)) || ((i==2) && (j==1))) &&
0086 (((k==3) && (l==4)) || ((k==4) && (l==3)))) ||
0087 ((((i==3) && (j==4)) || ((i==4) && (j==3))) &&
0088 (((k==1) && (l==2)) || ((k==2) && (l==1)))))
0089 t = ten;
0090
0091 else if (((((i==1) && (j==3)) || ((i==3) && (j==1))) &&
0092 (((k==2) && (l==4)) || ((k==4) && (l==2)))) ||
0093 ((((i==2) && (j==4)) || ((i==4) && (j==2))) &&
0094 (((k==1) && (l==3)) || ((k==3) && (l==1)))))
0095 t = ten.Transpose(2,3);
0096
0097 else if (((((i==1) && (j==4)) || ((i==4) && (j==1))) &&
0098 (((k==2) && (l==3)) || ((k==3) && (l==2)))) ||
0099 ((((i==2) && (j==3)) || ((i==3) && (j==2))) &&
0100 (((k==1) && (l==4)) || ((k==4) && (l==1)))))
0101 t = ten.Transpose(2,4);
0102 else
0103 return Scalar(0.);
0104 return Scalar( t.at(0,0,0,0)-t.at(0,0,1,1)-t.at(0,0,2,2)-t.at(0,0,3,3)
0105 -t.at(1,1,0,0)+t.at(1,1,1,1)+t.at(1,1,2,2)+t.at(1,1,3,3)
0106 -t.at(2,2,0,0)+t.at(2,2,1,1)+t.at(2,2,2,2)+t.at(2,2,3,3)
0107 -t.at(3,3,0,0)+t.at(3,3,1,1)+t.at(3,3,2,2)+t.at(3,3,3,3));
0108 }
0109
0110
0111
0112
0113
0114
0115
0116 template<typename Scal1, typename Scal2>
0117 Vec4<PROMOTE(Scal1,Scal2)>
0118 ATOOLS::Contraction(const Lorentz_Ten2<Scal1>& ten, int i, const Vec4<Scal2>& p) {
0119 Lorentz_Ten2<Scal1> t;
0120 if ((i==1) || (i==2)) {
0121
0122 if (i==1)
0123 t = ten.Transpose();
0124
0125 else if (i==2)
0126 t = ten;
0127 return Vec4<PROMOTE(Scal1,Scal2)>(
0128 t.at(0,0)*p[0]-t.at(0,1)*p[1]-t.at(0,2)*p[2]-t.at(0,3)*p[3],
0129 t.at(1,0)*p[0]-t.at(1,1)*p[1]-t.at(1,2)*p[2]-t.at(1,3)*p[3],
0130 t.at(2,0)*p[0]-t.at(2,1)*p[1]-t.at(2,2)*p[2]-t.at(2,3)*p[3],
0131 t.at(3,0)*p[0]-t.at(3,1)*p[1]-t.at(3,2)*p[2]-t.at(3,3)*p[3]);
0132 }
0133 return Vec4<PROMOTE(Scal1,Scal2)>();
0134 }
0135
0136 template<typename Scal1, typename Scal2, typename Scal3>
0137 PROMOTE(PROMOTE(Scal1,Scal2),Scal3)
0138 ATOOLS::Contraction(const Lorentz_Ten2<Scal1>& t,
0139 const Vec4<Scal2>& p, const Vec4<Scal3>& q) {
0140
0141 return q[0]*(t.at(0,0)*p[0]-t.at(1,0)*p[1]-t.at(2,0)*p[2]-t.at(3,0)*p[3])
0142 -q[1]*(t.at(0,1)*p[0]-t.at(1,1)*p[1]-t.at(2,1)*p[2]-t.at(3,1)*p[3])
0143 -q[2]*(t.at(0,2)*p[0]-t.at(1,2)*p[1]-t.at(2,2)*p[2]-t.at(3,2)*p[3])
0144 -q[3]*(t.at(0,3)*p[0]-t.at(1,3)*p[1]-t.at(2,3)*p[2]-t.at(3,3)*p[3]);
0145 }
0146
0147 template<typename Scal1, typename Scal2>
0148 Lorentz_Ten2<PROMOTE(Scal1,Scal2)>
0149 ATOOLS::Contraction(const Lorentz_Ten3<Scal1>& ten, int i, const Vec4<Scal2>& v) {
0150 Lorentz_Ten3<Scal1> t;
0151
0152 if (i==1)
0153 {t = ten.Transpose(1,2); t = t.Transpose(2,3);}
0154
0155 else if (i==2)
0156 t = ten.Transpose(2,3);
0157
0158 else if (i==3)
0159 t = ten;
0160 else
0161 return Lorentz_Ten2<PROMOTE(Scal1,Scal2)>();
0162 return Lorentz_Ten2<PROMOTE(Scal1,Scal2)>(
0163 t.at(0,0,0)*v[0]-t.at(0,0,1)*v[1]-t.at(0,0,2)*v[2]-t.at(0,0,3)*v[3],
0164 t.at(1,0,0)*v[0]-t.at(1,0,1)*v[1]-t.at(1,0,2)*v[2]-t.at(1,0,3)*v[3],
0165 t.at(2,0,0)*v[0]-t.at(2,0,1)*v[1]-t.at(2,0,2)*v[2]-t.at(2,0,3)*v[3],
0166 t.at(3,0,0)*v[0]-t.at(3,0,1)*v[1]-t.at(3,0,2)*v[2]-t.at(3,0,3)*v[3],
0167 t.at(0,1,0)*v[0]-t.at(0,1,1)*v[1]-t.at(0,1,2)*v[2]-t.at(0,1,3)*v[3],
0168 t.at(1,1,0)*v[0]-t.at(1,1,1)*v[1]-t.at(1,1,2)*v[2]-t.at(1,1,3)*v[3],
0169 t.at(2,1,0)*v[0]-t.at(2,1,1)*v[1]-t.at(2,1,2)*v[2]-t.at(2,1,3)*v[3],
0170 t.at(3,1,0)*v[0]-t.at(3,1,1)*v[1]-t.at(3,1,2)*v[2]-t.at(3,1,3)*v[3],
0171 t.at(0,2,0)*v[0]-t.at(0,2,1)*v[1]-t.at(0,2,2)*v[2]-t.at(0,2,3)*v[3],
0172 t.at(1,2,0)*v[0]-t.at(1,2,1)*v[1]-t.at(1,2,2)*v[2]-t.at(1,2,3)*v[3],
0173 t.at(2,2,0)*v[0]-t.at(2,2,1)*v[1]-t.at(2,2,2)*v[2]-t.at(2,2,3)*v[3],
0174 t.at(3,2,0)*v[0]-t.at(3,2,1)*v[1]-t.at(3,2,2)*v[2]-t.at(3,2,3)*v[3],
0175 t.at(0,3,0)*v[0]-t.at(0,3,1)*v[1]-t.at(0,3,2)*v[2]-t.at(0,3,3)*v[3],
0176 t.at(1,3,0)*v[0]-t.at(1,3,1)*v[1]-t.at(1,3,2)*v[2]-t.at(1,3,3)*v[3],
0177 t.at(2,3,0)*v[0]-t.at(2,3,1)*v[1]-t.at(2,3,2)*v[2]-t.at(2,3,3)*v[3],
0178 t.at(3,3,0)*v[0]-t.at(3,3,1)*v[1]-t.at(3,3,2)*v[2]-t.at(3,3,3)*v[3]);
0179 }
0180
0181 template<typename Scal1, typename Scal2>
0182 Lorentz_Ten3<PROMOTE(Scal1,Scal2)>
0183 ATOOLS::Contraction(const Lorentz_Ten4<Scal1>& ten, int i, const Vec4<Scal2>& v) {
0184 Lorentz_Ten4<Scal1> t;
0185
0186 if (i==1)
0187 {t = ten.Transpose(1,2); t = t.Transpose(2,3); t = t.Transpose(3,4);}
0188
0189 else if (i==2)
0190 {t = ten.Transpose(2,3); t = t.Transpose(3,4);}
0191
0192 else if (i==3)
0193 t = ten.Transpose(3,4);
0194
0195 else if (i==4)
0196 t = ten;
0197 else
0198 return Lorentz_Ten3<PROMOTE(Scal1,Scal2)>();
0199 return Lorentz_Ten3<PROMOTE(Scal1,Scal2)>(
0200 t.at(0,0,0,0)*v[0]-t.at(0,0,0,1)*v[1]-t.at(0,0,0,2)*v[2]-t.at(0,0,0,3)*v[3],
0201 t.at(1,0,0,0)*v[0]-t.at(1,0,0,1)*v[1]-t.at(1,0,0,2)*v[2]-t.at(1,0,0,3)*v[3],
0202 t.at(2,0,0,0)*v[0]-t.at(2,0,0,1)*v[1]-t.at(2,0,0,2)*v[2]-t.at(2,0,0,3)*v[3],
0203 t.at(3,0,0,0)*v[0]-t.at(3,0,0,1)*v[1]-t.at(3,0,0,2)*v[2]-t.at(3,0,0,3)*v[3],
0204 t.at(0,1,0,0)*v[0]-t.at(0,1,0,1)*v[1]-t.at(0,1,0,2)*v[2]-t.at(0,1,0,3)*v[3],
0205 t.at(1,1,0,0)*v[0]-t.at(1,1,0,1)*v[1]-t.at(1,1,0,2)*v[2]-t.at(1,1,0,3)*v[3],
0206 t.at(2,1,0,0)*v[0]-t.at(2,1,0,1)*v[1]-t.at(2,1,0,2)*v[2]-t.at(2,1,0,3)*v[3],
0207 t.at(3,1,0,0)*v[0]-t.at(3,1,0,1)*v[1]-t.at(3,1,0,2)*v[2]-t.at(3,1,0,3)*v[3],
0208 t.at(0,2,0,0)*v[0]-t.at(0,2,0,1)*v[1]-t.at(0,2,0,2)*v[2]-t.at(0,2,0,3)*v[3],
0209 t.at(1,2,0,0)*v[0]-t.at(1,2,0,1)*v[1]-t.at(1,2,0,2)*v[2]-t.at(1,2,0,3)*v[3],
0210 t.at(2,2,0,0)*v[0]-t.at(2,2,0,1)*v[1]-t.at(2,2,0,2)*v[2]-t.at(2,2,0,3)*v[3],
0211 t.at(3,2,0,0)*v[0]-t.at(3,2,0,1)*v[1]-t.at(3,2,0,2)*v[2]-t.at(3,2,0,3)*v[3],
0212 t.at(0,3,0,0)*v[0]-t.at(0,3,0,1)*v[1]-t.at(0,3,0,2)*v[2]-t.at(0,3,0,3)*v[3],
0213 t.at(1,3,0,0)*v[0]-t.at(1,3,0,1)*v[1]-t.at(1,3,0,2)*v[2]-t.at(1,3,0,3)*v[3],
0214 t.at(2,3,0,0)*v[0]-t.at(2,3,0,1)*v[1]-t.at(2,3,0,2)*v[2]-t.at(2,3,0,3)*v[3],
0215 t.at(3,3,0,0)*v[0]-t.at(3,3,0,1)*v[1]-t.at(3,3,0,2)*v[2]-t.at(3,3,0,3)*v[3],
0216
0217 t.at(0,0,1,0)*v[0]-t.at(0,0,1,1)*v[1]-t.at(0,0,1,2)*v[2]-t.at(0,0,1,3)*v[3],
0218 t.at(1,0,1,0)*v[0]-t.at(1,0,1,1)*v[1]-t.at(1,0,1,2)*v[2]-t.at(1,0,1,3)*v[3],
0219 t.at(2,0,1,0)*v[0]-t.at(2,0,1,1)*v[1]-t.at(2,0,1,2)*v[2]-t.at(2,0,1,3)*v[3],
0220 t.at(3,0,1,0)*v[0]-t.at(3,0,1,1)*v[1]-t.at(3,0,1,2)*v[2]-t.at(3,0,1,3)*v[3],
0221 t.at(0,1,1,0)*v[0]-t.at(0,1,1,1)*v[1]-t.at(0,1,1,2)*v[2]-t.at(0,1,1,3)*v[3],
0222 t.at(1,1,1,0)*v[0]-t.at(1,1,1,1)*v[1]-t.at(1,1,1,2)*v[2]-t.at(1,1,1,3)*v[3],
0223 t.at(2,1,1,0)*v[0]-t.at(2,1,1,1)*v[1]-t.at(2,1,1,2)*v[2]-t.at(2,1,1,3)*v[3],
0224 t.at(3,1,1,0)*v[0]-t.at(3,1,1,1)*v[1]-t.at(3,1,1,2)*v[2]-t.at(3,1,1,3)*v[3],
0225 t.at(0,2,1,0)*v[0]-t.at(0,2,1,1)*v[1]-t.at(0,2,1,2)*v[2]-t.at(0,2,1,3)*v[3],
0226 t.at(1,2,1,0)*v[0]-t.at(1,2,1,1)*v[1]-t.at(1,2,1,2)*v[2]-t.at(1,2,1,3)*v[3],
0227 t.at(2,2,1,0)*v[0]-t.at(2,2,1,1)*v[1]-t.at(2,2,1,2)*v[2]-t.at(2,2,1,3)*v[3],
0228 t.at(3,2,1,0)*v[0]-t.at(3,2,1,1)*v[1]-t.at(3,2,1,2)*v[2]-t.at(3,2,1,3)*v[3],
0229 t.at(0,3,1,0)*v[0]-t.at(0,3,1,1)*v[1]-t.at(0,3,1,2)*v[2]-t.at(0,3,1,3)*v[3],
0230 t.at(1,3,1,0)*v[0]-t.at(1,3,1,1)*v[1]-t.at(1,3,1,2)*v[2]-t.at(1,3,1,3)*v[3],
0231 t.at(2,3,1,0)*v[0]-t.at(2,3,1,1)*v[1]-t.at(2,3,1,2)*v[2]-t.at(2,3,1,3)*v[3],
0232 t.at(3,3,1,0)*v[0]-t.at(3,3,1,1)*v[1]-t.at(3,3,1,2)*v[2]-t.at(3,3,1,3)*v[3],
0233
0234 t.at(0,0,2,0)*v[0]-t.at(0,0,2,1)*v[1]-t.at(0,0,2,2)*v[2]-t.at(0,0,2,3)*v[3],
0235 t.at(1,0,2,0)*v[0]-t.at(1,0,2,1)*v[1]-t.at(1,0,2,2)*v[2]-t.at(1,0,2,3)*v[3],
0236 t.at(2,0,2,0)*v[0]-t.at(2,0,2,1)*v[1]-t.at(2,0,2,2)*v[2]-t.at(2,0,2,3)*v[3],
0237 t.at(3,0,2,0)*v[0]-t.at(3,0,2,1)*v[1]-t.at(3,0,2,2)*v[2]-t.at(3,0,2,3)*v[3],
0238 t.at(0,1,2,0)*v[0]-t.at(0,1,2,1)*v[1]-t.at(0,1,2,2)*v[2]-t.at(0,1,2,3)*v[3],
0239 t.at(1,1,2,0)*v[0]-t.at(1,1,2,1)*v[1]-t.at(1,1,2,2)*v[2]-t.at(1,1,2,3)*v[3],
0240 t.at(2,1,2,0)*v[0]-t.at(2,1,2,1)*v[1]-t.at(2,1,2,2)*v[2]-t.at(2,1,2,3)*v[3],
0241 t.at(3,1,2,0)*v[0]-t.at(3,1,2,1)*v[1]-t.at(3,1,2,2)*v[2]-t.at(3,1,2,3)*v[3],
0242 t.at(0,2,2,0)*v[0]-t.at(0,2,2,1)*v[1]-t.at(0,2,2,2)*v[2]-t.at(0,2,2,3)*v[3],
0243 t.at(1,2,2,0)*v[0]-t.at(1,2,2,1)*v[1]-t.at(1,2,2,2)*v[2]-t.at(1,2,2,3)*v[3],
0244 t.at(2,2,2,0)*v[0]-t.at(2,2,2,1)*v[1]-t.at(2,2,2,2)*v[2]-t.at(2,2,2,3)*v[3],
0245 t.at(3,2,2,0)*v[0]-t.at(3,2,2,1)*v[1]-t.at(3,2,2,2)*v[2]-t.at(3,2,2,3)*v[3],
0246 t.at(0,3,2,0)*v[0]-t.at(0,3,2,1)*v[1]-t.at(0,3,2,2)*v[2]-t.at(0,3,2,3)*v[3],
0247 t.at(1,3,2,0)*v[0]-t.at(1,3,2,1)*v[1]-t.at(1,3,2,2)*v[2]-t.at(1,3,2,3)*v[3],
0248 t.at(2,3,2,0)*v[0]-t.at(2,3,2,1)*v[1]-t.at(2,3,2,2)*v[2]-t.at(2,3,2,3)*v[3],
0249 t.at(3,3,2,0)*v[0]-t.at(3,3,2,1)*v[1]-t.at(3,3,2,2)*v[2]-t.at(3,3,2,3)*v[3],
0250
0251 t.at(0,0,3,0)*v[0]-t.at(0,0,3,1)*v[1]-t.at(0,0,3,2)*v[2]-t.at(0,0,3,3)*v[3],
0252 t.at(1,0,3,0)*v[0]-t.at(1,0,3,1)*v[1]-t.at(1,0,3,2)*v[2]-t.at(1,0,3,3)*v[3],
0253 t.at(2,0,3,0)*v[0]-t.at(2,0,3,1)*v[1]-t.at(2,0,3,2)*v[2]-t.at(2,0,3,3)*v[3],
0254 t.at(3,0,3,0)*v[0]-t.at(3,0,3,1)*v[1]-t.at(3,0,3,2)*v[2]-t.at(3,0,3,3)*v[3],
0255 t.at(0,1,3,0)*v[0]-t.at(0,1,3,1)*v[1]-t.at(0,1,3,2)*v[2]-t.at(0,1,3,3)*v[3],
0256 t.at(1,1,3,0)*v[0]-t.at(1,1,3,1)*v[1]-t.at(1,1,3,2)*v[2]-t.at(1,1,3,3)*v[3],
0257 t.at(2,1,3,0)*v[0]-t.at(2,1,3,1)*v[1]-t.at(2,1,3,2)*v[2]-t.at(2,1,3,3)*v[3],
0258 t.at(3,1,3,0)*v[0]-t.at(3,1,3,1)*v[1]-t.at(3,1,3,2)*v[2]-t.at(3,1,3,3)*v[3],
0259 t.at(0,2,3,0)*v[0]-t.at(0,2,3,1)*v[1]-t.at(0,2,3,2)*v[2]-t.at(0,2,3,3)*v[3],
0260 t.at(1,2,3,0)*v[0]-t.at(1,2,3,1)*v[1]-t.at(1,2,3,2)*v[2]-t.at(1,2,3,3)*v[3],
0261 t.at(2,2,3,0)*v[0]-t.at(2,2,3,1)*v[1]-t.at(2,2,3,2)*v[2]-t.at(2,2,3,3)*v[3],
0262 t.at(3,2,3,0)*v[0]-t.at(3,2,3,1)*v[1]-t.at(3,2,3,2)*v[2]-t.at(3,2,3,3)*v[3],
0263 t.at(0,3,3,0)*v[0]-t.at(0,3,3,1)*v[1]-t.at(0,3,3,2)*v[2]-t.at(0,3,3,3)*v[3],
0264 t.at(1,3,3,0)*v[0]-t.at(1,3,3,1)*v[1]-t.at(1,3,3,2)*v[2]-t.at(1,3,3,3)*v[3],
0265 t.at(2,3,3,0)*v[0]-t.at(2,3,3,1)*v[1]-t.at(2,3,3,2)*v[2]-t.at(2,3,3,3)*v[3],
0266 t.at(3,3,3,0)*v[0]-t.at(3,3,3,1)*v[1]-t.at(3,3,3,2)*v[2]-t.at(3,3,3,3)*v[3]);
0267 }
0268
0269
0270
0271
0272
0273
0274
0275 template<typename Scal1, typename Scal2>
0276 PROMOTE(Scal1,Scal2)
0277 ATOOLS::Contraction(const Lorentz_Ten2<Scal1>& ten, int i, int j,
0278 const Lorentz_Ten2<Scal2>& sen, int k, int l) {
0279 Lorentz_Ten2<Scal1> t; Lorentz_Ten2<Scal2> s;
0280
0281 if (((i==1) && (j==2) && (k==1) && (l==2)) ||
0282 ((i==2) && (j==1) && (k==2) && (l==1)))
0283 {t = ten.Transpose(); s = sen;}
0284
0285 else if (((i==1) && (j==2) && (k==2) && (l==1)) ||
0286 ((i==2) && (j==1) && (k==1) && (l==2)))
0287 {t = ten; s = sen;}
0288 else
0289 return PROMOTE(Scal1,Scal2)();
0290 return PROMOTE(Scal1,Scal2)
0291 (t.at(0,0)*s.at(0,0)-t.at(1,0)*s.at(0,1)-t.at(2,0)*s.at(0,2)-t.at(3,0)*s.at(0,3))
0292 -(t.at(0,1)*s.at(1,0)-t.at(1,1)*s.at(1,1)-t.at(2,1)*s.at(1,2)-t.at(3,1)*s.at(1,3))
0293 -(t.at(0,2)*s.at(2,0)-t.at(1,2)*s.at(2,1)-t.at(2,2)*s.at(2,2)-t.at(3,2)*s.at(2,3))
0294 -(t.at(0,3)*s.at(3,0)-t.at(1,3)*s.at(3,1)-t.at(2,3)*s.at(3,2)-t.at(3,3)*s.at(3,3));
0295 }
0296
0297 template<typename Scal1, typename Scal2>
0298 Lorentz_Ten2<PROMOTE(Scal1,Scal2)>
0299 ATOOLS::Contraction(const Lorentz_Ten2<Scal1>& ten,int i,
0300 const Lorentz_Ten2<Scal2>& sen, int j) {
0301 Lorentz_Ten2<Scal1> t; Lorentz_Ten2<Scal2> s;
0302 if (((i==1) || (i==2)) && ((j==1) || (j==2))) {
0303
0304 if ((i==1) && (j==1))
0305 {t = ten.Transpose(); s = sen;}
0306
0307 else if ((i==1) && (j==2))
0308 {t = ten.Transpose(); s = sen.Transpose();}
0309
0310 else if ((i==2) && (j==1))
0311 {t = ten; s = sen;}
0312
0313 else if ((i==2) && (j==2))
0314 {t = ten; s = sen.Transpose();}
0315 return Lorentz_Ten2<PROMOTE(Scal1,Scal2)>(
0316 s.at(0,0)*t.at(0,0)-s.at(1,0)*t.at(0,1)-s.at(2,0)*t.at(0,2)-s.at(3,0)*t.at(0,3),
0317 s.at(0,0)*t.at(1,0)-s.at(1,0)*t.at(1,1)-s.at(2,0)*t.at(1,2)-s.at(3,0)*t.at(1,3),
0318 s.at(0,0)*t.at(2,0)-s.at(1,0)*t.at(2,1)-s.at(2,0)*t.at(2,2)-s.at(3,0)*t.at(2,3),
0319 s.at(0,0)*t.at(3,0)-s.at(1,0)*t.at(3,1)-s.at(2,0)*t.at(3,2)-s.at(3,0)*t.at(3,3),
0320 s.at(0,1)*t.at(0,0)-s.at(1,1)*t.at(0,1)-s.at(2,1)*t.at(0,2)-s.at(3,1)*t.at(0,3),
0321 s.at(0,1)*t.at(1,0)-s.at(1,1)*t.at(1,1)-s.at(2,1)*t.at(1,2)-s.at(3,1)*t.at(1,3),
0322 s.at(0,1)*t.at(2,0)-s.at(1,1)*t.at(2,1)-s.at(2,1)*t.at(2,2)-s.at(3,1)*t.at(2,3),
0323 s.at(0,1)*t.at(3,0)-s.at(1,1)*t.at(3,1)-s.at(2,1)*t.at(3,2)-s.at(3,1)*t.at(3,3),
0324 s.at(0,2)*t.at(0,0)-s.at(1,2)*t.at(0,1)-s.at(2,2)*t.at(0,2)-s.at(3,2)*t.at(0,3),
0325 s.at(0,2)*t.at(1,0)-s.at(1,2)*t.at(1,1)-s.at(2,2)*t.at(1,2)-s.at(3,2)*t.at(1,3),
0326 s.at(0,2)*t.at(2,0)-s.at(1,2)*t.at(2,1)-s.at(2,2)*t.at(2,2)-s.at(3,2)*t.at(2,3),
0327 s.at(0,2)*t.at(3,0)-s.at(1,2)*t.at(3,1)-s.at(2,2)*t.at(3,2)-s.at(3,2)*t.at(3,3),
0328 s.at(0,3)*t.at(0,0)-s.at(1,3)*t.at(0,1)-s.at(2,3)*t.at(0,2)-s.at(3,3)*t.at(0,3),
0329 s.at(0,3)*t.at(1,0)-s.at(1,3)*t.at(1,1)-s.at(2,3)*t.at(1,2)-s.at(3,3)*t.at(1,3),
0330 s.at(0,3)*t.at(2,0)-s.at(1,3)*t.at(2,1)-s.at(2,3)*t.at(2,2)-s.at(3,3)*t.at(2,3),
0331 s.at(0,3)*t.at(3,0)-s.at(1,3)*t.at(3,1)-s.at(2,3)*t.at(3,2)-s.at(3,3)*t.at(3,3));
0332 }
0333 return Lorentz_Ten2<PROMOTE(Scal1,Scal2)>();
0334 }
0335
0336 template<typename Scal1, typename Scal2>
0337 Vec4<PROMOTE(Scal1,Scal2)>
0338 ATOOLS::Contraction(const Lorentz_Ten3<Scal1>& ten, int i, int j,
0339 const Lorentz_Ten2<Scal2>& sen, int k, int l) {
0340 Lorentz_Ten3<Scal1> t; Lorentz_Ten2<Scal2> s;
0341
0342 if (((i==2) && (j==3) && (k==1) && (l==2)) || ((i==3) && (j==2) && (k==2) && (l==1)))
0343
0344 {t = ten; s = sen;}
0345 else if (((i==1) && (j==3) && (k==1) && (l==2)) || ((i==3) && (j==1) && (k==2) && (l==1)))
0346 {t = ten.Transpose(1,2); s = sen;}
0347
0348 else if (((i==1) && (j==2) && (k==1) && (l==2)) || ((i==2) && (j==1) && (k==2) && (l==1)))
0349 {t = ten.Transpose(2,3); t = t.Transpose(1,2); s = sen;}
0350
0351 else if (((i==2) && (j==3) && (k==2) && (l==1)) || ((i==3) && (j==2) && (k==1) && (l==2)))
0352 {t = ten; s = sen.Transpose();}
0353
0354 else if (((i==1) && (j==3) && (k==2) && (l==1)) || ((i==3) && (j==1) && (k==1) && (l==2)))
0355 {t = ten.Transpose(1,2); s = sen.Transpose();}
0356
0357 else if (((i==1) && (j==2) && (k==2) && (l==1)) || ((i==2) && (j==1) && (k==1) && (l==2)))
0358 {t = ten.Transpose(2,3); t = t.Transpose(1,2); s = sen.Transpose();}
0359 else
0360 return Vec4<PROMOTE(Scal1,Scal2)>(0.,0.,0.,0.);
0361 return Vec4<PROMOTE(Scal1,Scal2)>(
0362 t.at(0,0,0)*s.at(0,0)-t.at(0,1,0)*s.at(1,0)-t.at(0,2,0)*s.at(2,0)-t.at(0,3,0)*s.at(3,0)
0363 -t.at(0,0,1)*s.at(0,1)+t.at(0,1,1)*s.at(1,1)+t.at(0,2,1)*s.at(2,1)+t.at(0,3,1)*s.at(3,1)
0364 -t.at(0,0,2)*s.at(0,2)+t.at(0,1,2)*s.at(1,2)+t.at(0,2,2)*s.at(2,2)+t.at(0,3,2)*s.at(3,2)
0365 -t.at(0,0,3)*s.at(0,3)+t.at(0,1,3)*s.at(1,3)+t.at(0,2,3)*s.at(2,3)+t.at(0,3,3)*s.at(3,3),
0366 t.at(1,0,0)*s.at(0,0)-t.at(1,1,0)*s.at(1,0)-t.at(1,2,0)*s.at(2,0)-t.at(1,3,0)*s.at(3,0)
0367 -t.at(1,0,1)*s.at(0,1)+t.at(1,1,1)*s.at(1,1)+t.at(1,2,1)*s.at(2,1)+t.at(1,3,1)*s.at(3,1)
0368 -t.at(1,0,2)*s.at(0,2)+t.at(1,1,2)*s.at(1,2)+t.at(1,2,2)*s.at(2,2)+t.at(1,3,2)*s.at(3,2)
0369 -t.at(1,0,3)*s.at(0,3)+t.at(1,1,3)*s.at(1,3)+t.at(1,2,3)*s.at(2,3)+t.at(1,3,3)*s.at(3,3),
0370 t.at(2,0,0)*s.at(0,0)-t.at(2,1,0)*s.at(1,0)-t.at(2,2,0)*s.at(2,0)-t.at(2,3,0)*s.at(3,0)
0371 -t.at(2,0,1)*s.at(0,1)+t.at(2,1,1)*s.at(1,1)+t.at(2,2,1)*s.at(2,1)+t.at(2,3,1)*s.at(3,1)
0372 -t.at(2,0,2)*s.at(0,2)+t.at(2,1,2)*s.at(1,2)+t.at(2,2,2)*s.at(2,2)+t.at(2,3,2)*s.at(3,2)
0373 -t.at(2,0,3)*s.at(0,3)+t.at(2,1,3)*s.at(1,3)+t.at(2,2,3)*s.at(2,3)+t.at(2,3,3)*s.at(3,3),
0374 t.at(3,0,0)*s.at(0,0)-t.at(3,1,0)*s.at(1,0)-t.at(3,2,0)*s.at(2,0)-t.at(3,3,0)*s.at(3,0)
0375 -t.at(3,0,1)*s.at(0,1)+t.at(3,1,1)*s.at(1,1)+t.at(3,2,1)*s.at(2,1)+t.at(3,3,1)*s.at(3,1)
0376 -t.at(3,0,2)*s.at(0,2)+t.at(3,1,2)*s.at(1,2)+t.at(3,2,2)*s.at(2,2)+t.at(3,3,2)*s.at(3,2)
0377 -t.at(3,0,3)*s.at(0,3)+t.at(3,1,3)*s.at(1,3)+t.at(3,2,3)*s.at(2,3)+t.at(3,3,3)*s.at(3,3));
0378 }
0379
0380 template<typename Scal1, typename Scal2>
0381 Lorentz_Ten3<PROMOTE(Scal1,Scal2)>
0382 ATOOLS::Contraction(const Lorentz_Ten3<Scal1>& ten, int i,
0383 const Lorentz_Ten2<Scal2>& sen, int j) {
0384 Lorentz_Ten3<Scal1> t; Lorentz_Ten2<Scal2> s;
0385
0386 if ((i==3) && (j==2))
0387 {t = ten; s = sen;}
0388 else if ((i==2) && (j==2))
0389 {t = ten.Transpose(2,3); s = sen;}
0390 else if ((i==1) && (j==2))
0391 {t = ten.Transpose(1,2); t = t.Transpose(2,3); s = sen;}
0392 else if ((i==3) && (j==1))
0393 {t = ten; s = sen.Transpose();}
0394 else if ((i==2) && (j==1))
0395 {t = ten.Transpose(2,3); s = sen.Transpose();}
0396 else if ((i==1) && (j==1))
0397 {t = ten.Transpose(1,2); t = t.Transpose(2,3); s = sen.Transpose();}
0398 else
0399 return Lorentz_Ten3<PROMOTE(Scal1,Scal2)>();
0400 return Lorentz_Ten3<PROMOTE(Scal1,Scal2)>(
0401 t.at(0,0,0)*s.at(0,0)-t.at(0,0,1)*s.at(0,1)
0402 -t.at(0,0,2)*s.at(0,2)-t.at(0,0,3)*s.at(0,3),
0403 t.at(1,0,0)*s.at(0,0)-t.at(1,0,1)*s.at(0,1)
0404 -t.at(1,0,2)*s.at(0,2)-t.at(1,0,3)*s.at(0,3),
0405 t.at(2,0,0)*s.at(0,0)-t.at(2,0,1)*s.at(0,1)
0406 -t.at(2,0,2)*s.at(0,2)-t.at(2,0,3)*s.at(0,3),
0407 t.at(3,0,0)*s.at(0,0)-t.at(3,0,1)*s.at(0,1)
0408 -t.at(3,0,2)*s.at(0,2)-t.at(3,0,3)*s.at(0,3),
0409 t.at(0,1,0)*s.at(0,0)-t.at(0,1,1)*s.at(0,1)
0410 -t.at(0,1,2)*s.at(0,2)-t.at(0,1,3)*s.at(0,3),
0411 t.at(1,1,0)*s.at(0,0)-t.at(1,1,1)*s.at(0,1)
0412 -t.at(1,1,2)*s.at(0,2)-t.at(1,1,3)*s.at(0,3),
0413 t.at(2,1,0)*s.at(0,0)-t.at(2,1,1)*s.at(0,1)
0414 -t.at(2,1,2)*s.at(0,2)-t.at(2,1,3)*s.at(0,3),
0415 t.at(3,1,0)*s.at(0,0)-t.at(3,1,1)*s.at(0,1)
0416 -t.at(3,1,2)*s.at(0,2)-t.at(3,1,3)*s.at(0,3),
0417 t.at(0,2,0)*s.at(0,0)-t.at(0,2,1)*s.at(0,1)
0418 -t.at(0,2,2)*s.at(0,2)-t.at(0,2,3)*s.at(0,3),
0419 t.at(1,2,0)*s.at(0,0)-t.at(1,2,1)*s.at(0,1)
0420 -t.at(1,2,2)*s.at(0,2)-t.at(1,2,3)*s.at(0,3),
0421 t.at(2,2,0)*s.at(0,0)-t.at(2,2,1)*s.at(0,1)
0422 -t.at(2,2,2)*s.at(0,2)-t.at(2,2,3)*s.at(0,3),
0423 t.at(3,2,0)*s.at(0,0)-t.at(3,2,1)*s.at(0,1)
0424 -t.at(3,2,2)*s.at(0,2)-t.at(3,2,3)*s.at(0,3),
0425 t.at(0,3,0)*s.at(0,0)-t.at(0,3,1)*s.at(0,1)
0426 -t.at(0,3,2)*s.at(0,2)-t.at(0,3,3)*s.at(0,3),
0427 t.at(1,3,0)*s.at(0,0)-t.at(1,3,1)*s.at(0,1)
0428 -t.at(1,3,2)*s.at(0,2)-t.at(1,3,3)*s.at(0,3),
0429 t.at(2,3,0)*s.at(0,0)-t.at(2,3,1)*s.at(0,1)
0430 -t.at(2,3,2)*s.at(0,2)-t.at(2,3,3)*s.at(0,3),
0431 t.at(3,3,0)*s.at(0,0)-t.at(3,3,1)*s.at(0,1)
0432 -t.at(3,3,2)*s.at(0,2)-t.at(3,3,3)*s.at(0,3),
0433
0434 t.at(0,0,0)*s.at(1,0)-t.at(0,0,1)*s.at(1,1)
0435 -t.at(0,0,2)*s.at(1,2)-t.at(0,0,3)*s.at(1,3),
0436 t.at(1,0,0)*s.at(1,0)-t.at(1,0,1)*s.at(1,1)
0437 -t.at(1,0,2)*s.at(1,2)-t.at(1,0,3)*s.at(1,3),
0438 t.at(2,0,0)*s.at(1,0)-t.at(2,0,1)*s.at(1,1)
0439 -t.at(2,0,2)*s.at(1,2)-t.at(2,0,3)*s.at(1,3),
0440 t.at(3,0,0)*s.at(1,0)-t.at(3,0,1)*s.at(1,1)
0441 -t.at(3,0,2)*s.at(1,2)-t.at(3,0,3)*s.at(1,3),
0442 t.at(0,1,0)*s.at(1,0)-t.at(0,1,1)*s.at(1,1)
0443 -t.at(0,1,2)*s.at(1,2)-t.at(0,1,3)*s.at(1,3),
0444 t.at(1,1,0)*s.at(1,0)-t.at(1,1,1)*s.at(1,1)
0445 -t.at(1,1,2)*s.at(1,2)-t.at(1,1,3)*s.at(1,3),
0446 t.at(2,1,0)*s.at(1,0)-t.at(2,1,1)*s.at(1,1)
0447 -t.at(2,1,2)*s.at(1,2)-t.at(2,1,3)*s.at(1,3),
0448 t.at(3,1,0)*s.at(1,0)-t.at(3,1,1)*s.at(1,1)
0449 -t.at(3,1,2)*s.at(1,2)-t.at(3,1,3)*s.at(1,3),
0450 t.at(0,2,0)*s.at(1,0)-t.at(0,2,1)*s.at(1,1)
0451 -t.at(0,2,2)*s.at(1,2)-t.at(0,2,3)*s.at(1,3),
0452 t.at(1,2,0)*s.at(1,0)-t.at(1,2,1)*s.at(1,1)
0453 -t.at(1,2,2)*s.at(1,2)-t.at(1,2,3)*s.at(1,3),
0454 t.at(2,2,0)*s.at(1,0)-t.at(2,2,1)*s.at(1,1)
0455 -t.at(2,2,2)*s.at(1,2)-t.at(2,2,3)*s.at(1,3),
0456 t.at(3,2,0)*s.at(1,0)-t.at(3,2,1)*s.at(1,1)
0457 -t.at(3,2,2)*s.at(1,2)-t.at(3,2,3)*s.at(1,3),
0458 t.at(0,3,0)*s.at(1,0)-t.at(0,3,1)*s.at(1,1)
0459 -t.at(0,3,2)*s.at(1,2)-t.at(0,3,3)*s.at(1,3),
0460 t.at(1,3,0)*s.at(1,0)-t.at(1,3,1)*s.at(1,1)
0461 -t.at(1,3,2)*s.at(1,2)-t.at(1,3,3)*s.at(1,3),
0462 t.at(2,3,0)*s.at(1,0)-t.at(2,3,1)*s.at(1,1)
0463 -t.at(2,3,2)*s.at(1,2)-t.at(2,3,3)*s.at(1,3),
0464 t.at(3,3,0)*s.at(1,0)-t.at(3,3,1)*s.at(1,1)
0465 -t.at(3,3,2)*s.at(1,2)-t.at(3,3,3)*s.at(1,3),
0466
0467 t.at(0,0,0)*s.at(2,0)-t.at(0,0,1)*s.at(2,1)
0468 -t.at(0,0,2)*s.at(2,2)-t.at(0,0,3)*s.at(2,3),
0469 t.at(1,0,0)*s.at(2,0)-t.at(1,0,1)*s.at(2,1)
0470 -t.at(1,0,2)*s.at(2,2)-t.at(1,0,3)*s.at(2,3),
0471 t.at(2,0,0)*s.at(2,0)-t.at(2,0,1)*s.at(2,1)
0472 -t.at(2,0,2)*s.at(2,2)-t.at(2,0,3)*s.at(2,3),
0473 t.at(3,0,0)*s.at(2,0)-t.at(3,0,1)*s.at(2,1)
0474 -t.at(3,0,2)*s.at(2,2)-t.at(3,0,3)*s.at(2,3),
0475 t.at(0,1,0)*s.at(2,0)-t.at(0,1,1)*s.at(2,1)
0476 -t.at(0,1,2)*s.at(2,2)-t.at(0,1,3)*s.at(2,3),
0477 t.at(1,1,0)*s.at(2,0)-t.at(1,1,1)*s.at(2,1)
0478 -t.at(1,1,2)*s.at(2,2)-t.at(1,1,3)*s.at(2,3),
0479 t.at(2,1,0)*s.at(2,0)-t.at(2,1,1)*s.at(2,1)
0480 -t.at(2,1,2)*s.at(2,2)-t.at(2,1,3)*s.at(2,3),
0481 t.at(3,1,0)*s.at(2,0)-t.at(3,1,1)*s.at(2,1)
0482 -t.at(3,1,2)*s.at(2,2)-t.at(3,1,3)*s.at(2,3),
0483 t.at(0,2,0)*s.at(2,0)-t.at(0,2,1)*s.at(2,1)
0484 -t.at(0,2,2)*s.at(2,2)-t.at(0,2,3)*s.at(2,3),
0485 t.at(1,2,0)*s.at(2,0)-t.at(1,2,1)*s.at(2,1)
0486 -t.at(1,2,2)*s.at(2,2)-t.at(1,2,3)*s.at(2,3),
0487 t.at(2,2,0)*s.at(2,0)-t.at(2,2,1)*s.at(2,1)
0488 -t.at(2,2,2)*s.at(2,2)-t.at(2,2,3)*s.at(2,3),
0489 t.at(3,2,0)*s.at(2,0)-t.at(3,2,1)*s.at(2,1)
0490 -t.at(3,2,2)*s.at(2,2)-t.at(3,2,3)*s.at(2,3),
0491 t.at(0,3,0)*s.at(2,0)-t.at(0,3,1)*s.at(2,1)
0492 -t.at(0,3,2)*s.at(2,2)-t.at(0,3,3)*s.at(2,3),
0493 t.at(1,3,0)*s.at(2,0)-t.at(1,3,1)*s.at(2,1)
0494 -t.at(1,3,2)*s.at(2,2)-t.at(1,3,3)*s.at(2,3),
0495 t.at(2,3,0)*s.at(2,0)-t.at(2,3,1)*s.at(2,1)
0496 -t.at(2,3,2)*s.at(2,2)-t.at(2,3,3)*s.at(2,3),
0497 t.at(3,3,0)*s.at(2,0)-t.at(3,3,1)*s.at(2,1)
0498 -t.at(3,3,2)*s.at(2,2)-t.at(3,3,3)*s.at(2,3),
0499
0500 t.at(0,0,0)*s.at(3,0)-t.at(0,0,1)*s.at(3,1)
0501 -t.at(0,0,2)*s.at(3,2)-t.at(0,0,3)*s.at(3,3),
0502 t.at(1,0,0)*s.at(3,0)-t.at(1,0,1)*s.at(3,1)
0503 -t.at(1,0,2)*s.at(3,2)-t.at(1,0,3)*s.at(3,3),
0504 t.at(2,0,0)*s.at(3,0)-t.at(2,0,1)*s.at(3,1)
0505 -t.at(2,0,2)*s.at(3,2)-t.at(2,0,3)*s.at(3,3),
0506 t.at(3,0,0)*s.at(3,0)-t.at(3,0,1)*s.at(3,1)
0507 -t.at(3,0,2)*s.at(3,2)-t.at(3,0,3)*s.at(3,3),
0508 t.at(0,1,0)*s.at(3,0)-t.at(0,1,1)*s.at(3,1)
0509 -t.at(0,1,2)*s.at(3,2)-t.at(0,1,3)*s.at(3,3),
0510 t.at(1,1,0)*s.at(3,0)-t.at(1,1,1)*s.at(3,1)
0511 -t.at(1,1,2)*s.at(3,2)-t.at(1,1,3)*s.at(3,3),
0512 t.at(2,1,0)*s.at(3,0)-t.at(2,1,1)*s.at(3,1)
0513 -t.at(2,1,2)*s.at(3,2)-t.at(2,1,3)*s.at(3,3),
0514 t.at(3,1,0)*s.at(3,0)-t.at(3,1,1)*s.at(3,1)
0515 -t.at(3,1,2)*s.at(3,2)-t.at(3,1,3)*s.at(3,3),
0516 t.at(0,2,0)*s.at(3,0)-t.at(0,2,1)*s.at(3,1)
0517 -t.at(0,2,2)*s.at(3,2)-t.at(0,2,3)*s.at(3,3),
0518 t.at(1,2,0)*s.at(3,0)-t.at(1,2,1)*s.at(3,1)
0519 -t.at(1,2,2)*s.at(3,2)-t.at(1,2,3)*s.at(3,3),
0520 t.at(2,2,0)*s.at(3,0)-t.at(2,2,1)*s.at(3,1)
0521 -t.at(2,2,2)*s.at(3,2)-t.at(2,2,3)*s.at(3,3),
0522 t.at(3,2,0)*s.at(3,0)-t.at(3,2,1)*s.at(3,1)
0523 -t.at(3,2,2)*s.at(3,2)-t.at(3,2,3)*s.at(3,3),
0524 t.at(0,3,0)*s.at(3,0)-t.at(0,3,1)*s.at(3,1)
0525 -t.at(0,3,2)*s.at(3,2)-t.at(0,3,3)*s.at(3,3),
0526 t.at(1,3,0)*s.at(3,0)-t.at(1,3,1)*s.at(3,1)
0527 -t.at(1,3,2)*s.at(3,2)-t.at(1,3,3)*s.at(3,3),
0528 t.at(2,3,0)*s.at(3,0)-t.at(2,3,1)*s.at(3,1)
0529 -t.at(2,3,2)*s.at(3,2)-t.at(2,3,3)*s.at(3,3),
0530 t.at(3,3,0)*s.at(3,0)-t.at(3,3,1)*s.at(3,1)
0531 -t.at(3,3,2)*s.at(3,2)-t.at(3,3,3)*s.at(3,3));
0532
0533 }
0534
0535 template<typename Scal1, typename Scal2>
0536 Vec4<PROMOTE(Scal1,Scal2)>
0537 ATOOLS::Contraction(const Lorentz_Ten4<Scal1>& ten, int i, int j, int k,
0538 const Lorentz_Ten3<Scal2>& sen, int l, int m, int n) {
0539
0540
0541 if ((i!=2) && (j!=3) && (k!=4) && (l!=2) && (m!=3) && (n!=4)) {
0542 THROW(fatal_error,"tensor contraction not specified for these indizes ...");
0543 }
0544 Vec4<PROMOTE(Scal1,Scal2)> end;
0545 for (unsigned short int I=0; I<4; ++I) {
0546 PROMOTE(Scal1,Scal2) res(ten.at(0,0,0,0)-ten.at(0,0,0,0));
0547 for (unsigned short int a=0; a<4; ++a)
0548 for (unsigned short int b=0; b<4; ++b)
0549 for (unsigned short int c=0; c<4; ++c) {
0550 double ga(-1.),gb(-1.),gc(-1.);
0551 if (a==0) ga=1.; if (b==0) gb=1.; if (c==0) gc=1.;
0552 res += ga*gb*gc*ten.at(I,a,b,c)*sen.at(a,b,c);
0553 }
0554 end[I] = res;
0555 }
0556 return end;
0557 }
0558
0559 template<typename Scal1, typename Scal2>
0560 Lorentz_Ten3<PROMOTE(Scal1,Scal2)>
0561 ATOOLS::Contraction(const Lorentz_Ten4<Scal1>& ten, int i, int j,
0562 const Lorentz_Ten3<Scal2>& sen, int k, int l) {
0563
0564
0565 if ((i!=3) && (j!=4) && (k!=3) && (l!=4)) {
0566 THROW(fatal_error,"tensor contraction not specified for these indizes ...");
0567 }
0568 Vec4<PROMOTE(Scal1,Scal2)> end;
0569 for (unsigned short int I=0; I<4; ++I)
0570 for (unsigned short int J=0; J<4; ++J)
0571 for (unsigned short int K=0; K<4; ++K) {
0572 PROMOTE(Scal1,Scal2) res(ten.at(0,0,0,0)-ten.at(0,0,0,0));
0573 for (unsigned short int a=0; a<4; ++a)
0574 for (unsigned short int b=0; b<4; ++b) {
0575 double ga(-1.),gb(-1.);
0576 if (a==0) ga=1.; if (b==0) gb=1.;
0577 res += ga*gb*ten.at(I,J,a,b)*sen.at(K,a,b);
0578 }
0579 end.at(I,J,K) = res;
0580 }
0581 return end;
0582 }
0583
0584 template<typename Scal1, typename Scal2>
0585 PROMOTE(Scal1,Scal2)
0586 ATOOLS::Contraction(const Lorentz_Ten4<Scal1>& ten, int i, int j, int k, int l,
0587 const Lorentz_Ten4<Scal2>& sen, int m, int n, int o, int p) {
0588 Lorentz_Ten4<Scal1> t; Lorentz_Ten4<Scal2> s;
0589
0590
0591 if ((i==m) && (j==n) && (k==o) && (l==p))
0592 {t=ten; s=sen;}
0593 else if ((i==m) && (j==n) && (k==p) && (l==o))
0594 {t=ten; s=sen.Transpose(3,4);}
0595 else if ((i==m) && (j==o) && (k==n) && (l==p))
0596 {t=ten; s=sen.Transpose(2,3);}
0597 else if ((i==m) && (j==o) && (k==p) && (l==n))
0598 {t=ten; s=sen.Transpose(3,4); s=s.Transpose(2,3);}
0599 else if ((i==n) && (j==m) && (k==o) && (l==p))
0600 {t=ten; s=sen.Transpose(1,2);}
0601 else if ((i==n) && (j==m) && (k==p) && (l==o))
0602 {t=ten; s=sen.Transpose(1,2); s=s.Transpose(3,4);}
0603 else if ((i==n) && (j==o) && (k==m) && (l==p))
0604 {t=ten; s=sen.Transpose(1,3); s=s.Transpose(2,3);}
0605 else if ((i==n) && (j==o) && (k==p) && (l==m))
0606 {t=ten; s=sen.Transpose(3,4); s=s.Transpose(2,3); s=s.Transpose(1,2);}
0607 else if ((i==n) && (j==p) && (k==m) && (l==o))
0608 {t=ten; s=sen.Transpose(1,3); s=s.Transpose(2,4); s=s.Transpose(2,3);}
0609 else if ((i==n) && (j==p) && (k==o) && (l==m))
0610 {t=ten; s=sen.Transpose(2,4); s=s.Transpose(1,2);}
0611 else if ((i==o) && (j==m) && (k==n) && (l==p))
0612 {t=ten; s=sen.Transpose(1,2); s=s.Transpose(2,3);}
0613 else if ((i==o) && (j==m) && (k==p) && (l==n))
0614 {t=ten; s=sen.Transpose(1,2); s=s.Transpose(2,3); s=s.Transpose(2,4);}
0615 else if ((i==o) && (j==n) && (k==m) && (l==p))
0616 {t=ten; s=sen.Transpose(1,3);}
0617 else if ((i==o) && (j==n) && (k==p) && (l==m))
0618 {t=ten; s=sen.Transpose(1,4); s=s.Transpose(3,4);}
0619 else if ((i==o) && (j==p) && (k==m) && (l==n))
0620 {t=ten; s=sen.Transpose(1,3); s=s.Transpose(2,4);}
0621 else if ((i==o) && (j==p) && (k==n) && (l==m))
0622 {t=ten; s=sen.Transpose(1,4); s=s.Transpose(2,3); s=s.Transpose(3,4);}
0623 else if ((i==p) && (j==m) && (k==n) && (l==o))
0624 {t=ten; s=sen.Transpose(1,2); s=s.Transpose(2,3); s=s.Transpose(3,4);}
0625 else if ((i==p) && (j==m) && (k==o) && (l==n))
0626 {t=ten; s=sen.Transpose(1,2); s=s.Transpose(2,4);}
0627 else if ((i==p) && (j==n) && (k==m) && (l==o))
0628 {t=ten; s=sen.Transpose(1,3); s=s.Transpose(3,4);}
0629 else if ((i==p) && (j==n) && (k==o) && (l==m))
0630 {t=ten; s=sen.Transpose(1,4);}
0631 else if ((i==p) && (j==o) && (k==m) && (l==n))
0632 {t=ten; s=sen.Transpose(1,3); s=s.Transpose(2,4); s=s.Transpose(3,4);}
0633 else if ((i==p) && (j==o) && (k==n) && (l==m))
0634 {t=ten; s=sen.Transpose(1,4); s=s.Transpose(2,3);}
0635 else
0636 return PROMOTE(Scal1,Scal2)();
0637 PROMOTE(Scal1,Scal2) res(ten.at(0,0,0,0)-ten.at(0,0,0,0));
0638 for (unsigned short int a=0; a<4; ++a)
0639 for (unsigned short int b=0; b<4; ++b)
0640 for (unsigned short int c=0; c<4; ++c)
0641 for (unsigned short int d=0; d<4; ++d) {
0642 double ga(-1.),gb(-1.),gc(-1.),gd(-1.);
0643 if (a==0) ga=1.; if (b==0) gb=1.; if (c==0) gc=1.; if (d==0) gd=1.;
0644 res += ga*gb*gc*gd*t.at(a,b,c,d)*s.at(a,b,c,d);
0645 }
0646 return res;
0647 }
0648
0649 template<typename Scal1, typename Scal2>
0650 Lorentz_Ten2<PROMOTE(Scal1,Scal2)>
0651 ATOOLS::Contraction(const Lorentz_Ten4<Scal1>& ten, int i, int j, int k,
0652 const Lorentz_Ten4<Scal2>& sen, int l, int m, int n) {
0653 Lorentz_Ten4<Scal1> t; Lorentz_Ten4<Scal2> s;
0654
0655
0656 if (((i==l) && (j==m) && (k==n)) && ((i==2) && (j==3) && (k==4)))
0657 {t=ten; s=sen;}
0658 else if (((i==l) && (j==m) && (k==n)) && ((i==1) && (j==3) && (k==4)))
0659 {t=ten.Transpose(1,2); s=sen.Transpose(1,2);}
0660 else if (((i==l) && (j==m) && (k==n)) && ((i==1) && (j==2) && (k==4)))
0661 {t=ten.Transpose(1,3); s=sen.Transpose(1,3);}
0662 else if (((i==l) && (j==m) && (k==n)) && ((i==1) && (j==2) && (k==3)))
0663 {t=ten.Transpose(1,4); s=sen.Transpose(1,4);}
0664
0665 else if (((i==l) && (j==n) && (k==m)) && ((i==2) && (j==3) && (k==4)))
0666 {t=ten; s=sen.Transpose(3,4);}
0667 else if (((i==l) && (j==n) && (k==m)) && ((i==1) && (j==3) && (k==4)))
0668 {t=ten.Transpose(1,2); s=sen.Transpose(1,2); s=s.Transpose(3,4);}
0669 else if (((i==l) && (j==n) && (k==m)) && ((i==1) && (j==2) && (k==4)))
0670 {t=ten.Transpose(1,3); s=sen.Transpose(1,3); s=s.Transpose(2,4);}
0671 else if (((i==l) && (j==n) && (k==m)) && ((i==1) && (j==2) && (k==3)))
0672 {t=ten.Transpose(1,4); s=sen.Transpose(1,4); s=s.Transpose(2,3);}
0673
0674 else if (((i==m) && (j==l) && (k==n)) && ((i==2) && (j==3) && (k==4)))
0675 {t=ten; s=sen.Transpose(2,3);}
0676 else if (((i==m) && (j==l) && (k==n)) && ((i==1) && (j==3) && (k==4)))
0677 {t=ten.Transpose(1,2); s=sen.Transpose(1,2); s=s.Transpose(2,3);}
0678 else if (((i==m) && (j==l) && (k==n)) && ((i==1) && (j==2) && (k==4)))
0679 {t=ten.Transpose(1,3); s=sen.Transpose(1,3); s=s.Transpose(2,3);}
0680 else if (((i==m) && (j==l) && (k==n)) && ((i==1) && (j==2) && (k==3)))
0681 {t=ten.Transpose(1,4); s=sen.Transpose(1,4); s=s.Transpose(2,4);}
0682
0683 else if (((i==m) && (j==n) && (k==l)) && ((i==2) && (j==3) && (k==4)))
0684 {t=ten; s=sen.Transpose(2,4); s=s.Transpose(3,4);}
0685 else if (((i==m) && (j==n) && (k==l)) && ((i==1) && (j==3) && (k==4)))
0686 {t=ten.Transpose(1,2); s=sen.Transpose(1,2); s=s.Transpose(2,4); s=s.Transpose(3,4);}
0687 else if (((i==m) && (j==n) && (k==l)) && ((i==1) && (j==2) && (k==4)))
0688 {t=ten.Transpose(1,3); s=sen.Transpose(1,3); s=s.Transpose(2,4); s=s.Transpose(2,3);}
0689 else if (((i==m) && (j==n) && (k==l)) && ((i==1) && (j==2) && (k==3)))
0690 {t=ten.Transpose(1,4); s=sen.Transpose(1,4); s=s.Transpose(2,4); s=s.Transpose(3,4);}
0691
0692 else if (((i==n) && (j==l) && (k==m)) && ((i==2) && (j==3) && (k==4)))
0693 {t=ten; s=sen.Transpose(2,3); s=s.Transpose(3,4);}
0694 else if (((i==n) && (j==l) && (k==m)) && ((i==1) && (j==3) && (k==4)))
0695 {t=ten.Transpose(1,2); s=sen.Transpose(1,2); s=s.Transpose(2,3); s=s.Transpose(3,4);}
0696 else if (((i==n) && (j==l) && (k==m)) && ((i==1) && (j==2) && (k==4)))
0697 {t=ten.Transpose(1,3); s=sen.Transpose(1,3); s=s.Transpose(3,4); s=s.Transpose(2,3);}
0698 else if (((i==n) && (j==l) && (k==m)) && ((i==1) && (j==2) && (k==3)))
0699 {t=ten.Transpose(1,4); s=sen.Transpose(1,4); s=s.Transpose(2,3); s=s.Transpose(3,4);}
0700
0701 else if (((i==n) && (j==m) && (k==l)) && ((i==2) && (j==3) && (k==4)))
0702 {t=ten; s=sen.Transpose(2,4);}
0703 else if (((i==n) && (j==m) && (k==l)) && ((i==1) && (j==3) && (k==4)))
0704 {t=ten.Transpose(1,2); s=sen.Transpose(1,2); s=s.Transpose(2,4);}
0705 else if (((i==n) && (j==m) && (k==l)) && ((i==1) && (j==2) && (k==4)))
0706 {t=ten.Transpose(1,3); s=sen.Transpose(1,3); s=s.Transpose(3,4);}
0707 else if (((i==n) && (j==m) && (k==l)) && ((i==1) && (j==2) && (k==3)))
0708 {t=ten.Transpose(1,4); s=sen.Transpose(1,4); s=s.Transpose(3,4);}
0709 else {
0710 THROW(fatal_error,"tensor contraction not specified for these indizes ...");
0711 return Lorentz_Ten2<PROMOTE(Scal1,Scal2)>();
0712 }
0713 Lorentz_Ten2<PROMOTE(Scal1,Scal2)> end;
0714 for (unsigned short int I=0; I<4; ++I)
0715 for (unsigned short int J=0; J<4; ++J) {
0716 PROMOTE(Scal1,Scal2) res(ten.at(0,0,0,0)-ten.at(0,0,0,0));
0717 for (unsigned short int a=0; a<4; ++a)
0718 for (unsigned short int b=0; b<4; ++b)
0719 for (unsigned short int c=0; c<4; ++c) {
0720 double ga(-1.),gb(-1.),gc(-1.);
0721 if (a==0) ga=1.; if (b==0) gb=1.; if (c==0) gc=1.;
0722 res += ga*gb*gc*t.at(I,a,b,c)*s.at(J,a,b,c);
0723 }
0724 end.at(I,J) = res;
0725 }
0726 return end;
0727 }
0728
0729 template<typename Scal1, typename Scal2>
0730 Lorentz_Ten4<PROMOTE(Scal1,Scal2)>
0731 ATOOLS::Contraction(const Lorentz_Ten4<Scal1>& ten, int i, int j,
0732 const Lorentz_Ten4<Scal2>& sen, int k, int l) {
0733
0734
0735 if ((i!=3) && (j!=4) && (k!=3) && (l!=4)) {
0736 THROW(fatal_error,"tensor contraction not specified for these indizes ...");
0737 return Lorentz_Ten4<PROMOTE(Scal1,Scal2)>();
0738 }
0739 Lorentz_Ten4<PROMOTE(Scal1,Scal2)> end;
0740 for (unsigned short int I=0; I<4; ++I)
0741 for (unsigned short int J=0; J<4; ++J)
0742 for (unsigned short int K=0; K<4; ++K)
0743 for (unsigned short int L=0; L<4; ++L) {
0744 PROMOTE(Scal1,Scal2) res(ten.at(0,0,0,0)-ten.at(0,0,0,0));
0745 for (unsigned short int a=0; a<4; ++a)
0746 for (unsigned short int b=0; b<4; ++b) {
0747 double ga(-1.),gb(-1.);
0748 if (a==0) ga=1.; if (b==0) gb=1.;
0749 res += ga*gb*ten.at(I,J,a,b)*sen.at(K,L,a,b);
0750 }
0751 end.at(I,J) = res;
0752 }
0753 return end;
0754 }
0755 #endif