PSCF v1.1
Average.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 "Average.h" // class header
9#include <util/format/Dbl.h>
10#include <util/format/Int.h>
11
12#include <math.h>
13
14namespace Util
15{
16
17 /*
18 * Default constructor.
19 */
20 Average::Average(int blockFactor)
21 : AverageStage(blockFactor),
23 descendants_(),
24 blockSum_(0.0),
25 iBlock_(0),
26 nSamplePerBlock_(0)
27 {
28 setClassName("Average");
29 // Register self as first "descendant" AverageStage.
30 descendants_.push_back(this);
31 }
32
33 /*
34 * Destructor.
35 */
37 {}
38
39 /*
40 * Reset all accumulators and counters to zero.
41 */
43 {
44 blockSum_ = 0;
45 iBlock_ = 0;
47 }
48
49 /*
50 * Read nSamplePerBlock from file.
51 */
52 void Average::readParameters(std::istream& in)
53 {
54 read<int>(in, "nSamplePerBlock", nSamplePerBlock_);
55 if (nSamplePerBlock_ < 0) {
56 UTIL_THROW("Invalid input: nSamplePerBlock < 0");
57 }
58 }
59
60 /*
61 * Set nSamplePerBlock parameter.
62 */
63 void Average::setNSamplePerBlock(int nSamplePerBlock)
64 {
65 if (nSamplePerBlock < 0) {
66 UTIL_THROW("Attempt to set nSamplePerBlock < 0");
67 }
68 nSamplePerBlock_ = nSamplePerBlock;
69 }
70
71 /*
72 * Load internal state from archive.
73 */
75 {
77 ar & blockSum_;
78 ar & iBlock_;
79 loadParameter<int>(ar, "nSamplePerBlock", nSamplePerBlock_);
80 if (nSamplePerBlock_ < 0) {
81 UTIL_THROW("Loading value nSamplePerBlock < 0");
82 }
83 }
84
85 /*
86 * Save internal state to archive.
87 */
89 { ar & *this; }
90
91 /*
92 * Add a sampled value to the ensemble.
93 */
94 void Average::sample(double value)
95 {
97
98 // Increment block average
99 if (nSamplePerBlock_) {
100 if (iBlock_ == nSamplePerBlock_) {
101 blockSum_ = 0.0;
102 iBlock_ = 0;
103 }
104 blockSum_ += value;
105 ++iBlock_;
106 }
107 }
108
109 /*
110 * Add a sampled value and output block average if complete.
111 */
112 void Average::sample(double value, std::ostream& out)
113 {
115
116 // Increment block average for output
117 if (nSamplePerBlock_) {
118 if (iBlock_ == nSamplePerBlock_) {
119 blockSum_ = 0.0;
120 iBlock_ = 0;
121 }
122 blockSum_ += value;
123 ++iBlock_;
124 if (iBlock_ == nSamplePerBlock_) {
125 out << Dbl(blockSum_/double(iBlock_)) << "\n";
126 }
127 }
128 }
129
130 /*
131 * Return estimate of error on average from blocking analysis.
132 */
134 {
135 // Find first stage (descending) with nSample >= 16
136 AverageStage* ptr = 0;
137 int n = descendants_.size();
138 int i = n;
139 int nSample = 1;
140 while (nSample < 16 && i > 0) {
141 --i;
142 ptr = descendants_[i];
143 nSample = ptr->nSample();
144 }
145
146 double error = ptr->error();
147 double sigma = error/sqrt(2.0*double(nSample-1));
148 double weight = 1.0/(sigma*sigma);
149 double sum = error*weight;
150 double norm = weight;
151 double aveErr = error;
152 double oldSig;
153
154 // Find weighted average within plateau
155 bool next = true;
156 while (next && i > 0) {
157 oldSig = sigma;
158 --i;
159 ptr = descendants_[i];
160 error = ptr->error();
161 if (fabs(error - aveErr) < 2.0*oldSig) {
162 nSample = ptr->nSample();
163 sigma = error/sqrt(2.0*double(nSample-1));
164 weight = 1.0/(sigma*sigma);
165 sum += error*weight;
166 norm += weight;
167 aveErr = sum/norm;
168 } else {
169 next = false;
170 }
171 }
172 return aveErr;
173 }
174
175 /*
176 * Output statistical properties to file
177 */
178 void Average::output(std::ostream& out) const
179 {
180 double aveErr = blockingError();
181
182 out << "Average " << Dbl(average())
183 << " +- " << Dbl(aveErr, 9, 2) << "\n";
184 out << "Variance " << Dbl(variance()) << "\n";
185 out << "Std Dev " << Dbl(stdDeviation()) << "\n";
186 out << "\n";
187
188 out << "Hierarchichal Error Analysis:" << "\n";
189 AverageStage* ptr = 0;
190 double error;
191 int interval;
192 int nSample;
193 int n = descendants_.size();
194 for (int i = 0; i < n; ++i) {
195 ptr = descendants_[i];
196 error = ptr->error();
197 nSample = ptr->nSample();
198 interval = ptr->stageInterval();
199 if (nSample >= 16) {
200 out << Int(i)
201 << Int(interval)
202 << Dbl(error)
203 << Dbl(error/sqrt(double(nSample)))
204 << Int(nSample) << "\n";
205 }
206 }
207 out << "\n";
208 }
209
210 /*
211 * Append pointer to a descendant to descendants_ array.
212 */
213 void Average::registerDescendant(AverageStage* descendantPtr)
214 { descendants_.push_back(descendantPtr); }
215
216}
Evaluate average with hierarchical blocking error analysis.
Definition: AverageStage.h:67
long stageInterval() const
Return the number of sampled values per block at this stage.
virtual void sample(double value)
Add a sampled value to the ensemble.
virtual void clear()
Initialize all accumulators and recursively destroy all children.
void serialize(Archive &ar, const unsigned int version)
Add a sampled value to the ensemble.
Definition: AverageStage.h:252
double average() const
Return the average of all sampled values.
double variance() const
Return the variance of all sampled values.
double error() const
Return a naive estimate for the std deviation of the average.
long nSample() const
Return the number of sampled values in this sequence.
double stdDeviation() const
Return the standard deviation of all sampled values.
void clear()
Clear all accumulators, set to empty initial state.
Definition: Average.cpp:42
virtual ~Average()
Destructor.
Definition: Average.cpp:36
int nSamplePerBlock() const
Get number of samples per block average.
Definition: Average.h:220
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Definition: Average.cpp:88
Average(int blockFactor=2)
Constructor.
Definition: Average.cpp:20
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
Definition: Average.cpp:74
void output(std::ostream &out) const
Output final statistical properties to file.
Definition: Average.cpp:178
void readParameters(std::istream &in)
Read parameter nSamplePerBlock from file and initialize.
Definition: Average.cpp:52
double blockingError() const
Return estimated error on average from blocking analysis.
Definition: Average.cpp:133
void sample(double value)
Add a sampled value to the ensemble.
Definition: Average.cpp:94
void setNSamplePerBlock(int nSamplePerBlock)
Set nSamplePerBlock.
Definition: Average.cpp:63
Saving archive for binary istream.
Saving / output archive for binary ostream.
Wrapper for a double precision number, for formatted ostream output.
Definition: Dbl.h:40
Wrapper for an int, for formatted ostream output.
Definition: Int.h:37
An object that can read multiple parameters from file.
void setClassName(const char *className)
Set class name string.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
Utility classes for scientific computation.
Definition: accumulators.mod:1