thepeg is hosted by Hepforge, IPPP Durham
ThePEG  2.2.1
CompSelector.h
1 // -*- C++ -*-
2 //
3 // CompSelector.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 1999-2019 Leif Lonnblad
5 //
6 // ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
8 //
9 #ifndef THEPEG_CompSelector_H
10 #define THEPEG_CompSelector_H
11 //
12 // This is the declaration of the CompSelector class.
13 //
14 
15 #include "ThePEG/Utilities/Selector.h"
16 
17 namespace ThePEG {
18 
46 template <typename T, typename WeightType = double>
47 class CompSelector {
48 
49 public:
50 
58  CompSelector(double newMargin = 1.1, double newTolerance = 1.0e-6)
59  : N(0), last(), theMargin(newMargin), theTolerance(newTolerance) {}
61 
62 public:
63 
75  WeightType insert(WeightType d, const T & t) {
76  reset();
77  return selector.insert(d, t);
78  }
79 
92  template <typename RNDGEN>
93  T & select(RNDGEN & rnd) {
94  ++N;
95  if ( !compensating() ) last = selector.select(rnd);
96  return last;
97  }
98 
105  WeightType reweight(double & weight) {
106  if ( abs(weight) > 1.0 + tolerance() ) {
107  // Retrieve the old overestimate of the object by seing how much
108  // the summed weights are decreased when removing the object.
109  WeightType oldtot = selector.sum();
110  WeightType oldmax = oldtot - selector.erase(last);
111  WeightType newmax = oldmax*abs(weight)*margin();
112  WeightType newtot = selector.insert(newmax, last);
113  double rat = newmax/oldmax;
114 
115  // Setup the new compensation level.
116  Level level;
117  level.weight = 1.0/rat;
118  level.lastN = long(N*newtot/oldtot);
119 
120  // If we are already compensating, reweight the previous
121  // compensation levels.
122  for ( int i = 0, M = levels.size(); i < M; ++i ) {
123  levels[i].lastN = long(levels[i].lastN*newtot/oldtot);
124  levels[i].weight /= rat;
125  }
126  levels.push_back(level);
127  weight /= rat;
128  return newmax;
129  }
130 
131  // If we are compensating we should only accept the selection if the
132  // weight is above the previous overestimate.
133  if ( compensating() ) if ( abs(weight) < levels.back().weight ) weight = 0.0;
134 
135  return WeightType();
136  }
137 
142  void reset() {
143  N = 0;
144  levels.clear();
145  last = T();
146  }
147 
151  void clear() {
152  selector.clear();
153  reset();
154  }
155 
160  void margin(double m) { theMargin = m; }
161 
166  void tolerance(double t) { theTolerance = t; }
168 
169 
175  bool compensating() {
176  // Leave all levels which has reached there 'expiry date'.
177  while ( levels.size() && levels.back().lastN < N ) levels.pop_back();
178  return !levels.empty();
179  }
180 
185  long compleft() const { return levels.empty()? 0: levels.back().lastN - N; }
186 
193  WeightType sum() const { return selector.sum(); }
194 
199  double margin() const { return theMargin; }
200 
205  double tolerance() const { return theTolerance; }
207 
213  template <typename OStream>
214  void output(OStream & os) const {
215  os << selector << N << last << theMargin << theTolerance << levels.size();
216  for ( int i = 0, M = levels.size(); i < M; ++i )
217  os << levels[i].lastN << levels[i].weight;
218  }
219 
223  template <typename IStream>
224  void input(IStream & is) {
225  long M;
226  is >> selector >> N >> last >> theMargin >> theTolerance >> M;
227  levels.resize(M);
228  for ( int i = 0; i < M; ++i ) is >> levels[i].lastN >> levels[i].weight;
229  }
231 
232 private:
233 
237  struct Level {
238 
243  long lastN;
244 
248  double weight;
249 
250  };
251 
252 private:
253 
258 
262  long N;
263 
267  T last;
268 
273  double theMargin;
274 
279  double theTolerance;
280 
284  vector<Level> levels;
285 
286 };
287 
291 template <typename OStream, typename T, typename WeightType>
292 inline OStream & operator<<(OStream & os,
293  const CompSelector<T,WeightType> & s) {
294  s.output(os);
295  return os;
296 }
297 
301 template <typename IStream, typename T, typename WeightType>
302 inline IStream & operator>>(IStream & is,
304  s.input(is);
305  return is;
306 }
307 
308 }
309 
310 #endif /* THEPEG_CompSelector_H */
double theMargin
The margin used to get a new overestimated probability for an object when entering compensation mode...
Definition: CompSelector.h:273
CompSelector(double newMargin=1.1, double newTolerance=1.0e-6)
The default constructor.
Definition: CompSelector.h:58
void output(OStream &os) const
Output to a stream.
Definition: CompSelector.h:214
void reset()
Exit compensation mode and start selection procedure from scratch.
Definition: CompSelector.h:142
bool compensating()
Return true if this CompSelector is in a compensating state.
Definition: CompSelector.h:175
void tolerance(double t)
Set the tolerance for how much a weight is allowed to be larger than unity before starting the compen...
Definition: CompSelector.h:166
T & select(RNDGEN &rnd)
Selct an object randomly.
Definition: CompSelector.h:93
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
double tolerance() const
Return the tolerance for how much a weight is allowed to be larger than unity before starting the com...
Definition: CompSelector.h:205
void margin(double m)
Set the margin used to get a new overestimated probability for an object when entering compensation m...
Definition: CompSelector.h:160
WeightType reweight(double &weight)
Report the weight associated with the last selected object.
Definition: CompSelector.h:105
void input(IStream &is)
Input from a stream.
Definition: CompSelector.h:224
long N
The number of selections so far.
Definition: CompSelector.h:262
Level is used to increment temporarily a given integer variable.
Definition: Level.h:27
Selector< T, WeightType > selector
The underlying selector.
Definition: CompSelector.h:257
vector< Level > levels
The currently active compensation levels.
Definition: CompSelector.h:284
vector< T > & operator>>(vector< T > &tv, U &u)
Overload the right shift operator for vector to pop objects from a vector.
Definition: Containers.h:192
Internal struct used for bookkeeping when compensating.
Definition: CompSelector.h:237
double weight
The minimum weight allowed when compensating on this level.
Definition: CompSelector.h:248
The CompSelector class works like the Selector class in that it can be used to randomly select object...
Definition: CompSelector.h:47
WeightType insert(WeightType d, const T &t)
Insert an object given a probability for this object.
Definition: CompSelector.h:75
long compleft() const
If in a compensating mode, return the number of selection needed before exiting this mode...
Definition: CompSelector.h:185
long lastN
The selection number at which point this level of compensation is ended.
Definition: CompSelector.h:243
Selector is a templated class for storing objects associated with probabilities in a way such that...
Definition: Selector.h:46
double theTolerance
Set the tolerance for how much a weight is allowed to be larger than unity before starting the compen...
Definition: CompSelector.h:279
WeightType sum() const
Return the sum of probabilities of the objects inserted.
Definition: CompSelector.h:193
T last
The last selected object.
Definition: CompSelector.h:267
vector< T > & operator<<(vector< T > &tv, const U &u)
Overload the left shift operator for vector to push_back objects to a vector.
Definition: Containers.h:179
double margin() const
Return the margin used to get a new overestimated probability for an object when entering compensatio...
Definition: CompSelector.h:199
void clear()
Erases all objects.
Definition: CompSelector.h:151