PSCF v1.1
AutoCorr.h
1#ifndef UTIL_AUTO_CORR_H
2#define UTIL_AUTO_CORR_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/RingBuffer.h> // member
13#include <util/containers/DArray.h> // member
14
15// Needed for implementation
16#include <util/accumulators/setToZero.h>
17#include <util/accumulators/product.h>
18#include <util/space/Vector.h>
19#include <util/format/Int.h>
20#include <util/format/Dbl.h>
21#include <util/format/write.h>
22
23#include <complex>
24
25using std::complex;
26
27namespace Util
28{
29
48 template <typename Data, typename Product>
49 class AutoCorr : public ParamComposite
50 {
51
52 public:
53
57 AutoCorr();
58
62 ~AutoCorr();
63
67 void clear();
68
74 void readParameters(std::istream& in);
75
81 void setParam(int bufferCapacity);
82
88 virtual void loadParameters(Serializable::IArchive& ar);
89
95 virtual void save(Serializable::OArchive& ar);
96
103 template <class Archive>
104 void serialize(Archive& ar, const unsigned int version);
105
111 void sample(Data value);
112
118 void output(std::ostream& out);
119
123 int bufferCapacity() const;
124
128 int nSample() const;
129
133 Data average() const;
134
138 double corrTime() const;
139
145 Product autoCorrelation(int t) const;
146
147 private:
148
149 // Ring buffer containing a sequence of stored Data values.
150 RingBuffer<Data> buffer_;
151
152 // Array in which corr[j] = sum of values of <x(i-j), x(i)>
153 DArray<Product> corr_;
154
155 // Array in which nCorr[i] = number of values added to corr[i]
156 DArray<int> nCorr_;
157
158 // Sum of all previous values of x(t)
159 Data sum_;
160
161 // Physical capacity (# of elements) of buffer, corr, and nCorr
162 int bufferCapacity_;
163
164 // Total number of previous values of x(t)
165 int nSample_;
166
170 void allocate();
171
175 bool isValid();
176
177 };
178
179 /*
180 * Default constructor.
181 */
182 template <typename Data, typename Product>
184 : buffer_(),
185 corr_(),
186 nCorr_(),
187 bufferCapacity_(0),
188 nSample_(0)
189 {
190 setClassName("AutoCorr");
191 setToZero(sum_);
192 }
193
194 /*
195 * Destructor
196 */
197 template <typename Data, typename Product>
199 {}
200
201 /*
202 * Read buffer capacity and allocate all required memory.
203 */
204 template <typename Data, typename Product>
206 {
207 read<int>(in, "capacity", bufferCapacity_);
208 allocate();
209 }
210
211 /*
212 * Set buffer capacity and initialize.
213 */
214 template <typename Data, typename Product>
215 void AutoCorr<Data, Product>::setParam(int bufferCapacity)
216 {
217 bufferCapacity_ = bufferCapacity;
218 allocate();
219 }
220
221 /*
222 * Load state from an archive.
223 */
224 template <typename Data, typename Product>
226 {
227 loadParameter<int>(ar, "capacity", bufferCapacity_);
228 ar & buffer_;
229 ar & corr_;
230 ar & nCorr_;
231 ar & sum_;
232 ar & nSample_;
233 isValid();
234 }
235
236 /*
237 * Save state to an archive.
238 */
239 template <typename Data, typename Product>
241 { ar & *this; }
242
243 /*
244 * Set previously allocated to initial empty state.
245 */
246 template <typename Data, typename Product>
248 {
249 setToZero(sum_);
250 nSample_ = 0;
251
252 if (bufferCapacity_ > 0) {
253 for (int i=0; i < bufferCapacity_; ++i) {
254 setToZero(corr_[i]);
255 nCorr_[i] = 0;
256 }
257 buffer_.clear();
258 }
259 }
260
261 /*
262 * Allocate arrays and CyclicBuffer, and initialize.
263 */
264 template <typename Data, typename Product>
266 {
267 if (bufferCapacity_ > 0) {
268 corr_.allocate(bufferCapacity_);
269 nCorr_.allocate(bufferCapacity_);
270 buffer_.allocate(bufferCapacity_);
271 }
272 clear();
273 }
274
275 /*
276 * Are capacities consistent?
277 */
278 template <typename Data, typename Product>
279 bool AutoCorr<Data, Product>::isValid()
280 {
281 bool valid = true;
282 if (bufferCapacity_ != corr_.capacity()) valid = false;
283 if (bufferCapacity_ != nCorr_.capacity()) valid = false;
284 if (bufferCapacity_ != buffer_.capacity()) valid = false;
285 if (!valid) {
286 UTIL_THROW("Invalid AutoCorr");
287 }
288 return valid;
289 }
290
291 /*
292 * Sample a single value from a time sequence.
293 */
294 template <typename Data, typename Product>
296 {
297 ++nSample_;
298 sum_ += value;
299 buffer_.append(value);
300 for (int i=0; i < buffer_.size(); ++i) {
301 corr_[i] += product(buffer_[i], value);
302 ++nCorr_[i];
303 };
304 }
305
306 /*
307 * Return capacity of history buffer.
308 */
309 template <typename Data, typename Product>
311 { return bufferCapacity_; }
312
313 /*
314 * Return number of values sampled thus far.
315 */
316 template <typename Data, typename Product>
318 { return nSample_; }
319
320 /*
321 * Return average of sampled values.
322 */
323 template <typename Data, typename Product>
325 {
326 Data ave = sum_;
327 ave /= double(nSample_);
328 return ave;
329 }
330
331 /*
332 * Final output
333 */
334 template <typename Data, typename Product>
335 void AutoCorr<Data, Product>::output(std::ostream& outFile)
336 {
337 Data ave;
338 Product autocorr;
339 Product aveSq;
340
341 // Calculate and output average of sampled values
342 ave = sum_;
343 ave /= double(nSample_);
344 aveSq = product(ave, ave);
345
346 // Calculate and output autocorrelation
347 for (int i = 0; i < buffer_.size(); ++i) {
348 autocorr = corr_[i]/double(nCorr_[i]);
349 autocorr = autocorr - aveSq;
350 outFile << Int(i);
351 write<Product>(outFile, autocorr);
352 outFile << std::endl;
353 }
354
355 }
356
357 /*
358 * Return correlation time in unit of sampling interval
359 */
360 template <typename Data, typename Product>
362 {
363 Data ave;
364 Product aveSq, variance, autocorr, sum;
365 int size;
366
367 size = buffer_.size();
368
369 // Calculate average sampled values
370 ave = sum_/double(nSample_);
371 ave /= double(nSample_);
372 aveSq = product(ave, ave);
373
374 // Calculate variance sampled values
375 variance = corr_[0]/double(nCorr_[0]);
376 variance = variance - aveSq;
377
378 setToZero(sum);
379 for (int i = 1; i < size/2; ++i) {
380 autocorr = corr_[i]/double(nCorr_[i]);
381 autocorr = autocorr - aveSq;
382 sum += autocorr;
383 }
384 sum = sum/variance;
385
386 return sum;
387 }
388
389 /*
390 * Return autocorrelation at a given lag time index
391 *
392 * \param t the lag time index
393 */
394 template <typename Data, typename Product>
396 {
397 Data ave;
398 Product autocorr;
399 Product aveSq;
400
401 // Calculate average of sampled values
402 ave = sum_;
403 ave /= double(nSample_);
404 aveSq = product(ave, ave);
405
406 // Calculate and return autocorrelation
407 assert(t < buffer_.size());
408 autocorr = corr_[t]/double(nCorr_[t]);
409 autocorr = autocorr - aveSq;
410
411 return autocorr;
412 }
413
414 /*
415 * Serialize this AutoCorr.
416 */
417 template <typename Data, typename Product>
418 template <class Archive>
420 const unsigned int version)
421 {
422 ar & bufferCapacity_;
423 ar & buffer_;
424 ar & corr_;
425 ar & nCorr_;
426 ar & sum_;
427 ar & nSample_;
428 isValid();
429 }
430
431}
432#endif
Auto-correlation function for one sequence of Data values.
Definition: AutoCorr.h:50
Data average() const
Return average of all sampled values.
Definition: AutoCorr.h:324
double corrTime() const
Numerical integration of autocorrelation function.
Definition: AutoCorr.h:361
Product autoCorrelation(int t) const
Return autocorrelation at a given lag time.
Definition: AutoCorr.h:395
AutoCorr()
Constructor.
Definition: AutoCorr.h:183
int bufferCapacity() const
Return capacity of history buffer.
Definition: AutoCorr.h:310
void sample(Data value)
Sample a value.
Definition: AutoCorr.h:295
void clear()
Reset to empty state.
Definition: AutoCorr.h:247
void setParam(int bufferCapacity)
Set buffer capacity, allocate memory and initialize.
Definition: AutoCorr.h:215
int nSample() const
Return number of values sampled thus far.
Definition: AutoCorr.h:317
~AutoCorr()
Destructor.
Definition: AutoCorr.h:198
void readParameters(std::istream &in)
Read buffer capacity, allocate memory and initialize.
Definition: AutoCorr.h:205
void output(std::ostream &out)
Output the autocorrelation function.
Definition: AutoCorr.h:335
void serialize(Archive &ar, const unsigned int version)
Serialize to/from an archive.
Definition: AutoCorr.h:419
virtual void loadParameters(Serializable::IArchive &ar)
Load state from an archive.
Definition: AutoCorr.h:225
virtual void save(Serializable::OArchive &ar)
Save state to an archive.
Definition: AutoCorr.h:240
Saving archive for binary istream.
Saving / output archive for binary ostream.
Dynamically allocatable contiguous array template.
Definition: DArray.h:32
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.
Class for storing history of previous values in an array.
Definition: RingBuffer.h:27
#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