diff --git a/src/Tensor.cc b/src/Tensor.cc index 4972e69..5aad2f4 100644 --- a/src/Tensor.cc +++ b/src/Tensor.cc @@ -1,766 +1,741 @@ /** * \authors The HEJ collaboration (see AUTHORS for details) * \date 2019 * \copyright GPLv2 or later */ #include "HEJ/Tensor.hh" #include <array> #include <iostream> #include <valarray> #include <CLHEP/Vector/LorentzVector.h> #include "HEJ/currents.hh" // only for CCurrent (?) namespace HEJ { namespace{ // Tensor Template definitions short int sigma_index5[1024]; short int sigma_index3[64]; std::valarray<COM> permfactor5; std::valarray<COM> permfactor3; short int helfactor5[2][1024]; short int helfactor3[2][64]; // 2D sigma matrices const COM sigma0[2][2] = { {1.,0.}, {0., 1.} }; const COM sigma1[2][2] = { {0.,1.}, {1., 0.} }; const COM sigma2[2][2] = { {0,-1.*COM(0,1)}, {1.*COM(0,1), 0.} }; const COM sigma3[2][2] = { {1.,0.}, {0., -1.} }; // map from a list of tensor lorentz indices onto a single index // in d dimensional spacetime // TODO: basically the same as detail::accumulate_idx template<std::size_t N> std::size_t tensor_to_list_idx(std::array<int, N> const & indices) { std::size_t list_idx = 0; for(std::size_t i = 1, factor = 1; i <= N; ++i) { list_idx += factor*indices[N-i]; factor *= detail::d; } assert(list_idx < (1u << 2*N)); return list_idx; } // generate all unique perms of vectors {a,a,a,a,b}, return in perms // set_permfactor is a bool which encodes the anticommutation relations of the // sigma matrices namely if we have sigma0, set_permfactor= false because it // commutes with all others otherwise we need to assign a minus sign to odd // permutations, set in permfactor // note, inital perm is always even void perms41(int same4, int diff, std::vector<std::array<int,5>> & perms){ bool set_permfactor(true); if(same4==0||diff==0) set_permfactor=false; for(int diffpos=0;diffpos<5;diffpos++){ std::array<int,5> tempvec={same4,same4,same4,same4,same4}; tempvec[diffpos]=diff; perms.push_back(tempvec); if(set_permfactor){ if(diffpos%2==1) permfactor5[tensor_to_list_idx(tempvec)]=-1.; } } } // generate all unique perms of vectors {a,a,a,b,b}, return in perms // note, inital perm is always even void perms32(int same3, int diff, std::vector<std::array<int,5>> & perms){ bool set_permfactor(true); if(same3==0||diff==0) set_permfactor=false; for(int diffpos1=0;diffpos1<5;diffpos1++){ for(int diffpos2=diffpos1+1;diffpos2<5;diffpos2++){ std::array<int,5> tempvec={same3,same3,same3,same3,same3}; tempvec[diffpos1]=diff; tempvec[diffpos2]=diff; perms.push_back(tempvec); if(set_permfactor){ if((diffpos2-diffpos1)%2==0) permfactor5[tensor_to_list_idx(tempvec)]=-1.; } } } } // generate all unique perms of vectors {a,a,a,b,c}, return in perms // we have two bools since there are three distinct type of sigma matrices to // permute, so need to test if the 3xrepeated = sigma0 or if one of the // singles is sigma0 // if diff1/diff2 are distinct, flipping them results in a change of perm, // otherwise it'll be symmetric under flip -> encode this in set_permfactor2 // as long as diff2!=0 can ensure inital perm is even // if diff2=0 then it is not possible to ensure inital perm even -> encode in // bool signflip void perms311(int same3, int diff1, int diff2, std::vector<std::array<int,5>> & perms ){ bool set_permfactor2(true); bool same0(false); bool diff0(false); bool signflip(false); // if true, inital perm is odd if(same3==0) // is the repeated matrix sigma0? same0 = true; else if(diff2==0){ // is one of the single matrices sigma0 diff0=true; if((diff1%3-same3)!=-1) signflip=true; } else if(diff1==0){ std::cerr<<"Note, only first and last argument may be zero"<<std::endl; return; } // possible outcomes: tt, ft, tf for(int diffpos1=0;diffpos1<5;diffpos1++){ for(int diffpos2=diffpos1+1;diffpos2<5;diffpos2++){ std::array<int,5> tempvec={same3,same3,same3,same3,same3}; tempvec[diffpos1]=diff1; tempvec[diffpos2]=diff2; perms.push_back(tempvec); if(!same0 && !diff0){ // full antisymmetric under exchange of same3,diff1,diff2 if((diffpos2-diffpos1)%2==0){ permfactor5[tensor_to_list_idx(tempvec)]=-1.*COM(0,1); // odd perm // if this perm is odd, swapping diff1<->diff2 automatically even set_permfactor2=false; } else { permfactor5[tensor_to_list_idx(tempvec)]=COM(0,1); // even perm // if this perm is even, swapping diff1<->diff2 automatically odd set_permfactor2=true; } } else if(diff0){// one of the single matrices is sigma0 if(signflip){ // initial config is odd! if(diffpos1%2==1){ permfactor5[tensor_to_list_idx(tempvec)]=COM(0,1); // even perm // initally symmetric under diff1<->diff2 => // if this perm is even, automatically even for first diffpos2 set_permfactor2=false; } else { permfactor5[tensor_to_list_idx(tempvec)]=-1.*COM(0,1); // odd perm // initally symmetric under diff1<->diff2 => // if this perm is odd, automatically odd for first diffpos2 set_permfactor2=true; } } else {// diff0=true, initial config is even if(diffpos1%2==1){ permfactor5[tensor_to_list_idx(tempvec)]=-1.*COM(0,1); // odd perm // initally symmetric under diff1<->diff2 => // if this perm is odd, automatically odd for first diffpos2 set_permfactor2=true; } else { permfactor5[tensor_to_list_idx(tempvec)]=COM(0,1); // even perm // initally symmetric under diff1<->diff2 => // if this perm is even, automatically even for first diffpos2 set_permfactor2=false; } } if((diffpos2-diffpos1-1)%2==1) set_permfactor2=!set_permfactor2; // change to account for diffpos2 } else if(same0){ // the repeated matrix is sigma0 // => only relative positions of diff1, diff2 matter. // always even before flip because diff1pos<diff2pos permfactor5[tensor_to_list_idx(tempvec)]=COM(0,1); // if this perm is odd, swapping diff1<->diff2 automatically odd set_permfactor2=true; } tempvec[diffpos1]=diff2; tempvec[diffpos2]=diff1; perms.push_back(tempvec); if(set_permfactor2) permfactor5[tensor_to_list_idx(tempvec)]=-1.*COM(0,1); else permfactor5[tensor_to_list_idx(tempvec)]=COM(0,1); } } } // end perms311 // generate all unique perms of vectors {a,a,b,b,c}, return in perms void perms221(int same2a, int same2b, int diff, std::vector<std::array<int,5>> & perms ){ bool set_permfactor1(true); bool set_permfactor2(true); if(same2b==0){ std::cerr<<"second entry in perms221() shouldn't be zero" <<std::endl; return; } else if(same2a==0) set_permfactor1=false; else if(diff==0) set_permfactor2=false; for(int samepos=0;samepos<5;samepos++){ int permcount = 0; for(int samepos2=samepos+1;samepos2<5;samepos2++){ for(int diffpos=0;diffpos<5;diffpos++){ if(diffpos==samepos||diffpos==samepos2) continue; std::array<int,5> tempvec={same2a,same2a,same2a,same2a,same2a}; tempvec[samepos]=same2b; tempvec[samepos2]=same2b; tempvec[diffpos]=diff; perms.push_back(tempvec); if(set_permfactor1){ if(set_permfactor2){// full anti-symmetry if(permcount%2==1) permfactor5[tensor_to_list_idx(tempvec)]=-1.; } else { // diff is sigma0 if( ((samepos2-samepos-1)%3>0) && (abs(abs(samepos2-diffpos)-abs(samepos-diffpos))%3>0) ) permfactor5[tensor_to_list_idx(tempvec)]=-1.; } } else { // same2a is sigma0 if((diffpos>samepos) && (diffpos<samepos2)) permfactor5[tensor_to_list_idx(tempvec)]=-1.; } permcount++; } } } } // generate all unique perms of vectors {a,a,b,b,c}, return in perms // there must be a sigma zero if we have 4 different matrices in string // bool is true if sigma0 is the repeated matrix void perms2111(int same2, int diff1,int diff2,int diff3, std::vector<std::array<int,5>> & perms ){ bool twozero(false); if(same2==0) twozero=true; else if (diff1!=0){ std::cerr<<"One of first or second argurments must be a zero"<<std::endl; return; } else if(diff2==0|| diff3==0){ std::cerr<<"Only first and second arguments may be a zero."<<std::endl; return; } int permcount = 0; for(int diffpos1=0;diffpos1<5;diffpos1++){ for(int diffpos2=0;diffpos2<5;diffpos2++){ if(diffpos2==diffpos1) continue; for(int diffpos3=0;diffpos3<5;diffpos3++){ if(diffpos3==diffpos2||diffpos3==diffpos1) continue; std::array<int,5> tempvec={same2,same2,same2,same2,same2}; tempvec[diffpos1]=diff1; tempvec[diffpos2]=diff2; tempvec[diffpos3]=diff3; perms.push_back(tempvec); if(twozero){// don't care about exact positions of singles, just order if(diffpos2>diffpos3 && diffpos3>diffpos1) permfactor5[tensor_to_list_idx(tempvec)]=-1.*COM(0,1);// odd else if(diffpos1>diffpos2 && diffpos2>diffpos3) permfactor5[tensor_to_list_idx(tempvec)]=-1.*COM(0,1);// odd else if(diffpos3>diffpos1 && diffpos1>diffpos2) permfactor5[tensor_to_list_idx(tempvec)]=-1.*COM(0,1);// odd else permfactor5[tensor_to_list_idx(tempvec)]=COM(0,1);// evwn } else { if(permcount%2==1) permfactor5[tensor_to_list_idx(tempvec)]=-1.*COM(0,1); else permfactor5[tensor_to_list_idx(tempvec)]=COM(0,1); } permcount++; } } } } void perms21(int same, int diff, std::vector<std::array<int,3>> & perms){ bool set_permfactor(true); if(same==0||diff==0) set_permfactor=false; for(int diffpos=0; diffpos<3;diffpos++){ std::array<int,3> tempvec={same,same,same}; tempvec[diffpos]=diff; perms.push_back(tempvec); if(set_permfactor && diffpos==1) permfactor3[tensor_to_list_idx(tempvec)]=-1.; } } void perms111(int diff1, int diff2, int diff3, std::vector<std::array<int,3>> & perms ){ bool sig_zero(false); if(diff1==0) sig_zero=true; else if(diff2==0||diff3==0){ std::cerr<<"Only first argument may be a zero."<<std::endl; return; } int permcount=0; for(int pos1=0;pos1<3;pos1++){ for(int pos2=pos1+1;pos2<3;pos2++){ std::array<int,3> tempvec={diff1,diff1,diff1}; tempvec[pos1]=diff2; tempvec[pos2]=diff3; perms.push_back(tempvec); if(sig_zero){ permfactor3[tensor_to_list_idx(tempvec)]=1.*COM(0,1); // even } else if(permcount%2==1){ permfactor3[tensor_to_list_idx(tempvec)]=-1.*COM(0,1); // odd } else { permfactor3[tensor_to_list_idx(tempvec)]=1.*COM(0,1); // even } tempvec[pos1]=diff3; tempvec[pos2]=diff2; perms.push_back(tempvec); if(sig_zero){ permfactor3[tensor_to_list_idx(tempvec)]=-1.*COM(0,1); // odd } else if(permcount%2==1){ permfactor3[tensor_to_list_idx(tempvec)]=1.*COM(0,1); // even } else { permfactor3[tensor_to_list_idx(tempvec)]=-1.*COM(0,1); // odd } permcount++; } } } void SpinorO(CLHEP::HepLorentzVector p, Helicity hel, COM *sp){ // sp is pointer to COM sp[2] COM pplus = p.e() +p.z(); COM pminus = p.e() -p.z(); COM sqpp= sqrt(pplus); COM sqpm= sqrt(pminus); COM pperp = p.x() + COM(0,1)*p.y(); if(hel == helicity::plus){ sp[0] = sqpp; sp[1] = sqpm*pperp/abs(pperp); } else { sp[0] = sqpm*conj(pperp)/abs(pperp); sp[1] = -sqpp; } } void SpinorIp(COM sqpp, Helicity hel, COM *sp){ // if hel=+ if(hel == helicity::plus){ sp[0] = sqpp; sp[1] = 0.; } else { sp[0] = 0.; sp[1] = -sqpp; } } void SpinorIm(COM sqpm, Helicity hel, COM *sp){ // if hel=+ if(hel == helicity::plus){ sp[0] = 0; sp[1] = -sqpm; } else { sp[0] = -sqpm; sp[1] = 0.; } } void Spinor(CLHEP::HepLorentzVector p, Helicity hel, COM *sp){ COM pplus = p.e() +p.z(); COM pminus = p.e() -p.z(); // If incoming along +ve z if (pminus==0.){ COM sqpp= sqrt(pplus); SpinorIp(sqpp,hel,sp); } // If incoming along -ve z else if(pplus==0.){ COM sqpm= sqrt(pminus); SpinorIm(sqpm,hel,sp); } // Outgoing else { SpinorO(p,hel,sp); } } COM perp(CLHEP::HepLorentzVector p) { return COM{p.x(), p.y()}; } } // anonymous namespace Tensor<2> metric(){ static const Tensor<2> g = [](){ Tensor<2> g(0.); g(0,0) = 1.; g(1,1) = -1.; g(2,2) = -1.; g(3,3) = -1.; return g; }(); return g; } // <1|mu|2> // see eqs. (48), (49) in developer manual Tensor<1> current( CLHEP::HepLorentzVector const & p, CLHEP::HepLorentzVector const & q, Helicity h ){ using namespace helicity; const COM p_perp = perp(p); const COM q_perp = perp(q); const COM p_perp_hat = (p_perp != COM{0., 0.})?p_perp/std::abs(p_perp):-1.; const COM q_perp_hat = (q_perp != COM{0., 0.})?q_perp/std::abs(q_perp):-1.; std::array<std::array<COM, 2>, 2> sqrt_pq; sqrt_pq[minus][minus] = std::sqrt(p.minus()*q.minus())*p_perp_hat*conj(q_perp_hat); sqrt_pq[minus][plus] = std::sqrt(p.minus()*q.plus())*p_perp_hat; sqrt_pq[plus][minus] = std::sqrt(p.plus()*q.minus())*conj(q_perp_hat); sqrt_pq[plus][plus] = std::sqrt(p.plus()*q.plus()); Tensor<1> j; j(0) = sqrt_pq[plus][plus] + sqrt_pq[minus][minus]; j(1) = sqrt_pq[plus][minus] + sqrt_pq[minus][plus]; j(2) = COM{0., 1.}*(sqrt_pq[plus][minus] - sqrt_pq[minus][plus]); j(3) = sqrt_pq[plus][plus] - sqrt_pq[minus][minus]; return (h == minus)?j:j.complex_conj(); } // <1|mu nu sigma|2> + // TODO: how does this work? Tensor<3> rank3_current( CLHEP::HepLorentzVector const & p1, CLHEP::HepLorentzVector const & p2, Helicity h ){ + const CLHEP::HepLorentzVector p1new{ p1.e()<0?-p1:p1 }; + const CLHEP::HepLorentzVector p2new{ p2.e()<0?-p2:p2 }; - COM sp1[2]; - COM sp2[2]; - - Tensor<3> newT(0.); - - CLHEP::HepLorentzVector p1new{ p1.e()<0?-p1:p1 }; - CLHEP::HepLorentzVector p2new{ p2.e()<0?-p2:p2 }; - - Spinor(p1new, h, sp1); - Spinor(p2new, h, sp2); - - COM current[4]; - - for(int i=0; i<2;i++){ - for(int j=0; j<2;j++){ - current[0]+=conj(sp1[i])*sigma0[i][j]*sp2[j]; - current[1]+=conj(sp1[i])*sigma1[i][j]*sp2[j]; - current[2]+=conj(sp1[i])*sigma2[i][j]*sp2[j]; - current[3]+=conj(sp1[i])*sigma3[i][j]*sp2[j]; - } + auto j = HEJ::current(p1new, p2new, h); + if(h == helicity::minus) { + j *= -1; + j(0) *= -1; } - for( std::size_t itensor=0; itensor<newT.size(); itensor++ ){ - double hfact = double( helfactor3[h][itensor] ); - newT.components[itensor] = current[sigma_index3[itensor]] * hfact - * permfactor3[itensor]; + Tensor<3> j3; + for(std::size_t tensor_idx=0; tensor_idx < j3.size(); ++tensor_idx){ + const double hfact = helfactor3[h][tensor_idx]; + j3.components[tensor_idx] = j(sigma_index3[tensor_idx]) * hfact + * permfactor3[tensor_idx]; } - return newT; + return j3; } // <1|mu nu sigma tau rho|2> Tensor<5> rank5_current( CLHEP::HepLorentzVector const & p1, CLHEP::HepLorentzVector const & p2, Helicity h ){ + const CLHEP::HepLorentzVector p1new{ p1.e()<0?-p1:p1 }; + const CLHEP::HepLorentzVector p2new{ p2.e()<0?-p2:p2 }; - COM sp1[2]; - COM sp2[2]; - - Tensor<5> newT(0.); - - CLHEP::HepLorentzVector p1new{ p1.e()<0?-p1:p1 }; - CLHEP::HepLorentzVector p2new{ p2.e()<0?-p2:p2 }; - - Spinor(p1new, h, sp1); - Spinor(p2new, h, sp2); - - COM current[4]; - - for(int i=0; i<2;i++){ - for(int j=0; j<2;j++){ - current[0]+=conj(sp1[i])*sigma0[i][j]*sp2[j]; - current[1]+=conj(sp1[i])*sigma1[i][j]*sp2[j]; - current[2]+=conj(sp1[i])*sigma2[i][j]*sp2[j]; - current[3]+=conj(sp1[i])*sigma3[i][j]*sp2[j]; - } + auto j = HEJ::current(p1new, p2new, h); + if(h == helicity::minus) { + j *= -1; + j(0) *= -1; } - for(std::size_t itensor=0;itensor<newT.size();itensor++){ - double hfact = double(helfactor5[h][itensor]); - newT.components[itensor] = current[sigma_index5[itensor]] * hfact - * permfactor5[itensor]; + Tensor<5> j5; + for(std::size_t tensor_idx=0; tensor_idx < j5.size(); ++tensor_idx){ + const double hfact = helfactor5[h][tensor_idx]; + j5.components[tensor_idx] = j(sigma_index5[tensor_idx]) * hfact + * permfactor5[tensor_idx]; } - return newT; + return j5; } Tensor<1> Construct1Tensor(CCurrent j){ Tensor<1> newT; newT.components={j.c0,j.c1,j.c2,j.c3}; return newT; } Tensor<1> Construct1Tensor(CLHEP::HepLorentzVector p){ Tensor<1> newT; newT.components={p.e(),p.x(),p.y(),p.z()}; return newT; } Tensor<1> eps(CLHEP::HepLorentzVector k, CLHEP::HepLorentzVector ref, Helicity pol){ Tensor<1> polvec; COM spk[2]; COM spr[2]; COM denom; CLHEP::HepLorentzVector knew{ k.e()<0?-k:k }; Spinor(knew, pol, spk); Spinor(ref, flip(pol), spr); denom = pow(-1.,pol)*sqrt(2)*(conj(spr[0])*spk[0] + conj(spr[1])*spk[1]); polvec = current(ref,knew,flip(pol))/denom; return polvec; } // slow function! - but only need to evaluate once. bool init_sigma_index(){ // initialize permfactor(3) to list of ones (change to minus one for each odd // permutation and multiply by i for all permutations in perms2111, perms311, // perms111) permfactor5.resize(1024,1.); permfactor3.resize(64,1.); // first set sigma_index (5) std::vector<std::array<int,5>> sigma0indices; std::vector<std::array<int,5>> sigma1indices; std::vector<std::array<int,5>> sigma2indices; std::vector<std::array<int,5>> sigma3indices; // need to generate all possible permuations of {i,j,k,l,m} // where each index can be {0,1,2,3,4} // 1024 possibilities // perms with 5 same sigma0indices.push_back({0,0,0,0,0}); sigma1indices.push_back({1,1,1,1,1}); sigma2indices.push_back({2,2,2,2,2}); sigma3indices.push_back({3,3,3,3,3}); // perms with 4 same perms41(1,0,sigma0indices); perms41(2,0,sigma0indices); perms41(3,0,sigma0indices); perms41(0,1,sigma1indices); perms41(2,1,sigma1indices); perms41(3,1,sigma1indices); perms41(0,2,sigma2indices); perms41(1,2,sigma2indices); perms41(3,2,sigma2indices); perms41(0,3,sigma3indices); perms41(1,3,sigma3indices); perms41(2,3,sigma3indices); // perms with 3 same, 2 same perms32(0,1,sigma0indices); perms32(0,2,sigma0indices); perms32(0,3,sigma0indices); perms32(1,0,sigma1indices); perms32(1,2,sigma1indices); perms32(1,3,sigma1indices); perms32(2,0,sigma2indices); perms32(2,1,sigma2indices); perms32(2,3,sigma2indices); perms32(3,0,sigma3indices); perms32(3,1,sigma3indices); perms32(3,2,sigma3indices); // perms with 3 same, 2 different perms311(1,2,3,sigma0indices); perms311(2,3,1,sigma0indices); perms311(3,1,2,sigma0indices); perms311(0,2,3,sigma1indices); perms311(2,3,0,sigma1indices); perms311(3,2,0,sigma1indices); perms311(0,3,1,sigma2indices); perms311(1,3,0,sigma2indices); perms311(3,1,0,sigma2indices); perms311(0,1,2,sigma3indices); perms311(1,2,0,sigma3indices); perms311(2,1,0,sigma3indices); perms221(1,2,0,sigma0indices); perms221(1,3,0,sigma0indices); perms221(2,3,0,sigma0indices); perms221(0,2,1,sigma1indices); perms221(0,3,1,sigma1indices); perms221(2,3,1,sigma1indices); perms221(0,1,2,sigma2indices); perms221(0,3,2,sigma2indices); perms221(1,3,2,sigma2indices); perms221(0,1,3,sigma3indices); perms221(0,2,3,sigma3indices); perms221(1,2,3,sigma3indices); perms2111(0,1,2,3,sigma0indices); perms2111(1,0,2,3,sigma1indices); perms2111(2,0,3,1,sigma2indices); perms2111(3,0,1,2,sigma3indices); if(sigma0indices.size()!=256){ std::cerr<<"sigma_index not set: "; std::cerr<<"sigma0indices has "<< sigma0indices.size() << " components" << std::endl; return false; } else if(sigma1indices.size()!=256){ std::cerr<<"sigma_index not set: "; std::cerr<<"sigma1indices has "<< sigma0indices.size() << " components" << std::endl; return false; } else if(sigma2indices.size()!=256){ std::cerr<<"sigma_index not set: "; std::cerr<<"sigma2indices has "<< sigma0indices.size() << " components" << std::endl; return false; } else if(sigma3indices.size()!=256){ std::cerr<<"sigma_index not set: "; std::cerr<<"sigma3indices has "<< sigma0indices.size() << " components" << std::endl; return false; } for(int i=0;i<256;i++){ // map each unique set of tensor indices to its position in a list int index0 = tensor_to_list_idx(sigma0indices.at(i)); int index1 = tensor_to_list_idx(sigma1indices.at(i)); int index2 = tensor_to_list_idx(sigma2indices.at(i)); int index3 = tensor_to_list_idx(sigma3indices.at(i)); sigma_index5[index0]=0; sigma_index5[index1]=1; sigma_index5[index2]=2; sigma_index5[index3]=3; short int sign[4]={1,-1,-1,-1}; // plus->true->1 helfactor5[1][index0] = sign[sigma0indices.at(i)[1]] * sign[sigma0indices.at(i)[3]]; helfactor5[1][index1] = sign[sigma1indices.at(i)[1]] * sign[sigma1indices.at(i)[3]]; helfactor5[1][index2] = sign[sigma2indices.at(i)[1]] * sign[sigma2indices.at(i)[3]]; helfactor5[1][index3] = sign[sigma3indices.at(i)[1]] * sign[sigma3indices.at(i)[3]]; // minus->false->0 helfactor5[0][index0] = sign[sigma0indices.at(i)[0]] * sign[sigma0indices.at(i)[2]] * sign[sigma0indices.at(i)[4]]; helfactor5[0][index1] = sign[sigma1indices.at(i)[0]] * sign[sigma1indices.at(i)[2]] * sign[sigma1indices.at(i)[4]]; helfactor5[0][index2] = sign[sigma2indices.at(i)[0]] * sign[sigma2indices.at(i)[2]] * sign[sigma2indices.at(i)[4]]; helfactor5[0][index3] = sign[sigma3indices.at(i)[0]] * sign[sigma3indices.at(i)[2]] * sign[sigma3indices.at(i)[4]]; } // now set sigma_index3 std::vector<std::array<int,3>> sigma0indices3; std::vector<std::array<int,3>> sigma1indices3; std::vector<std::array<int,3>> sigma2indices3; std::vector<std::array<int,3>> sigma3indices3; // perms with 3 same sigma0indices3.push_back({0,0,0}); sigma1indices3.push_back({1,1,1}); sigma2indices3.push_back({2,2,2}); sigma3indices3.push_back({3,3,3}); // 2 same perms21(1,0,sigma0indices3); perms21(2,0,sigma0indices3); perms21(3,0,sigma0indices3); perms21(0,1,sigma1indices3); perms21(2,1,sigma1indices3); perms21(3,1,sigma1indices3); perms21(0,2,sigma2indices3); perms21(1,2,sigma2indices3); perms21(3,2,sigma2indices3); perms21(0,3,sigma3indices3); perms21(1,3,sigma3indices3); perms21(2,3,sigma3indices3); // none same perms111(1,2,3,sigma0indices3); perms111(0,2,3,sigma1indices3); perms111(0,3,1,sigma2indices3); perms111(0,1,2,sigma3indices3); if(sigma0indices3.size()!=16){ std::cerr<<"sigma_index3 not set: "; std::cerr<<"sigma0indices3 has "<< sigma0indices3.size() << " components" << std::endl; return false; } else if(sigma1indices3.size()!=16){ std::cerr<<"sigma_index3 not set: "; std::cerr<<"sigma1indices3 has "<< sigma0indices3.size() << " components" << std::endl; return false; } else if(sigma2indices3.size()!=16){ std::cerr<<"sigma_index3 not set: "; std::cerr<<"sigma2indices3 has "<< sigma0indices3.size() << " components" << std::endl; return false; } else if(sigma3indices3.size()!=16){ std::cerr<<"sigma_index3 not set: "; std::cerr<<"sigma3indices3 has "<< sigma0indices3.size() << " components" << std::endl; return false; } for(int i=0;i<16;i++){ int index0 = tensor_to_list_idx(sigma0indices3.at(i)); int index1 = tensor_to_list_idx(sigma1indices3.at(i)); int index2 = tensor_to_list_idx(sigma2indices3.at(i)); int index3 = tensor_to_list_idx(sigma3indices3.at(i)); sigma_index3[index0]=0; sigma_index3[index1]=1; sigma_index3[index2]=2; sigma_index3[index3]=3; short int sign[4]={1,-1,-1,-1}; // plus->true->1 helfactor3[1][index0] = sign[sigma0indices3.at(i)[1]]; helfactor3[1][index1] = sign[sigma1indices3.at(i)[1]]; helfactor3[1][index2] = sign[sigma2indices3.at(i)[1]]; helfactor3[1][index3] = sign[sigma3indices3.at(i)[1]]; // minus->false->0 helfactor3[0][index0] = sign[sigma0indices3.at(i)[0]] * sign[sigma0indices3.at(i)[2]]; helfactor3[0][index1] = sign[sigma1indices3.at(i)[0]] * sign[sigma1indices3.at(i)[2]]; helfactor3[0][index2] = sign[sigma2indices3.at(i)[0]] * sign[sigma2indices3.at(i)[2]]; helfactor3[0][index3] = sign[sigma3indices3.at(i)[0]] * sign[sigma3indices3.at(i)[2]]; } return true; } // end init_sigma_index }