Simpatico  v1.10
Distribution.cpp
1 /*
2 * Util Package - C++ Utilities for Scientific Computation
3 *
4 * Copyright 2010 - 2017, The Regents of the University of Minnesota
5 * Distributed under the terms of the GNU General Public License.
6 */
7 
8 #include "Distribution.h"
9 #include <util/format/Dbl.h>
10 #include <util/global.h>
11 
12 namespace Util
13 {
14 
15  /*
16  * Default constructor.
17  */
19  : histogram_(),
20  min_(0.0),
21  max_(0.0),
22  binWidth_(0.0),
23  nBin_(0),
24  nSample_(0),
25  nReject_(0)
26  { setClassName("Distribution"); }
27 
28  /*
29  * Copy constructor.
30  */
32  : histogram_(),
33  min_(other.min_),
34  max_(other.max_),
35  binWidth_(other.binWidth_),
36  nBin_(other.nBin_),
37  nSample_(other.nSample_),
38  nReject_(other.nReject_)
39  {
40  if (nBin_ > 0) {
41  assert(other.histogram_.capacity() != 0);
43  for (int i=0; i < nBin_; ++i) {
44  histogram_[i] = other.histogram_[i];
45  }
46  } else {
47  assert(nBin_ == 0);
48  assert(histogram_.capacity() == 0);
49  assert(nSample_ == 0);
50  assert(nReject_ == 0);
51  }
52  }
53 
54  /*
55  * Assignment operator.
56  */
58  {
59  // Check for self assignment
60  if (this == &other) return *this;
61 
62  // Check validity of other object
63  if (other.nBin_ > 0) {
64  assert(other.histogram_.capacity() != 0);
65  } else {
66  assert(other.nBin_ == 0);
67  assert(other.histogram_.capacity() == 0);
68  assert(other.nSample_ == 0);
69  assert(other.nReject_ == 0);
70  }
71 
72  // Assign primitive values
73  min_ = other.min_;
74  max_ = other.max_;
75  binWidth_ = other.binWidth_;
76  nBin_ = other.nBin_;
77  nSample_ = other.nSample_;
78  nReject_ = other.nReject_;
79 
80  // Allocate and copy histogram, if necessary
81  if (nBin_ > 0) {
83  for (int i=0; i < nBin_; ++i) {
84  histogram_[i] = other.histogram_[i];
85  }
86  }
87 
88  return *this;
89  }
90 
91  /*
92  * Destructor.
93  */
95  {}
96 
97  /*
98  * Read parameters and initialize.
99  */
100  void Distribution::readParameters(std::istream& in)
101  {
102  read<double>(in, "min", min_);
103  read<double>(in, "max", max_);
104  read<int>(in, "nBin", nBin_);
105  binWidth_ = (max_ - min_)/double(nBin_);
107  clear();
108  }
109 
110  /*
111  * Set parameters and initialize.
112  *
113  * \param min lower bound of range
114  * \param max upper bound of range
115  * \param nBin number of bins in range [min, max]
116  */
117  void Distribution::setParam(double min, double max, int nBin)
118  {
119  min_ = min;
120  max_ = max;
121  nBin_ = nBin;
122  binWidth_ = (max_ - min_)/double(nBin_);
124  clear();
125  }
126 
127  /*
128  * Load internal state from archive.
129  */
131  {
132  loadParameter<double>(ar, "min", min_);
133  loadParameter<double>(ar, "max", max_);
134  loadParameter<int>(ar, "nBin", nBin_);
135  ar & nSample_;
136  ar & nReject_;
137  ar & binWidth_;
138  ar & histogram_;
139 
140  // Validate
141  if (histogram_.capacity() != nBin_) {
142  UTIL_THROW("Inconsistent histogram capacity");
143  }
144  if (!feq(binWidth_, (max_ - min_)/double(nBin_))) {
145  UTIL_THROW("Inconsistent binWidth_");
146  }
147  }
148 
149  /*
150  * Save internal state to archive.
151  */
153  { ar & *this; }
154 
155  /*
156  * Zero all accumulators.
157  */
159  {
160  nSample_ = 0;
161  nReject_ = 0;
162  for (int i=0; i < nBin_; ++i) {
163  histogram_[i] = 0;
164  }
165  }
166 
167  /*
168  * Add a value to the histogram
169  */
170  void Distribution::sample(double value)
171  {
172  int i;
173  if (value > min_ && value < max_) {
174  i = binIndex(value);
175  histogram_[i] += 1;
176  nSample_ += 1;
177  } else {
178  nReject_ += 1;
179  }
180  }
181 
182  /*
183  * Output histogram
184  */
185  void Distribution::output(std::ostream& out)
186  {
187  double x, rho;
188  for (int i=0; i < nBin_; ++i) {
189  x = min_ + binWidth_*(double(i) + 0.5);
190  rho = double(histogram_[i])/double(nSample_);
191  rho = rho/binWidth_;
192  out << Dbl(x, 18, 8) << Dbl(rho, 18, 8) << std::endl;
193  }
194  }
195 
196  #ifdef UTIL_MPI
197  /*
198  * Reduce (add) distributions from multiple MPI processors.
199  */
200  void Distribution::reduce(MPI::Intracomm& communicator, int root)
201  {
202 
203  long* totHistogram = new long[nBin_];
204  communicator.Reduce(histogram_.cArray(), totHistogram, nBin_, MPI::LONG, MPI::SUM, root);
205  if (communicator.Get_rank() == root) {
206  for (int i=0; i < nBin_; ++i) {
207  histogram_[i] = totHistogram[i];
208  }
209  } else {
210  for (int i=0; i < nBin_; ++i) {
211  histogram_[i] = 0.0;
212  }
213  }
214  delete [] totHistogram;
215 
216  long totSample;
217  communicator.Reduce(&nSample_, &totSample, 1, MPI::LONG, MPI::SUM, root);
218  if (communicator.Get_rank() == root) {
219  nSample_ = totSample;
220  } else {
221  nSample_ = 0;
222  }
223 
224  long totReject;
225  communicator.Reduce(&nReject_, &totReject, 1, MPI::LONG, MPI::SUM, root);
226  if (communicator.Get_rank() == root) {
227  nReject_ = totReject;
228  } else {
229  nReject_ = 0;
230  }
231 
232  }
233  #endif
234 
235 }
double max_
maximum value.
Definition: Distribution.h:154
int nBin_
number of bins.
Definition: Distribution.h:156
int nSample_
Number of sampled values in Histogram.
Definition: Distribution.h:157
Data * cArray()
Return pointer to underlying C array.
Definition: Array.h:208
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
int binIndex(double value) const
Return the index of the bin for a value.
Definition: Distribution.h:167
Wrapper for a double precision number, for formatted ostream output.
Definition: Dbl.h:39
File containing preprocessor macros for error handling.
double min_
minimum value.
Definition: Distribution.h:153
Saving / output archive for binary ostream.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
double binWidth_
width of bin = (max_-min_)/nBin_ .
Definition: Distribution.h:155
Utility classes for scientific computation.
Definition: accumulators.mod:1
Distribution & operator=(const Distribution &other)
Assignment operator.
void sample(double value)
Sample a value.
double min() const
Get minimum value in range of histogram.
Definition: Distribution.h:173
virtual void readParameters(std::istream &in)
Read parameters from file and initialize.
void output(std::ostream &out)
Output the distribution to file.
virtual void clear()
Clear (i.e., zero) previously allocated histogram.
DArray< long > histogram_
Histogram of occurences, one element per bin.
Definition: Distribution.h:152
Saving archive for binary istream.
int nReject_
Number of sampled values that were out of range.
Definition: Distribution.h:158
int nBin() const
Get the number of bins.
Definition: Distribution.h:191
void reduce(MPI::Intracomm &communicator, int root)
Reduce (add) distributions from multiple MPI processors.
void setClassName(const char *className)
Set class name string.
virtual ~Distribution()
Destructor.
int capacity() const
Return allocated size.
Definition: Array.h:153
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
void setParam(double min, double max, int nBin)
Set parameters and initialize.
A distribution (or histogram) of values for a real variable.
Definition: Distribution.h:23
Distribution()
Default constructor.
bool feq(double x, double y, double eps=1.0E-10)
Are two floating point numbers equal to within round-off error?
Definition: feq.h:27
double max() const
Get maximum value in range of histogram.
Definition: Distribution.h:179
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.