00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ThePEG_VSelector_H
00010 #define ThePEG_VSelector_H
00011
00012
00013 #include "ThePEG/Config/ThePEG.h"
00014 #include <stdexcept>
00015 #include <algorithm>
00016 #include <stdexcept>
00017
00018 namespace ThePEG {
00019
00020 template <typename T, typename WeightType = double>
00046 class VSelector {
00047
00048 public:
00049
00051 typedef vector<WeightType> WeightVector;
00052
00054 typedef typename WeightVector::const_iterator WIterator;
00055
00057 typedef vector<T> ObjectVector;
00058
00060 typedef typename ObjectVector::iterator iterator;
00061
00063 typedef typename ObjectVector::const_iterator const_iterator;
00064
00066 typedef typename ObjectVector::size_type size_type;
00067
00068 public:
00069
00073 VSelector(size_type reserved = 0) : theSum()
00074 {
00075 reserve(reserved);
00076 }
00077
00081 void swap(VSelector & s) {
00082 theSums.swap(s.theSums);
00083 theWeights.swap(s.theWeights);
00084 theObjects.swap(s.theObjects);
00085 std::swap(theSum, s.theSum);
00086 }
00087
00094 WeightType insert(WeightType d, const T & t) {
00095 WeightType newSum = theSum + d;
00096 if ( newSum <= theSum ) return d;
00097 theSums.push_back(theSum = newSum);
00098 theWeights.push_back(d);
00099 theObjects.push_back(t);
00100 return theSum;
00101 }
00102
00108 WeightType reweight(WeightType, const T &);
00109
00116 WeightType erase(const T &);
00117
00122 void replace(const T & told, const T & tnew) {
00123 for ( iterator it = theObjects.begin(); it != theObjects.end(); ++it )
00124 if ( *it == told ) *it = tnew;
00125 }
00126
00138 T & select(double rnd, double * remainder = 0) throw(range_error) {
00139 return theObjects[iselect(rnd, remainder)];
00140 }
00141
00149 T & operator[](double rnd) throw(range_error) {
00150 return select(rnd, 0);
00151 }
00152
00164 const T & select(double rnd, double * remainder = 0) const throw(range_error) {
00165 return theObjects[iselect(rnd, remainder)];
00166 }
00167
00175 const T & operator[](double rnd) const throw(range_error) {
00176 return select(rnd, 0);
00177 }
00178
00191 template <typename RNDGEN>
00192 T & select(RNDGEN & rnd) throw(range_error) {
00193 double rem = 0.0;
00194 T & t = select(rnd(), &rem);
00195 rnd.push_back(rem);
00196 return t;
00197 }
00198
00211 template <typename RNDGEN>
00212 const T & select(RNDGEN & rnd) const throw(range_error) {
00213 double rem = 0.0;
00214 const T & t = select(rnd(), &rem);
00215 rnd.push_back(rem);
00216 return t;
00217 }
00218
00225 WeightType sum() const { return theSum; }
00226
00231 const_iterator begin() const { return theObjects.begin(); }
00232
00237 const_iterator end() const { return theObjects.end(); }
00238
00242 bool empty() const { return theObjects.empty(); }
00243
00247 size_type size() const { return theObjects.size(); }
00248
00252 void reserve(size_type reserved) {
00253 theSums.reserve(reserved);
00254 theWeights.reserve(reserved);
00255 theObjects.reserve(reserved);
00256 }
00257
00261 void clear() {
00262 theSums.clear();
00263 theWeights.clear();
00264 theObjects.clear();
00265 theSum = WeightType();
00266 }
00267
00271 template <typename OStream>
00272 void output(OStream &) const;
00273
00277 template <typename IStream>
00278 void input(IStream &);
00279
00280 protected:
00281
00285 size_type iselect(double rnd, double * remainder) const throw(range_error);
00286
00287 private:
00288
00292 WeightVector theSums;
00293
00297 WeightVector theWeights;
00298
00302 ObjectVector theObjects;
00303
00307 WeightType theSum;
00308
00309 };
00310
00314 template <typename OStream, typename T, typename WeightType>
00315 inline OStream & operator<<(OStream & os,
00316 const VSelector<T,WeightType> & s) {
00317 s.output(os);
00318 return os;
00319 }
00320
00324 template <typename IStream, typename T, typename WeightType>
00325 inline IStream & operator>>(IStream & is,
00326 VSelector<T,WeightType> & s) {
00327 s.input(is);
00328 return is;
00329 }
00330
00331
00332 }
00333
00334 #include "VSelector.tcc"
00335
00336 #endif