--- a/src/applications/v4ping/v4ping.cc Fri Dec 18 19:10:28 2009 +0100
+++ b/src/applications/v4ping/v4ping.cc Sat Dec 19 17:54:08 2009 +0300
@@ -243,7 +243,7 @@
if (m_avgRtt.Count () > 0)
os << "rtt min/avg/max/mdev = " << m_avgRtt.Min() << "/" << m_avgRtt.Avg() << "/"
- << m_avgRtt.Max() << "/" << m_avgRtt.Err()
+ << m_avgRtt.Max() << "/" << m_avgRtt.Stddev()
<< " ms\n";
std::cout << os.str();
}
--- a/src/contrib/average.h Fri Dec 18 19:10:28 2009 +0100
+++ b/src/contrib/average.h Sat Dec 19 17:54:08 2009 +0300
@@ -16,56 +16,86 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Authors: Pavel Boyko <boyko@iitp.ru>
+ * Corrections and extensions: Timo Bingmann <tbns@idlebox.net>
*/
#ifndef AVERAGE_H
#define AVERAGE_H
#include <cmath>
-#include <iostream>
+#include <ostream>
#include <limits>
+namespace ns3 {
+
/// Simple average, min, max and std. deviation calculator
template <typename T = double>
class Average
{
public:
- Average () :
- size (0), min (std::numeric_limits<T>::max ()), max (0), avg (0), avg2 (0)
+ Average ()
+ : m_size (0), m_min (std::numeric_limits<T>::max ()), m_max (0),
+ m_avg (0), m_avg2 (0)
{
}
- /// Add new value
+ /// Add new sample
void Update (T const & x)
{
- min = std::min (x, min);
- max = std::max (x, max);
- avg = (size * avg + x) / (size + 1);
- avg2 = (size * avg2 + x * x) / (size + 1);
- size++;
+ m_min = std::min (x, m_min);
+ m_max = std::max (x, m_max);
+ m_avg = (m_size * m_avg + x) / (m_size + 1);
+ m_avg2 = (m_size * m_avg2 + x * x) / (m_size + 1);
+ m_size++;
}
/// Reset statistics
void Reset ()
{
- size = 0;
- min = std::numeric_limits<T>::max ();
- max = 0;
- avg = 0;
- avg2 = 0;
+ m_size = 0;
+ m_min = std::numeric_limits<T>::max ();
+ m_max = 0;
+ m_avg = 0;
+ m_avg2 = 0;
}
- ///\name Access results
+ ///\name Sample statistics
//\{
- uint32_t Count () const { return size; }
- T Min () const { return min; }
- T Max () const { return max; }
- double Avg () const { return avg; }
- double Err () const { return sqrt ((avg2 - avg*avg)/(size - 1)); }
+ /// Sample size
+ uint32_t Count () const { return m_size; }
+ /// Minimum
+ T Min () const { return m_min; }
+ /// Maximum
+ T Max () const { return m_max; }
+ /// Sample average
+ double Avg () const { return m_avg; }
+ /// Estimate of mean, alias to Avg
+ double Mean () const { return Avg (); }
+ /// Unbiased estimate of variance
+ double Var () const { return Count() / (double)(Count() - 1) * (m_avg2 - m_avg*m_avg); }
+ /// Standard deviation
+ double Stddev () const { return sqrt (Var ());}
+ //\}
+
+ /**
+ * \name Error of the mean estimates
+ *
+ * Note that estimates are valid for
+ * - uncorrelated measurements,
+ * - normal distribution and
+ * - large enough sample size.
+ */
+ //\{
+ /// Margin of error of the mean for 90% confidence level
+ double Error90() const { return 1.645 * sqrt (Var () / Count ()); }
+ /// Margin of error of the mean for 95% confidence level
+ double Error95() const { return 1.960 * sqrt (Var () / Count ()); }
+ /// Margin of error of the mean for 99% confidence level
+ double Error99() const { return 2.576 * sqrt (Var () / Count ()); }
//\}
private:
- uint32_t size;
- T min, max;
- double avg, avg2;
+ uint32_t m_size;
+ T m_min, m_max;
+ double m_avg, m_avg2;
};
/// Print avg (err) [min, max]
@@ -73,10 +103,10 @@
std::ostream & operator<< (std::ostream & os, Average<T> const & x)
{
if (x.Count () != 0)
- os << x.Avg () << " (" << x.Err () << ") [" << x.Min () << ", " << x.Max () << "]";
+ os << x.Avg () << " (" << x.Stddev () << ") [" << x.Min () << ", " << x.Max () << "]";
else
- os << "NA"; // not avaliable
+ os << "NA"; // not available
return os;
}
-
+}
#endif /* AVERAGE_H */