1 #include "EvtGenBase/EvtPatches.hh"
2 #include "EvtGenBase/EvtReport.hh"
3 #include "EvtGenBase/EvtSpinAmp.hh"
9 operator<<( std::ostream& os, const EvtSpinAmp& amp )
11 vector<int> index = amp.iterinit();
16 for(size_t i=0; i<index.size()-1; ++i) {
19 os<<index[index.size()-1]<<">"<<amp(index)<<":";
20 } while( amp.iterate( index ) );
25 EvtSpinAmp operator*( const EvtComplex& real, const EvtSpinAmp& cont )
27 EvtSpinAmp ret( cont );
29 for( size_t i=0; i<ret._elem.size(); ++i ) {
36 EvtSpinAmp operator*( const EvtSpinAmp& cont, const EvtComplex& real )
41 EvtSpinAmp operator/( const EvtSpinAmp& cont, const EvtComplex& real )
43 EvtSpinAmp ret( cont );
45 for( size_t i=0; i<ret._elem.size(); ++i ) {
52 vector<unsigned int> EvtSpinAmp::calctwospin( const vector<EvtSpinType::spintype>& type ) const
54 vector<unsigned int> twospin;
56 for( size_t i=0; i<type.size(); ++i ) {
57 twospin.push_back( EvtSpinType::getSpin2( type[i] ) );
63 EvtSpinAmp::EvtSpinAmp( const vector<EvtSpinType::spintype>& type )
67 _twospin=calctwospin( type );
69 for( size_t i=0; i<_twospin.size(); ++i )
72 _elem=vector<EvtComplex>( num );
75 EvtSpinAmp::EvtSpinAmp( const vector<EvtSpinType::spintype>& type, const EvtComplex & val )
79 _twospin=calctwospin( type );
81 for( size_t i=0; i<_twospin.size(); ++i )
84 _elem=vector<EvtComplex>( num, val );
87 EvtSpinAmp::EvtSpinAmp( const vector<EvtSpinType::spintype>& type,
88 const vector<EvtComplex>& elem )
93 _twospin=calctwospin( type );
96 for( size_t i=0; i<_twospin.size(); ++i ){
100 if(_elem.size() != num ) {
101 report(ERROR,"EvtGen")<<"Wrong number of elements input:"
102 <<_elem.size()<<" vs. "<<num<<endl;
108 EvtSpinAmp::EvtSpinAmp( const EvtSpinAmp& copy )
110 _twospin = copy._twospin;
115 void EvtSpinAmp::checktwospin( const vector<unsigned int>& twospin ) const
117 if( _twospin == twospin )
120 report( ERROR, "EvtGen" )
121 <<"Dimension or order of tensors being operated on does not match"
126 void EvtSpinAmp::checkindexargs( const vector<int>& index ) const
128 if( index.size()==0 ) {
129 report(ERROR,"EvtGen") << "EvtSpinAmp can't handle no indices" << endl;
133 if( index.size() != _twospin.size() ) {
134 report( ERROR, "EvtGen" ) << "Rank of EvtSpinAmp index does not match: "
135 <<_twospin.size()<<" expected "<<index.size()<<" input."<<endl;
139 for( size_t i=0; i<_twospin.size(); ++i ) {
140 if( static_cast<int>(_twospin[i])>=abs(index[i]) && static_cast<int>(_twospin[i])%2==index[i]%2 )
142 report(ERROR,"EvtGen")<<"EvtSpinAmp index out of range" << endl;
143 report(ERROR,"EvtGen")<<" Index: ";
144 for(size_t j=0; j<_twospin.size(); ++j )
145 report(ERROR," ")<<_twospin[j];
147 report(ERROR, " ")<<endl<<" Index: ";
148 for(size_t j=0; j<index.size(); ++j )
149 report(ERROR," ")<<index[j];
150 report(ERROR, " ")<<endl;
155 int EvtSpinAmp::findtrueindex( const vector<int>& index ) const
159 for( size_t i = index.size()-1; i>0; --i ) {
160 trueindex += (index[i]+_twospin[i])/2;
161 trueindex *= _twospin[i-1]+1;
164 trueindex += (index[0]+_twospin[0])/2;
169 EvtComplex & EvtSpinAmp::operator()( const vector<int>& index )
171 checkindexargs( index );
173 size_t trueindex = findtrueindex(index);
174 if(trueindex >= _elem.size()) {
175 report(ERROR,"EvtGen")<<"indexing error "<<trueindex<<" "<<_elem.size()<<endl;
176 for(size_t i=0; i<_twospin.size(); ++i) {
177 report(ERROR,"")<<_twospin[i]<<" ";
179 report(ERROR,"")<<endl;
181 for(size_t i=0; i<index.size(); ++i) {
182 report(ERROR,"")<<index[i]<<" ";
184 report(ERROR,"")<<endl;
189 return _elem[trueindex];
192 const EvtComplex & EvtSpinAmp::operator()( const vector<int>& index ) const
194 checkindexargs( index );
196 size_t trueindex = findtrueindex(index);
197 if(trueindex >= _elem.size()) {
198 report(ERROR,"EvtGen")<<"indexing error "<<trueindex<<" "<<_elem.size()<<endl;
199 for(size_t i=0; i<_twospin.size(); ++i) {
200 report(ERROR,"")<<_twospin[i]<<" ";
202 report(ERROR,"")<<endl;
204 for(size_t i=0; i<index.size(); ++i) {
205 report(ERROR,"")<<index[i]<<" ";
207 report(ERROR,"")<<endl;
212 return _elem[trueindex];
215 EvtComplex & EvtSpinAmp::operator()( int i, ... )
218 vector<int> index( _twospin.size() );
223 for(size_t n=1; n<_twospin.size(); ++n )
224 index[n]=va_arg( ap, int );
228 return (*this)( index );
231 const EvtComplex & EvtSpinAmp::operator()( int i, ... ) const
233 vector<int> index( _twospin.size() );
239 for(size_t n=1; n<_twospin.size(); ++n )
240 index[n]=va_arg( ap, int );
244 return (*this)( index );
247 EvtSpinAmp& EvtSpinAmp::operator=( const EvtSpinAmp& cont )
249 _twospin=cont._twospin;
256 EvtSpinAmp EvtSpinAmp::operator+( const EvtSpinAmp & cont ) const
258 checktwospin( cont._twospin );
260 EvtSpinAmp ret( cont );
261 for( size_t i=0; i<ret._elem.size(); ++i ) {
262 ret._elem[i]+=_elem[i];
268 EvtSpinAmp& EvtSpinAmp::operator+=( const EvtSpinAmp&
271 checktwospin( cont._twospin );
273 for( size_t i=0; i<_elem.size(); ++i )
274 _elem[i]+=cont._elem[i];
279 EvtSpinAmp EvtSpinAmp::operator-( const EvtSpinAmp & cont ) const
281 checktwospin( cont._twospin );
283 EvtSpinAmp ret( *this );
284 for( size_t i=0; i<ret._elem.size(); ++i )
285 ret._elem[i]-=cont._elem[i];
290 EvtSpinAmp& EvtSpinAmp::operator-=( const EvtSpinAmp& cont )
292 checktwospin( cont._twospin );
294 for( size_t i=0; i<_elem.size(); ++i )
295 _elem[i]-=cont._elem[i];
301 EvtSpinAmp EvtSpinAmp::operator*( const EvtSpinAmp & amp2 ) const
303 vector<int> index(rank()+amp2.rank());
304 vector<int> index1(rank()), index2(amp2.rank());
307 amp._twospin=_twospin;
310 for( size_t i=0; i<amp2._twospin.size(); ++i ) {
311 amp._twospin.push_back( amp2._twospin[i] );
312 amp._type.push_back( amp2._type[i] );
315 amp._elem = vector<EvtComplex>( _elem.size() * amp2._elem.size() );
317 for( size_t i=0; i<index1.size(); ++i )
318 index[i]=index1[i]=-_twospin[i];
320 for( size_t i=0; i<index2.size(); ++i )
321 index[i+rank()]=index2[i]=-amp2._twospin[i];
324 amp( index ) = (*this)( index1 )*amp2( index2 );
325 if(!amp.iterate( index )) break;
327 for( size_t i=0; i<index1.size(); ++i )
330 for( size_t i=0; i<index2.size(); ++i )
331 index2[i]=index[i+rank()];
337 EvtSpinAmp& EvtSpinAmp::operator*=( const EvtSpinAmp& cont )
339 EvtSpinAmp ret = (*this)*cont;
344 EvtSpinAmp& EvtSpinAmp::operator*=( const EvtComplex& real )
346 for( size_t i=0; i<_elem.size(); ++i )
352 EvtSpinAmp& EvtSpinAmp::operator/=( const EvtComplex& real )
354 for( size_t i=0; i<_elem.size(); ++i )
360 vector<int> EvtSpinAmp::iterinit() const
362 vector<int> init( _twospin.size() );
364 for( size_t i=0; i<_twospin.size(); ++i )
365 init[i]=-_twospin[i];
370 bool EvtSpinAmp::iterate( vector<int>& index ) const
372 int last = _twospin.size() - 1;
375 for( size_t j=0; static_cast<int>(j)<last; ++j ) {
376 if( index[j] > static_cast<int>(_twospin[j]) ) {
377 index[j] = -_twospin[j];
382 return (abs(index[last]))<=((int)_twospin[last]);
385 // Test whether a particular index is an allowed one (specifically to deal with
386 // photons and possibly neutrinos)
387 bool EvtSpinAmp::allowed( const vector<int>& index ) const
389 if( index.size() != _type.size() ) {
390 report(ERROR,"EvtGen")
391 <<"Wrong dimensino index input to allowed."<<endl;
395 for(size_t i=0; i<index.size(); ++i) {
397 case EvtSpinType::PHOTON:
398 if(abs(index[i])!=2) return false;
400 case EvtSpinType::NEUTRINO:
401 report(ERROR,"EvtGen")
402 <<"EvMultibody currently cannot handle neutrinos."<<endl;
412 bool EvtSpinAmp::iterateallowed( vector<int>& index ) const
415 if(!iterate( index ))
422 vector<int> EvtSpinAmp::iterallowedinit() const
424 vector<int> init = iterinit();
425 while(!allowed(init)) {
432 void EvtSpinAmp::intcont( size_t a, size_t b )
436 report(ERROR,"EvtGen")<<"EvtSpinAmp can't handle no indices" << endl;
440 size_t newrank=rank()-2;
442 if(_twospin[a]!=_twospin[b]) {
443 report(ERROR,"EvtGen")
444 <<"Contaction called on indices of different dimension"
446 report(ERROR,"EvtGen")
447 <<"Called on "<<_twospin[a]<<" and "<<_twospin[b]
452 vector<int> newtwospin( newrank );
453 vector<EvtSpinType::spintype> newtype( newrank );
455 for( size_t i=0, j=0; i<_twospin.size(); ++i ){
456 if(i==a || i==b) continue;
458 newtwospin[j] = _twospin[i];
459 newtype[j] = _type[i];
463 EvtSpinAmp newamp( newtype );
464 vector<int> index( rank() ), newindex = newamp.iterinit();
466 for( size_t i=0; i<newrank; ++i )
467 newindex[i] = -newtwospin[i];
471 for( size_t i=0, j=0; i<rank(); ++i ) {
472 if(i==a || i==b) continue;
473 index[i]=newindex[j];
477 index[b]=index[a]=-_twospin[a];
478 newamp(newindex) = (*this)(index);
479 for( size_t i=-_twospin[a]+2; i<=_twospin[a]; i+=2 ) {
481 newamp(newindex) += (*this)(index);
484 if(!newamp.iterate(newindex)) break;
490 // In A.extcont(B), a is the index in A and b is the index in B - note that this
491 // routine can be extremely improved!
492 void EvtSpinAmp::extcont( const EvtSpinAmp& cont, int a, int b )
494 EvtSpinAmp ret = (*this)*cont;
495 ret.intcont( a, rank()+b );