Stats_T.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef OPENDDS_DCPS_STATS_T_H
00009 #define OPENDDS_DCPS_STATS_T_H
00010 
00011 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00012 #pragma once
00013 #endif /* ACE_LACKS_PRAGMA_ONCE */
00014 
00015 #include "DataCollector_T.h"
00016 
00017 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00018 
00019 namespace OpenDDS {
00020 namespace DCPS {
00021 
00022 /**
00023  * @class Stats<DataType>
00024  *
00025  * @brief Accumulates average, n, variance, minimum, and maximum statistics
00026  */
00027 template<typename DataType>
00028 class Stats : public DataCollector<DataType> {
00029 public:
00030   /// Default constructor.
00031   Stats(unsigned int amount = 0,
00032         typename DataCollector<DataType>::OnFull type =
00033           DataCollector<DataType>::KeepOldest);
00034 
00035   /// Default bitwise copy is sufficient.
00036 
00037   /// Assignment operator
00038   Stats& operator=(const Stats& rhs);
00039 
00040   /// Reset statistics to nil.
00041   void reset();
00042 
00043   /**
00044    * Accumulate a new value.
00045    * @param value the new value to be accumulated.
00046    */
00047   void add(DataType value);
00048 
00049   /// Calculate the average value.
00050   long double mean() const;
00051 
00052   /// Calculate the variance value.
00053   long double var() const;
00054 
00055   /// Access the minimum value.
00056   DataType minimum() const;
00057 
00058   /// Access the maximum value.
00059   DataType maximum() const;
00060 
00061   /// Access the number of values accumulated.
00062   unsigned long n() const;
00063 
00064 private:
00065   // Direct statistics.
00066   unsigned long n_;
00067   DataType      minimum_;
00068   DataType      maximum_;
00069 
00070   // Internal variables have the largest range and highest precision possible.
00071   long double an_ ;
00072   long double bn_ ;
00073   long double cn_ ;
00074   long double variance_ ;
00075 };
00076 
00077 template<typename DataType>
00078 inline
00079 Stats<DataType>::Stats(
00080   unsigned int amount,
00081   typename DataCollector<DataType>::OnFull type) : DataCollector<DataType>(amount, type)
00082 {
00083   this->reset();
00084 }
00085 
00086 template<typename DataType>
00087 inline
00088 Stats<DataType>&
00089 Stats<DataType>::operator=(const Stats& rhs)
00090 {
00091   this->n_        = rhs.n_;
00092   this->minimum_  = rhs.minimum_;
00093   this->maximum_  = rhs.maximum_;
00094   this->an_       = rhs.an_ ;
00095   this->bn_       = rhs.bn_ ;
00096   this->cn_       = rhs.cn_ ;
00097   this->variance_ = rhs.variance_ ;
00098   return *this;
00099 }
00100 
00101 template<typename DataType>
00102 inline
00103 void
00104 Stats<DataType>::reset()
00105 {
00106   this->n_        = 0;
00107   this->minimum_  = static_cast<DataType>(0);
00108   this->maximum_  = static_cast<DataType>(0);
00109   this->an_       = 0.0;
00110   this->bn_       = 0.0;
00111   this->cn_       = 0.0;
00112   this->variance_ = 0.0;
00113 }
00114 
00115 template<typename DataType>
00116 inline
00117 void
00118 Stats<DataType>::add(DataType value)
00119 {
00120   // Save the raw value if configured to.
00121   this->collect(value);
00122 
00123   // Slide rule style calculations.
00124   long double term;
00125 
00126   //
00127   // V(N+1) = V(N) * N^2 / (N+1)^2
00128   //        + A(N)
00129   //        - B(N) * X(N+1)
00130   //        + C(N) * X(N+1)^2
00131   //
00132   this->variance_ /= (this->n_ + 1);
00133   this->variance_ *=  this->n_;
00134   this->variance_ /= (this->n_ + 1);
00135   this->variance_ *=  this->n_;
00136 
00137   term = static_cast<long double>(value);
00138   this->variance_ +=  this->an_;
00139   this->variance_ -=  this->bn_ * term;
00140   this->variance_ +=  this->cn_ * term * term;
00141 
00142   // The internal variable updates _must_ follow the variance update.
00143 
00144   //
00145   // A(N+1) = (A(N) * (N+1)^2 / (N+2)^2) + (X(N+1) / (N+2)^2)
00146   //
00147   this->an_ /= (this->n_ + 2);
00148   this->an_ *= (this->n_ + 1);
00149   this->an_ /= (this->n_ + 2);
00150   this->an_ *= (this->n_ + 1);
00151 
00152   // term = static_cast<long double>( value);
00153   term *= term;
00154   term /= (this->n_ + 2);
00155   term /= (this->n_ + 2);
00156   this->an_ += term;
00157 
00158   //
00159   // B(N+1) = (B(N) * (N+1)^2 / (N+2)^2) + (2 * X(N+1) / (N+2)^2)
00160   //
00161   this->bn_ /= (this->n_ + 2);
00162   this->bn_ *= (this->n_ + 1);
00163   this->bn_ /= (this->n_ + 2);
00164   this->bn_ *= (this->n_ + 1);
00165 
00166   term = static_cast<long double>(value * 2);
00167   term /= (this->n_ + 2);
00168   term /= (this->n_ + 2);
00169   this->bn_ += term;
00170 
00171   //
00172   // C(N+1) = (N+1) / (N+2)^2
00173   //
00174   this->cn_  =  this->n_ + 1;
00175   this->cn_ /= (this->n_ + 2);
00176   this->cn_ /= (this->n_ + 2);
00177 
00178   if ((this->n_ == 0) || (value < this->minimum_)) {
00179     this->minimum_ = value;
00180   }
00181 
00182   if ((this->n_ == 0) || (value > this->maximum_)) {
00183     this->maximum_ = value;
00184   }
00185 
00186   this->n_ += 1; // Must follow internal variable updates.
00187 }
00188 
00189 template<typename DataType>
00190 inline
00191 long double
00192 Stats<DataType>::mean() const
00193 {
00194   if (this->n_ == 0) {
00195     /// @TODO: return qNaN with no data.
00196     return 0.0;
00197   }
00198 
00199   // Slide rule style calculations.
00200 
00201   //
00202   // MEAN = B(N) * (N+1)^2 / (2 * N)
00203   //
00204   long double average = this->bn_ / 2.0 ;
00205 
00206   average *= (this->n_ + 1) ;
00207   average /=  this->n_ ;
00208   average *= (this->n_ + 1) ;
00209 
00210   return average ;
00211 }
00212 
00213 template<typename DataType>
00214 inline
00215 long double
00216 Stats<DataType>::var() const
00217 {
00218   return this->variance_ ;
00219 }
00220 
00221 template<typename DataType>
00222 inline
00223 DataType
00224 Stats<DataType>::minimum() const
00225 {
00226   /// @TODO: return qNaN with no data.
00227   return (this->n_ == 0)? 0: this->minimum_;
00228 }
00229 
00230 template<typename DataType>
00231 inline
00232 DataType
00233 Stats<DataType>::maximum() const
00234 {
00235   /// @TODO: return qNaN with no data.
00236   return (this->n_ == 0)? 0: this->maximum_;
00237 }
00238 
00239 template<typename DataType>
00240 inline
00241 unsigned long
00242 Stats<DataType>::n() const
00243 {
00244   return this->n_;
00245 }
00246 
00247 } // namespace DCPS
00248 } // namespace OpenDDS
00249 
00250 OPENDDS_END_VERSIONED_NAMESPACE_DECL
00251 
00252 #endif // OPENDDS_DCPS_STATS_T_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1