OpenMPCD
Autocorrelation.py
1 """
2 General class for analyzing autocorrelations.
3 """
4 
5 class Autocorrelation:
6  """
7  Analysis class for autocorrelation of data.
8 
9  Let \f$ X \left( t \right) \f$ be a function of time \f$ t \f$, which is
10  known at evenly-spaced points in time; that is, one knows
11  \f$ X_n = X \left( n \Delta t \right) \f$ for
12  \f$ n \in \left[0, n_{\textrm{max}} \right] \f$.
13 
14  This class calculates the autocorrelation function
15  \f[ C \left( N \right) =
16  \left< X \left( 0 \right) \cdot X \left( N \Delta t \right) \right> =
17  \frac{1}{n_{\textrm{max}} + 1 - N}
18  \sum_{i = 0}^{n_{\textrm{max}} - N} X_i X_{i + N}
19  \f]
20  for arbitrary \f$ N \in \left[0, N_{\textrm{max}} \right] \f$, where
21  \f$ N_{\textrm{max}} \f$ is specified upon construction of an instance of
22  this class.
23 
24  The argument \f$ N \f$ to the autocorrelation function will be called
25  "correlation time" in the context of this class. It is measured in units of
26  \f$ \Delta t \f$.
27  """
28 
29  def __init__(self, maxCorrelationTime):
30  """
31  The constructor.
32 
33  @throw TypeError
34  Throws if any of the arguments have invalid types.
35  @throw ValueError
36  Throws if any of the arguments have invalid values.
37 
38  @param[in] maxCorrelationTime
39  The maximal correlation time to measure,
40  \f$ N_{\textrm{max}} \f$, which must be a non-negative `int`.
41  """
42 
43  if not isinstance(maxCorrelationTime, int):
44  raise TypeError()
45 
46  if maxCorrelationTime < 0:
47  raise ValueError()
48 
49 
50  self._maxCorrelationTime = maxCorrelationTime
51  self._correlations = []
52  self._dataBuffers = []
53 
54  from .OnTheFlyStatisticsDDDA import OnTheFlyStatisticsDDDA
55  for _ in range(0, maxCorrelationTime + 1):
56  self._correlations.append(OnTheFlyStatisticsDDDA())
57  self._dataBuffers.append([])
58 
59 
60  def getMaxCorrelationTime(self):
61  """
62  Returns the maximal correlation time \f$ N_{\textrm{max}} \f$.
63  """
64 
65  return self._maxCorrelationTime
66 
67 
68  def correlationTimeIsAvailable(self, correlationTime):
69  """
70  Returns whether enough data have been supplied for there to be data on
71  the correlation function with the given correlation time \f$ N \f$.
72 
73  One needs to supply at least \f$ N + 1 \f$ data points before one can
74  query the correlation function for \f$ N \f$.
75 
76  @throw TypeError
77  Throws if any of the arguments have invalid types.
78  @throw ValueError
79  Throws if any of the arguments have invalid values.
80 
81  @param[in] correlationTime
82  The correlation time \f$ N \f$ as an `int` in the range
83  `[0, self.getMaxCorrelationTime()]`.
84  """
85 
86  if not isinstance(correlationTime, int):
87  raise TypeError()
88 
89  if correlationTime < 0:
90  raise ValueError()
91 
92  if correlationTime > self.getMaxCorrelationTime():
93  raise ValueError()
94 
95 
96  return self._correlations[0].getSampleSize() > correlationTime
97 
98 
99  def getAutocorrelation(self, correlationTime):
100  """
101  Returns an `OnTheFlyStatisticsDDDA` object that holds information on the
102  sample of measured autocorrelations \f$ C \left( N \right) \f$ for the
103  given correlation time `correlationTime`, \f$ N \f$.
104 
105  @throw TypeError
106  Throws if any of the arguments have invalid types.
107  @throw ValueError
108  Throws if any of the arguments have invalid values.
109  @throw ValueError
110  Throws if `not self.correlationTimeIsAvailable(correlationTime)`.
111 
112  @param[in] correlationTime
113  The correlation time \f$ N \f$ to return results for, as an
114  `int` in the range `[0, self.getMaxCorrelationTime()]`. Also,
115  `self.correlationTimeIsAvailable(correlationTime)` must
116  return `True` for this call to be valid.
117  """
118 
119  if not isinstance(correlationTime, int):
120  raise TypeError()
121 
122  if correlationTime < 0:
123  raise ValueError()
124 
125  if correlationTime > self.getMaxCorrelationTime():
126  raise ValueError()
127 
128  if not self.correlationTimeIsAvailable(correlationTime):
129  raise ValueError()
130 
131  return self._correlations[correlationTime]
132 
133 
134  def addDatum(self, datum, multiplicator = None):
135  """
136  Supplies a new datum \f$ X_i \f$, where \f$ i \f$ is implied to be the
137  number of times `addDatum` has been called previously.
138 
139  @param[in] datum
140  The datum to add, which must be compatible with the
141  `multiplicator`.
142  @param[in] multiplicator
143  A callable that takes two variables, let them be called
144  \f$ X_i \f$ and \f$ X_j \f$, which are of the type that
145  `datum` is an instance of, and returns their product
146  \f$ X_i \cdot X_j \f$ as a type that is compatible with
147  `OnTheFlyStatisticsDDDA.addDatum`.
148  If `None` is given, the default multiplication operator
149  (`datum.__mul__`) is used.
150  No guarantee is given regarding the order of the operands of
151  the multiplication operator.
152  """
153 
154  def defaultMultiplicator(first, second):
155  return first.__mul__(second)
156 
157  if multiplicator is None:
158  multiplicator = defaultMultiplicator
159 
160  self._correlations[0].addDatum(multiplicator(datum, datum))
161 
162  for N in range(1, self.getMaxCorrelationTime() + 1):
163  if len(self._dataBuffers[N]) == N:
164  multiplied = multiplicator(datum, self._dataBuffers[N][0])
165  self._correlations[N].addDatum(multiplied)
166  self._dataBuffers[N] = self._dataBuffers[N][1:] + [datum]
167  else:
168  self._dataBuffers[N].append(datum)
169 
170 
171  def getMPLAxes(self, showEstimatedStandardDeviation = True):
172  """
173  Returns an `matplotlib.axes.Axes` object that plots the autocorrelation
174  function against the correlation time.
175 
176  @throw TypeError
177  Throws if any of the arguments have invalid types.
178  @throw ValueError
179  Throws if any of the arguments have invalid values.
180 
181  @param[in] showEstimatedStandardDeviation
182  Whether to show, for each data point, the estimated standard
183  deviation.
184  """
185 
186  if not isinstance(showEstimatedStandardDeviation, bool):
187  raise TypeError()
188 
189 
190  import matplotlib.figure
191 
192  figure = matplotlib.figure.Figure()
193  axes = figure.add_subplot(1, 1, 1)
194 
195  times = []
196  values = []
197  errorbars = []
198  for N in range(0, self.getMaxCorrelationTime() + 1):
199  if not self.correlationTimeIsAvailable(N):
200  break
201 
202  autocorrelation = self.getAutocorrelation(N)
203 
204  times.append(N)
205  values.append(autocorrelation.getSampleMean())
206  if showEstimatedStandardDeviation:
207  errorbars.append(
208  autocorrelation.getOptimalStandardErrorOfTheMean())
209 
210  if len(errorbars) == 0:
211  errorbars = None
212 
213 
214  axes.errorbar(times, values, yerr = errorbars)
215 
216  axes.set_xlabel(r'Correlation Time $ N $')
217  axes.set_ylabel(r'$ C(N) $')
218 
219  return axes
MPCDAnalysis.Autocorrelation.Autocorrelation._maxCorrelationTime
_maxCorrelationTime
Definition: Autocorrelation.py:53
MPCDAnalysis.Autocorrelation.Autocorrelation.getMaxCorrelationTime
def getMaxCorrelationTime(self)
Definition: Autocorrelation.py:67
MPCDAnalysis.Autocorrelation.Autocorrelation.__init__
def __init__(self, maxCorrelationTime)
Definition: Autocorrelation.py:44
MPCDAnalysis.Autocorrelation.Autocorrelation._dataBuffers
_dataBuffers
Definition: Autocorrelation.py:55
MPCDAnalysis.Autocorrelation.Autocorrelation.getAutocorrelation
def getAutocorrelation(self, correlationTime)
Definition: Autocorrelation.py:123
MPCDAnalysis.Autocorrelation.Autocorrelation.addDatum
def addDatum(self, datum, multiplicator=None)
Definition: Autocorrelation.py:159
MPCDAnalysis.Autocorrelation.Autocorrelation._correlations
_correlations
Definition: Autocorrelation.py:54
MPCDAnalysis.Autocorrelation.Autocorrelation.correlationTimeIsAvailable
def correlationTimeIsAvailable(self, correlationTime)
Definition: Autocorrelation.py:89
MPCDAnalysis.Autocorrelation.Autocorrelation.getMPLAxes
def getMPLAxes(self, showEstimatedStandardDeviation=True)
Definition: Autocorrelation.py:192