PSCF v1.1
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
12namespace 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}
Data * cArray()
Return a pointer to the underlying C array.
Definition: Array.h:214
int capacity() const
Return allocated size.
Definition: Array.h:159
Saving archive for binary istream.
Saving / output archive for binary ostream.
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:199
Wrapper for a double precision number, for formatted ostream output.
Definition: Dbl.h:40
A distribution (or histogram) of values for a real variable.
Definition: Distribution.h:24
int nBin() const
Get the number of bins.
Definition: Distribution.h:191
void sample(double value)
Sample a value.
double binWidth_
width of bin = (max_-min_)/nBin_ .
Definition: Distribution.h:155
double min_
minimum value.
Definition: Distribution.h:153
DArray< long > histogram_
Histogram of occurences, one element per bin.
Definition: Distribution.h:152
double min() const
Get minimum value in range of histogram.
Definition: Distribution.h:173
void setParam(double min, double max, int nBin)
Set parameters and initialize.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
void reduce(MPI::Intracomm &communicator, int root)
Reduce (add) distributions from multiple MPI processors.
double max_
maximum value.
Definition: Distribution.h:154
int nBin_
number of bins.
Definition: Distribution.h:156
virtual void readParameters(std::istream &in)
Read parameters from file and initialize.
void output(std::ostream &out)
Output the distribution to file.
int binIndex(double value) const
Return the index of the bin for a value.
Definition: Distribution.h:167
Distribution & operator=(const Distribution &other)
Assignment operator.
virtual ~Distribution()
Destructor.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Distribution()
Default constructor.
int nSample_
Number of sampled values in Histogram.
Definition: Distribution.h:157
int nReject_
Number of sampled values that were out of range.
Definition: Distribution.h:158
virtual void clear()
Clear (i.e., zero) previously allocated histogram.
double max() const
Get maximum value in range of histogram.
Definition: Distribution.h:179
void setClassName(const char *className)
Set class name string.
File containing preprocessor macros for error handling.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
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
Utility classes for scientific computation.
Definition: accumulators.mod:1