ThePEG  1.8.0
VSelector.h
1 // -*- C++ -*-
2 //
3 // VSelector.h is a part of ThePEG - Toolkit for HEP Event Generation
4 // Copyright (C) 1999-2011 Leif Lonnblad
5 //
6 // ThePEG is licenced under version 2 of the GPL, see COPYING for details.
7 // Please respect the MCnet academic guidelines, see GUIDELINES for details.
8 //
9 #ifndef ThePEG_VSelector_H
10 #define ThePEG_VSelector_H
11 // This is the definition of the ThePEG::VSelector class.
12 
13 #include "ThePEG/Config/ThePEG.h"
14 #include <stdexcept>
15 #include <algorithm>
16 #include <stdexcept>
17 
18 namespace ThePEG {
19 
20 template <typename T, typename WeightType = double>
46 class VSelector {
47 
48 public:
49 
51  typedef vector<WeightType> WeightVector;
52 
54  typedef typename WeightVector::const_iterator WIterator;
55 
57  typedef vector<T> ObjectVector;
58 
60  typedef typename ObjectVector::iterator iterator;
61 
63  typedef typename ObjectVector::const_iterator const_iterator;
64 
66  typedef typename ObjectVector::size_type size_type;
67 
68 public:
69 
73  VSelector(size_type reserved = 0) : theSum()
74  {
75  reserve(reserved);
76  }
77 
81  void swap(VSelector & s) {
82  theSums.swap(s.theSums);
83  theWeights.swap(s.theWeights);
84  theObjects.swap(s.theObjects);
86  }
87 
94  WeightType insert(WeightType d, const T & t) {
95  WeightType newSum = theSum + d;
96  if ( newSum <= theSum ) return d;
97  theSums.push_back(theSum = newSum);
98  theWeights.push_back(d);
99  theObjects.push_back(t);
100  return theSum;
101  }
102 
108  WeightType reweight(WeightType, const T &);
109 
116  WeightType erase(const T &);
117 
122  void replace(const T & told, const T & tnew) {
123  for ( iterator it = theObjects.begin(); it != theObjects.end(); ++it )
124  if ( *it == told ) *it = tnew;
125  }
126 
138  T & select(double rnd, double * remainder = 0) throw(range_error) {
139  return theObjects[iselect(rnd, remainder)];
140  }
141 
149  T & operator[](double rnd) throw(range_error) {
150  return select(rnd, 0);
151  }
152 
164  const T & select(double rnd, double * remainder = 0) const throw(range_error) {
165  return theObjects[iselect(rnd, remainder)];
166  }
167 
175  const T & operator[](double rnd) const throw(range_error) {
176  return select(rnd, 0);
177  }
178 
191  template <typename RNDGEN>
192  T & select(RNDGEN & rnd) throw(range_error) {
193  double rem = 0.0;
194  T & t = select(rnd(), &rem);
195  rnd.push_back(rem);
196  return t;
197  }
198 
211  template <typename RNDGEN>
212  const T & select(RNDGEN & rnd) const throw(range_error) {
213  double rem = 0.0;
214  const T & t = select(rnd(), &rem);
215  rnd.push_back(rem);
216  return t;
217  }
218 
225  WeightType sum() const { return theSum; }
226 
231  const_iterator begin() const { return theObjects.begin(); }
232 
237  const_iterator end() const { return theObjects.end(); }
238 
242  bool empty() const { return theObjects.empty(); }
243 
247  size_type size() const { return theObjects.size(); }
248 
252  void reserve(size_type reserved) {
253  theSums.reserve(reserved);
254  theWeights.reserve(reserved);
255  theObjects.reserve(reserved);
256  }
257 
261  void clear() {
262  theSums.clear();
263  theWeights.clear();
264  theObjects.clear();
265  theSum = WeightType();
266  }
267 
271  template <typename OStream>
272  void output(OStream &) const;
273 
277  template <typename IStream>
278  void input(IStream &);
279 
280 protected:
281 
285  size_type iselect(double rnd, double * remainder) const throw(range_error);
286 
287 private:
288 
293 
298 
303 
307  WeightType theSum;
308 
309 };
310 
314 template <typename OStream, typename T, typename WeightType>
315 inline OStream & operator<<(OStream & os,
316  const VSelector<T,WeightType> & s) {
317  s.output(os);
318  return os;
319 }
320 
324 template <typename IStream, typename T, typename WeightType>
325 inline IStream & operator>>(IStream & is,
327  s.input(is);
328  return is;
329 }
330 
331 
332 }
333 
334 #include "VSelector.tcc"
335 
336 #endif /* ThePEG_VSelector_H */