51 const string& reactionName) :
53 m_optimizeParIteration( false )
55 cout << endl <<
"## AMPLITUDE MANAGER INITIALIZATION ##" << endl;
56 cout <<
" Creating amplitude manager for reaction: " << reactionName << endl;
61 map< string, vector< pair< int, int > > > swapsByType;
62 for(
unsigned int i = 0; i < reaction.size(); ++i ){
64 cout <<
"\t particle index assignment: " << reaction[i] <<
" -->> " << i << endl;
66 for(
unsigned int j = i + 1; j < reaction.size(); ++j ){
68 if( reaction[i] == reaction[j] ){
70 swapsByType[reaction[i]].push_back( pair< int, int >( i, j ) );
77 int numberOfCombos = 1;
78 for( map<
string, vector< pair< int, int > > >::iterator partItr = swapsByType.begin();
79 partItr != swapsByType.end(); ++partItr ){
82 int partCombos = partItr->second.size() + 1;
84 cout <<
"There are " << partCombos
85 <<
" ways of rearranging particles of type: " 86 << partItr->first << endl;
88 numberOfCombos *= partCombos;
94 vector< int > defaultOrder( reaction.size() );
95 for(
unsigned int i = 0; i < reaction.size(); ++i ){
102 vector< vector< pair< int, int > > > swaps;
103 for( map<
string, vector< pair< int, int > > >::iterator itr = swapsByType.begin();
104 itr != swapsByType.end(); ++itr ){
106 swaps.push_back( itr->second );
112 swaps.back().push_back( pair< int, int >( 0, 0 ) );
118 generateSymmetricCombos( vector< pair< int, int > >( 0 ),
119 swaps, defaultOrder );
121 if( m_symmCombos.size() > 1 ){
123 cout <<
"The following " << numberOfCombos <<
" orderings of the particles are" << endl
124 <<
"indistinguishable and will be permuted when computing amplitudes." << endl;
126 for(
unsigned int i = 0; i < m_symmCombos.size(); ++i ){
128 for(
unsigned int j = 0; j < reaction.size(); ++j ){
130 cout <<
"\t" << m_symmCombos[i][j];
139 for( map< string, Amplitude* >::iterator mapItr = m_registeredFactors.begin();
140 mapItr != m_registeredFactors.end(); ++mapItr ){
142 delete mapItr->second;
145 for( map<
string, vector< const Amplitude* > >::iterator mapItr = m_mapNameToAmps.begin();
146 mapItr != m_mapNameToAmps.end(); ++mapItr ){
148 for( vector< const Amplitude* >::iterator vecItr = mapItr->second.begin();
149 vecItr != mapItr->second.end(); ++vecItr ){
162 unsigned int nAmpFactorsAndPerms = 0;
167 unsigned int iNFactors =
getFactors( ampNames[i] ).size();
169 assert( iNPermutations*iNFactors );
171 if( ( iNPermutations * iNFactors ) > nAmpFactorsAndPerms )
172 nAmpFactorsAndPerms = iNPermutations * iNFactors;
178 return 2 * nAmpFactorsAndPerms;
194 for( vector< bool >::const_iterator isFixed = m_vbIsAmpFixed.begin();
195 isFixed != m_vbIsAmpFixed.end();
198 if( !(*isFixed) )
return true;
209 VT_TRACER(
"AmplitudeManager::calcTerms" );
212 bool modifiedTerm =
false;
216 int iNAmps = ampNames.size();
219 #ifndef GPU_ACCELERATION 224 for( iAmpIndex = 0; iAmpIndex < iNAmps; iAmpIndex++ )
227 map< string, vector< vector< int > > >::const_iterator permItr =
228 m_ampPermutations.find( ampNames[iAmpIndex] );
229 assert( permItr != m_ampPermutations.end() );
230 const vector< vector< int > >& vvPermuations = permItr->second;
231 int iNPermutations = vvPermuations.size();
233 vector< const Amplitude* > vAmps =
234 m_mapNameToAmps.find(ampNames.at(iAmpIndex))->second;
236 int iFactor, iNFactors = vAmps.size();
242 if( a.
m_termsValid && m_vbIsAmpFixed[iAmpIndex] )
continue;
249 bool recalculateFactors =
false;
252 for( iFactor=0; iFactor < iNFactors; iFactor++ ){
254 pCurrAmp = vAmps.at( iFactor );
261 m_dataAmpIteration[&a][pCurrAmp] == m_ampIteration[pCurrAmp] ) ){
263 recalculateFactors =
true;
264 m_dataAmpIteration[&a][pCurrAmp] = m_ampIteration[pCurrAmp];
268 if( !recalculateFactors )
continue;
277 int iLocalOffset = 0;
278 for( iFactor=0; iFactor < iNFactors;
279 iFactor++, iLocalOffset += 2 * a.
m_iNEvents * iNPermutations ){
281 pCurrAmp = vAmps.at( iFactor );
283 #ifndef GPU_ACCELERATION 291 #endif//GPU_ACCELERATION 298 #ifndef GPU_ACCELERATION 301 GDouble dAmpFacRe, dAmpFacIm, dTRe, dTIm;
303 unsigned long long iOffsetA, iOffsetP, iOffsetF;
314 iOffsetA = 2 * a.
m_iNEvents * iAmpIndex + 2 * iEvent;
316 for( iPerm = 0; iPerm < iNPermutations; iPerm++ )
318 iOffsetP = 2 * a.
m_iNEvents * iPerm + 2 * iEvent;
323 for( iFactor = 1; iFactor < iNFactors; iFactor++ )
325 iOffsetF = iOffsetP + 2 * a.
m_iNEvents * iNPermutations * iFactor;
337 a.
m_pdAmps[iOffsetA+1] += dAmpFacIm;
340 a.
m_pdAmps[iOffsetA] *= dSymmFactor;
341 a.
m_pdAmps[iOffsetA+1] *= dSymmFactor;
363 VT_TRACER(
"AmplitudeManager::calcIntensities" );
383 #ifdef GPU_ACCELERATION 390 int iNAmps = ampNames.size();
393 double* pdViVjRe =
new double[iNAmps*(iNAmps+1)/2];
394 double* pdViVjIm =
new double[iNAmps*(iNAmps+1)/2];
397 complex< double > cTmp;
398 for( i = 0; i < iNAmps; i++ ){
399 for( j = 0; j <= i; j++ ){
405 cTmp /=
sqrt(
normInt()->ampInt( ampNames[i], ampNames[i] ) *
406 normInt()->ampInt( ampNames[j], ampNames[j] ) );
409 pdViVjRe[i*(i+1)/2+j] = cTmp.real();
410 pdViVjIm[i*(i+1)/2+j] = cTmp.imag();
414 pdViVjRe[i*(i+1)/2+j] *= 2;
415 pdViVjIm[i*(i+1)/2+j] *= 2;
421 double cAiAjRe,cAiAjIm;
429 for( i = 0; i < iNAmps; i++ ){
430 for( j = 0; j <= i; j++ ){
433 if( !m_sumCoherently[i][j] )
continue;
446 dIntensity += pdViVjRe[i*(i+1)/2+j] * cAiAjRe -
447 pdViVjIm[i*(i+1)/2+j] * cAiAjIm;
454 if( dIntensity > maxInten ) maxInten = dIntensity;
469 VT_TRACER(
"AmplitudeManager::calcSumLogIntensity" );
480 #ifndef GPU_ACCELERATION 502 vector< complex< double > > gpuProdPars( ampNames.size() );
504 for(
int i = 0; i < ampNames.size(); ++i ){
510 gpuProdPars[i] /=
sqrt(
normInt()->ampInt( ampNames[i], ampNames[i] ) );
535 VT_TRACER(
"AmplitudeManager::calcIntegrals" );
546 assert( iNGenEvents );
555 for( i = 0; i < iNAmps;i++ ) {
556 for( j = 0; j <= i; j++ ) {
571 integralMatrix[2*i*iNAmps+2*j] = 0;
572 integralMatrix[2*i*iNAmps+2*j+1] = 0;
576 if( m_sumCoherently[i][j] ){
578 #ifndef GPU_ACCELERATION 583 integralMatrix[2*i*iNAmps+2*j] += a.
m_pdWeights[iEvent] *
589 integralMatrix[2*i*iNAmps+2*j+1] += a.
m_pdWeights[iEvent] *
596 integralMatrix[2*i*iNAmps+2*j] /=
static_cast< GDouble >( iNGenEvents );
597 integralMatrix[2*i*iNAmps+2*j+1] /=
static_cast< GDouble >( iNGenEvents );
607 integralMatrix[2*j*iNAmps+2*i] = integralMatrix[2*i*iNAmps+2*j];
608 integralMatrix[2*j*iNAmps+2*i+1] = -integralMatrix[2*i*iNAmps+2*j+1];
616 const vector< vector< int > >&
619 map< string, vector< vector< int > > >::const_iterator mapItr =
620 m_ampPermutations.find( name );
623 assert( mapItr != m_ampPermutations.end() );
625 return( mapItr->second );
628 const vector< const Amplitude* >&
631 map< string, vector< const Amplitude* > >::const_iterator mapItr =
632 m_mapNameToAmps.find( name );
635 assert( mapItr != m_mapNameToAmps.end() );
637 return( mapItr->second );
642 const string& factorName,
643 const vector< string >& args,
645 const string& scale ){
647 map< string, Amplitude* >::iterator defaultAmp =
648 m_registeredFactors.find( factorName );
650 if( defaultAmp == m_registeredFactors.end() ){
652 cout <<
"ERROR: amplitude factor with name " << factorName
653 <<
" has not been registered." << endl;
664 m_ampSum.push_back( sum );
665 m_vbIsAmpFixed.push_back(
true );
667 m_mapNameToAmps[name] = vector< const Amplitude* >( 0 );
673 if( m_ampPermutations.find( name ) != m_ampPermutations.end() )
676 for( vector< vector< int > >::iterator vecItr = m_symmCombos.begin();
677 vecItr != m_symmCombos.end(); ++vecItr )
679 m_ampPermutations[name].push_back( *vecItr );
686 m_ampPermutations[name] = m_symmCombos;
691 int nAmps = m_ampSum.size();
692 vector< bool > lastRow;
696 for(
int i = 0; i < nAmps; ++i ){
698 bool coh = ( m_ampSum[i] == sum );
702 m_sumCoherently[i].push_back( coh );
703 lastRow.push_back( coh );
707 lastRow.push_back(
true );
708 m_sumCoherently.push_back( lastRow );
711 m_mapNameToAmps[name].push_back( newAmp );
721 map< string, vector< vector< int > > >::iterator mapItr = m_ampPermutations.find( ampName );
723 if( mapItr == m_ampPermutations.end() ){
725 cout <<
"WARNING: adding permutation for nonexistent amplitude " << ampName
728 m_ampPermutations[ampName] = vector< vector< int > >( 0 );
729 m_ampPermutations[ampName].push_back( permutation );
734 bool foundPermutation =
false;
736 for( vector< vector< int > >::const_iterator vecItr = mapItr->second.begin();
737 vecItr != mapItr->second.end();
740 if( permutation == *vecItr ) foundPermutation =
true;
743 if( !foundPermutation ){
745 cout <<
"Adding a new permutation for " << ampName <<
": ";
746 for( vector< int >::const_iterator itr = permutation.begin();
747 itr != permutation.end();
754 mapItr->second.push_back( permutation );
758 cout <<
"The permutation ";
759 for( vector< int >::const_iterator itr = permutation.begin();
760 itr != permutation.end();
765 cout <<
"already exists for " << ampName << endl;
773 vector< string > sumName;
777 for (
unsigned int i = 0; i < ampInfoVector.size(); i++){
779 string ampName = ampInfoVector[i]->fullName();
780 string sumName = ampInfoVector[i]->sumName();
781 string scale = ampInfoVector[i]->scale();
784 vector< vector<string> > ampFactors = ampInfoVector[i]->factors();
785 for (
unsigned int j = 0; j < ampFactors.size(); j++){
786 string factorName = ampFactors[j][0];
787 vector<string> ampParameters = ampFactors[j];
788 ampParameters.erase(ampParameters.begin());
789 addAmpFactor( ampName, factorName, ampParameters, sumName, scale );
793 vector< vector<int> > permutations = ampInfoVector[i]->permutations();
794 for (
unsigned int j = 0; j < permutations.size(); j++){
805 vector< ParameterInfo* > pars = ampInfoVector[i]->parameters();
806 for( vector< ParameterInfo* >::iterator parItr = pars.begin();
807 parItr != pars.end();
810 setParValue( ampName, (**parItr).parName(), (**parItr).value() );
814 vector< const Amplitude* > ampVec = m_mapNameToAmps[ampName];
815 for( vector< const Amplitude* >::iterator amp = ampVec.begin();
832 const double* ampParPtr ){
838 for( vector< const Amplitude* >::iterator factorItr = m_mapNameToAmps[name].begin();
839 factorItr != m_mapNameToAmps[name].end();
842 if( (**factorItr).setParPtr( parName, ampParPtr ) ){
861 for( vector< const Amplitude* >::iterator factorItr = m_mapNameToAmps[name].begin();
862 factorItr != m_mapNameToAmps[name].end();
865 (**factorItr).setParValue( parName, val );
868 !(**factorItr).containsFreeParameters();
875 for( map<
string, vector< const Amplitude* > >::const_iterator mapItr = m_mapNameToAmps.begin();
876 mapItr != m_mapNameToAmps.end();
879 for( vector< const Amplitude* >::const_iterator ampItr = mapItr->second.begin();
880 ampItr != mapItr->second.end();
886 if( (**ampItr).updatePar( parName ) ){
888 ++m_ampIteration[*ampItr];
897 m_registeredFactors[amplitude.
name()] = amplitude.
clone();
903 AmplitudeManager::generateSymmetricCombos(
const vector< pair< int, int > >& prevSwaps,
904 vector< vector< pair< int, int > > > remainingSwaps,
905 const vector< int >& defaultOrder ){
907 if( remainingSwaps.size() == 0 ){
912 vector< int > swappedOrder = defaultOrder;
913 for( vector< pair< int, int > >::const_iterator swapItr = prevSwaps.begin();
914 swapItr != prevSwaps.end(); ++swapItr ){
916 int temp = swappedOrder[swapItr->first];
917 swappedOrder[swapItr->first] = swappedOrder[swapItr->second];
918 swappedOrder[swapItr->second] = temp;
922 m_symmCombos.push_back( swappedOrder );
927 vector< pair< int, int > > currentSwaps = remainingSwaps.back();
928 remainingSwaps.pop_back();
931 for( vector< pair< int, int > >::iterator itr = currentSwaps.begin();
932 itr != currentSwaps.end(); ++itr ){
934 vector< pair< int, int > > newPrevSwaps = prevSwaps;
935 newPrevSwaps.push_back( *itr );
936 generateSymmetricCombos( newPrevSwaps, remainingSwaps, defaultOrder );
void setParValue(const string &termName, const string &parName, double ampParValue)
void calcAmplitudeAll(const Amplitude *amp, unsigned long long offset, const vector< vector< int > > *pvPermutations)
unsigned long long m_iNEvents
string reactionName() const
virtual Amplitude * clone() const =0
void calcIntegral(GDouble *result, int iAmp, int jAmp, int iNGenEvents)
unsigned int termStoragePerEvent() const
bool calcTerms(AmpVecs &Vecs) const
void allocateCPUAmpStorage(const IntensityManager &intenMan)
void registerAmplitudeFactor(const Amplitude &defaultAmplitude)
void assembleTerms(int iAmpInd, int nFact, int nPerm)
virtual void setParValue(const string &termName, const string &parName, double ampParValue)
bool hasTerm(const string &termName) const
virtual Amplitude * newAmplitude(const vector< string > &args) const =0
double calcIntensities(AmpVecs &Vecs) const
void copyAmpsFromGPU(AmpVecs &a)
int termIndex(const string &termName) const
virtual void setParPtr(const string &termName, const string &parName, const double *ampParPtr)
const NormIntInterface * normInt() const
const vector< string > & getTermNames() const
const vector< const Amplitude *> & getFactors(const string &name) const
virtual string name() const =0
unsigned long long m_iNTrueEvents
bool termsAreRenormalized() const
double calcSumLogIntensity(const vector< complex< double > > &prodCoef, const vector< vector< bool > > &cohMtx)
void calcIntegrals(AmpVecs &Vecs, int iNGenEvents) const
void updatePar(const string &parName) const
void setDefaultProductionFactor(const string &termName, complex< double > prodAmp)
void addAmpFactor(const string &Name, const string &factorName, const vector< string > &args, const string &sum="", const string &scale="1.0")
bool hasTermWithFreeParam() const
int addTerm(const string &termName, const string &scale="1.0")
void setupFromConfigurationInfo(const ConfigurationInfo *configInfo)
void setParPtr(const string &termName, const string &parName, const double *ampParPtr)
void addAmpPermutation(const string &Name, const vector< int > &permutation)
const vector< vector< int > > & getPermutations(const string &name) const
complex< double > productionFactor(const string &termName) const
vector< AmplitudeInfo * > amplitudeList(const string &reactionName="", const string &sumName="", const string &Name="") const
double calcSumLogIntensity(AmpVecs &Vecs) const
bool containsFreeParameters() const
unsigned int maxFactorStoragePerEvent() const
GDouble * m_pdIntegralMatrix
AmplitudeManager(const vector< string > &finalState, const string &reactionName="")