Simpatico  v1.10
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>
23 using std::complex;
24 
25 namespace Util
26 {
27 
28  template <typename> class Array;
29 
56  template <typename Data, typename Product>
58  {
59 
60  public:
61 
63  AutoCorrArray();
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>
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
void sample(const Array< Data > &values)
Sample an array of current values.
float product(float a, float b)
Product for float Data.
Definition: product.h:22
void setParam(int ensembleCapacity, int bufferCapacity)
Allocate memory, and clear history.
Wrapper for a double precision number, for formatted ostream output.
Definition: Dbl.h:39
Array container class template.
Definition: AutoCorrArray.h:28
~AutoCorrArray()
Default destructor.
Saving / output archive for binary ostream.
Auto-correlation function for an ensemble of sequences.
Definition: AutoCorrArray.h:57
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
void output(std::ostream &out)
Output the autocorrelation function.
int nSample() const
Return the total number of samples per sequence thus far.
void setToZero(int &value)
Set an int variable to zero.
Definition: setToZero.h:25
Utility classes for scientific computation.
Definition: accumulators.mod:1
AutoCorrArray()
Default constructor.
void serialize(Archive &ar, const unsigned int version)
Serialize this AutoCorrArray to/from an archive.
Wrapper for an int, for formatted ostream output.
Definition: Int.h:36
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.
virtual void readParameters(std::istream &in)
Read parameters, allocate memory and clear history.
void clear()
Reset to empty state.
int bufferCapacity() const
Return maximum number of samples in history for each sequence.
Dynamically allocatable contiguous array template.
Definition: DArray.h:31
Saving archive for binary istream.
double corrTime() const
Numerical integral of autocorrelation function.
Data average() const
Return average of sampled values.
void setClassName(const char *className)
Set class name string.
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
int nEnsemble() const
Return nEnsemble.
An object that can read multiple parameters from file.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
void setNEnsemble(int nEnsemble)
Set actual number of sequences in ensemble.