1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 Drexel University
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author: Joe Kopena (tjkopena@cs.drexel.edu)
19  */
20 
21 #ifndef BASIC_DATA_CALCULATORS_H
22 #define BASIC_DATA_CALCULATORS_H
23 
24 #include "data-calculator.h"
25 #include "data-output-interface.h"
26 #include "ns3/type-name.h"
27 
28 namespace ns3 {
29 
30 /**
31  * \ingroup stats
32  * \class MinMaxAvgTotalCalculator
33  * \brief Template class MinMaxAvgTotalCalculator
34  *
35  */
36 //------------------------------------------------------------
37 //--------------------------------------------
38 template <typename T  = uint32_t>
39 class MinMaxAvgTotalCalculator : public DataCalculator,
40                                  public StatisticalSummary {
41 public:
42   MinMaxAvgTotalCalculator();
43   virtual ~MinMaxAvgTotalCalculator();
44 
45   /**
46    * Register this type.
47    * \return The TypeId.
48    */
49   static TypeId GetTypeId (void);
50 
51   /**
52    * Updates all variables of MinMaxAvgTotalCalculator
53    * \param i value of type T to use for updating the calculator
54    */
55   void Update (const T i);
56   /**
57    * Reinitializes all variables of MinMaxAvgTotalCalculator
58    */
59   void Reset ();
60 
61   /**
62    * Outputs the data based on the provided callback
63    * \param callback
64    */
65   virtual void Output (DataOutputCallback &callback) const;
66 
67   /**
68    * Returns the count
69    * \return Count
70    */
getCount()71   long getCount () const { return m_count; }
72   /**
73    * Returns the sum
74    * \return Total
75    */
getSum()76   double getSum () const { return m_total; }
77   /**
78    * Returns the minimum value
79    * \return Min
80    */
getMin()81   double getMin () const { return m_min; }
82   /**
83    * Returns the maximum value
84    * \return Max
85    */
getMax()86   double getMax () const { return m_max; }
87   /**
88    * Returns the mean value
89    * \return Mean
90    */
getMean()91   double getMean () const { return m_meanCurr; }
92   /**
93    * Returns the standard deviation
94    * \return Standard deviation
95    */
getStddev()96   double getStddev () const { return std::sqrt (m_varianceCurr); }
97   /**
98    * Returns the current variance
99    * \return Variance
100    */
getVariance()101   double getVariance () const { return m_varianceCurr; }
102   /**
103    * Returns the sum of squares
104    * \return Sum of squares
105    */
getSqrSum()106   double getSqrSum () const { return m_squareTotal; }
107 
108 protected:
109   virtual void DoDispose (void);
110 
111   uint32_t m_count;      //!< Count value of MinMaxAvgTotalCalculator
112 
113   T m_total;             //!< Total value of MinMaxAvgTotalCalculator
114   T m_squareTotal;       //!< Sum of squares value of MinMaxAvgTotalCalculator
115   T m_min;               //!< Minimum value of MinMaxAvgTotalCalculator
116   T m_max;               //!< Maximum value of MinMaxAvgTotalCalculator
117 
118   double m_meanCurr;     //!< Current mean of MinMaxAvgTotalCalculator
119   double m_sCurr;        //!< Current s of MinMaxAvgTotalCalculator
120   double m_varianceCurr; //!< Current variance of MinMaxAvgTotalCalculator
121 
122   double m_meanPrev;     //!< Previous mean of MinMaxAvgTotalCalculator
123   double m_sPrev;        //!< Previous s of MinMaxAvgTotalCalculator
124 
125   // end MinMaxAvgTotalCalculator
126 };
127 
128 //----------------------------------------------
129 template <typename T>
MinMaxAvgTotalCalculator()130 MinMaxAvgTotalCalculator<T>::MinMaxAvgTotalCalculator()
131 {
132   m_count = 0;
133 
134   m_total       = 0;
135   m_squareTotal = 0;
136 
137   m_meanCurr     = NaN;
138   m_sCurr        = NaN;
139   m_varianceCurr = NaN;
140 
141   m_meanPrev     = NaN;
142   m_sPrev        = NaN;
143 }
144 
145 template <typename T>
~MinMaxAvgTotalCalculator()146 MinMaxAvgTotalCalculator<T>::~MinMaxAvgTotalCalculator()
147 {
148 }
149 
150 template <typename T>
151 void
DoDispose(void)152 MinMaxAvgTotalCalculator<T>::DoDispose (void)
153 {
154   DataCalculator::DoDispose ();
155   // MinMaxAvgTotalCalculator::DoDispose
156 }
157 
158 /* static */
159 template <typename T>
160 TypeId
GetTypeId(void)161 MinMaxAvgTotalCalculator<T>::GetTypeId (void)
162 {
163   static TypeId tid = TypeId ( ("ns3::MinMaxAvgTotalCalculator<"
164                                 + TypeNameGet<T> ()
165                                 + ">").c_str () )
166     .SetParent<Object> ()
167     .SetGroupName ("Stats")
168     .AddConstructor<MinMaxAvgTotalCalculator<T> > ()
169     ;
170   return tid;
171 }
172 
173 template <typename T>
174 void
Update(const T i)175 MinMaxAvgTotalCalculator<T>::Update (const T i)
176 {
177   if (m_enabled) {
178       m_count++;
179 
180       m_total       += i;
181       m_squareTotal += i*i;
182 
183       if (m_count == 1)
184         {
185           m_min = i;
186           m_max = i;
187         }
188       else
189         {
190           m_min = (i < m_min) ? i : m_min;
191           m_max = (i > m_max) ? i : m_max;
192         }
193 
194       // Calculate the variance based on equations (15) and (16) on
195       // page 216 of "The Art of Computer Programming, Volume 2",
196       // Second Edition. Donald E. Knuth.  Addison-Wesley
197       // Publishing Company, 1973.
198       //
199       // The relationships between the variance, standard deviation,
200       // and s are as follows
201       //
202       //                      s
203       //     variance  =  -----------
204       //                   count - 1
205       //
206       //                                -------------
207       //                               /
208       //     standard_deviation  =    /  variance
209       //                            \/
210       //
211       if (m_count == 1)
212         {
213           // Set the very first values.
214           m_meanCurr     = i;
215           m_sCurr        = 0;
216           m_varianceCurr = m_sCurr;
217         }
218       else
219         {
220           // Save the previous values.
221           m_meanPrev     = m_meanCurr;
222           m_sPrev        = m_sCurr;
223 
224           // Update the current values.
225           m_meanCurr     = m_meanPrev + (i - m_meanPrev) / m_count;
226           m_sCurr        = m_sPrev    + (i - m_meanPrev) * (i - m_meanCurr);
227           m_varianceCurr = m_sCurr / (m_count - 1);
228         }
229     }
230   // end MinMaxAvgTotalCalculator::Update
231 }
232 
233 template <typename T>
234 void
Reset()235 MinMaxAvgTotalCalculator<T>::Reset ()
236 {
237   m_count = 0;
238 
239   m_total       = 0;
240   m_squareTotal = 0;
241 
242   m_meanCurr     = NaN;
243   m_sCurr        = NaN;
244   m_varianceCurr = NaN;
245 
246   m_meanPrev     = NaN;
247   m_sPrev        = NaN;
248   // end MinMaxAvgTotalCalculator::Reset
249 }
250 
251 template <typename T>
252 void
Output(DataOutputCallback & callback)253 MinMaxAvgTotalCalculator<T>::Output (DataOutputCallback &callback) const
254 {
255   callback.OutputStatistic (m_context, m_key, this);
256 }
257 
258 
259 /**
260  * \ingroup stats
261  * \class CounterCalculator
262  * \brief Template class CounterCalculator
263  *
264  */
265 //------------------------------------------------------------
266 //--------------------------------------------
267 template <typename T  = uint32_t>
268 class CounterCalculator : public DataCalculator {
269 public:
270   CounterCalculator();
271   virtual ~CounterCalculator();
272 
273   /**
274    * Register this type.
275    * \return The TypeId.
276    */
277   static TypeId GetTypeId (void);
278 
279   /**
280    * Increments count by 1
281    */
282   void Update ();
283   /**
284    * Increments count by i
285    * \param i value of type T to increment count
286    */
287   void Update (const T i);
288 
289   /**
290    * Returns the count of the CounterCalculator
291    * \return Count as a value of type T
292    */
293   T GetCount () const;
294 
295   /**
296    * Outputs the data based on the provided callback
297    * \param callback
298    */
299   virtual void Output (DataOutputCallback &callback) const;
300 
301 protected:
302   virtual void DoDispose (void);
303 
304   T m_count; //!< Count value of CounterCalculator
305 
306   // end CounterCalculator
307 };
308 
309 
310 //--------------------------------------------
311 template <typename T>
CounterCalculator()312 CounterCalculator<T>::CounterCalculator() :
313   m_count (0)
314 {
315 }
316 
317 template <typename T>
~CounterCalculator()318 CounterCalculator<T>::~CounterCalculator()
319 {
320 }
321 /* static */
322 template <typename T>
323 TypeId
GetTypeId(void)324 CounterCalculator<T>::GetTypeId (void)
325 {
326   static TypeId tid = TypeId ( ("ns3::CounterCalculator<"
327                                 + TypeNameGet<T> ()
328                                 + ">").c_str () )
329     .SetParent<Object> ()
330     .SetGroupName ("Stats")
331     .AddConstructor<CounterCalculator<T> > ()
332     ;
333   return tid;
334 }
335 
336 template <typename T>
337 void
DoDispose(void)338 CounterCalculator<T>::DoDispose (void)
339 {
340   DataCalculator::DoDispose ();
341   // CounterCalculator::DoDispose
342 }
343 
344 template <typename T>
345 void
Update()346 CounterCalculator<T>::Update ()
347 {
348   if (m_enabled) {
349       m_count++;
350     }
351   // end CounterCalculator::Update
352 }
353 
354 template <typename T>
355 void
Update(const T i)356 CounterCalculator<T>::Update (const T i)
357 {
358   if (m_enabled) {
359       m_count += i;
360     }
361   // end CounterCalculator::Update
362 }
363 
364 template <typename T>
365 T
GetCount()366 CounterCalculator<T>::GetCount () const
367 {
368   return m_count;
369   // end CounterCalculator::GetCount
370 }
371 
372 template <typename T>
373 void
Output(DataOutputCallback & callback)374 CounterCalculator<T>::Output (DataOutputCallback &callback) const
375 {
376   callback.OutputSingleton (m_context, m_key, m_count);
377   // end CounterCalculator::Output
378 }
379 
380 // end namespace ns3
381 };
382 
383 
384 #endif /* BASIC_DATA_CALCULATORS_H */
385