Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-06 09:38:17

0001 // -*- C++ -*-
0002 //
0003 // ACDCGen.h is a part of ThePEG - Toolkit for HEP Event Generation
0004 // Copyright (C) 1999-2019 Leif Lonnblad
0005 //
0006 // ThePEG 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 #ifndef ACDCGen_H
0010 #define ACDCGen_H
0011 
0012 #include <algorithm>
0013 #include "ACDCGenConfig.h"
0014 #include "ACDCTraits.h"
0015 #include "ACDCGenCell.h"
0016 #include "ThePEG/Utilities/Exception.h"
0017 
0018 namespace ACDCGenerator {
0019 
0020 /**
0021  * ACDCGen is a general class for sampling multi-dimensional
0022  * functions. ACDCGen can sample several functions simultaneously,
0023  * selecting different functions according to the relative
0024  * probabilities determined by their total integrals. The functions
0025  * are sampled on a unit hypercube. Function object of any class can
0026  * be used as long as the ACDCFncTraits class is specialized
0027  * correctly. ACDCFncTraits can also be used to rescale values in the
0028  * unit hypercube to any desired range. ACDCGen needs a random number
0029  * generator. Again, random number generators of any class can be used
0030  * as long as the ACDCRandomTraits class is specialized correctly.
0031  *
0032  * To give an unweighted samlpe ACDCGen uses a compensating
0033  * algorithm. Before the production sampling begins, the functions are
0034  * sampled randomly in the hypercube a user-defined number of times to
0035  * find an approximate maxumum value. The hypercube is then divided
0036  * into cells each of which have an approximate maximum value of the
0037  * function, to enable efficient sampling. The maxima are only
0038  * approximate though and, if a function value is found above the
0039  * maximum in a cell the ACDCGen will go into a compensating mode. The
0040  * cell is then first subdivided further and in the following this
0041  * cell will be over-sampled to compensate for that fact that it was
0042  * under-sampled before. In this way the probability of obtaining a
0043  * biased sample is reduced. Also rather functions with large peaks
0044  * are then sampled rather efficiently. Functions with narrow peaks
0045  * should, however, be avoided since there is no guarantee that the
0046  * peack is actually hit.
0047  */
0048 template <typename Rnd, typename FncPtr>
0049 class ACDCGen {
0050 
0051 public:
0052 
0053   /** Template argument typedef. */
0054   typedef Rnd RndType;
0055   /** Template argument typedef. */
0056   typedef ACDCRandomTraits<RndType> RndTraits;
0057   /** Template argument typedef. */
0058   typedef FncPtr FncPtrType;
0059   /** A vector of cells. */
0060   typedef vector<ACDCGenCell*> CellVector;
0061   /** A vector of function objects. */
0062   typedef vector<FncPtrType> FncVector;
0063   /** A vector of integers. */
0064   typedef vector<DimType> DimVector;
0065   /** The size type of the vectors used. */
0066   typedef DimVector::size_type size_type;
0067   /** Template argument typedef. */
0068   typedef ACDCFncTraits<FncPtrType> FncTraits;
0069 
0070 public:
0071 
0072   /**
0073    * Standard constructor requiring a random generator object to be
0074    * used.
0075    */
0076   inline ACDCGen(Rnd * r);
0077 
0078   /**
0079    * Default Constructor.
0080    */
0081   inline ACDCGen();
0082 
0083   /**
0084    * Destructor.
0085    */
0086   inline ~ACDCGen();
0087 
0088   /**
0089    * Add a function of a given dimension, \a dim, according to which
0090    * points will be generated. Note that each function, \a f, added
0091    * like this will have its own tree of cells. The \a maxrat argument
0092    * determines the lowest ratio of values allowed between the cell
0093    * with lowest and highest value. If negative it is given by 1/nTry().
0094    */
0095   inline bool addFunction(DimType dim, FncPtrType f, double maxrat = -1.0);
0096 
0097   /**
0098    * Remove all added functions and reset the generator;
0099    */
0100   inline void clear();
0101 
0102 public:
0103 
0104   /**
0105    * Generate a point, choosing between the different functions
0106    * specified. The chosen function is returned, while the generated
0107    * point is obtained by the function lastPoint().
0108    */
0109   inline FncPtrType generate();
0110 
0111   /**
0112    * Reject the last generated point. Only used in the evaluation of
0113    * the total integral.
0114    */
0115   inline void reject();
0116 
0117   /**
0118    * Return the last generated point.
0119    * @return a vector of doubles, each in the interval ]0,1[.
0120    */
0121   inline const DVector & lastPoint() const;
0122 
0123   /**
0124    * Return the value of the last chosen function in the last point.
0125    */
0126   inline double lastF() const;
0127 
0128   /**
0129    * Return the function chosen for the last generated point.
0130    */
0131   inline FncPtrType lastFunction() const;
0132 
0133   /**
0134    * return the index of the function chosen for the last generated
0135    * point.
0136    */
0137   inline size_type last() const;
0138 
0139 public:
0140 
0141   /** @name Functions influencing the efficiency of the generation. */
0142   //@{
0143   /**
0144    * Set the minimum cell size considered for this generation. The
0145    * default is the machine limit for double precision times a
0146    * hundred.
0147    */
0148   inline void eps(double newEps);
0149 
0150   /**
0151    * Set the safety margin used to multiply the highest found function
0152    * value in a cell when setting its overestimated value. (Default is
0153    * 1.1.)
0154    */
0155   inline void margin(double newMargin);
0156 
0157   /**
0158    * Set the number of points (with non-zero function value) used to
0159    * initialize the tree of cells to use in the generation for each
0160    * function.
0161    */
0162   inline void nTry(size_type newNTry);
0163 
0164   /**
0165    * Set the maximum number of attempts to generate a phase space
0166    * point, or to find non-zero points in the initialization.
0167    */
0168   inline void maxTry(long);
0169   //@}
0170 
0171 public:
0172 
0173   /** @name Information about the current generation. */
0174   //@{
0175   /**
0176    * Return the current Monte Carlo estimate of the integral of the
0177    * specified function (or all functions if NULL) over the unit volume. 
0178    */
0179   inline double integral(FncPtrType f = FncPtrType()) const;
0180 
0181   /**
0182    * Return the error on the current Monte Carlo estimate of the
0183    * integral of the specified function (or all functions if NULL)
0184    * over the unit volume.
0185    */
0186   inline double integralErr(FncPtrType f = FncPtrType()) const;
0187 
0188   /**
0189    * The number of accepted points so far.
0190    */
0191   inline long n() const;
0192 
0193   /**
0194    * The number of calls to generate() so far. Note that the number of
0195    * calls to the specified functions may be larger. It is up to the
0196    * user to keep track of those.
0197    */
0198   inline long N() const;
0199 
0200   /**
0201    * The ratio of the number of accepted and number of tried points
0202    * n()/N();
0203    */
0204   inline double efficiency() const;
0205 
0206   /**
0207    * Return the number of active cells created so far.
0208    */
0209   inline int nBins() const;
0210 
0211   /**
0212    * Return the maximum depth of any tree of cells used.
0213    */
0214   inline int depth() const;
0215 
0216   /**
0217    * Return the current overestimation of the full integral of all
0218    * specified functions over the unit volume.
0219    */
0220   inline double maxInt() const;
0221   //@}
0222 
0223   /** @name Access to member variables. */
0224   //@{
0225   /**
0226    * The minimum cell size considered for this generation.
0227    */
0228   inline double eps() const;
0229 
0230   /**
0231    * The safety margin used to multiply the highest found function
0232    * value in a cell when setting its overestimated value.
0233    */
0234   inline double margin() const;
0235 
0236   /**
0237    * The number of points used to initialize the tree of cells to use
0238    * in the generation.
0239    */
0240   inline size_type nTry() const;
0241 
0242   /**
0243    * The maximum number of attempts to generate a phase space point,
0244    * or to find non-zero points in the initialization.
0245    */
0246   inline long maxTry() const;
0247 
0248   /**
0249    * Returns true if generating random numbers are so cheap that a new
0250    * one can be thrown everytime a sub-cell is chosen. Otherwise
0251    * random numbers used for this will be reused.
0252    */
0253   inline bool cheapRandom() const;
0254 
0255   /**
0256    * The number of functions used.
0257    */
0258   inline size_type size() const;
0259 
0260   /**
0261    * Returns true if the generator is currently in a state of
0262    * compensating an erroneous overestimation of one of the specified
0263    * functions. If so, the integral and the generated points are not
0264    * statistically correct.
0265    */
0266   inline bool compensating();
0267 
0268   /**
0269    * Return an estimate of how many points need to be sampled before
0270    * the generator finishes compensating.
0271    */
0272   inline long compleft() const;
0273 
0274   /**
0275    * Return a vector with information about all cells.
0276    */
0277   vector<ACDCGenCellInfo> extractCellInfo() const;
0278   //@}
0279 
0280 public:
0281 
0282   /** @name Functions related to the random number generator. */
0283   //@{
0284   /**
0285    * Set to true if generating random numbers are so cheap that a new
0286    * one can be thrown everytime a sub-cell is chosen. Otherwise
0287    * random numbers used for this will be reused.
0288    */
0289   inline void cheapRandom(bool b);
0290 
0291   /**
0292    * Set a new random number generator.
0293    */
0294   inline void setRnd(Rnd * r);
0295 
0296   /**
0297    * Double precision number in the interval ]0,1[.
0298    */
0299   inline double rnd() const;
0300 
0301   /**
0302    * Double precision number in the interval ]lo,up[.
0303    */
0304   inline double rnd(double lo, double up) const;
0305 
0306   /**
0307    * Fill the r vector with doubles r[i] in the interval ]lo[i],up[i][.
0308    */
0309   inline void rnd(const DVector & lo, const DVector & up, DVector & r)const;
0310 
0311   /**
0312    * Fill the D first elements in the r vector with doubles in the
0313    * interval ]0,1[.
0314    */
0315   inline void rnd(DimType D, DVector & r) const;
0316 
0317   /**
0318    * Integer in the interval [0,x[
0319    */
0320   inline long rndInt(long x) const;
0321   //@}
0322 
0323 public:
0324 
0325   /**
0326    * This function is to be used in ThePEG for output to
0327    * a persistent stream and will not work properly for normal
0328    * ostreams.
0329    */
0330   template <typename POStream>
0331   void output(POStream &) const;
0332 
0333   /**
0334    * This function is to be used in ThePEG for input from a persistent
0335    * stream and will not work properly for normal istreams.
0336    */
0337   template <typename PIStream>
0338   void input(PIStream &);
0339 
0340 private:
0341 
0342   /**
0343    * Calculate the overestimated integral for all functions.
0344    */
0345   inline double doMaxInt();
0346 
0347   /**
0348    * Return the vector of functions.
0349    */
0350   inline const FncVector & functions() const;
0351 
0352   /**
0353    * Return the i'th function.
0354    */
0355   inline FncPtrType function(size_type i) const;
0356 
0357   /**
0358    * Return a vector with the dimensions of all functions.
0359    */
0360   inline const DimVector & dimensions() const;
0361 
0362   /**
0363    * Return the dimension of the i'th function.
0364    */
0365   inline DimType dimension(size_type i) const;
0366 
0367   /**
0368    * Return the dimension of the function chosen for the last
0369    * generated point.
0370    */
0371   inline DimType lastDimension() const;
0372 
0373   /**
0374    * Return the roots of all cell trees.
0375    */
0376   inline const CellVector & cells() const;
0377 
0378   /**
0379    * Return the root cell for the i'th function.
0380    */
0381   inline ACDCGenCell * cell(size_type i) const;
0382 
0383   /**
0384    * Return the root cell for the function chosen for the last
0385    * generated point.
0386    */
0387   inline ACDCGenCell * lastPrimary() const;
0388 
0389   /**
0390    * Return a vector with the incremental sum of overestimated
0391    * integrals for each function.
0392    */
0393   inline const DVector & sumMaxInts() const;
0394 
0395   /**
0396    * Return the cell chosen for the last generated point.
0397    */
0398   inline ACDCGenCell * lastCell() const;
0399 
0400 
0401   /**
0402    * Choose a function according to its overestimated integral and
0403    * choose a cell to generate a point in.
0404    */
0405   inline void chooseCell(DVector & lo, DVector & up);
0406 
0407   /**
0408    * Start the compensation procedure for the last chosen cell when a
0409    * function velue has been found which exceeds the previous
0410    * overestimation.
0411    */
0412   inline void  compensate(const DVector & lo, const DVector & up);
0413 
0414 private:
0415 
0416   /**
0417    * The random number generator to be used for this Generator.
0418    */
0419   RndType * theRnd;
0420   
0421   /**
0422    * The number of accepted points (weight > 0) so far.
0423    */
0424   long theNAcc;
0425 
0426   /**
0427    * The number of attempted points so far.
0428    */
0429   long theN;
0430 
0431   /**
0432    * The number of attempts per function so far.
0433    */
0434   vector<long> theNI;
0435 
0436   /**
0437    * The summed weights per function so far.
0438    */
0439   DVector theSumW;
0440 
0441   /**
0442    * The summed squared weights per function so far.
0443    */
0444   DVector theSumW2;
0445 
0446   /**
0447    * The smallest possible division allowed.
0448    */
0449   double theEps;
0450 
0451   /**
0452    * The factor controlling the loss of efficiency when compensating.
0453    */
0454   double theMargin;
0455 
0456   /**
0457    * The number of points to use to find initial average.
0458    */
0459   size_type theNTry;
0460 
0461   /**
0462    * The maximum number of attempts to generate a phase space point,
0463    * or to find non-zero points in the initialization.
0464    */
0465   long theMaxTry;
0466 
0467   /**
0468    * True if generating random numbers are so cheap that a new one can
0469    * be thrown everytime a sub-cell is chosen. Otherwise random
0470    * numbers used for this will be reused.
0471    */
0472   bool useCheapRandom;
0473 
0474   /**
0475    * A vector of functions.
0476    */
0477   FncVector theFunctions;
0478 
0479   /**
0480    * The dimensions of the functions in theFunctions.
0481    */
0482   DimVector theDimensions;
0483 
0484   /**
0485    * The root of the cell tree for the functions in theFunctions.
0486    */
0487   CellVector thePrimaryCells;
0488 
0489   /**
0490    * The accumulated sum of overestimated integrals of the functions
0491    * in theFunctions.
0492    */
0493   DVector theSumMaxInts;
0494 
0495   /**
0496    * The last index chosen
0497    */
0498   size_type theLast;
0499 
0500   /**
0501    * The last cell chosen.
0502    */
0503   ACDCGenCell * theLastCell;
0504 
0505   /**
0506    * The last point generated.
0507    */
0508   DVector theLastPoint;
0509 
0510   /**
0511    * The function value of the last point.
0512    */
0513   double theLastF;
0514 
0515   /**
0516    * A helper struct representing a level of compensation.
0517    */
0518   struct Level {
0519 
0520     /**
0521      * The number of attempts after which this level disapprears.
0522      */
0523     long lastN;
0524 
0525     /**
0526      * The previous max value in the Cell to compensate.
0527      */
0528     double g;
0529 
0530     /**
0531      * The cell which is being compensated.
0532      */
0533     ACDCGenCell * cell;
0534 
0535     /**
0536      * The index corresponding to the cell being compensated.
0537      */
0538     size_type index;
0539 
0540     /**
0541      * The integration limits for the cell being compensated.
0542      */
0543     DVector up;
0544     /**
0545      * The integration limits for the cell being compensated.
0546      */
0547     DVector lo;
0548 
0549   };
0550 
0551   /**
0552    * A vector (stack) of levels
0553    */
0554   typedef vector<Level> LevelVector;
0555 
0556   /**
0557    * The vector (stack) of levels
0558    */
0559   LevelVector levels;
0560 
0561 
0562   /**
0563    * This is a help struct to perform the divide-and-conquer slicing
0564    * of cells before starting the compensation procedure.
0565    */
0566   struct Slicer {
0567 
0568     /**
0569      * The constructor takes the number of dimensions of the function
0570      * approximated by the current cell, the ACDCGen object
0571      * controlling the generation and the lower-left and upper-right
0572      * corners of the cell to be sliced.
0573      */
0574     Slicer(DimType, ACDCGen &, const DVector &, const DVector &);
0575 
0576     /**
0577      * The constructor used internally when diagonally chopped-off
0578      * cells need to be sliced themselves.
0579      */
0580     Slicer(DimType Din, const Slicer & s, ACDCGenCell * cellin,
0581        const DVector & loin, const DVector & xselin, const DVector & upin,
0582        double fselin);
0583 
0584     /**
0585      * Destructor.
0586      */
0587     ~Slicer();
0588 
0589     /**
0590      * Called from both constructors to do the actual work.
0591      */
0592     void divideandconquer();
0593 
0594     /**
0595      * Initialize the procedure, finding the slicing points around the
0596      * current point
0597      */
0598     void init();
0599 
0600     /**
0601      * Do the slicing and increase the overestimate of the function in
0602      * the resulting cell. If a point with a higher function value has
0603      * been found repeat the slicing around that point etc.
0604      */
0605     void slice();
0606 
0607     /**
0608      * After slicing a cell, find the maximum function value found in
0609      * the resulting cell. Also set the minimum value found.
0610      */
0611     double shiftmaxmin();
0612 
0613     /**
0614      * Find the slice point of the current cell in the direction given.
0615      */
0616     void dohalf(DimType);
0617 
0618     /**
0619      * If split is in more than one dimensions check the overestimate
0620      * for the chopped-off cell.
0621      */
0622     void checkdiag(ACDCGenCell * cell, DimType d, double lod, double upd);
0623 
0624     /**
0625      * The dimension of the cell to be sliced.
0626      */
0627     DimType D;
0628 
0629     /**
0630      * The lower-left corner of the current cell.
0631      */
0632     DVector lo;
0633     /**
0634      * The  upper-right corner of the current cell.
0635      */
0636     DVector up;
0637 
0638     /**
0639      * The lower-left point found closest to the current
0640      * point which gives a function value below the overestimate.
0641      */
0642     DVector xcl;
0643     /**
0644      * The upper-right point found closest to the current point which
0645      * gives a function value below the overestimate.
0646      */
0647     DVector xcu;
0648 
0649     /**
0650      * The lower-left point furthest away from the
0651      * current point which gives a function value abov the
0652      * overestimate.
0653      */
0654     DVector xhl;
0655     /**
0656      * The upper-right point furthest away from the
0657      * current point which gives a function value abov the
0658      * overestimate.
0659      */
0660     DVector xhu;
0661 
0662     /**
0663      * The function values found for the xhl point.
0664      */
0665     DVector fhl;
0666 
0667     /**
0668      * The function values found for the xhu point.
0669      */
0670     DVector fhu;
0671 
0672     /**
0673      * The current point around which we are slicing.
0674      */
0675     DVector xsel;
0676 
0677     /**
0678      * The function value in the current point.
0679      */
0680     double fsel;
0681 
0682     /**
0683      * The current cell.
0684      */
0685     ACDCGenCell * current;
0686 
0687     /**
0688      * The cell which resulted from the first slicing procedure. This
0689      * is the first one to get an increased overestimate and is the
0690      * one to be compensated. All other cells with increased
0691      * overestimates are sub-cells to this one
0692      */
0693     ACDCGenCell * first;
0694 
0695     /**
0696      * The lower-left corner of the 'first' cell.
0697      */
0698     DVector firstlo;
0699     /**
0700      * The upper-right corner of the 'first' cell.
0701      */
0702     DVector firstup;
0703 
0704     /**
0705      * A pointer to the function to be used.
0706      */
0707     FncPtr f;
0708 
0709     /**
0710      * The epsilon() value obtained from the controlling
0711      * ACDCGen object.
0712      */
0713     double epsilon;
0714 
0715     /**
0716      * The margin() value obtained from the controlling
0717      * ACDCGen object.
0718      */
0719     double margin;
0720 
0721     /**
0722      * The dimensions to slice in rated by the resulting fractional
0723      * volume of the resulting slice. If the dimension is negative it
0724      * means that the cell should be slized from below.
0725      */
0726     multimap<double,DimType> rateslice;
0727 
0728     /**
0729      * The minimu function value found in the current sliced cell (set
0730      * by shiftmaxmin()).
0731      */
0732     double minf;
0733 
0734     /**
0735      * If true, then the whole original cell should compensated in the
0736      * continued generation.
0737      */
0738     bool wholecomp;
0739 
0740   };
0741 
0742 public:
0743 
0744   /** The maximum recursion depth of the compensation so far. */
0745   static size_type maxsize;
0746 
0747 private:
0748 
0749   /**
0750    * Copy constructor is private and not implemented.
0751    */
0752   ACDCGen(const ACDCGen &);
0753 
0754   /**
0755    * Assignment is private and not implemented.
0756    */
0757   ACDCGen & operator=(const ACDCGen &) = delete;
0758 
0759 };
0760 
0761 }
0762 
0763 #include "ACDCGen.icc"
0764 
0765 #endif