LCOV - code coverage report
Current view: top level - DCPS - Stats_T.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 73 0.0 %
Date: 2023-04-30 01:32:43 Functions: 0 9 0.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *
       4             :  * Distributed under the OpenDDS License.
       5             :  * See: http://www.opendds.org/license.html
       6             :  */
       7             : 
       8             : #ifndef OPENDDS_DCPS_STATS_T_H
       9             : #define OPENDDS_DCPS_STATS_T_H
      10             : 
      11             : #if !defined (ACE_LACKS_PRAGMA_ONCE)
      12             : #pragma once
      13             : #endif /* ACE_LACKS_PRAGMA_ONCE */
      14             : 
      15             : #include "DataCollector_T.h"
      16             : 
      17             : OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
      18             : 
      19             : namespace OpenDDS {
      20             : namespace DCPS {
      21             : 
      22             : /**
      23             :  * @class Stats<DataType>
      24             :  *
      25             :  * @brief Accumulates average, n, variance, minimum, and maximum statistics
      26             :  */
      27             : template<typename DataType>
      28             : class Stats : public DataCollector<DataType> {
      29             : public:
      30             :   /// Default constructor.
      31             :   Stats(unsigned int amount = 0,
      32             :         typename DataCollector<DataType>::OnFull type =
      33             :           DataCollector<DataType>::KeepOldest);
      34             : 
      35             :   Stats(const Stats&);
      36             : 
      37             :   /// Default bitwise copy is sufficient.
      38             : 
      39             :   /// Assignment operator
      40             :   Stats& operator=(const Stats& rhs);
      41             : 
      42             :   /// Reset statistics to nil.
      43             :   void reset();
      44             : 
      45             :   /**
      46             :    * Accumulate a new value.
      47             :    * @param value the new value to be accumulated.
      48             :    */
      49             :   void add(DataType value);
      50             : 
      51             :   /// Calculate the average value.
      52             :   long double mean() const;
      53             : 
      54             :   /// Calculate the variance value.
      55             :   long double var() const;
      56             : 
      57             :   /// Access the minimum value.
      58             :   DataType minimum() const;
      59             : 
      60             :   /// Access the maximum value.
      61             :   DataType maximum() const;
      62             : 
      63             :   /// Access the number of values accumulated.
      64             :   unsigned long n() const;
      65             : 
      66             : private:
      67             :   // Direct statistics.
      68             :   unsigned long n_;
      69             :   DataType      minimum_;
      70             :   DataType      maximum_;
      71             : 
      72             :   // Internal variables have the largest range and highest precision possible.
      73             :   long double an_ ;
      74             :   long double bn_ ;
      75             :   long double cn_ ;
      76             :   long double variance_ ;
      77             : };
      78             : 
      79             : template<typename DataType>
      80             : inline
      81           0 : Stats<DataType>::Stats(
      82             :   unsigned int amount,
      83           0 :   typename DataCollector<DataType>::OnFull type) : DataCollector<DataType>(amount, type)
      84             : {
      85           0 :   this->reset();
      86           0 : }
      87             : 
      88             : template<typename DataType>
      89             : inline
      90           0 : Stats<DataType>::Stats(const Stats<DataType>& v) : DataCollector<DataType>(v),
      91           0 :   n_(v.n_),
      92           0 :   minimum_(v.minimum_),
      93           0 :   maximum_(v.maximum_),
      94           0 :   an_(v.an_),
      95           0 :   bn_(v.bn_),
      96           0 :   cn_(v.cn_),
      97           0 :   variance_(v.variance_)
      98             : {
      99           0 : }
     100             : 
     101             : template<typename DataType>
     102             : inline
     103             : Stats<DataType>&
     104             : Stats<DataType>::operator=(const Stats& rhs)
     105             : {
     106             :   this->n_        = rhs.n_;
     107             :   this->minimum_  = rhs.minimum_;
     108             :   this->maximum_  = rhs.maximum_;
     109             :   this->an_       = rhs.an_ ;
     110             :   this->bn_       = rhs.bn_ ;
     111             :   this->cn_       = rhs.cn_ ;
     112             :   this->variance_ = rhs.variance_ ;
     113             :   return *this;
     114             : }
     115             : 
     116             : template<typename DataType>
     117             : inline
     118             : void
     119           0 : Stats<DataType>::reset()
     120             : {
     121           0 :   this->n_        = 0;
     122           0 :   this->minimum_  = static_cast<DataType>(0);
     123           0 :   this->maximum_  = static_cast<DataType>(0);
     124           0 :   this->an_       = 0.0;
     125           0 :   this->bn_       = 0.0;
     126           0 :   this->cn_       = 0.0;
     127           0 :   this->variance_ = 0.0;
     128           0 : }
     129             : 
     130             : template<typename DataType>
     131             : inline
     132             : void
     133           0 : Stats<DataType>::add(DataType value)
     134             : {
     135             :   // Save the raw value if configured to.
     136           0 :   this->collect(value);
     137             : 
     138             :   // Slide rule style calculations.
     139             :   long double term;
     140             : 
     141             :   //
     142             :   // V(N+1) = V(N) * N^2 / (N+1)^2
     143             :   //        + A(N)
     144             :   //        - B(N) * X(N+1)
     145             :   //        + C(N) * X(N+1)^2
     146             :   //
     147           0 :   this->variance_ /= (this->n_ + 1);
     148           0 :   this->variance_ *=  this->n_;
     149           0 :   this->variance_ /= (this->n_ + 1);
     150           0 :   this->variance_ *=  this->n_;
     151             : 
     152           0 :   term = static_cast<long double>(value);
     153           0 :   this->variance_ +=  this->an_;
     154           0 :   this->variance_ -=  this->bn_ * term;
     155           0 :   this->variance_ +=  this->cn_ * term * term;
     156             : 
     157             :   // The internal variable updates _must_ follow the variance update.
     158             : 
     159             :   //
     160             :   // A(N+1) = (A(N) * (N+1)^2 / (N+2)^2) + (X(N+1) / (N+2)^2)
     161             :   //
     162           0 :   this->an_ /= (this->n_ + 2);
     163           0 :   this->an_ *= (this->n_ + 1);
     164           0 :   this->an_ /= (this->n_ + 2);
     165           0 :   this->an_ *= (this->n_ + 1);
     166             : 
     167             :   // term = static_cast<long double>( value);
     168           0 :   term *= term;
     169           0 :   term /= (this->n_ + 2);
     170           0 :   term /= (this->n_ + 2);
     171           0 :   this->an_ += term;
     172             : 
     173             :   //
     174             :   // B(N+1) = (B(N) * (N+1)^2 / (N+2)^2) + (2 * X(N+1) / (N+2)^2)
     175             :   //
     176           0 :   this->bn_ /= (this->n_ + 2);
     177           0 :   this->bn_ *= (this->n_ + 1);
     178           0 :   this->bn_ /= (this->n_ + 2);
     179           0 :   this->bn_ *= (this->n_ + 1);
     180             : 
     181           0 :   term = static_cast<long double>(value * 2);
     182           0 :   term /= (this->n_ + 2);
     183           0 :   term /= (this->n_ + 2);
     184           0 :   this->bn_ += term;
     185             : 
     186             :   //
     187             :   // C(N+1) = (N+1) / (N+2)^2
     188             :   //
     189           0 :   this->cn_  =  this->n_ + 1;
     190           0 :   this->cn_ /= (this->n_ + 2);
     191           0 :   this->cn_ /= (this->n_ + 2);
     192             : 
     193           0 :   if ((this->n_ == 0) || (value < this->minimum_)) {
     194           0 :     this->minimum_ = value;
     195             :   }
     196             : 
     197           0 :   if ((this->n_ == 0) || (value > this->maximum_)) {
     198           0 :     this->maximum_ = value;
     199             :   }
     200             : 
     201           0 :   this->n_ += 1; // Must follow internal variable updates.
     202           0 : }
     203             : 
     204             : template<typename DataType>
     205             : inline
     206             : long double
     207           0 : Stats<DataType>::mean() const
     208             : {
     209           0 :   if (this->n_ == 0) {
     210             :     /// @TODO: return qNaN with no data.
     211           0 :     return 0.0;
     212             :   }
     213             : 
     214             :   // Slide rule style calculations.
     215             : 
     216             :   //
     217             :   // MEAN = B(N) * (N+1)^2 / (2 * N)
     218             :   //
     219           0 :   long double average = this->bn_ / 2.0 ;
     220             : 
     221           0 :   average *= (this->n_ + 1) ;
     222           0 :   average /=  this->n_ ;
     223           0 :   average *= (this->n_ + 1) ;
     224             : 
     225           0 :   return average ;
     226             : }
     227             : 
     228             : template<typename DataType>
     229             : inline
     230             : long double
     231           0 : Stats<DataType>::var() const
     232             : {
     233           0 :   return this->variance_ ;
     234             : }
     235             : 
     236             : template<typename DataType>
     237             : inline
     238             : DataType
     239           0 : Stats<DataType>::minimum() const
     240             : {
     241             :   /// @TODO: return qNaN with no data.
     242           0 :   return (this->n_ == 0)? 0: this->minimum_;
     243             : }
     244             : 
     245             : template<typename DataType>
     246             : inline
     247             : DataType
     248           0 : Stats<DataType>::maximum() const
     249             : {
     250             :   /// @TODO: return qNaN with no data.
     251           0 :   return (this->n_ == 0)? 0: this->maximum_;
     252             : }
     253             : 
     254             : template<typename DataType>
     255             : inline
     256             : unsigned long
     257           0 : Stats<DataType>::n() const
     258             : {
     259           0 :   return this->n_;
     260             : }
     261             : 
     262             : } // namespace DCPS
     263             : } // namespace OpenDDS
     264             : 
     265             : OPENDDS_END_VERSIONED_NAMESPACE_DECL
     266             : 
     267             : #endif // OPENDDS_DCPS_STATS_T_H

Generated by: LCOV version 1.16