14 for (
int i = 0; i < index.size() - 1; ++i ) { os << index[i]; }
15 os << index[index.size() - 1] <<
">" << amp( index ) <<
":";
16 }
while ( amp.
iterate( index ) );
24 for (
int i = 0; i < ret._elem.size(); ++i ) { ret._elem[i] *=
real; }
34 for (
int i = 0; i < ret._elem.size(); ++i ) { ret._elem[i] /=
real; }
39vector<int> EvtSpinAmp::calctwospin(
const vector<EvtSpinType::spintype>&
type )
const {
42 for (
int i = 0; i <
type.size(); ++i )
51 _twospin = calctwospin(
type );
53 for (
int i = 0; i < _twospin.size(); ++i )
num *= _twospin[i] + 1;
55 _elem = vector<EvtComplex>(
num );
61 _twospin = calctwospin(
type );
63 for (
int i = 0; i < _twospin.size(); ++i )
num *= _twospin[i] + 1;
65 _elem = vector<EvtComplex>(
num, val );
69 const vector<EvtComplex>& elem ) {
73 _twospin = calctwospin(
type );
76 for (
int i = 0; i < _twospin.size(); ++i )
num *= _twospin[i] + 1;
78 if ( _elem.size() !=
num )
80 report(
ERROR,
"EvtGen" ) <<
"Wrong number of elements input:" << _elem.size() <<
" vs. "
87 _twospin = copy._twospin;
92void EvtSpinAmp::checktwospin(
const vector<int>& twospin )
const {
93 if ( _twospin == twospin )
return;
95 report(
ERROR,
"EvtGen" ) <<
"Dimension or order of tensors being operated on does not match"
100void EvtSpinAmp::checkindexargs(
const vector<int>& index )
const {
101 if ( index.size() == 0 )
103 report(
ERROR,
"EvtGen" ) <<
"EvtSpinAmp can't handle no indices" << endl;
107 if ( index.size() != _twospin.size() )
109 report(
ERROR,
"EvtGen" ) <<
"Rank of EvtSpinAmp index does not match: " << _twospin.size()
110 <<
" expected " << index.size() <<
" input." << endl;
114 for (
int i = 0; i < _twospin.size(); ++i )
116 if ( _twospin[i] >=
abs( index[i] ) && _twospin[i] % 2 == index[i] % 2 )
continue;
117 report(
ERROR,
"EvtGen" ) <<
"EvtSpinAmp index out of range" << endl;
119 for (
int j = 0; j < _twospin.size(); ++j )
report(
ERROR,
" " ) << _twospin[j];
122 for (
int j = 0; j < index.size(); ++j )
report(
ERROR,
" " ) << index[j];
128int EvtSpinAmp::findtrueindex(
const vector<int>& index )
const {
131 for (
int i = index.size() - 1; i > 0; --i )
133 trueindex += ( index[i] + _twospin[i] ) / 2;
134 trueindex *= _twospin[i - 1] + 1;
137 trueindex += ( index[0] + _twospin[0] ) / 2;
143 checkindexargs( index );
145 int trueindex = findtrueindex( index );
146 if ( trueindex >= _elem.size() )
148 report(
ERROR,
"EvtGen" ) <<
"indexing error " << trueindex <<
" " << _elem.size() << endl;
149 for (
int i = 0; i < _twospin.size(); ++i ) {
report(
ERROR,
"" ) << _twospin[i] <<
" "; }
152 for (
int i = 0; i < index.size(); ++i ) {
report(
ERROR,
"" ) << index[i] <<
" "; }
158 return _elem[trueindex];
162 checkindexargs( index );
164 int trueindex = findtrueindex( index );
165 if ( trueindex >= _elem.size() )
167 report(
ERROR,
"EvtGen" ) <<
"indexing error " << trueindex <<
" " << _elem.size() << endl;
168 for (
int i = 0; i < _twospin.size(); ++i ) {
report(
ERROR,
"" ) << _twospin[i] <<
" "; }
171 for (
int i = 0; i < index.size(); ++i ) {
report(
ERROR,
"" ) << index[i] <<
" "; }
177 return _elem[trueindex];
182 vector<int> index( _twospin.size() );
187 for (
int n = 1;
n < _twospin.size(); ++
n ) index[
n] = va_arg( ap,
int );
191 return ( *
this )( index );
195 vector<int> index( _twospin.size() );
201 for (
int n = 1;
n < _twospin.size(); ++
n ) index[
n] = va_arg( ap,
int );
205 return ( *
this )( index );
209 _twospin =
cont._twospin;
217 checktwospin(
cont._twospin );
220 for (
int i = 0; i < ret._elem.size(); ++i ) { ret._elem[i] += _elem[i]; }
226 checktwospin(
cont._twospin );
228 for (
int i = 0; i < _elem.size(); ++i ) _elem[i] +=
cont._elem[i];
234 checktwospin(
cont._twospin );
237 for (
int i = 0; i < ret._elem.size(); ++i ) ret._elem[i] -=
cont._elem[i];
243 checktwospin(
cont._twospin );
245 for (
int i = 0; i < _elem.size(); ++i ) _elem[i] -=
cont._elem[i];
252 vector<int> index(
rank() + amp2.
rank() );
253 vector<int> index1(
rank() ), index2( amp2.
rank() );
256 amp._twospin = _twospin;
259 for (
int i = 0; i < amp2._twospin.size(); ++i )
261 amp._twospin.push_back( amp2._twospin[i] );
262 amp._type.push_back( amp2._type[i] );
265 amp._elem = vector<EvtComplex>( _elem.size() * amp2._elem.size() );
267 for (
int i = 0; i < index1.size(); ++i ) index[i] = index1[i] = -_twospin[i];
269 for (
int i = 0; i < index2.size(); ++i ) index[i +
rank()] = index2[i] = -amp2._twospin[i];
273 amp( index ) = ( *this )(index1)*amp2( index2 );
274 if ( !amp.
iterate( index ) )
break;
276 for (
int i = 0; i < index1.size(); ++i ) index1[i] = index[i];
278 for (
int i = 0; i < index2.size(); ++i ) index2[i] = index[i +
rank()];
291 for (
int i = 0; i < _elem.size(); ++i ) _elem[i] *=
real;
297 for (
int i = 0; i < _elem.size(); ++i ) _elem[i] /=
real;
303 vector<int> init( _twospin.size() );
305 for (
int i = 0; i < _twospin.size(); ++i ) init[i] = -_twospin[i];
311 int last = _twospin.size() - 1;
314 for (
int j = 0; j < last; ++j )
316 if ( index[j] > _twospin[j] )
318 index[j] = -_twospin[j];
323 return abs( index[last] ) <= _twospin[last];
329 if ( index.size() != _type.size() )
331 report(
ERROR,
"EvtGen" ) <<
"Wrong dimensino index input to allowed." << endl;
335 for (
int i = 0; i < index.size(); ++i )
340 if (
abs( index[i] ) != 2 )
return false;
343 report(
ERROR,
"EvtGen" ) <<
"EvMultibody currently cannot handle neutrinos." << endl;
355 if ( !
iterate( index ) )
return false;
356 if (
allowed( index ) )
return true;
368 int newrank =
rank() - 2;
371 report(
ERROR,
"EvtGen" ) <<
"EvtSpinAmp can't handle no indices" << endl;
375 if ( _twospin[a] != _twospin[b] )
377 report(
ERROR,
"EvtGen" ) <<
"Contaction called on indices of different dimension" << endl;
378 report(
ERROR,
"EvtGen" ) <<
"Called on " << _twospin[a] <<
" and " << _twospin[b] << endl;
382 vector<int> newtwospin( newrank );
383 vector<EvtSpinType::spintype> newtype( newrank );
385 for (
int i = 0, j = 0; i < _twospin.size(); ++i )
387 if ( i == a || i == b )
continue;
389 newtwospin[j] = _twospin[i];
390 newtype[j] = _type[i];
395 vector<int> index(
rank() ), newindex = newamp.
iterinit();
397 for (
int i = 0; i < newrank; ++i ) newindex[i] = -newtwospin[i];
402 for (
int i = 0, j = 0; i <
rank(); ++i )
404 if ( i == a || i == b )
continue;
405 index[i] = newindex[j];
409 index[b] = index[a] = -_twospin[a];
410 newamp( newindex ) = ( *this )( index );
411 for (
int i = -_twospin[a] + 2; i <= _twospin[a]; i += 2 )
413 index[b] = index[a] = i;
414 newamp( newindex ) += ( *this )( index );
417 if ( !newamp.
iterate( newindex ) )
break;
ostream & report(Severity severity, const char *facility)
std::ostream & operator<<(std::ostream &os, const EvtSpinAmp &)
EvtSpinAmp operator*(const EvtComplex &real, const EvtSpinAmp &cont)
EvtSpinAmp operator/(const EvtSpinAmp &cont, const EvtComplex &real)
EvtComplex cont(const EvtTensor4C &t1, const EvtTensor4C &t2)
EvtComplex & operator()(const vector< int > &)
EvtSpinAmp & operator-=(const EvtSpinAmp &)
EvtSpinAmp & operator=(const EvtSpinAmp &)
vector< int > iterinit() const
bool iterate(vector< int > &index) const
bool iterateallowed(vector< int > &index) const
EvtSpinAmp & operator*=(const EvtSpinAmp &)
EvtSpinAmp operator+(const EvtSpinAmp &) const
vector< int > iterallowedinit() const
EvtSpinAmp & operator+=(const EvtSpinAmp &)
bool allowed(const vector< int > &index) const
EvtSpinAmp & operator/=(const EvtComplex &)
friend EvtSpinAmp operator*(const EvtComplex &, const EvtSpinAmp &)
void extcont(const EvtSpinAmp &, int, int)
EvtSpinAmp operator-(const EvtSpinAmp &) const
static int getSpin2(spintype stype)