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

Generated on Fri Feb 12 20:05:27 2016 for OpenDDS by  doxygen 1.4.7