libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
ave_deviation_meter.hpp
Go to the documentation of this file.
1 #ifndef LIBJMMCG_CORE_AVE_DEVIATION_METER_HPP
2 #define LIBJMMCG_CORE_AVE_DEVIATION_METER_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2002 by J.M.McGuiness, coder@hussar.me.uk
6 **
7 ** This library is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU Lesser General Public
9 ** License as published by the Free Software Foundation; either
10 ** version 2.1 of the License, or (at your option) any later version.
11 **
12 ** This library is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** Lesser General Public License for more details.
16 **
17 ** You should have received a copy of the GNU Lesser General Public
18 ** License along with this library; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
23 #include "ttypes.hpp"
24 
25 #include <cstdlib>
26 #include <iomanip>
27 #include <limits>
28 
29 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE {
30 
31  /// A class used to compute the arithmetic mean and mean-average deviation [1] of a series of events.
32  /**
33  Note that if this class is used in a multi-threaded manner, it is not thread-safe, so these invariants are not guaranteed.
34 
35  [1] <a href="http://mathbits.com/MathBits/TISection/Statistics1/MAD.html"/>
36 
37  \see invariant()
38  */
39  template<typename MeteredObjType>
41  public:
42  /**
43  This is an overly-complicated way of saying "although this might look atomic - I want a sequential version" so it is just the MeteredObjType. std::atomic with program-consistency is not used, because it introduces a lock prefix, which would slow the program being measured. Speed has been traded off for reliable numbers...
44  */
46  /// The type of the object upon which the events will be recorded.
48 
49  constexpr ave_deviation_meter() noexcept(true) FORCE_INLINE;
50  explicit constexpr ave_deviation_meter(const value_type val) noexcept(true) FORCE_INLINE;
51  constexpr ave_deviation_meter(value_type const val, double const dev) noexcept(true) FORCE_INLINE;
52  ave_deviation_meter(ave_deviation_meter const &rm) noexcept(true) FORCE_INLINE;
53  ~ave_deviation_meter() noexcept(true) FORCE_INLINE;
54 
55  ave_deviation_meter & __fastcall operator=(ave_deviation_meter const &rm) noexcept(true);
56 
57  ave_deviation_meter & __fastcall operator+=(ave_deviation_meter const &rm) noexcept(true);
58 
59  /// Record a new event that occurred.
60  /**
61  This will update the minimum, maximum, running arithmetic mean and average-deviation measurements.
62  */
63  ave_deviation_meter & __fastcall update(value_type const new_val) noexcept(true);
64 
65  /// Return the minimum of the samples taken.
66  constexpr value_type __fastcall FORCE_INLINE min() const noexcept(true);
67  /// Return the arithmetic mean of the samples taken.
68  constexpr value_type __fastcall FORCE_INLINE arithmetic_mean() const noexcept(true);
69  /// Return the maximum of the samples taken.
70  constexpr value_type __fastcall FORCE_INLINE max() const noexcept(true);
71  /// Return the total of all of the samples taken.
72  constexpr value_type __fastcall FORCE_INLINE total() const noexcept(true);
73 
74  /// Return the average deviation of the samples taken.
75  /**
76  Note that when using this value you should round to one significant figure.
77  \return The average deviation.
78  */
79  constexpr double __fastcall FORCE_INLINE deviation() const noexcept(true);
80  /// Return the average deviation, as a percent of the mean, of the samples taken.
81  /**
82  Note that when using this value you should round to one significant figure.
83  \return The average deviation as a percentage.
84  */
85  constexpr double __fastcall FORCE_INLINE deviation_percentage() const noexcept(true);
86  /// Return the average deviation as a percentage of the arithmetic mean.
87  constexpr unsigned short FORCE_INLINE percent() const noexcept(true);
88 
89  tstring __fastcall to_string() const noexcept(false);
90 
91  tstring __fastcall to_csv() const noexcept(false);
92 
93  private:
94  unsigned long num_samples_;
95  value_type minimum_, maximum_, total_;
96  double arithmetic_mean_;
97  double ave_deviation;
98 
99  void invariant() const noexcept(true);
100  };
101 
102  template<typename MeteredObjType>
103  inline tostream & __fastcall FORCE_INLINE
104  operator<<(tostream &os, ave_deviation_meter<MeteredObjType> const &p) noexcept(false);
105 
106  /// An algorithm to estimate the average deviation returned after a functor is computed N times.
107  /**
108  \param computations The number of times the functor fn should be computed.
109  \param fn The functor to be computed. It should take no arguments and return ave_deviation_meter::value_type.
110  \return The computed ave_deviation_meter.
111  */
112  template<class MeteredObjType, class Fn>
113  inline ave_deviation_meter<MeteredObjType>
114  estimate_average_deviation(typename ave_deviation_meter<MeteredObjType>::value_type const computations, Fn fn);
115 
116  /// An algorithm to compute the ave_deviation_meter of a functor when a specific average deviation is requested.
117  /**
118  \param target_deviation The maximum, target average deviation, as a percentage number, that should be achieved.
119  \param max_computations The maximum number of times the functor fn should be computed, to ensure termination.
120  \param fn The functor to be computed. It should take no arguments and return ave_deviation_meter::value_type.
121  \return The computed ave_deviation_meter and a boolean that if set indicates that the target_deviation could not be achieved within max_computations attempts.
122  */
123  template<class MeteredObjType, class Fn>
124  inline std::pair<ave_deviation_meter<MeteredObjType>, bool>
125  compute_average_deviation(double const target_deviation, typename ave_deviation_meter<MeteredObjType>::value_type const max_computations, Fn fn);
126 
127 } }
128 
130 
131 #endif