All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ComputePi_module.cc
Go to the documentation of this file.
1 /**
2  * @file ComputePi_module.cc
3  * @brief Computes pi
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date August 19th, 2014
6  */
7 
8 // C/C++ standard libraries
9 #include <random> // std::default_random_engine, std::uniform_real_distribution
10 #include <ios> // std::fixed
11 #include <iomanip> // std::setprecision
12 
13 // art libraries
14 #include "messagefacility/MessageLogger/MessageLogger.h"
15 #include "fhiclcpp/ParameterSet.h"
16 #include "art/Framework/Core/EDAnalyzer.h"
17 #include "art/Framework/Core/ModuleMacros.h"
18 
19 
20 namespace lar {
21 
22  /**
23  * @brief Computes pi (but it does not make it available)
24  *
25  * This module performs a extensive computation whose duration can be
26  * indirectly controlled by a parameter.
27  * The time taken is supposed to be independent from the framework.
28  * This is meant to help establish an absolute time scale.
29  *
30  * The module performs some Monte Carlo integration to compute pi.
31  * The same number of cycles is used regardless the result.
32  * We use a simple pseudo-random generator
33  * (<tt>std::linear_congruential_engine</tt>) with a constant extraction time
34  * (and poor randomness quality, and a period so small that in about 20 events
35  * the sequence might repeat itself). The fluctuations of the result don't
36  * reflect a fluctuation in time.
37  *
38  * A test performed on uboonegpvm06,fnal.gov on August 19th, 2014 on 1000
39  * events with Ksamples=50000 (i.e., 50M samples per event), default seed
40  * and verbosity on took 0.9179 +/- 0.0009 s, with an RMS of ~3%.
41  * It was observed that processing time asymptotically decreased.
42  *
43  * <b>Parameters</b>
44  * - <b>Ksamples</b> (integer, default: 10000) number of digits to be computed
45  * - <b>Seed</b> (unsigned integer, default: 314159) chooses the seed for the
46  * Monte Carlo integration
47  * - <b>Fixed</b> (boolean, default: false) if true, the same pseudo-random
48  * number sequence will be used for all events; otherwise, each event will
49  * get its own specific sequence
50  * - <b>Verbose</b> (boolean, default: false) writes the result into the log
51  */
52  class ComputePi: public art::EDAnalyzer {
53  public:
54  using Counter_t = unsigned long long; ///< type used for integral counters
55  using Seed_t = std::default_random_engine::result_type;
56  ///< type for seed and random numbers
57 
58  explicit ComputePi(fhicl::ParameterSet const & p);
59 
60  virtual ~ComputePi() = default;
61 
62  virtual void analyze(const art::Event&) override;
63 
64  /// Returns the current best estimation of pi
65  double best_pi() const
66  { return tries? 4. * double(hits) / double(tries): 3.0; }
67 
68  /// Returns the current best estimation of pi
69  Counter_t best_pi_tries() const { return tries; }
70 
71 
72  static const char* VersionString; ///< version of the algorithm
73 
74  private:
75  Counter_t samples; ///< number of samples to try on each event
76  Seed_t seed; ///< number of digits to compute
77  bool bFixed; ///< whether the random sequence is always the same
78  bool bVerbose; ///< whether to put stuff on screen
79 
80  std::default_random_engine generator; ///< random generator
81  Counter_t hits = 0; ///< total number of hits
82  Counter_t tries = 0; ///< total number of tries (samples)
83 
84 
85  }; // class ComputePi
86 
87 } // namespace lar
88 
89 
90 //------------------------------------------------------------------------------
91 
92 DEFINE_ART_MODULE(lar::ComputePi)
93 
94 const char* lar::ComputePi::VersionString = "1.0";
95 
96 template <typename T>
97 inline constexpr T sqr(T v) { return v*v; }
98 
99 
100 lar::ComputePi::ComputePi(const fhicl::ParameterSet& p):
101  EDAnalyzer(p),
102  samples(p.get<Counter_t>("Ksamples", 10000) * 1000),
103  seed(p.get<Seed_t>("Seed", 314159)),
104  bFixed(p.get<bool>("Fixed", false)),
105  bVerbose(p.get<bool>("Verbose", false)),
106  generator(seed)
107 {
108  mf::LogInfo("ComputePi")
109  << "version " << VersionString
110  << " using " << samples << " samples per event, random seed " << seed;
111 } // lar::ComputePi::ComputePi()
112 
113 
114 void lar::ComputePi::analyze(const art::Event&) {
115 
116  // prepare our personal pseudo-random engine;
117  // we'll use always the same sequence!
118  std::uniform_real_distribution<float> flat(0.0, 1.0);
119 
120  // if we want to fix the random sequence, we reseed the generator
121  // with the same value over and over again
122  if (bFixed) generator.seed(seed);
123 
124  Counter_t local_hits = 0, tries_left = samples;
125  while (tries_left-- > 0) {
126  float x = flat(generator), y = flat(generator);
127  if (sqr(x) + sqr(y) < 1.0) ++local_hits;
128  } // while
129 
130  double local_pi = double(local_hits) / double(samples) * 4.0;
131  hits += local_hits;
132  tries += samples;
133 
134  if (bVerbose) {
135  mf::LogInfo("ComputePi") << "today's pi = "
136  << std::fixed << std::setprecision(9) << local_pi
137  << " (pi = "
138  << std::fixed << std::setprecision(12) << best_pi()
139  << " after " << best_pi_tries() << " samples)";
140  } // if verbose
141 
142 } // lar::ComputePi::analyze()
143 
Counter_t tries
total number of tries (samples)
process_name opflash particleana ie x
std::default_random_engine generator
random generator
pdgs p
Definition: selectors.fcl:22
Counter_t best_pi_tries() const
Returns the current best estimation of pi.
static constexpr bool
unsigned long long Counter_t
type used for integral counters
Counter_t hits
total number of hits
virtual ~ComputePi()=default
process_name opflash particleana ie ie y
double best_pi() const
Returns the current best estimation of pi.
bool bFixed
whether the random sequence is always the same
constexpr T sqr(T v)
unsigned int seed
Seed_t seed
number of digits to compute
Counter_t samples
number of samples to try on each event
virtual void analyze(const art::Event &) override
Computes pi (but it does not make it available)
static const char * VersionString
version of the algorithm
bool bVerbose
whether to put stuff on screen
std::default_random_engine::result_type Seed_t
type for seed and random numbers
ComputePi(fhicl::ParameterSet const &p)