Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Herwig/Utilities/GaussianIntegrator.tcc is written in an unsupported language. File is not indexed.

0001 // -*- C++ -*-
0002 //
0003 // GaussianIntegrator.tcc is a part of Herwig - A multi-purpose Monte Carlo event generator
0004 // Copyright (C) 2002-2019 The Herwig Collaboration
0005 //
0006 // Herwig is licenced under version 3 of the GPL, see COPYING for details.
0007 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
0008 //
0009 //
0010 // This is the implementation of the non-inlined templated member
0011 // functions of the GaussianIntegrator class.
0012 //
0013 
0014 namespace Herwig {
0015 using namespace ThePEG;
0016 
0017 template <class T>
0018 inline GaussianIntegrator::ValT<T>
0019 GaussianIntegrator::value(const T & function, 
0020                           const typename T::ArgType lower, 
0021                           const typename T::ArgType upper) const {
0022   typedef typename T::ValType ValType;
0023   typedef typename T::ArgType ArgType;
0024   const ValType ValUnit = TypeTraits<ValType>::baseunit();
0025   const ArgType ArgUnit = TypeTraits<ArgType>::baseunit();
0026 
0027   // vector for the limits of the bin
0028   vector<double> lowerlim,upperlim;
0029   // start with the whole interval as 1 bin
0030   lowerlim.push_back(lower/ArgUnit);upperlim.push_back(upper/ArgUnit);
0031   // set the minimum bin width
0032   double xmin=_binwidth*abs(upper-lower)/ArgUnit;
0033   // counters for the number of function evals
0034   int neval=0;
0035   // and number of bad intervals
0036   int nbad=0;
0037   // the output value
0038   double output=0.;
0039   // the loop for the evaluation
0040   double mid,wid; unsigned int ibin,ix=0,iorder;
0041   double testvalue,value,tolerance;
0042   do {
0043     // the bin we are doing (always the last one in the list)
0044     ibin = lowerlim.size()-1;
0045     // midpoint and width of the bin
0046     mid=0.5*(upperlim[ibin]+lowerlim[ibin]);
0047     wid=0.5*(upperlim[ibin]-lowerlim[ibin]);
0048     value=0.;
0049     iorder=0;
0050     // compute a trail value using sixth order GQ
0051     for(ix=0;ix<_weights[0].size();++ix) {
0052       value+=_weights[0][ix]
0053         *( function((mid+wid*_abscissae[0][ix])*ArgUnit)
0054           +function((mid-wid*_abscissae[0][ix])*ArgUnit)
0055            )/ValUnit;
0056       ++neval;
0057       if(neval>_maxeval) 
0058         CurrentGenerator::log() << "Error in Gaussian Integrator: Setting to zero" 
0059                                 << endl;
0060     }
0061     value *=wid;
0062     // compute more accurate answers using higher order GQ
0063     do {
0064       // use the next order of quadrature
0065       testvalue=value;
0066       ++iorder;
0067       value=0.;
0068       for(ix=0;ix<_weights[iorder].size();++ix) {
0069         value+=_weights[iorder][ix]*
0070           ( function((mid+wid*_abscissae[iorder][ix])*ArgUnit)
0071            +function((mid-wid*_abscissae[iorder][ix])*ArgUnit)
0072             )/ValUnit;
0073         ++neval;
0074         if(neval>_maxeval)
0075            CurrentGenerator::log() << "Error in Gaussian Integrator: Setting to zero" 
0076                                    << endl;
0077       }
0078       value *=wid;
0079       tolerance=max(_abserr,_relerr*abs(value));
0080     }
0081     // keep going if possible and not accurate enough
0082     while(iorder<_weights.size()-1&&abs(testvalue-value)>tolerance);
0083     // now decide what to do
0084     // accept this value
0085     if(abs(testvalue-value)<tolerance) {
0086       output+=value;
0087       lowerlim.pop_back();upperlim.pop_back();
0088     }
0089     // bin too small to redivide contribution set to zero
0090     else if(wid<xmin) {
0091       ++nbad;
0092       lowerlim.pop_back(); upperlim.pop_back();
0093     }
0094     // otherwise split the bin into two
0095     else {
0096       // reset the limits for the bin
0097       upperlim[ibin]=mid;
0098       // set up a new bin
0099       lowerlim.push_back(mid);
0100       upperlim.push_back(mid+wid);
0101     }
0102   }
0103   // keep going if there's still some bins to evaluate
0104   while(lowerlim.size()>0);
0105   // output an error message if needed
0106   if(nbad!=0)
0107     CurrentGenerator::log() << "Error in GaussianIntegrator: Bad Convergence for " 
0108                             << nbad << "intervals" << endl;
0109   // return the answer
0110   return output * ValUnit * ArgUnit;
0111 }
0112 
0113 }