#include "EvtGenBase/EvtPatches.hh" #include "EvtGenBase/EvtReport.hh" #include "EvtGenBase/EvtSpinAmp.hh" #include using std::endl; std::ostream& operator<<( std::ostream& os, const EvtSpinAmp& amp ) { vector index = amp.iterinit(); os << ":"; do { os<<"<"; for(size_t i=0; i"< EvtSpinAmp::calctwospin( const vector& type ) const { vector twospin; for( size_t i=0; i& type ) { int num = 1; _type = type; _twospin=calctwospin( type ); for( size_t i=0; i<_twospin.size(); ++i ) num*=_twospin[i]+1; _elem=vector( num ); } EvtSpinAmp::EvtSpinAmp( const vector& type, const EvtComplex & val ) { int num = 1; _type = type; _twospin=calctwospin( type ); for( size_t i=0; i<_twospin.size(); ++i ) num*=_twospin[i]+1; _elem=vector( num, val ); } EvtSpinAmp::EvtSpinAmp( const vector& type, const vector& elem ) { size_t num = 1; _type = type; _twospin=calctwospin( type ); _elem=elem; for( size_t i=0; i<_twospin.size(); ++i ){ num*=(_twospin[i]+1); } if(_elem.size() != num ) { report(ERROR,"EvtGen")<<"Wrong number of elements input:" <<_elem.size()<<" vs. "<& twospin ) const { if( _twospin == twospin ) return; report( ERROR, "EvtGen" ) <<"Dimension or order of tensors being operated on does not match" <& index ) const { if( index.size()==0 ) { report(ERROR,"EvtGen") << "EvtSpinAmp can't handle no indices" << endl; ::abort(); } if( index.size() != _twospin.size() ) { report( ERROR, "EvtGen" ) << "Rank of EvtSpinAmp index does not match: " <<_twospin.size()<<" expected "<(_twospin[i])>=abs(index[i]) && static_cast(_twospin[i])%2==index[i]%2 ) continue; report(ERROR,"EvtGen")<<"EvtSpinAmp index out of range" << endl; report(ERROR,"EvtGen")<<" Index: "; for(size_t j=0; j<_twospin.size(); ++j ) report(ERROR," ")<<_twospin[j]; report(ERROR, " ")<& index ) const { int trueindex = 0; for( size_t i = index.size()-1; i>0; --i ) { trueindex += (index[i]+_twospin[i])/2; trueindex *= _twospin[i-1]+1; } trueindex += (index[0]+_twospin[0])/2; return trueindex; } EvtComplex & EvtSpinAmp::operator()( const vector& index ) { checkindexargs( index ); size_t trueindex = findtrueindex(index); if(trueindex >= _elem.size()) { report(ERROR,"EvtGen")<<"indexing error "<& index ) const { checkindexargs( index ); size_t trueindex = findtrueindex(index); if(trueindex >= _elem.size()) { report(ERROR,"EvtGen")<<"indexing error "< index( _twospin.size() ); va_start(ap, i); index[0]=i; for(size_t n=1; n<_twospin.size(); ++n ) index[n]=va_arg( ap, int ); va_end(ap); return (*this)( index ); } const EvtComplex & EvtSpinAmp::operator()( int i, ... ) const { vector index( _twospin.size() ); va_list ap; va_start(ap, i); index[0]=i; for(size_t n=1; n<_twospin.size(); ++n ) index[n]=va_arg( ap, int ); va_end(ap); return (*this)( index ); } EvtSpinAmp& EvtSpinAmp::operator=( const EvtSpinAmp& cont ) { _twospin=cont._twospin; _elem=cont._elem; _type=cont._type; return *this; } EvtSpinAmp EvtSpinAmp::operator+( const EvtSpinAmp & cont ) const { checktwospin( cont._twospin ); EvtSpinAmp ret( cont ); for( size_t i=0; i index(rank()+amp2.rank()); vector index1(rank()), index2(amp2.rank()); EvtSpinAmp amp; amp._twospin=_twospin; amp._type=_type; for( size_t i=0; i( _elem.size() * amp2._elem.size() ); for( size_t i=0; i EvtSpinAmp::iterinit() const { vector init( _twospin.size() ); for( size_t i=0; i<_twospin.size(); ++i ) init[i]=-_twospin[i]; return init; } bool EvtSpinAmp::iterate( vector& index ) const { int last = _twospin.size() - 1; index[0]+=2; for( size_t j=0; static_cast(j) static_cast(_twospin[j]) ) { index[j] = -_twospin[j]; index[j+1]+=2; } } return abs(index[last])<=_twospin[last]; } // Test whether a particular index is an allowed one (specifically to deal with // photons and possibly neutrinos) bool EvtSpinAmp::allowed( const vector& index ) const { if( index.size() != _type.size() ) { report(ERROR,"EvtGen") <<"Wrong dimensino index input to allowed."<& index ) const { while(true) { if(!iterate( index )) return false; if(allowed( index )) return true; } } vector EvtSpinAmp::iterallowedinit() const { vector init = iterinit(); while(!allowed(init)) { iterate(init); } return init; } void EvtSpinAmp::intcont( size_t a, size_t b ) { if(rank()<=2) { report(ERROR,"EvtGen")<<"EvtSpinAmp can't handle no indices" << endl; ::abort(); } size_t newrank=rank()-2; if(_twospin[a]!=_twospin[b]) { report(ERROR,"EvtGen") <<"Contaction called on indices of different dimension" < newtwospin( newrank ); vector newtype( newrank ); for( size_t i=0, j=0; i<_twospin.size(); ++i ){ if(i==a || i==b) continue; newtwospin[j] = _twospin[i]; newtype[j] = _type[i]; ++j; } EvtSpinAmp newamp( newtype ); vector index( rank() ), newindex = newamp.iterinit(); for( size_t i=0; i