OpenMPCD
ImplementationDetails/OnTheFlyStatisticsDDDA.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * Implements functionality of `OpenMPCD::OnTheFlyStatisticsDDDA`.
4  */
5 
6 #ifndef OPENMPCD_IMPLEMENTATIONDETAILS_ONTHEFLYSTATISTICSDDDA_HPP
7 #define OPENMPCD_IMPLEMENTATIONDETAILS_ONTHEFLYSTATISTICSDDDA_HPP
8 
12 
13 #include <cmath>
14 
15 
16 namespace OpenMPCD
17 {
18 
19 template<typename T>
21 {
22  blocks.reserve(5);
23  waiting.reserve(5);
24 
25  blocks.resize(1);
26  waiting.resize(1);
27 }
28 
29 template<typename T>
31 {
32  addDatum(datum, 0);
33 }
34 
35 template<typename T>
37 {
38  return blocks[0].getSampleSize();
39 }
40 
41 template<typename T>
43 {
44  if(getSampleSize() == 0)
45  {
48  "Tried to get mean without having supplied data.");
49  }
50 
51  return blocks[0].getSampleMean();
52 }
53 
54 template<typename T>
56 {
57  if(getSampleSize() == 0)
58  {
61  "Tried to get mean without having supplied data.");
62  }
63 
64  return std::size_t(1) << getMaximumBlockID();
65 }
66 
67 template<typename T>
69 {
70  OPENMPCD_DEBUG_ASSERT(blocks.size() > 0);
71 
72  return blocks.size() - 1;
73 }
74 
75 template<typename T>
77  const std::size_t blockID) const
78 {
80  blockID <= getMaximumBlockID(),
82 
83  return blocks[blockID].getSampleSize() >= 2;
84 }
85 
86 template<typename T>
88  const std::size_t blockID) const
89 {
91  blockID <= getMaximumBlockID(),
93 
94  if(!hasBlockVariance(blockID))
95  OPENMPCD_THROW(InvalidCallException, "!hasBlockVariance(blockID)");
96 
97  return blocks[blockID].getSampleVariance();
98 }
99 
100 template<typename T>
102  const std::size_t blockID) const
103 {
104  return sqrt(getBlockVariance(blockID));
105 }
106 
107 template<typename T>
109 {
110  return getBlockStandardDeviation(0);
111 }
112 
113 template<typename T>
115  const std::size_t blockID) const
116 {
118  blockID <= getMaximumBlockID(),
120 
121  if(!hasBlockVariance(blockID))
122  OPENMPCD_THROW(InvalidCallException, "!hasBlockVariance(blockID)");
123 
124  return blocks[blockID].getStandardErrorOfTheMean();
125 }
126 
127 template<typename T>
130  const std::size_t blockID) const
131 {
133  blockID <= getMaximumBlockID(),
135 
136  if(!hasBlockVariance(blockID))
137  OPENMPCD_THROW(InvalidCallException, "!hasBlockVariance(blockID)");
138 
139  const T se = getBlockStandardErrorOfTheMean(blockID);
140  const std::size_t reducedSampleSize = blocks[blockID].getSampleSize();
141 
142  return se / sqrt(2 * reducedSampleSize);
143 }
144 
145 template<typename T>
146 std::size_t
148 {
149  if(getSampleSize() < 2)
150  OPENMPCD_THROW(InvalidCallException, "Not enough data added.");
151 
152  const T rawStandardError = blocks[0].getStandardErrorOfTheMean();
153 
154  if(rawStandardError == 0)
155  return 0;
156 
157  std::size_t optimalBlockID = getMaximumBlockID();
158 
159  for(std::size_t blockID = getMaximumBlockID(); ; --blockID)
160  {
161  if(!hasBlockVariance(blockID))
162  {
163  OPENMPCD_DEBUG_ASSERT(blockID == getMaximumBlockID());
164 
165  --optimalBlockID;
166  continue;
167  }
168 
169  const std::size_t blockSize = std::size_t(1) << blockID;
170  const T blockedStandardError =
171  blocks[blockID].getStandardErrorOfTheMean();
172  const T quotient = blockedStandardError / rawStandardError;
173  const T quotientPower2 = quotient * quotient;
174  const T quotientPower4 = quotientPower2 * quotientPower2;
175 
176  const T threshold = 2 * getSampleSize() * quotientPower4;
177  if(blockSize * blockSize * blockSize > threshold)
178  optimalBlockID = blockID;
179 
180  if(blockID == 0)
181  break;
182  }
183 
184  return optimalBlockID;
185 }
186 
187 template<typename T>
188 bool
190 const
191 {
192  const std::size_t blockID = getOptimalBlockIDForStandardErrorOfTheMean();
193  const std::size_t blockSize = std::size_t(1) << blockID;
194 
195  return 50 * blockSize < getSampleSize();
196 }
197 
198 template<typename T>
200 {
201  const std::size_t blockID = getOptimalBlockIDForStandardErrorOfTheMean();
202 
203  return getBlockStandardErrorOfTheMean(blockID);
204 }
205 
206 template<typename T>
207 void
208 OnTheFlyStatisticsDDDA<T>::addDatum(const T& datum, const std::size_t blockID)
209 {
210  OPENMPCD_DEBUG_ASSERT(blockID < blocks.size());
211  OPENMPCD_DEBUG_ASSERT(blocks.size() == waiting.size());
212 
213  blocks[blockID].addDatum(datum);
214 
215  if(waiting[blockID])
216  {
217  const T mean = (datum + *waiting[blockID]) / 2.0;
218 
219  waiting[blockID] = boost::none;
220  if(blockID + 1 == blocks.size())
221  {
222  blocks.push_back(OnTheFlyStatistics<T>());
223  waiting.push_back(boost::none);
224  }
225 
226  addDatum(mean, blockID + 1);
227  }
228  else
229  {
230  waiting[blockID] = datum;
231  }
232 }
233 
234 template<typename T>
236 {
237  BOOST_STATIC_ASSERT(boost::is_arithmetic<T>::value);
238 
239  std::stringstream ss;
240 
241  ss.precision(std::numeric_limits<T>::digits10 + 2);
242 
243  ss << "1|"; //format version
244  ss << blocks.size();
245  for(std::size_t i = 0; i < blocks.size(); ++i)
246  ss << "|" << blocks[i].serializeToString();
247 
248  OPENMPCD_DEBUG_ASSERT(blocks.size() == waiting.size());
249  for(std::size_t i = 0; i < blocks.size(); ++i)
250  {
251  ss << "|";
252  if(waiting[i])
253  ss << *waiting[i];
254  }
255 
256  return ss.str();
257 }
258 
259 template<typename T>
261 {
262  BOOST_STATIC_ASSERT(boost::is_arithmetic<T>::value);
263 
264  std::vector<std::string> parts;
265  boost::algorithm::split(parts, state, boost::algorithm::is_any_of("|"));
266 
267  try
268  {
269  if(parts[0][0] == '-')
271  const unsigned int version =
272  boost::lexical_cast<unsigned int>(parts[0]);
273 
274  if(version != 1)
275  OPENMPCD_THROW(InvalidArgumentException, "Unknown version");
276 
277  if(parts[1][0] == '-')
279  const std::size_t blockCount =
280  boost::lexical_cast<unsigned int>(parts[1]);
281 
282  if(parts.size() != 2 + 2 * blockCount)
284 
285  std::vector<OnTheFlyStatistics<T> > _blocks;
286  for(std::size_t i = 0; i < blockCount; ++i)
287  {
288  OnTheFlyStatistics<T> block;
289  block.unserializeFromString(parts[2 + i]);
290  _blocks.push_back(block);
291  }
292 
293  std::vector<boost::optional<T> > _waiting;
294  for(std::size_t i = 0; i < blockCount; ++i)
295  {
296  boost::optional<T> w;
297  const std::string& part = parts[2 + blockCount + i];
298  if(part.size() > 0)
299  w = boost::lexical_cast<T>(part);
300  _waiting.push_back(w);
301  }
302 
303  blocks = _blocks;
304  waiting = _waiting;
305 
306  if(blockCount == 0)
307  {
308  blocks.resize(1);
309  waiting.resize(1);
310  }
311  }
312  catch(const boost::bad_lexical_cast&)
313  {
315  }
316 }
317 
318 } //namespace OpenMPCD
319 
320 #endif //OPENMPCD_IMPLEMENTATIONDETAILS_ONTHEFLYSTATISTICSDDDA_HPP
OpenMPCD::OnTheFlyStatisticsDDDA::getBlockStandardErrorOfTheMean
const T getBlockStandardErrorOfTheMean(const std::size_t blockID) const
Returns an estimate for the standard deviation of the standard error of the mean for a given blockID.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:114
OpenMPCD::InvalidCallException
Exception for a forbidden function call.
Definition: Exceptions.hpp:144
Exceptions.hpp
OPENMPCD_THROW
#define OPENMPCD_THROW(ExceptionType, message)
Throws the given ExceptionType, passing the given message along with file and line number information...
Definition: Exceptions.hpp:22
OpenMPCD::OnTheFlyStatisticsDDDA::getMaximumBlockSize
std::size_t getMaximumBlockSize() const
Returns the largest block size for which there is at least one data point.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:55
OpenMPCD::OnTheFlyStatisticsDDDA::unserializeFromString
void unserializeFromString(const std::string &state)
Discards the current state, and loads the state specified in the given string instead.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:260
OPENMPCD_DEBUG_ASSERT
#define OPENMPCD_DEBUG_ASSERT(assertion)
Asserts that the given expression evaluates to true, but only if OPENMPCD_DEBUG is defined.
Definition: OPENMPCD_DEBUG_ASSERT.hpp:88
OpenMPCD::OnTheFlyStatisticsDDDA::getOptimalBlockIDForStandardErrorOfTheMean
std::size_t getOptimalBlockIDForStandardErrorOfTheMean() const
Returns the block ID corresponding to the optimal block size, in the sense that the corresponding blo...
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:147
OpenMPCD::OnTheFlyStatisticsDDDA::addDatum
void addDatum(const T &datum)
Adds a datum to the sample.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:30
OpenMPCD::OnTheFlyStatisticsDDDA::getBlockVariance
const T getBlockVariance(const std::size_t blockID) const
Returns the sample variance in the block with the given blockID.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:87
OPENMPCD_DEBUG_ASSERT.hpp
OpenMPCD::OnTheFlyStatisticsDDDA::getMaximumBlockID
std::size_t getMaximumBlockID() const
Returns the ID of the largest block size created so far.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:68
OpenMPCD::OnTheFlyStatisticsDDDA::getBlockStandardDeviation
const T getBlockStandardDeviation(const std::size_t blockID) const
Returns the sample standard deviation in the block with the given blockID.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:101
OPENMPCD_DEBUG_ASSERT_EXCEPTIONTYPE
#define OPENMPCD_DEBUG_ASSERT_EXCEPTIONTYPE(assertion, ExceptionType)
Definition: OPENMPCD_DEBUG_ASSERT.hpp:76
OpenMPCD::OnTheFlyStatisticsDDDA::serializeToString
const std::string serializeToString() const
Returns a string that contains the state of this instance.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:235
OpenMPCD::OnTheFlyStatisticsDDDA::getEstimatedStandardDeviationOfBlockStandardErrorOfTheMean
const T getEstimatedStandardDeviationOfBlockStandardErrorOfTheMean(const std::size_t blockID) const
Returns an estimate for the standard deviation of the standard error of the mean for a given blockID.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:129
OpenMPCD::OnTheFlyStatistics::unserializeFromString
void unserializeFromString(const std::string &state)
Discards the current state, and loads the state specified in the given string instead.
Definition: ImplementationDetails/OnTheFlyStatistics.hpp:40
OnTheFlyStatisticsDDDA.hpp
OpenMPCD::OnTheFlyStatisticsDDDA::OnTheFlyStatisticsDDDA
OnTheFlyStatisticsDDDA()
The constructor.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:20
OpenMPCD::Utility::MathematicalFunctions::sqrt
OPENMPCD_CUDA_HOST_AND_DEVICE T sqrt(const T x)
Returns the sqaure root of the argument.
OpenMPCD::OnTheFlyStatisticsDDDA::getSampleMean
const T getSampleMean() const
Returns the mean of all the values added so far.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:42
OpenMPCD::OnTheFlyStatistics
Computes sample means and variances "on-the-fly" or "online", i.e.
Definition: OnTheFlyStatistics.hpp:34
OpenMPCD::OnTheFlyStatisticsDDDA::hasBlockVariance
bool hasBlockVariance(const std::size_t blockID) const
Returns whether the block with the given blockID has enough data to compute a sample variance.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:76
OpenMPCD::OnTheFlyStatisticsDDDA::getSampleStandardDeviation
const T getSampleStandardDeviation() const
Returns the raw sample standard deviation, i.e.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:108
OpenMPCD::OnTheFlyStatisticsDDDA::getOptimalStandardErrorOfTheMean
const T getOptimalStandardErrorOfTheMean() const
Returns the best estimation of the true standard error of the mean of the data, after decorrelation.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:199
OpenMPCD::OnTheFlyStatisticsDDDA::optimalStandardErrorOfTheMeanEstimateIsReliable
bool optimalStandardErrorOfTheMeanEstimateIsReliable() const
Returns whether the sample is large enough for the estimate of the standard error of the mean,...
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:189
OpenMPCD::InvalidArgumentException
Invalid argument exception.
Definition: Exceptions.hpp:128
OpenMPCD::OnTheFlyStatisticsDDDA::getSampleSize
std::size_t getSampleSize() const
Returns the number of data points added so far.
Definition: ImplementationDetails/OnTheFlyStatisticsDDDA.hpp:36