|
|
|||
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
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|