File indexing completed on 2026-08-06 09:24:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef EXSAMPLE_utility_h_included
0012 #define EXSAMPLE_utility_h_included
0013
0014 #include "config.h"
0015 #include <memory>
0016
0017 namespace exsample {
0018
0019
0020 template<class OStream>
0021 struct ostream_traits {
0022
0023
0024 static void separator(OStream& os) { os << "\n"; }
0025
0026 };
0027
0028 #ifdef EXSAMPLE_has_ThePEG
0029
0030
0031 template<>
0032 struct ostream_traits<ThePEG::PersistentOStream> {
0033
0034
0035 static void separator(ThePEG::PersistentOStream&) { }
0036
0037 };
0038
0039 #endif
0040
0041
0042 template<unsigned long>
0043 struct static_binary {
0044 enum { value = 1 };
0045 };
0046
0047
0048 template<>
0049 struct static_binary<0> {
0050 enum { value = 0 };
0051 };
0052
0053
0054 template<unsigned long bits>
0055 struct bit_container {
0056
0057 enum {
0058
0059 n_bits = bits,
0060
0061 uint_bits = CHAR_BIT * sizeof(unsigned long),
0062
0063 n_segments = bits / uint_bits + static_binary<bits % uint_bits>::value
0064 };
0065
0066
0067
0068 bit_container() {
0069 for (std::size_t i = 0; i < n_segments; ++i)
0070 segments[i] = 0;
0071 }
0072
0073
0074 void reset() {
0075 for (std::size_t i = 0; i < n_segments; ++i)
0076 segments[i] = 0;
0077 }
0078
0079
0080 bool operator==(const bit_container& x) const {
0081 for (std::size_t i = 0; i < n_segments; ++i)
0082 if(segments[i] != x.segments[i])
0083 return false;
0084 return true;
0085 }
0086
0087
0088 bool operator<(const bit_container& x) const {
0089 for (std::size_t i = 0; i < n_segments; ++i)
0090 if(segments[i] != x.segments[i])
0091 return (segments[i] < x.segments[i]);
0092 return false;
0093 }
0094
0095
0096 void bit(unsigned long k, bool value) {
0097 assert(k<n_bits);
0098 if (value)
0099 segments[n_segments-k/uint_bits-1] |= (1ul << (k % uint_bits));
0100 else
0101 segments[n_segments-k/uint_bits-1] &= ~(1ul << (k % uint_bits));
0102 }
0103
0104
0105 bool bit(unsigned long k) const {
0106 assert(k<n_bits);
0107 return (segments[n_segments-k/uint_bits-1] & (1ul << (k % uint_bits)));
0108 }
0109
0110
0111 template<class OStream>
0112 void dump(OStream& os) const {
0113 for ( unsigned int k = 0; k < n_segments; ++k )
0114 os << segments[k] << " ";
0115 }
0116
0117
0118 template<class OStream>
0119 void put(OStream& os) const {
0120 for ( size_t k = 0; k < n_segments; ++k ) {
0121 os << segments[k];
0122 ostream_traits<OStream>::separator(os);
0123 }
0124 }
0125
0126
0127 template<class IStream>
0128 void get(IStream& is) {
0129 for ( size_t k = 0; k < n_segments; ++k ) {
0130 is >> segments[k];
0131 }
0132 }
0133
0134 private:
0135
0136
0137 unsigned long segments[n_segments];
0138
0139 };
0140
0141
0142 template<class T>
0143 T sqr(T x) {
0144 return x*x;
0145 }
0146
0147
0148 template<class T>
0149 T cube(T x) {
0150 return x*x*x;
0151 }
0152
0153
0154
0155
0156 template<class T>
0157 T round(T x) {
0158 T f = std::floor(x);
0159 T c = std::ceil(x);
0160 if (x < (f+c)/2.)
0161 return f;
0162 return c;
0163 }
0164
0165
0166 inline std::size_t two_to(std::size_t n) {
0167 assert(n <= sizeof(std::size_t)*CHAR_BIT);
0168 return (1 << n);
0169 }
0170
0171
0172
0173 template<class Statistics>
0174 struct fast_small_histogram {
0175
0176
0177 fast_small_histogram()
0178 : depth(0), bins(nullptr) {}
0179
0180
0181 fast_small_histogram(const fast_small_histogram& x)
0182 : depth(x.depth), bins(0) {
0183 if (x.bins) {
0184 bins.reset(new Statistics[two_to(depth)]);
0185 for(std::size_t k = 0; k < two_to(depth); ++k)
0186 bins[k] = x.bins[k];
0187 }
0188 }
0189
0190
0191 fast_small_histogram& operator=(const fast_small_histogram& x) {
0192 if (&x == this)
0193 return *this;
0194 depth = x.depth;
0195 bins.reset(nullptr);
0196 if (x.bins) {
0197 bins.reset(new Statistics[two_to(depth)]);
0198 for(std::size_t k = 0; k < two_to(depth); ++k)
0199 bins[k] = x.bins[k];
0200 }
0201 return *this;
0202 }
0203
0204
0205 explicit fast_small_histogram(std::size_t d)
0206 : depth(d), bins(nullptr) {
0207 bins.reset(new Statistics[two_to(d)]);
0208 }
0209
0210
0211 Statistics& bin(double lower,
0212 double upper,
0213 double event) {
0214 double thelower = lower;
0215 double theupper = upper;
0216 std::size_t bindex = 0;
0217 std::size_t current_depth = 0;
0218 while (true) {
0219 double cut
0220 = (thelower+theupper)/2.;
0221 if (event < cut) {
0222 theupper = cut;
0223 } else {
0224 thelower = cut;
0225 bindex += two_to(depth-current_depth-1);
0226 }
0227 if(++current_depth == depth)
0228 break;
0229 }
0230 return bins[bindex];
0231 }
0232
0233
0234 std::size_t depth;
0235
0236
0237 std::unique_ptr<Statistics[]> bins;
0238
0239
0240 template<class OStream>
0241 void put(OStream& os) const {
0242 os << depth;
0243 ostream_traits<OStream>::separator(os);
0244 for (std::size_t k = 0; k < two_to(depth); ++k) {
0245 bins[k].put(os);
0246 }
0247 }
0248
0249
0250 template<class IStream>
0251 void get(IStream& is) {
0252 is >> depth;
0253 bins.reset(new Statistics[two_to(depth)]);
0254 for(std::size_t k = 0; k < two_to(depth); ++k) {
0255 bins[k].get(is);
0256 }
0257 }
0258
0259 };
0260
0261
0262
0263 template<class FirstInputIterator,
0264 class SecondInputIterator,
0265 class FlagIterator,
0266 class OutputIterator,
0267 class BinaryOperation>
0268 OutputIterator conditional_transform(FirstInputIterator first1,
0269 FirstInputIterator last1,
0270 SecondInputIterator first2,
0271 FlagIterator firstf,
0272 OutputIterator result,
0273 BinaryOperation binary_op) {
0274 for (; first1 != last1; ++first1, ++first2, ++firstf, ++result)
0275 if (*firstf)
0276 *result = binary_op(*first1, *first2);
0277 return result;
0278 }
0279
0280
0281
0282 inline double volume(const std::vector<double>& lower_left,
0283 const std::vector<double>& upper_right) {
0284 std::vector<double> delta;
0285 std::transform(upper_right.begin(),upper_right.end(),
0286 lower_left.begin(),std::back_inserter(delta),
0287 std::minus<double>());
0288 return
0289 std::accumulate(delta.begin(),delta.end(),1.,std::multiplies<double>());
0290 }
0291
0292
0293
0294
0295
0296 inline double volume(const std::vector<double>& lower_left,
0297 const std::vector<double>& upper_right,
0298 const std::vector<bool>& flags) {
0299 std::vector<double> delta;
0300 conditional_transform(upper_right.begin(),upper_right.end(),
0301 lower_left.begin(),flags.begin(),
0302 std::back_inserter(delta),
0303 std::minus<double>());
0304 return
0305 std::accumulate(delta.begin(),delta.end(),1.,std::multiplies<double>());
0306 }
0307
0308
0309
0310
0311 struct selection_maxtry{};
0312
0313
0314
0315 struct hit_and_miss_maxtry{};
0316
0317
0318 template<class Random>
0319 struct rnd_generator {
0320
0321
0322 double operator()() const {
0323 return Random::rnd();
0324 }
0325
0326
0327 double operator()(double a) const {
0328 return a*Random::rnd();
0329 }
0330
0331
0332 double operator()(double a, double b) const {
0333 return (a + (b-a)*Random::rnd());
0334 }
0335
0336 };
0337
0338 }
0339
0340 #endif