CGEM BOSS 6.6.5.h
BESIII Offline Software System
Loading...
Searching...
No Matches
EvtSpinAmp.cc
Go to the documentation of this file.
4#include <cstdlib>
5
6using std::endl;
7
8std::ostream&
9operator<<( std::ostream& os, const EvtSpinAmp& amp )
10{
11 vector<int> index = amp.iterinit();
12
13 os << ":";
14 do {
15 os<<"<";
16 for(int i=0; i<index.size()-1; ++i) {
17 os<<index[i];
18 }
19 os<<index[index.size()-1]<<">"<<amp(index)<<":";
20 } while( amp.iterate( index ) );
22 return os;
23}
24
26{
27 EvtSpinAmp ret( cont );
28
29 for( int i=0; i<ret._elem.size(); ++i ) {
30 ret._elem[i] *= real;
31 }
32
33 return ret;
34}
35
37{
38 return real*cont;
39}
40
42{
43 EvtSpinAmp ret( cont );
44
45 for( int i=0; i<ret._elem.size(); ++i ) {
46 ret._elem[i] /= real;
47 }
48
49 return ret;
50}
51
52vector<int> EvtSpinAmp::calctwospin( const vector<EvtSpinType::spintype>& type ) const
53{
54 vector<int> twospin;
55
56 for( int i=0; i<type.size(); ++i ) {
57 twospin.push_back( EvtSpinType::getSpin2( type[i] ) );
58 }
59
60 return twospin;
61}
62
63EvtSpinAmp::EvtSpinAmp( const vector<EvtSpinType::spintype>& type )
64{
65 int num = 1;
66 _type = type;
67 _twospin=calctwospin( type );
68
69 for( int i=0; i<_twospin.size(); ++i )
70 num*=_twospin[i]+1;
71
72 _elem=vector<EvtComplex>( num );
73}
74
75EvtSpinAmp::EvtSpinAmp( const vector<EvtSpinType::spintype>& type, const EvtComplex & val )
76{
77 int num = 1;
78 _type = type;
79 _twospin=calctwospin( type );
80
81 for( int i=0; i<_twospin.size(); ++i )
82 num*=_twospin[i]+1;
83
84 _elem=vector<EvtComplex>( num, val );
85}
86
87EvtSpinAmp::EvtSpinAmp( const vector<EvtSpinType::spintype>& type,
88 const vector<EvtComplex>& elem )
89{
90 int num = 1;
91
92 _type = type;
93 _twospin=calctwospin( type );
94 _elem=elem;
95
96 for( int i=0; i<_twospin.size(); ++i )
97 num*=_twospin[i]+1;
98
99 if(_elem.size() != num ) {
100 report(ERROR,"EvtGen")<<"Wrong number of elements input:"
101 <<_elem.size()<<" vs. "<<num<<endl;
102 ::abort();
103 }
104
105}
106
108{
109 _twospin = copy._twospin;
110 _elem = copy._elem;
111 _type = copy._type;
112}
113
114void EvtSpinAmp::checktwospin( const vector<int>& twospin ) const
115{
116 if( _twospin == twospin )
117 return;
118
119 report( ERROR, "EvtGen" )
120 <<"Dimension or order of tensors being operated on does not match"
121 <<endl;
122 ::abort();
123}
124
125void EvtSpinAmp::checkindexargs( const vector<int>& index ) const
126{
127 if( index.size()==0 ) {
128 report(ERROR,"EvtGen") << "EvtSpinAmp can't handle no indices" << endl;
129 ::abort();
130 }
131
132 if( index.size() != _twospin.size() ) {
133 report( ERROR, "EvtGen" ) << "Rank of EvtSpinAmp index does not match: "
134 <<_twospin.size()<<" expected "<<index.size()<<" input."<<endl;
135 ::abort();
136 }
137
138 for( int i=0; i<_twospin.size(); ++i ) {
139 if( _twospin[i]>=abs(index[i]) && _twospin[i]%2==index[i]%2 )
140 continue;
141 report(ERROR,"EvtGen")<<"EvtSpinAmp index out of range" << endl;
142 report(ERROR,"EvtGen")<<" Index: ";
143 for(int j=0; j<_twospin.size(); ++j )
144 report(ERROR," ")<<_twospin[j];
145
146 report(ERROR, " ")<<endl<<" Index: ";
147 for(int j=0; j<index.size(); ++j )
148 report(ERROR," ")<<index[j];
149 report(ERROR, " ")<<endl;
150 ::abort();
151 }
152}
153
154int EvtSpinAmp::findtrueindex( const vector<int>& index ) const
155{
156 int trueindex = 0;
157
158 for( int i = index.size()-1; i>0; --i ) {
159 trueindex += (index[i]+_twospin[i])/2;
160 trueindex *= _twospin[i-1]+1;
161 }
162
163 trueindex += (index[0]+_twospin[0])/2;
164
165 return trueindex;
166}
167
168EvtComplex & EvtSpinAmp::operator()( const vector<int>& index )
169{
170 checkindexargs( index );
171
172 int trueindex = findtrueindex(index);
173 if(trueindex >= _elem.size()) {
174 report(ERROR,"EvtGen")<<"indexing error "<<trueindex<<" "<<_elem.size()<<endl;
175 for(int i=0; i<_twospin.size(); ++i) {
176 report(ERROR,"")<<_twospin[i]<<" ";
177 }
178 report(ERROR,"")<<endl;
179
180 for(int i=0; i<index.size(); ++i) {
181 report(ERROR,"")<<index[i]<<" ";
182 }
183 report(ERROR,"")<<endl;
184
185 ::abort();
186 }
187
188 return _elem[trueindex];
189}
190
191const EvtComplex & EvtSpinAmp::operator()( const vector<int>& index ) const
192{
193 checkindexargs( index );
194
195 int trueindex = findtrueindex(index);
196 if(trueindex >= _elem.size()) {
197 report(ERROR,"EvtGen")<<"indexing error "<<trueindex<<" "<<_elem.size()<<endl;
198 for(int i=0; i<_twospin.size(); ++i) {
199 report(ERROR,"")<<_twospin[i]<<" ";
200 }
201 report(ERROR,"")<<endl;
202
203 for(int i=0; i<index.size(); ++i) {
204 report(ERROR,"")<<index[i]<<" ";
205 }
206 report(ERROR,"")<<endl;
207
208 ::abort();
209 }
210
211 return _elem[trueindex];
212}
213
215{
216 va_list ap;
217 vector<int> index( _twospin.size() );
218
219 va_start(ap, i);
220
221 index[0]=i;
222 for(int n=1; n<_twospin.size(); ++n )
223 index[n]=va_arg( ap, int );
224
225 va_end(ap);
226
227 return (*this)( index );
228}
229
230const EvtComplex & EvtSpinAmp::operator()( int i, ... ) const
231{
232 vector<int> index( _twospin.size() );
233 va_list ap;
234
235 va_start(ap, i);
236
237 index[0]=i;
238 for(int n=1; n<_twospin.size(); ++n )
239 index[n]=va_arg( ap, int );
240
241 va_end(ap);
242
243 return (*this)( index );
244}
245
247{
248 _twospin=cont._twospin;
249 _elem=cont._elem;
250 _type=cont._type;
251
252 return *this;
253}
254
256{
257 checktwospin( cont._twospin );
258
259 EvtSpinAmp ret( cont );
260 for( int i=0; i<ret._elem.size(); ++i ) {
261 ret._elem[i]+=_elem[i];
262 }
263
264 return ret;
265}
266
268 cont )
269{
270 checktwospin( cont._twospin );
271
272 for( int i=0; i<_elem.size(); ++i )
273 _elem[i]+=cont._elem[i];
274
275 return *this;
276}
277
279{
280 checktwospin( cont._twospin );
281
282 EvtSpinAmp ret( *this );
283 for( int i=0; i<ret._elem.size(); ++i )
284 ret._elem[i]-=cont._elem[i];
285
286 return ret;
287}
288
290{
291 checktwospin( cont._twospin );
292
293 for( int i=0; i<_elem.size(); ++i )
294 _elem[i]-=cont._elem[i];
295
296 return *this;
297}
298
299// amp = amp1 * amp2
301{
302 vector<int> index(rank()+amp2.rank());
303 vector<int> index1(rank()), index2(amp2.rank());
304 EvtSpinAmp amp;
305
306 amp._twospin=_twospin;
307 amp._type=_type;
308
309 for( int i=0; i<amp2._twospin.size(); ++i ) {
310 amp._twospin.push_back( amp2._twospin[i] );
311 amp._type.push_back( amp2._type[i] );
312 }
313
314 amp._elem = vector<EvtComplex>( _elem.size() * amp2._elem.size() );
315
316 for( int i=0; i<index1.size(); ++i )
317 index[i]=index1[i]=-_twospin[i];
318
319 for( int i=0; i<index2.size(); ++i )
320 index[i+rank()]=index2[i]=-amp2._twospin[i];
321
322 while(true) {
323 amp( index ) = (*this)( index1 )*amp2( index2 );
324 if(!amp.iterate( index )) break;
325
326 for( int i=0; i<index1.size(); ++i )
327 index1[i]=index[i];
328
329 for( int i=0; i<index2.size(); ++i )
330 index2[i]=index[i+rank()];
331 }
332
333 return amp;
334}
335
337{
338 EvtSpinAmp ret = (*this)*cont;
339 *this=ret;
340 return *this;
341}
342
344{
345 for( int i=0; i<_elem.size(); ++i )
346 _elem[i] *= real;
347
348 return *this;
349}
350
352{
353 for( int i=0; i<_elem.size(); ++i )
354 _elem[i] /= real;
355
356 return *this;
357}
358
359vector<int> EvtSpinAmp::iterinit() const
360{
361 vector<int> init( _twospin.size() );
362
363 for( int i=0; i<_twospin.size(); ++i )
364 init[i]=-_twospin[i];
365
366 return init;
367}
368
369bool EvtSpinAmp::iterate( vector<int>& index ) const
370{
371 int last = _twospin.size() - 1;
372
373 index[0]+=2;
374 for( int j=0; j<last; ++j ) {
375 if( index[j] > _twospin[j] ) {
376 index[j] = -_twospin[j];
377 index[j+1]+=2;
378 }
379 }
380
381 return abs(index[last])<=_twospin[last];
382}
383
384// Test whether a particular index is an allowed one (specifically to deal with
385// photons and possibly neutrinos)
386bool EvtSpinAmp::allowed( const vector<int>& index ) const
387{
388 if( index.size() != _type.size() ) {
389 report(ERROR,"EvtGen")
390 <<"Wrong dimensino index input to allowed."<<endl;
391 ::abort();
392 }
393
394 for(int i=0; i<index.size(); ++i) {
395 switch(_type[i]) {
397 if(abs(index[i])!=2) return false;
398 break;
400 report(ERROR,"EvtGen")
401 <<"EvMultibody currently cannot handle neutrinos."<<endl;
402 ::abort();
403 default:
404 break;
405 }
406 }
407
408 return true;
409}
410
411bool EvtSpinAmp::iterateallowed( vector<int>& index ) const
412{
413 while(true) {
414 if(!iterate( index ))
415 return false;
416 if(allowed( index ))
417 return true;
418 }
419}
420
422{
423 vector<int> init = iterinit();
424 while(!allowed(init)) {
425 iterate(init);
426 }
427
428 return init;
429}
430
431void EvtSpinAmp::intcont( int a, int b )
432{
433 int newrank=rank()-2;
434 if(newrank<=0) {
435 report(ERROR,"EvtGen")<<"EvtSpinAmp can't handle no indices" << endl;
436 ::abort();
437 }
438
439 if(_twospin[a]!=_twospin[b]) {
440 report(ERROR,"EvtGen")
441 <<"Contaction called on indices of different dimension"
442 <<endl;
443 report(ERROR,"EvtGen")
444 <<"Called on "<<_twospin[a]<<" and "<<_twospin[b]
445 <<endl;
446 ::abort();
447 }
448
449 vector<int> newtwospin( newrank );
450 vector<EvtSpinType::spintype> newtype( newrank );
451
452 for( int i=0, j=0; i<_twospin.size(); ++i ){
453 if(i==a || i==b) continue;
454
455 newtwospin[j] = _twospin[i];
456 newtype[j] = _type[i];
457 ++j;
458 }
459
460 EvtSpinAmp newamp( newtype );
461 vector<int> index( rank() ), newindex = newamp.iterinit();
462
463 for( int i=0; i<newrank; ++i )
464 newindex[i] = -newtwospin[i];
465
466 while(true) {
467
468 for( int i=0, j=0; i<rank(); ++i ) {
469 if(i==a || i==b) continue;
470 index[i]=newindex[j];
471 ++j;
472 }
473
474 index[b]=index[a]=-_twospin[a];
475 newamp(newindex) = (*this)(index);
476 for( int i=-_twospin[a]+2; i<=_twospin[a]; i+=2 ) {
477 index[b]=index[a]=i;
478 newamp(newindex) += (*this)(index);
479 }
480
481 if(!newamp.iterate(newindex)) break;
482 }
483
484 *this=newamp;
485}
486
487// In A.extcont(B), a is the index in A and b is the index in B - note that this
488// routine can be extremely improved!
489void EvtSpinAmp::extcont( const EvtSpinAmp& cont, int a, int b )
490{
491 EvtSpinAmp ret = (*this)*cont;
492 ret.intcont( a, rank()+b );
493
494 *this=ret;
495}
const Int_t n
double real(const EvtComplex &c)
double abs(const EvtComplex &c)
ostream & report(Severity severity, const char *facility)
Definition EvtReport.cc:36
@ ERROR
Definition EvtReport.hh:49
std::ostream & operator<<(std::ostream &os, const EvtSpinAmp &amp)
Definition EvtSpinAmp.cc:9
EvtSpinAmp operator*(const EvtComplex &real, const EvtSpinAmp &cont)
Definition EvtSpinAmp.cc:25
EvtSpinAmp operator/(const EvtSpinAmp &cont, const EvtComplex &real)
Definition EvtSpinAmp.cc:41
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
int rank() const
Definition EvtSpinAmp.hh:64
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 &)
Definition EvtSpinAmp.cc:25
void intcont(int, int)
void extcont(const EvtSpinAmp &, int, int)
EvtSpinAmp operator-(const EvtSpinAmp &) const
static int getSpin2(spintype stype)
int num[96]
Definition ranlxd.c:373