thepeg is hosted by Hepforge, IPPP Durham
ThePEG 2.3.0
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
17namespace ThePEG {
18
46template <typename T, typename WeightType = double>
48
49public:
50
58 CompSelector(double newMargin = 1.1, double newTolerance = 1.0e-6)
59 : N(0), last(), theMargin(newMargin), theTolerance(newTolerance) {}
61
62public:
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
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
232private:
233
237 struct Level {
238
243 long lastN;
244
248 double weight;
249
250 };
251
252private:
253
258
262 long N;
263
268
273 double theMargin;
274
280
284 vector<Level> levels;
285
286};
287
291template <typename OStream, typename T, typename WeightType>
292inline OStream & operator<<(OStream & os,
293 const CompSelector<T,WeightType> & s) {
294 s.output(os);
295 return os;
296}
297
301template <typename IStream, typename T, typename WeightType>
302inline IStream & operator>>(IStream & is,
304 s.input(is);
305 return is;
306}
307
308}
309
310#endif /* THEPEG_CompSelector_H */
The CompSelector class works like the Selector class in that it can be used to randomly select object...
Definition: CompSelector.h:47
CompSelector(double newMargin=1.1, double newTolerance=1.0e-6)
The default constructor.
Definition: CompSelector.h:58
WeightType reweight(double &weight)
Report the weight associated with the last selected object.
Definition: CompSelector.h:105
void reset()
Exit compensation mode and start selection procedure from scratch.
Definition: CompSelector.h:142
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
WeightType insert(WeightType d, const T &t)
Insert an object given a probability for this object.
Definition: CompSelector.h:75
Selector< T, WeightType > selector
The underlying selector.
Definition: CompSelector.h:257
WeightType sum() const
Return the sum of probabilities of the objects inserted.
Definition: CompSelector.h:193
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
void output(OStream &os) const
Output to a stream.
Definition: CompSelector.h:214
T & select(RNDGEN &rnd)
Selct an object randomly.
Definition: CompSelector.h:93
void input(IStream &is)
Input from a stream.
Definition: CompSelector.h:224
T last
The last selected object.
Definition: CompSelector.h:267
bool compensating()
Return true if this CompSelector is in a compensating state.
Definition: CompSelector.h:175
long compleft() const
If in a compensating mode, return the number of selection needed before exiting this mode.
Definition: CompSelector.h:185
vector< Level > levels
The currently active compensation levels.
Definition: CompSelector.h:284
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
long N
The number of selections so far.
Definition: CompSelector.h:262
void clear()
Erases all objects.
Definition: CompSelector.h:151
double margin() const
Return the margin used to get a new overestimated probability for an object when entering compensatio...
Definition: CompSelector.h:199
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
double theMargin
The margin used to get a new overestimated probability for an object when entering compensation mode.
Definition: CompSelector.h:273
Selector is a templated class for storing objects associated with probabilities in a way such that,...
Definition: Selector.h:46
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
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
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
Internal struct used for bookkeeping when compensating.
Definition: CompSelector.h:237
long lastN
The selection number at which point this level of compensation is ended.
Definition: CompSelector.h:243
double weight
The minimum weight allowed when compensating on this level.
Definition: CompSelector.h:248