LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ComputePi_module.cc
Go to the documentation of this file.
1 
8 // C/C++ standard libraries
9 #include <iomanip> // std::setprecision
10 #include <ios> // std::fixed
11 #include <random> // std::default_random_engine, std::uniform_real_distribution
12 
13 // art libraries
16 #include "fhiclcpp/ParameterSet.h"
18 
19 namespace lar {
20 
51  class ComputePi : public art::EDAnalyzer {
52  public:
53  using Counter_t = unsigned long long;
54  using Seed_t = std::default_random_engine::result_type;
56 
57  explicit ComputePi(fhicl::ParameterSet const& p);
58 
59  virtual ~ComputePi() = default;
60 
61  virtual void analyze(const art::Event&) override;
62 
64  double best_pi() const { return tries ? 4. * double(hits) / double(tries) : 3.0; }
65 
67  Counter_t best_pi_tries() const { return tries; }
68 
69  static const char* VersionString;
70 
71  private:
74  bool bFixed;
75  bool bVerbose;
76 
77  std::default_random_engine generator;
80 
81  }; // class ComputePi
82 
83 } // namespace lar
84 
85 //------------------------------------------------------------------------------
86 
88 
89 const char* lar::ComputePi::VersionString = "1.0";
90 
91 template <typename T>
92 inline constexpr T sqr(T v)
93 {
94  return v * v;
95 }
96 
98  : EDAnalyzer(p)
99  , samples(p.get<Counter_t>("Ksamples", 10000) * 1000)
100  , seed(p.get<Seed_t>("Seed", 314159))
101  , bFixed(p.get<bool>("Fixed", false))
102  , bVerbose(p.get<bool>("Verbose", false))
103  , generator(seed)
104 {
105  mf::LogInfo("ComputePi") << "version " << VersionString << " using " << samples
106  << " samples per event, random seed " << seed;
107 } // lar::ComputePi::ComputePi()
108 
110 {
111 
112  // prepare our personal pseudo-random engine;
113  // we'll use always the same sequence!
114  std::uniform_real_distribution<float> flat(0.0, 1.0);
115 
116  // if we want to fix the random sequence, we reseed the generator
117  // with the same value over and over again
118  if (bFixed) generator.seed(seed);
119 
120  Counter_t local_hits = 0, tries_left = samples;
121  while (tries_left-- > 0) {
122  float x = flat(generator), y = flat(generator);
123  if (sqr(x) + sqr(y) < 1.0) ++local_hits;
124  } // while
125 
126  double local_pi = double(local_hits) / double(samples) * 4.0;
127  hits += local_hits;
128  tries += samples;
129 
130  if (bVerbose) {
131  mf::LogInfo("ComputePi") << "today's pi = " << std::fixed << std::setprecision(9) << local_pi
132  << " (pi = " << std::fixed << std::setprecision(12) << best_pi()
133  << " after " << best_pi_tries() << " samples)";
134  } // if verbose
135 
136 } // lar::ComputePi::analyze()
Float_t x
Definition: compare.C:6
Counter_t tries
total number of tries (samples)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::default_random_engine generator
random generator
Float_t y
Definition: compare.C:6
Counter_t best_pi_tries() const
Returns the current best estimation of pi.
unsigned long long Counter_t
type used for integral counters
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.cc:6
Counter_t hits
total number of hits
virtual ~ComputePi()=default
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
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)
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
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
Definition: StdUtils.h:120
std::default_random_engine::result_type Seed_t
type for seed and random numbers
LArSoft-specific namespace.
ComputePi(fhicl::ParameterSet const &p)