+++ /dev/null
-#include "EvtGenBase/EvtPatches.hh"
-#include "EvtGenBase/EvtReport.hh"
-#include "EvtGenBase/EvtSpinAmp.hh"
-#include <stdlib.h>
-
-using std::endl;
-
-std::ostream&
-operator<<( std::ostream& os, const EvtSpinAmp& amp )
-{
- vector<int> index = amp.iterinit();
-
- os << ":";
- do {
- os<<"<";
- for(size_t i=0; i<index.size()-1; ++i) {
- os<<index[i];
- }
- os<<index[index.size()-1]<<">"<<amp(index)<<":";
- } while( amp.iterate( index ) );
-
- return os;
-}
-
-EvtSpinAmp operator*( const EvtComplex& real, const EvtSpinAmp& cont )
-{
- EvtSpinAmp ret( cont );
-
- for( size_t i=0; i<ret._elem.size(); ++i ) {
- ret._elem[i] *= real;
- }
-
- return ret;
-}
-
-EvtSpinAmp operator*( const EvtSpinAmp& cont, const EvtComplex& real )
-{
- return real*cont;
-}
-
-EvtSpinAmp operator/( const EvtSpinAmp& cont, const EvtComplex& real )
-{
- EvtSpinAmp ret( cont );
-
- for( size_t i=0; i<ret._elem.size(); ++i ) {
- ret._elem[i] /= real;
- }
-
- return ret;
-}
-
-vector<unsigned int> EvtSpinAmp::calctwospin( const vector<EvtSpinType::spintype>& type ) const
-{
- vector<unsigned int> twospin;
-
- for( size_t i=0; i<type.size(); ++i ) {
- twospin.push_back( EvtSpinType::getSpin2( type[i] ) );
- }
-
- return twospin;
-}
-
-EvtSpinAmp::EvtSpinAmp( const vector<EvtSpinType::spintype>& type )
-{
- int num = 1;
- _type = type;
- _twospin=calctwospin( type );
-
- for( size_t i=0; i<_twospin.size(); ++i )
- num*=_twospin[i]+1;
-
- _elem=vector<EvtComplex>( num );
-}
-
-EvtSpinAmp::EvtSpinAmp( const vector<EvtSpinType::spintype>& 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<EvtComplex>( num, val );
-}
-
-EvtSpinAmp::EvtSpinAmp( const vector<EvtSpinType::spintype>& type,
- const vector<EvtComplex>& 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. "<<num<<endl;
- ::abort();
- }
-
-}
-
-EvtSpinAmp::EvtSpinAmp( const EvtSpinAmp& copy )
-{
- _twospin = copy._twospin;
- _elem = copy._elem;
- _type = copy._type;
-}
-
-void EvtSpinAmp::checktwospin( const vector<unsigned int>& twospin ) const
-{
- if( _twospin == twospin )
- return;
-
- report( ERROR, "EvtGen" )
- <<"Dimension or order of tensors being operated on does not match"
- <<endl;
- ::abort();
-}
-
-void EvtSpinAmp::checkindexargs( const vector<int>& 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 "<<index.size()<<" input."<<endl;
- ::abort();
- }
-
- for( size_t i=0; i<_twospin.size(); ++i ) {
- if( static_cast<int>(_twospin[i])>=abs(index[i]) && static_cast<int>(_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, " ")<<endl<<" Index: ";
- for(size_t j=0; j<index.size(); ++j )
- report(ERROR," ")<<index[j];
- report(ERROR, " ")<<endl;
- ::abort();
- }
-}
-
-int EvtSpinAmp::findtrueindex( const vector<int>& 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<int>& index )
-{
- checkindexargs( index );
-
- size_t trueindex = findtrueindex(index);
- if(trueindex >= _elem.size()) {
- report(ERROR,"EvtGen")<<"indexing error "<<trueindex<<" "<<_elem.size()<<endl;
- for(size_t i=0; i<_twospin.size(); ++i) {
- report(ERROR,"")<<_twospin[i]<<" ";
- }
- report(ERROR,"")<<endl;
-
- for(size_t i=0; i<index.size(); ++i) {
- report(ERROR,"")<<index[i]<<" ";
- }
- report(ERROR,"")<<endl;
-
- ::abort();
- }
-
- return _elem[trueindex];
-}
-
-const EvtComplex & EvtSpinAmp::operator()( const vector<int>& index ) const
-{
- checkindexargs( index );
-
- size_t trueindex = findtrueindex(index);
- if(trueindex >= _elem.size()) {
- report(ERROR,"EvtGen")<<"indexing error "<<trueindex<<" "<<_elem.size()<<endl;
- for(size_t i=0; i<_twospin.size(); ++i) {
- report(ERROR,"")<<_twospin[i]<<" ";
- }
- report(ERROR,"")<<endl;
-
- for(size_t i=0; i<index.size(); ++i) {
- report(ERROR,"")<<index[i]<<" ";
- }
- report(ERROR,"")<<endl;
-
- ::abort();
- }
-
- return _elem[trueindex];
-}
-
-EvtComplex & EvtSpinAmp::operator()( int i, ... )
-{
- va_list ap;
- vector<int> 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<int> 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<ret._elem.size(); ++i ) {
- ret._elem[i]+=_elem[i];
- }
-
- return ret;
-}
-
-EvtSpinAmp& EvtSpinAmp::operator+=( const EvtSpinAmp&
- cont )
-{
- checktwospin( cont._twospin );
-
- for( size_t i=0; i<_elem.size(); ++i )
- _elem[i]+=cont._elem[i];
-
- return *this;
-}
-
-EvtSpinAmp EvtSpinAmp::operator-( const EvtSpinAmp & cont ) const
-{
- checktwospin( cont._twospin );
-
- EvtSpinAmp ret( *this );
- for( size_t i=0; i<ret._elem.size(); ++i )
- ret._elem[i]-=cont._elem[i];
-
- return ret;
-}
-
-EvtSpinAmp& EvtSpinAmp::operator-=( const EvtSpinAmp& cont )
-{
- checktwospin( cont._twospin );
-
- for( size_t i=0; i<_elem.size(); ++i )
- _elem[i]-=cont._elem[i];
-
- return *this;
-}
-
-// amp = amp1 * amp2
-EvtSpinAmp EvtSpinAmp::operator*( const EvtSpinAmp & amp2 ) const
-{
- vector<int> index(rank()+amp2.rank());
- vector<int> index1(rank()), index2(amp2.rank());
- EvtSpinAmp amp;
-
- amp._twospin=_twospin;
- amp._type=_type;
-
- for( size_t i=0; i<amp2._twospin.size(); ++i ) {
- amp._twospin.push_back( amp2._twospin[i] );
- amp._type.push_back( amp2._type[i] );
- }
-
- amp._elem = vector<EvtComplex>( _elem.size() * amp2._elem.size() );
-
- for( size_t i=0; i<index1.size(); ++i )
- index[i]=index1[i]=-_twospin[i];
-
- for( size_t i=0; i<index2.size(); ++i )
- index[i+rank()]=index2[i]=-amp2._twospin[i];
-
- while(true) {
- amp( index ) = (*this)( index1 )*amp2( index2 );
- if(!amp.iterate( index )) break;
-
- for( size_t i=0; i<index1.size(); ++i )
- index1[i]=index[i];
-
- for( size_t i=0; i<index2.size(); ++i )
- index2[i]=index[i+rank()];
- }
-
- return amp;
-}
-
-EvtSpinAmp& EvtSpinAmp::operator*=( const EvtSpinAmp& cont )
-{
- EvtSpinAmp ret = (*this)*cont;
- *this=ret;
- return *this;
-}
-
-EvtSpinAmp& EvtSpinAmp::operator*=( const EvtComplex& real )
-{
- for( size_t i=0; i<_elem.size(); ++i )
- _elem[i] *= real;
-
- return *this;
-}
-
-EvtSpinAmp& EvtSpinAmp::operator/=( const EvtComplex& real )
-{
- for( size_t i=0; i<_elem.size(); ++i )
- _elem[i] /= real;
-
- return *this;
-}
-
-vector<int> EvtSpinAmp::iterinit() const
-{
- vector<int> init( _twospin.size() );
-
- for( size_t i=0; i<_twospin.size(); ++i )
- init[i]=-_twospin[i];
-
- return init;
-}
-
-bool EvtSpinAmp::iterate( vector<int>& index ) const
-{
- int last = _twospin.size() - 1;
-
- index[0]+=2;
- for( size_t j=0; static_cast<int>(j)<last; ++j ) {
- if( index[j] > static_cast<int>(_twospin[j]) ) {
- index[j] = -_twospin[j];
- index[j+1]+=2;
- }
- }
-
- return (abs(index[last]))<=((int)_twospin[last]);
-}
-
-// Test whether a particular index is an allowed one (specifically to deal with
-// photons and possibly neutrinos)
-bool EvtSpinAmp::allowed( const vector<int>& index ) const
-{
- if( index.size() != _type.size() ) {
- report(ERROR,"EvtGen")
- <<"Wrong dimensino index input to allowed."<<endl;
- ::abort();
- }
-
- for(size_t i=0; i<index.size(); ++i) {
- switch(_type[i]) {
- case EvtSpinType::PHOTON:
- if(abs(index[i])!=2) return false;
- break;
- case EvtSpinType::NEUTRINO:
- report(ERROR,"EvtGen")
- <<"EvMultibody currently cannot handle neutrinos."<<endl;
- ::abort();
- default:
- break;
- }
- }
-
- return true;
-}
-
-bool EvtSpinAmp::iterateallowed( vector<int>& index ) const
-{
- while(true) {
- if(!iterate( index ))
- return false;
- if(allowed( index ))
- return true;
- }
-}
-
-vector<int> EvtSpinAmp::iterallowedinit() const
-{
- vector<int> 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"
- <<endl;
- report(ERROR,"EvtGen")
- <<"Called on "<<_twospin[a]<<" and "<<_twospin[b]
- <<endl;
- ::abort();
- }
-
- vector<int> newtwospin( newrank );
- vector<EvtSpinType::spintype> 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<int> index( rank() ), newindex = newamp.iterinit();
-
- for( size_t i=0; i<newrank; ++i )
- newindex[i] = -newtwospin[i];
-
- while(true) {
-
- for( size_t i=0, j=0; i<rank(); ++i ) {
- if(i==a || i==b) continue;
- index[i]=newindex[j];
- ++j;
- }
-
- index[b]=index[a]=-_twospin[a];
- newamp(newindex) = (*this)(index);
- for( size_t i=-_twospin[a]+2; i<=_twospin[a]; i+=2 ) {
- index[b]=index[a]=i;
- newamp(newindex) += (*this)(index);
- }
-
- if(!newamp.iterate(newindex)) break;
- }
-
- *this=newamp;
-}
-
-// In A.extcont(B), a is the index in A and b is the index in B - note that this
-// routine can be extremely improved!
-void EvtSpinAmp::extcont( const EvtSpinAmp& cont, int a, int b )
-{
- EvtSpinAmp ret = (*this)*cont;
- ret.intcont( a, rank()+b );
-
- *this=ret;
-}