PSCF v1.1
MeanSqDispArray.h
1#ifndef UTIL_MEAN_SQ_DISP_ARRAY_H
2#define UTIL_MEAN_SQ_DISP_ARRAY_H
3
4/*
5* Util Package - C++ Utilities for Scientific Computation
6*
7* Copyright 2010 - 2017, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11// Needed in header
12#include <util/param/ParamComposite.h>
13#include <util/containers/RingBuffer.h>
14#include <util/containers/Array.h>
15
16// Needed in implementation
17#include <util/accumulators/MeanSqDispArray.h>
18#include <util/accumulators/setToZero.h>
19#include <util/space/Vector.h>
20#include <util/format/Int.h>
21#include <util/format/Dbl.h>
22
23#include <complex>
24using std::complex;
25
26namespace Util
27{
28
40 template <typename Data>
42 {
43
44 public:
45
46 /*
47 * Constructor.
48 */
50
51 /*
52 * Destructor.
53 */
55
64 void readParameters(std::istream& in);
65
75 void setParam(int ensembleCapacity, int bufferCapacity);
76
82 virtual void loadParameters(Serializable::IArchive &ar);
83
89 virtual void save(Serializable::OArchive &ar);
90
97 template <class Archive>
98 void serialize(Archive& ar, const unsigned int version);
99
108 void setNEnsemble(int nEnsemble);
109
113 void clear();
114
120 void sample(const Array<Data>& values);
121
125 void output(std::ostream& out);
126
131 { return bufferCapacity_; }
132
137 { return nEnsemble_; }
138
142 int nSample()
143 { return nSample_; }
144
145 private:
146
148 DArray< RingBuffer<Data> > buffers_;
149
151 DArray<double> sqDiffSums_;
152
154 DArray<int> nValues_;
155
157 int ensembleCapacity_;
158
160 int bufferCapacity_;
161
163 int nEnsemble_;
164
166 int nSample_;
167
175 void allocate();
176
187 double sqDiff(const Data& data1, const Data& data2);
188
189 };
190
191
192 /*
193 * Default constructor.
194 */
195 template <typename Data>
196 MeanSqDispArray<Data>::MeanSqDispArray()
197 : buffers_(),
198 sqDiffSums_(),
199 nValues_(),
200 ensembleCapacity_(0),
201 bufferCapacity_(0),
202 nEnsemble_(0),
203 nSample_(0)
204 { setClassName("MeanSqDispArray"); }
205
206 /*
207 * Default destructor.
208 */
209 template <typename Data>
210 MeanSqDispArray<Data>::~MeanSqDispArray()
211 {}
212
213 /*
214 * Read parameters from file.
215 */
216 template <typename Data>
218 {
219 read<int>(in, "ensembleCapacity", ensembleCapacity_);
220 read<int>(in, "bufferCapacity", bufferCapacity_);
221 allocate();
222 nEnsemble_ = ensembleCapacity_;
223 }
224
225 /*
226 * Set parameters and initialize.
227 */
228 template <typename Data>
229 void
230 MeanSqDispArray<Data>::setParam(int ensembleCapacity, int bufferCapacity)
231 {
232 ensembleCapacity_ = ensembleCapacity;
233 bufferCapacity_ = bufferCapacity;
234 allocate();
235 // Set number of sequences to maximum capacity as a default.
236 nEnsemble_ = ensembleCapacity;
237 }
238
239 /*
240 * Set or reset nEnsemble.
241 */
242 template <typename Data>
244 {
245 if (ensembleCapacity_ == 0)
246 UTIL_THROW("No memory has been allocated: ensembleCapacity_ == 0");
247 if (nEnsemble > ensembleCapacity_)
248 UTIL_THROW("nEnsemble > ensembleCapacity_");
249 nEnsemble_ = nEnsemble;
250 }
251
252 /*
253 * Load internal state from archive.
254 */
255 template <typename Data>
257 {
258 loadParameter<int>(ar, "ensembleCapacity", ensembleCapacity_);
259 loadParameter<int>(ar, "bufferCapacity", bufferCapacity_);
260 ar & nEnsemble_;
261 ar & nValues_;
262 ar & nSample_;
263 ar & buffers_;
264 ar & sqDiffSums_;
265 }
266
267 /*
268 * Serialize this MeanSqDispArray.
269 */
270 template <typename Data>
271 template <class Archive>
272 void MeanSqDispArray<Data>::serialize(Archive& ar, const unsigned int version)
273 {
274 ar & ensembleCapacity_;
275 ar & bufferCapacity_;
276 ar & nEnsemble_;
277 ar & nValues_;
278 ar & nSample_;
279 ar & buffers_;
280 ar & sqDiffSums_;
281 }
282
283 /*
284 * Save internal state to archive.
285 */
286 template <typename Data>
288 { ar & *this; }
289
290 /*
291 * Set previously allocated to initial empty state.
292 */
293 template <typename Data>
295 {
296 nSample_ = 0;
297
298 if (bufferCapacity_ > 0) {
299
300 int i;
301 for (i = 0; i < bufferCapacity_; ++i) {
302 setToZero(sqDiffSums_[i]);
303 nValues_[i] = 0;
304 }
305
306 for (i = 0; i < ensembleCapacity_; ++i) {
307 buffers_[i].clear();
308 }
309
310 }
311
312 }
313
314 /*
315 * Allocate arrays and an array of CyclicBuffer objects (private method).
316 */
317 template <typename Data>
319 {
320 if (bufferCapacity_ > 0) {
321
322 // Allocate accumulator arrays
323 sqDiffSums_.allocate(bufferCapacity_);
324 nValues_.allocate(bufferCapacity_);
325
326 // Allocate buffers
327 buffers_.allocate(ensembleCapacity_);
328 for (int i=0; i < ensembleCapacity_; ++i) {
329 buffers_[i].allocate(bufferCapacity_);
330 }
331
332 }
333 clear();
334 }
335
336 /*
337 * Sample a single value from a time sequence.
338 */
339 template <typename Data>
341 {
342 int i, j;
343
344 ++nSample_;
345
346 for (i = 0; i < nEnsemble_; ++i) {
347 buffers_[i].append(values[i]);
348 }
349
350 int bufferSize = buffers_[0].size();
351 for (j = 0; j < bufferSize; ++j) {
352 for (i = 0; i < nEnsemble_; ++i) {
353 sqDiffSums_[j] += sqDiff(buffers_[i][j], values[i]);
354 }
355 ++nValues_[j];
356 };
357 }
358
365 template <>
366 inline double
367 MeanSqDispArray<int>::sqDiff(const int& data1, const int& data2)
368 {
369 int diff;
370 diff = data1 - data2;
371 return double(diff*diff);
372 }
373
380 template <>
381 inline double
382 MeanSqDispArray<double>::sqDiff(const double& data1, const double& data2)
383 {
384 double diff;
385 diff = data1 - data2;
386 return diff*diff;
387 }
388
395 template <>
396 inline double
397 MeanSqDispArray<Vector>::sqDiff(const Vector& data1, const Vector& data2)
398 {
399 Vector diff;
400 diff.subtract(data1, data2);
401 return diff.square();
402 }
403
404 /*
405 * Final output
406 */
407 template <typename Data>
408 void MeanSqDispArray<Data>::output(std::ostream& out)
409 {
410 double msd;
411
412 // Calculate and output mean-squared difference
413 int bufferSize = buffers_[0].size();
414 for (int i = 0; i < bufferSize; ++i) {
415 msd = sqDiffSums_[i]/double(nValues_[i]*nEnsemble_);
416 out << Int(i) << Dbl(msd) << std::endl;
417 }
418
419 }
420
421}
422#endif
Array container class template.
Definition: Array.h:34
Saving archive for binary istream.
Saving / output archive for binary ostream.
Dynamically allocatable contiguous array template.
Definition: DArray.h:32
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
Mean-squared displacement (MSD) vs.
void output(std::ostream &out)
Output the autocorrelation function.
int nEnsemble()
Return number of sequences in the ensemble.
void clear()
Reset to empty state.
void setParam(int ensembleCapacity, int bufferCapacity)
Set parameters, allocate memory, and clear history.
void sample(const Array< Data > &values)
Sample an array of current values.
int bufferCapacity()
Return capacity of the history buffer for each sequence.
void serialize(Archive &ar, const unsigned int version)
Serialize this MeanSqDispArray to/from an archive.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
int nSample()
Return number of values sampled from each sequence thus far.
void setNEnsemble(int nEnsemble)
Set actual number of sequences in ensemble.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
void readParameters(std::istream &in)
Read parameters, allocate memory and clear history.
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
void setToZero(int &value)
Set an int variable to zero.
Definition: setToZero.h:25