PSCF v1.1
AutoCorrArray.h
1#ifndef UTIL_AUTO_CORR_ARRAY_H
2#define UTIL_AUTO_CORR_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#include <util/param/ParamComposite.h> // base class
12#include <util/containers/DArray.h> // member template
13#include <util/containers/RingBuffer.h> // member template parameter
14
15#include <util/accumulators/setToZero.h>
16#include <util/accumulators/product.h>
17#include <util/containers/Array.h>
18#include <util/space/Vector.h>
19#include <util/format/Int.h>
20#include <util/format/Dbl.h>
21
22#include <complex>
23using std::complex;
24
25namespace Util
26{
27
28 template <typename> class Array;
29
56 template <typename Data, typename Product>
58 {
59
60 public:
61
64
67
76 virtual void readParameters(std::istream& in);
77
87 void setParam(int ensembleCapacity, int bufferCapacity);
88
94 virtual void loadParameters(Serializable::IArchive &ar);
95
101 virtual void save(Serializable::OArchive &ar);
102
111 void setNEnsemble(int nEnsemble);
112
116 void clear();
117
123 void sample(const Array<Data>& values);
124
128 void output(std::ostream& out);
129
136 template <class Archive>
137 void serialize(Archive& ar, const unsigned int version);
138
142 int bufferCapacity() const;
143
147 int nEnsemble() const;
148
152 int nSample() const;
153
157 Data average() const;
158
162 double corrTime() const;
163
164 private:
165
167 DArray< RingBuffer<Data> > buffers_;
168
170 DArray<Product> corr_;
171
173 DArray<int> nCorr_;
174
176 Data sum_;
177
179 int ensembleCapacity_;
180
182 int bufferCapacity_;
183
185 int nEnsemble_;
186
188 int nSample_;
189
197 void allocate();
198
199 };
200
201 /*
202 * Default constructor.
203 */
204 template <typename Data, typename Product>
206 : buffers_(),
207 corr_(),
208 nCorr_(),
209 ensembleCapacity_(0),
210 bufferCapacity_(0),
211 nEnsemble_(0),
212 nSample_(0)
213 {
214 setClassName("AutoCorrArray");
215 setToZero(sum_);
216 }
217
218 /*
219 * Destructor.
220 */
221 template <typename Data, typename Product>
223 {}
224
225 /*
226 * Read parameters from file.
227 */
228 template <typename Data, typename Product>
230 {
231 read<int>(in, "ensembleCapacity", ensembleCapacity_);
232 read<int>(in, "bufferCapacity", bufferCapacity_);
233 nEnsemble_ = ensembleCapacity_;
234 allocate();
235 }
236
237 /*
238 * Set parameters and initialize.
239 */
240 template <typename Data, typename Product>
241 void AutoCorrArray<Data, Product>::setParam(int ensembleCapacity, int bufferCapacity)
242 {
243 ensembleCapacity_ = ensembleCapacity;
244 bufferCapacity_ = bufferCapacity;
245 allocate();
246 nEnsemble_ = ensembleCapacity;
247 }
248
249 /*
250 * Load internal state from archive.
251 */
252 template <typename Data, typename Product>
254 {
255 loadParameter<int>(ar, "ensembleCapacity", ensembleCapacity_);
256 loadParameter<int>(ar, "bufferCapacity", bufferCapacity_);
257 ar & nEnsemble_;
258 ar & buffers_;
259 ar & corr_;
260 ar & nCorr_;
261 ar & sum_;
262 ar & nSample_;
263 }
264
265 /*
266 * Save internal state to archive.
267 */
268 template <typename Data, typename Product>
270 { ar & *this; }
271
272 /*
273 * Set or reset nEnsemble.
274 */
275 template <typename Data, typename Product>
277 {
278 if (ensembleCapacity_ == 0) {
279 UTIL_THROW("No memory has been allocated: ensembleCapacity_ == 0");
280 }
281 if (nEnsemble > ensembleCapacity_) {
282 UTIL_THROW("nEnsemble > ensembleCapacity_");
283 }
284 nEnsemble_ = nEnsemble;
285 }
286
287 /*
288 * Set accumulator to initial empty state.
289 */
290 template <typename Data, typename Product>
292 {
293 setToZero(sum_);
294 nSample_ = 0;
295 if (bufferCapacity_ > 0) {
296 int i;
297 for (i = 0; i < bufferCapacity_; ++i) {
298 setToZero(corr_[i]);
299 nCorr_[i] = 0;
300 }
301 for (i = 0; i < ensembleCapacity_; ++i) {
302 buffers_[i].clear();
303 }
304 }
305 }
306
307 /*
308 * Allocate arrays and CyclicBuffer (private method).
309 */
310 template <typename Data, typename Product>
312 {
313 if (bufferCapacity_ > 0) {
314 // Allocate autocorrelation accumulators
315 corr_.allocate(bufferCapacity_);
316 nCorr_.allocate(bufferCapacity_);
317
318 // Allocate buffers
319 buffers_.allocate(ensembleCapacity_);
320 for (int i=0; i < ensembleCapacity_; ++i) {
321 buffers_[i].allocate(bufferCapacity_);
322 }
323 }
324 clear();
325 }
326
327 /*
328 * Sample a single value from a time sequence.
329 */
330 template <typename Data, typename Product>
332 {
333 int i, j;
334 ++nSample_;
335
336 for (i = 0; i < nEnsemble_; ++i) {
337 sum_ += values[i];
338 buffers_[i].append(values[i]);
339 }
340
341 int bufferSize = buffers_[0].size();
342 for (j=0; j < bufferSize; ++j) {
343 for (i = 0; i < nEnsemble_; ++i) {
344 corr_[j] += product(buffers_[i][j], values[i]);
345 }
346 ++nCorr_[j];
347 };
348 }
349
350 /*
351 * Return capacity of history buffer for each sequence.
352 */
353 template <typename Data, typename Product>
355 { return bufferCapacity_; }
356
357 /*
358 * Return number of independent sequences.
359 */
360 template <typename Data, typename Product>
362 { return nEnsemble_; }
363
364 /*
365 * Return number of sampled values.
366 */
367 template <typename Data, typename Product>
369 { return nSample_; }
370
371 /*
372 * Return average of sampled values.
373 */
374 template <typename Data, typename Product>
376 {
377 Data ave = sum_;
378 ave /= double(nSample_*nEnsemble_);
379 return ave;
380 }
381
382 /*
383 * Final output.
384 */
385 template <typename Data, typename Product>
386 void AutoCorrArray<Data, Product>::output(std::ostream& outFile)
387 {
388 Product autocorr;
389 // Product aveSq;
390 // Data ave = average();
391
392 // Calculate and output autocorrelation
393 // aveSq = product(ave, ave);
394 int bufferSize = buffers_[0].size();
395 for (int i = 0; i < bufferSize; ++i) {
396 autocorr = corr_[i]/double(nCorr_[i]*nEnsemble_);
397 //autocorr = autocorr - aveSq;
398 //outFile << Int(i) << Dbl(autocorr) << Int(nCorr_[i]) << std::endl;
399 outFile << Int(i) << Dbl(autocorr) << std::endl;
400 }
401 }
402
403 /*
404 * Return correlation time in unit of sampling interval
405 */
406 template <typename Data, typename Product>
408 {
409 Data ave;
410 Product aveSq, variance, autocorr, sum;
411 int bufferSize = buffers_[0].size();
412
413 // Calculate average of sampled values
414 ave = sum_;
415 ave /= double(nSample_*nEnsemble_);
416 aveSq = product(ave, ave);
417 variance = corr_[0]/double(nCorr_[0]*nEnsemble_);
418 variance = variance - aveSq;
419
420 // Sum over autocorrelation function
421 setToZero(sum);
422 for (int i = 1; i < bufferSize/2; ++i) {
423 autocorr = corr_[i]/double(nCorr_[i]*nEnsemble_);
424 autocorr = autocorr - aveSq;
425 sum += autocorr;
426 }
427 sum /= variance;
428 return sum;
429 }
430
431 /*
432 * Serialize this AutoCorrArray.
433 */
434 template <typename Data, typename Product>
435 template <class Archive>
437 const unsigned int version)
438 {
439 ar & ensembleCapacity_;
440 ar & bufferCapacity_;
441 ar & nEnsemble_;
442 ar & buffers_;
443 ar & corr_;
444 ar & nCorr_;
445 ar & sum_;
446 ar & nSample_;
447 }
448
449}
450#endif
Array container class template.
Definition: Array.h:34
Auto-correlation function for an ensemble of sequences.
Definition: AutoCorrArray.h:58
double corrTime() const
Numerical integral of autocorrelation function.
int nEnsemble() const
Return nEnsemble.
~AutoCorrArray()
Default destructor.
void output(std::ostream &out)
Output the autocorrelation function.
void serialize(Archive &ar, const unsigned int version)
Serialize this AutoCorrArray to/from an archive.
int bufferCapacity() const
Return maximum number of samples in history for each sequence.
void setNEnsemble(int nEnsemble)
Set actual number of sequences in ensemble.
void setParam(int ensembleCapacity, int bufferCapacity)
Allocate memory, and clear history.
Data average() const
Return average of sampled values.
int nSample() const
Return the total number of samples per sequence thus far.
void sample(const Array< Data > &values)
Sample an array of current values.
virtual void readParameters(std::istream &in)
Read parameters, allocate memory and clear history.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
AutoCorrArray()
Default constructor.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
void clear()
Reset to empty state.
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
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
float product(float a, float b)
Product for float Data.
Definition: product.h:22