diff --git a/doc/main.hh b/doc/main.hh index 8b5c235aab10dc26539a8ed8724915d820ea025f..8d3ff821d1002faa68198ea463bc7d1a98e919be 100644 --- a/doc/main.hh +++ b/doc/main.hh @@ -15,7 +15,7 @@ // hpp-statistics. If not, see <http://www.gnu.org/licenses/>. namespace hpp { - namespace statistics { +namespace statistics { /** \mainpage @@ -29,5 +29,5 @@ namespace hpp { \li SuccessStatistics enhances Statistics<SuccessBin>. **/ - } } +} // namespace hpp diff --git a/include/hpp/statistics/bin.hh b/include/hpp/statistics/bin.hh index ac6421f2ce4d4a15068b1bcf0f6f08768f682fdd..2403a44dc888b1268e3eec5ebeb413b2bbe230bd 100644 --- a/include/hpp/statistics/bin.hh +++ b/include/hpp/statistics/bin.hh @@ -15,258 +15,221 @@ // hpp-statistics. If not, see <http://www.gnu.org/licenses/>. #ifndef HPP_STATISTICS_BIN_HH -# define HPP_STATISTICS_BIN_HH +#define HPP_STATISTICS_BIN_HH -# include <ostream> -# include <list> -# include <algorithm> +#include <algorithm> +#include <list> +#include <ostream> -# include "hpp/statistics/config.hh" -# include "hpp/statistics/fwd.hh" +#include "hpp/statistics/config.hh" +#include "hpp/statistics/fwd.hh" namespace hpp { - namespace statistics { - /// Abstract class representing a bin. - /// - /// Bins are use for statistics. They keep the number of - /// of apparition of a given value. - /// Inherited class should also implement comparison and equality - /// operators. - class HPP_STATISTICS_DLLAPI Bin - { - public: - /// Return the number of element in the bin. - const std::size_t& freq () const - { - return freq_; - } - - /// Add an occurence - /// \return The frequency after increment; - std::size_t operator ++() - { - return ++freq_; - } - - /// Add an occurence - /// \return The frequency before increment; - std::size_t operator ++(int) - { - return freq_++; - } - - /// Print the bin. - virtual std::ostream& print (std::ostream& os) const - { - return printValue (os << freq () << " - "); - } - - /// Print the inner value of the bin. - virtual std::ostream& printValue (std::ostream& os) const = 0; - - protected: - /// Constructor - Bin () : freq_ (0) {} - - private: - /// The number of occurence. - std::size_t freq_; - }; - - inline std::ostream& operator<< (std::ostream& os, const hpp::statistics::Bin& b) - { - return b.print (os); - } - - /// Template class to do statistics. - /// You should derivate class Bin and construct a class - /// Statistics < YourBin >. - template < typename T > - class HPP_STATISTICS_DLLAPI Statistics - { - public: - typedef typename std::list < T > Container; - typedef typename Container::iterator iterator; - typedef typename Container::const_iterator const_iterator; - - /// Return the number of occurence of a Bin. - /// \param bin a Bin for which only the value is useful. - /// \note It searches for the equivalent Bin is the set and - /// returns the frequency of the result. - virtual std::size_t freq (const T& bin) const; - - /// Return the relative frequency of a Bin. - /// \param bin a Bin for which only the value is useful. - /// \note It searches for the equivalent Bin is the set and - /// returns the frequency of the result. - virtual Proba_t relativeFreq (const T& bin) const; - - /// Return the number of times an observation has recorded. It is the - /// total number of observations. - std::size_t numberOfObservations () const - { - return counts_; - } - - /// Return the number of bins. - unsigned int numberOfBins () const - { - return bins_.size (); - } - - /// Put the results in a stream. - virtual std::ostream& print (std::ostream& os) const; - - const_iterator find (const T& bin) const; - - template < typename U > const_iterator find (const U& value) const; - - /// Return an iterator pointing at the beginning of - /// the set of bins. - const_iterator begin() const - { - return bins_.begin(); - } - - /// Return an iterator pointing at the end of - /// the set of bins. - const_iterator end() const - { - return bins_.end(); - } - - /// Remove all element - void clear () - { - bins_.clear(); - } - - protected: - /// Constructor - Statistics(); - - /// Increment a Bin - /// \note bin is inserted in the set of bins if it was not - /// already in the set. - virtual T& increment (const T& bin) __attribute__ ((deprecated)); - - /// insert a Bin. - /// \note bin is inserted in the set of bins if it was not - /// already in the set. - virtual iterator insert (const T& bin); - - private: - Container bins_; - - std::size_t counts_; - }; - - template < typename T > - std::ostream& operator<< (std::ostream& os, const hpp::statistics::Statistics <T>& ss); - } // namespace statistics -} // namespace hpp +namespace statistics { +/// Abstract class representing a bin. +/// +/// Bins are use for statistics. They keep the number of +/// of apparition of a given value. +/// Inherited class should also implement comparison and equality +/// operators. +class HPP_STATISTICS_DLLAPI Bin { + public: + /// Return the number of element in the bin. + const std::size_t& freq() const { return freq_; } + + /// Add an occurence + /// \return The frequency after increment; + std::size_t operator++() { return ++freq_; } + + /// Add an occurence + /// \return The frequency before increment; + std::size_t operator++(int) { return freq_++; } + + /// Print the bin. + virtual std::ostream& print(std::ostream& os) const { + return printValue(os << freq() << " - "); + } + + /// Print the inner value of the bin. + virtual std::ostream& printValue(std::ostream& os) const = 0; + + protected: + /// Constructor + Bin() : freq_(0) {} + + private: + /// The number of occurence. + std::size_t freq_; +}; + +inline std::ostream& operator<<(std::ostream& os, + const hpp::statistics::Bin& b) { + return b.print(os); +} + +/// Template class to do statistics. +/// You should derivate class Bin and construct a class +/// Statistics < YourBin >. +template <typename T> +class HPP_STATISTICS_DLLAPI Statistics { + public: + typedef typename std::list<T> Container; + typedef typename Container::iterator iterator; + typedef typename Container::const_iterator const_iterator; + + /// Return the number of occurence of a Bin. + /// \param bin a Bin for which only the value is useful. + /// \note It searches for the equivalent Bin is the set and + /// returns the frequency of the result. + virtual std::size_t freq(const T& bin) const; + + /// Return the relative frequency of a Bin. + /// \param bin a Bin for which only the value is useful. + /// \note It searches for the equivalent Bin is the set and + /// returns the frequency of the result. + virtual Proba_t relativeFreq(const T& bin) const; + + /// Return the number of times an observation has recorded. It is the + /// total number of observations. + std::size_t numberOfObservations() const { return counts_; } + + /// Return the number of bins. + unsigned int numberOfBins() const { return bins_.size(); } + + /// Put the results in a stream. + virtual std::ostream& print(std::ostream& os) const; + + const_iterator find(const T& bin) const; + + template <typename U> + const_iterator find(const U& value) const; + + /// Return an iterator pointing at the beginning of + /// the set of bins. + const_iterator begin() const { return bins_.begin(); } + + /// Return an iterator pointing at the end of + /// the set of bins. + const_iterator end() const { return bins_.end(); } + + /// Remove all element + void clear() { bins_.clear(); } + + protected: + /// Constructor + Statistics(); + + /// Increment a Bin + /// \note bin is inserted in the set of bins if it was not + /// already in the set. + virtual T& increment(const T& bin) __attribute__((deprecated)); + + /// insert a Bin. + /// \note bin is inserted in the set of bins if it was not + /// already in the set. + virtual iterator insert(const T& bin); + + private: + Container bins_; + + std::size_t counts_; +}; + +template <typename T> +std::ostream& operator<<(std::ostream& os, + const hpp::statistics::Statistics<T>& ss); +} // namespace statistics +} // namespace hpp /// Implementation namespace hpp { - namespace statistics { - template < typename T > - T& Statistics <T>::increment (const T& b) - { - counts_++; - iterator it = bins_.begin (); - for (; it != bins_.end (); it++) { - if (! (*it < b)) { - if (! (*it == b)) - it = bins_.insert (it, b); - (*it)++; - return *it; - } - } - it = bins_.insert (it, b); +namespace statistics { +template <typename T> +T& Statistics<T>::increment(const T& b) { + counts_++; + iterator it = bins_.begin(); + for (; it != bins_.end(); it++) { + if (!(*it < b)) { + if (!(*it == b)) it = bins_.insert(it, b); (*it)++; return *it; } - - template < typename T > - typename Statistics<T>::iterator Statistics <T>::insert (const T& b) - { - counts_++; - iterator it = bins_.begin (); - for (; it != bins_.end (); it++) { - if (! (*it < b)) { - if (! (*it == b)) - it = bins_.insert (it, b); - (*it)++; - return it; - } - } - it = bins_.insert (it, b); + } + it = bins_.insert(it, b); + (*it)++; + return *it; +} + +template <typename T> +typename Statistics<T>::iterator Statistics<T>::insert(const T& b) { + counts_++; + iterator it = bins_.begin(); + for (; it != bins_.end(); it++) { + if (!(*it < b)) { + if (!(*it == b)) it = bins_.insert(it, b); (*it)++; return it; } - - template < typename T> - typename Statistics<T>::const_iterator Statistics <T>::find (const T& b) const - { - for (const_iterator it = bins_.begin (); - it != bins_.end (); it++) { - if (*it < b) - continue; - if (*it == b) - return it; - break; - } - return bins_.end (); - } - - template < typename T> template < typename U > - typename Statistics<T>::const_iterator Statistics <T>::find (const U& v) const - { - return find (T (v)); - } - - template < typename T > - size_t Statistics <T>::freq (const T& b) const - { - const_iterator it = std::find (bins_.begin (), bins_.end (), b); - if (it == bins_.end ()) { - return 0; - } - return it->freq (); - } - - template < typename T > - Proba_t Statistics <T>::relativeFreq (const T& b) const - { - const_iterator it = std::find (bins_.begin (), bins_.end (), b); - if (it == bins_.end ()) { - return 0; - } - return (Proba_t)it->freq () / (Proba_t)numberOfObservations(); - } - - template < typename T > - Statistics <T>::Statistics () :bins_ (), counts_(0) - {} - - template < typename T > - std::ostream& Statistics<T>::print (std::ostream& os) const - { - const_iterator it; - for (it = begin(); it != end(); it++) { - it->print (os) << std::endl; - } - os << "Total number of observations: " << numberOfObservations (); - return os; - } - - template < typename T > - std::ostream& operator<< (std::ostream& os, const hpp::statistics::Statistics <T>& ss) - { - return ss.print (os); - } - } // namespace statistics -} // namespace hpp - -#endif // HPP_STATISTICS_BIN_HH + } + it = bins_.insert(it, b); + (*it)++; + return it; +} + +template <typename T> +typename Statistics<T>::const_iterator Statistics<T>::find(const T& b) const { + for (const_iterator it = bins_.begin(); it != bins_.end(); it++) { + if (*it < b) continue; + if (*it == b) return it; + break; + } + return bins_.end(); +} + +template <typename T> +template <typename U> +typename Statistics<T>::const_iterator Statistics<T>::find(const U& v) const { + return find(T(v)); +} + +template <typename T> +size_t Statistics<T>::freq(const T& b) const { + const_iterator it = std::find(bins_.begin(), bins_.end(), b); + if (it == bins_.end()) { + return 0; + } + return it->freq(); +} + +template <typename T> +Proba_t Statistics<T>::relativeFreq(const T& b) const { + const_iterator it = std::find(bins_.begin(), bins_.end(), b); + if (it == bins_.end()) { + return 0; + } + return (Proba_t)it->freq() / (Proba_t)numberOfObservations(); +} + +template <typename T> +Statistics<T>::Statistics() : bins_(), counts_(0) {} + +template <typename T> +std::ostream& Statistics<T>::print(std::ostream& os) const { + const_iterator it; + for (it = begin(); it != end(); it++) { + it->print(os) << std::endl; + } + os << "Total number of observations: " << numberOfObservations(); + return os; +} + +template <typename T> +std::ostream& operator<<(std::ostream& os, + const hpp::statistics::Statistics<T>& ss) { + return ss.print(os); +} +} // namespace statistics +} // namespace hpp + +#endif // HPP_STATISTICS_BIN_HH diff --git a/include/hpp/statistics/distribution.hh b/include/hpp/statistics/distribution.hh index cdb374c28fe2a389a38a36093627068532f57c29..a7bc8bcf264f7aac74fc80e3c3fd256e20124840 100644 --- a/include/hpp/statistics/distribution.hh +++ b/include/hpp/statistics/distribution.hh @@ -15,166 +15,154 @@ // hpp-statistics. If not, see <http://www.gnu.org/licenses/>. #ifndef HPP_STATISTICS_DISTRIBUTION_HH -# define HPP_STATISTICS_DISTRIBUTION_HH +#define HPP_STATISTICS_DISTRIBUTION_HH -# include <vector> -# include <assert.h> -# include <stdlib.h> -# include <climits> +#include <assert.h> +#include <stdlib.h> -# include "hpp/statistics/fwd.hh" +#include <climits> +#include <vector> + +#include "hpp/statistics/fwd.hh" namespace hpp { - namespace statistics { - template < typename Value_t > - class DiscreteDistribution - { - public: - typedef std::size_t Weight_t; - typedef typename std::pair < Weight_t, Value_t> ProbaTPair; - typedef typename std::vector < ProbaTPair >::iterator iterator; - typedef typename std::vector < ProbaTPair >::const_iterator const_iterator; - - DiscreteDistribution () = default; - - Value_t operator() () const { - assert (values_.size() > 0); - Weight_t r = rand() % cumulative_weights_.back(); - return operator() (r); - } - Value_t operator() (const Proba_t& p) const { - return operator() ((Weight_t)(p * cumulative_weights_.back ())); - } - Value_t operator() (const Weight_t& w) const { - assert (values_.size() > 0); - return values_[dichotomy (w % cumulative_weights_.back())].second; - } - - /// Update the distribution. - /// If v is already in the set, then update its weight. - /// Otherwise, insert it. - void insert (Value_t v, Weight_t w = 1) { - iterator itv = values_.begin (); - WeightsIterator itcumul = cumulative_weights_.begin(); - Weight_t c = 0; - while (itv != values_.end()) { - if (itv->second == v) - break; - c = *itcumul; - itv++; itcumul++; - } - if (itv == values_.end ()) { - values_.push_back (ProbaTPair(w,v)); - cumulative_weights_.push_back (c + w); - if (cumulative_weights_.back () >= INT_MAX / 2) - shrink (); - return; - } - itv->first = w; - while (itv != values_.end()) { - c = c + itv->first; - *itcumul = c; - itv++; itcumul++; - } - if (cumulative_weights_.back () >= INT_MAX / 2) - shrink (); - } - - /// Get the weight of a value - /// Return 0 if value was not found. - Weight_t get (const Value_t& v) const { - const_iterator itv = values_.begin (); - while (itv != values_.end()) { - if (itv->second == v) - return itv->first; - itv++; - } - return 0; - } - - /// Return the number of value. - size_t size () const { - return values_.size (); - } - - /// Return the probabilities. - std::vector < Proba_t > probabilities () const { - if (values_.empty ()) return std::vector < Proba_t > (0); - std::vector < Proba_t > proba (values_.size()); - Proba_t total = (double)cumulative_weights_.back(); - for (size_t i = 0; i < values_.size (); i++) - proba[i] = (Proba_t)values_[i].first / total; - return proba; - } - - /// Return the values. - std::vector < Value_t > values () const { - if (values_.empty ()) return std::vector < Value_t > (0); - std::vector < Value_t > v (values_.size()); - for (size_t i = 0; i < values_.size (); i++) - v[i] = values_[i].second; - return v; - } - - /// Return the total weight. - Weight_t totalWeight () const { - if (cumulative_weights_.empty ()) return 0; - return cumulative_weights_.back (); - } - - /// \name Iterators - /// Iterate on the values. - /// \{ - iterator begin () { - return values_.begin (); - } - const_iterator begin () const { - return values_.begin (); - } - iterator end () { - return values_.end (); - } - const_iterator end () const { - return values_.end (); - } - /// \} - private: - size_t dichotomy (const Weight_t& r) const { - if (r < cumulative_weights_[0]) return 0; - size_t l = 0, h = values_.size () - 1, m; - while (l < h - 1) { - m = (l + h) / 2; - if (cumulative_weights_[m] <= r) - l = m; - else if (cumulative_weights_[m] > r) - h = m; - else - return m; - } - return h; - } - - /// Diminish the weights while keeping their ratio. - void shrink () { - iterator itv = values_.begin (); - WeightsIterator itcumul = cumulative_weights_.begin(); - Weight_t total = 0; - while (itv != values_.end()) { - if (itv->first > 1) { - itv->first = itv->first >> 1; - } - total += itv->first; - *itcumul = total; - itv++; itcumul++; - } - } - - std::vector < ProbaTPair > values_; - std::vector < Weight_t > cumulative_weights_; - - typedef std::vector < Weight_t >::iterator WeightsIterator; - }; - } // namespace statistics -} // namespace hpp - -#endif // HPP_STATISTICS_DISTRIBUTION_HH +namespace statistics { +template <typename Value_t> +class DiscreteDistribution { + public: + typedef std::size_t Weight_t; + typedef typename std::pair<Weight_t, Value_t> ProbaTPair; + typedef typename std::vector<ProbaTPair>::iterator iterator; + typedef typename std::vector<ProbaTPair>::const_iterator const_iterator; + + DiscreteDistribution() = default; + + Value_t operator()() const { + assert(values_.size() > 0); + Weight_t r = rand() % cumulative_weights_.back(); + return operator()(r); + } + Value_t operator()(const Proba_t& p) const { + return operator()((Weight_t)(p * cumulative_weights_.back())); + } + Value_t operator()(const Weight_t& w) const { + assert(values_.size() > 0); + return values_[dichotomy(w % cumulative_weights_.back())].second; + } + + /// Update the distribution. + /// If v is already in the set, then update its weight. + /// Otherwise, insert it. + void insert(Value_t v, Weight_t w = 1) { + iterator itv = values_.begin(); + WeightsIterator itcumul = cumulative_weights_.begin(); + Weight_t c = 0; + while (itv != values_.end()) { + if (itv->second == v) break; + c = *itcumul; + itv++; + itcumul++; + } + if (itv == values_.end()) { + values_.push_back(ProbaTPair(w, v)); + cumulative_weights_.push_back(c + w); + if (cumulative_weights_.back() >= INT_MAX / 2) shrink(); + return; + } + itv->first = w; + while (itv != values_.end()) { + c = c + itv->first; + *itcumul = c; + itv++; + itcumul++; + } + if (cumulative_weights_.back() >= INT_MAX / 2) shrink(); + } + + /// Get the weight of a value + /// Return 0 if value was not found. + Weight_t get(const Value_t& v) const { + const_iterator itv = values_.begin(); + while (itv != values_.end()) { + if (itv->second == v) return itv->first; + itv++; + } + return 0; + } + + /// Return the number of value. + size_t size() const { return values_.size(); } + + /// Return the probabilities. + std::vector<Proba_t> probabilities() const { + if (values_.empty()) return std::vector<Proba_t>(0); + std::vector<Proba_t> proba(values_.size()); + Proba_t total = (double)cumulative_weights_.back(); + for (size_t i = 0; i < values_.size(); i++) + proba[i] = (Proba_t)values_[i].first / total; + return proba; + } + + /// Return the values. + std::vector<Value_t> values() const { + if (values_.empty()) return std::vector<Value_t>(0); + std::vector<Value_t> v(values_.size()); + for (size_t i = 0; i < values_.size(); i++) v[i] = values_[i].second; + return v; + } + + /// Return the total weight. + Weight_t totalWeight() const { + if (cumulative_weights_.empty()) return 0; + return cumulative_weights_.back(); + } + + /// \name Iterators + /// Iterate on the values. + /// \{ + iterator begin() { return values_.begin(); } + const_iterator begin() const { return values_.begin(); } + iterator end() { return values_.end(); } + const_iterator end() const { return values_.end(); } + /// \} + private: + size_t dichotomy(const Weight_t& r) const { + if (r < cumulative_weights_[0]) return 0; + size_t l = 0, h = values_.size() - 1, m; + while (l < h - 1) { + m = (l + h) / 2; + if (cumulative_weights_[m] <= r) + l = m; + else if (cumulative_weights_[m] > r) + h = m; + else + return m; + } + return h; + } + + /// Diminish the weights while keeping their ratio. + void shrink() { + iterator itv = values_.begin(); + WeightsIterator itcumul = cumulative_weights_.begin(); + Weight_t total = 0; + while (itv != values_.end()) { + if (itv->first > 1) { + itv->first = itv->first >> 1; + } + total += itv->first; + *itcumul = total; + itv++; + itcumul++; + } + } + + std::vector<ProbaTPair> values_; + std::vector<Weight_t> cumulative_weights_; + + typedef std::vector<Weight_t>::iterator WeightsIterator; +}; +} // namespace statistics +} // namespace hpp + +#endif // HPP_STATISTICS_DISTRIBUTION_HH diff --git a/include/hpp/statistics/fwd.hh b/include/hpp/statistics/fwd.hh index 016909eda51a1559dd830a963154feb15d5825dc..6356933ff475c5f6ef4bac7269a718851d721e52 100644 --- a/include/hpp/statistics/fwd.hh +++ b/include/hpp/statistics/fwd.hh @@ -15,17 +15,18 @@ // hpp-statistics. If not, see <http://www.gnu.org/licenses/>. #ifndef HPP_STATISTICS_FWD_HH -# define HPP_STATISTICS_FWD_HH +#define HPP_STATISTICS_FWD_HH namespace hpp { - namespace statistics { - typedef double Proba_t; +namespace statistics { +typedef double Proba_t; - class Bin; - template < typename T > class Statistics; - class SuccessBin; - class SuccessStatistics; - } // namespace statistics -} // namespace hpp +class Bin; +template <typename T> +class Statistics; +class SuccessBin; +class SuccessStatistics; +} // namespace statistics +} // namespace hpp -#endif // HPP_STATISTICS_FWD_HH +#endif // HPP_STATISTICS_FWD_HH diff --git a/include/hpp/statistics/success-bin.hh b/include/hpp/statistics/success-bin.hh index b3bebc810ad45c4325a76e638ec88f2515d25d6c..841147d62a04b9cf659df3dafcf6004db6181351 100644 --- a/include/hpp/statistics/success-bin.hh +++ b/include/hpp/statistics/success-bin.hh @@ -14,175 +14,144 @@ // received a copy of the GNU Lesser General Public License along with // hpp-statistics. If not, see <http://www.gnu.org/licenses/>. - #ifndef HPP_STATISTICS_SUCCESSBIN_HH -# define HPP_STATISTICS_SUCCESSBIN_HH - -# include <iostream> -# include <set> +#define HPP_STATISTICS_SUCCESSBIN_HH -# include <hpp/util/debug.hh> +#include <hpp/util/debug.hh> +#include <iostream> +#include <set> -# include "hpp/statistics/config.hh" -# include "hpp/statistics/bin.hh" -# include "hpp/statistics/fwd.hh" +#include "hpp/statistics/bin.hh" +#include "hpp/statistics/config.hh" +#include "hpp/statistics/fwd.hh" -# define HPP_DEFINE_REASON_FAILURE(ID, STRING) \ - const ::hpp::statistics::SuccessBin::Reason ID = \ - ::hpp::statistics::SuccessBin::createReason ( STRING ); \ +#define HPP_DEFINE_REASON_FAILURE(ID, STRING) \ + const ::hpp::statistics::SuccessBin::Reason ID = \ + ::hpp::statistics::SuccessBin::createReason(STRING); \ struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n namespace hpp { - namespace statistics { - /// This class count the number of success and failure. - class HPP_STATISTICS_DLLAPI SuccessBin : public Bin - { - public: - /// In case of failure, you can provide a reason. - /// Use macro DEFINE_REASON_FAILURE (REASON_NAME, Reason string) - /// to define a new reason. - struct Reason { - std::size_t id; - std::string what; - Reason (std::size_t a_id, std::string a_what) : - id (a_id), what (a_what) {} - }; - - /// The default reason for 'failure'. - const static Reason REASON_UNKNOWN; - - /// Constructor - SuccessBin (const bool success, const Reason& r = REASON_UNKNOWN) : - Bin(), success_ (success), reason_(r) - { - if (success_) - reason_ = REASON_SUCCESS; - } - - /// Value of the bin. - /// \return True is it counts "success", False otherwise. - inline bool isSuccess () const - { - return success_; - } - - /// If this bin represents 'failure', returns the reason. - inline const Reason& reason () const - { - return reason_; - } - - /// If this bin represents 'failure', returns the reason as a string. - inline const std::string& reasonString () const; - - /// Check for equality. - /// \return True if both are 'success' or if they are both 'failure' - /// with the same Reason. - inline bool operator == (const SuccessBin& other) const - { - return reason_.id == other.reason().id; - } - - /// Comparison - /// \return the comparison of their reason id. - /// 'success' has a reason id of INT_MIN. - inline bool operator < (const SuccessBin& other) const - { - return reason_.id < other.reason ().id; - } - - /// Create a new Reason - /// \param what The text associated with the reason. - static Reason createReason (const std::string& what) - { - return Reason (reasonID_last++, what); - } - - private: - bool success_; - size_t freq_; - Reason reason_; - - /// The reason for 'success'. - const static Reason REASON_SUCCESS; - static std::size_t reasonID_last; - - inline std::ostream& printValue (std::ostream& os) const - { - os << "Event "; - if (success_) os << "'Success'"; - else os << "'Failure': " << reason_.what; - return os; - } - }; - - class HPP_STATISTICS_DLLAPI SuccessStatistics : - public Statistics < SuccessBin > - { - public: - typedef Statistics <SuccessBin> Parent; - - /// Constructor - SuccessStatistics (const std::string name = "", - const std::size_t& logRatio = 2) - : name_ (name), logRatio_ (logRatio) - {} - - /// Copy Constructor - SuccessStatistics (const SuccessStatistics& other) - : name_ (other.name_), logRatio_ (other.logRatio_) - {} - - /// Add a 'success' - void addSuccess () - { - insert (SuccessBin (true)); - } - - /// Add a 'failure' - /// \param r the reason of the 'failure' - /// \note Use macro DEFINE_REASON_FAILURE (REASON_NAME, 'Reason details') - /// to define a new reason. - void addFailure (const SuccessBin::Reason& r = SuccessBin::REASON_UNKNOWN) - { - insert (SuccessBin (false, r)); +namespace statistics { +/// This class count the number of success and failure. +class HPP_STATISTICS_DLLAPI SuccessBin : public Bin { + public: + /// In case of failure, you can provide a reason. + /// Use macro DEFINE_REASON_FAILURE (REASON_NAME, Reason string) + /// to define a new reason. + struct Reason { + std::size_t id; + std::string what; + Reason(std::size_t a_id, std::string a_what) : id(a_id), what(a_what) {} + }; + + /// The default reason for 'failure'. + const static Reason REASON_UNKNOWN; + + /// Constructor + SuccessBin(const bool success, const Reason& r = REASON_UNKNOWN) + : Bin(), success_(success), reason_(r) { + if (success_) reason_ = REASON_SUCCESS; + } + + /// Value of the bin. + /// \return True is it counts "success", False otherwise. + inline bool isSuccess() const { return success_; } + + /// If this bin represents 'failure', returns the reason. + inline const Reason& reason() const { return reason_; } + + /// If this bin represents 'failure', returns the reason as a string. + inline const std::string& reasonString() const; + + /// Check for equality. + /// \return True if both are 'success' or if they are both 'failure' + /// with the same Reason. + inline bool operator==(const SuccessBin& other) const { + return reason_.id == other.reason().id; + } + + /// Comparison + /// \return the comparison of their reason id. + /// 'success' has a reason id of INT_MIN. + inline bool operator<(const SuccessBin& other) const { + return reason_.id < other.reason().id; + } + + /// Create a new Reason + /// \param what The text associated with the reason. + static Reason createReason(const std::string& what) { + return Reason(reasonID_last++, what); + } + + private: + bool success_; + size_t freq_; + Reason reason_; + + /// The reason for 'success'. + const static Reason REASON_SUCCESS; + static std::size_t reasonID_last; + + inline std::ostream& printValue(std::ostream& os) const { + os << "Event "; + if (success_) + os << "'Success'"; + else + os << "'Failure': " << reason_.what; + return os; + } +}; + +class HPP_STATISTICS_DLLAPI SuccessStatistics : public Statistics<SuccessBin> { + public: + typedef Statistics<SuccessBin> Parent; + + /// Constructor + SuccessStatistics(const std::string name = "", + const std::size_t& logRatio = 2) + : name_(name), logRatio_(logRatio) {} + + /// Copy Constructor + SuccessStatistics(const SuccessStatistics& other) + : name_(other.name_), logRatio_(other.logRatio_) {} + + /// Add a 'success' + void addSuccess() { insert(SuccessBin(true)); } + + /// Add a 'failure' + /// \param r the reason of the 'failure' + /// \note Use macro DEFINE_REASON_FAILURE (REASON_NAME, 'Reason details') + /// to define a new reason. + void addFailure(const SuccessBin::Reason& r = SuccessBin::REASON_UNKNOWN) { + insert(SuccessBin(false, r)); #ifdef HPP_DEBUG - isLowRatio (true); + isLowRatio(true); #endif - } - - inline bool isLowRatio (const bool autoPrint = false) const - { - bool lowRatio = (logRatio_ * nbSuccess () < numberOfObservations()); - if (autoPrint && lowRatio) - hppDout (info, name_ << ":\n" << *this); - return lowRatio; - } - - /// Count the number of success. - std::size_t nbSuccess () const - { - return freq (SuccessBin(true)); - } - - /// Count the number of failure, in total. - std::size_t nbFailure () const - { - return numberOfObservations() - nbSuccess(); - } - - /// Count the number of a particular failure. - std::size_t nbFailure (const SuccessBin::Reason& r) const - { - return freq (SuccessBin (false, r)); - } - - std::string name_; - - /// If nbSuccess() * logRatio < numberOfObservations(), write to log. - std::size_t logRatio_; - }; - } // namespace statistics -} // namespace hpp - -#endif // HPP_STATISTICS_SUCCESSBIN_HH + } + + inline bool isLowRatio(const bool autoPrint = false) const { + bool lowRatio = (logRatio_ * nbSuccess() < numberOfObservations()); + if (autoPrint && lowRatio) hppDout(info, name_ << ":\n" << *this); + return lowRatio; + } + + /// Count the number of success. + std::size_t nbSuccess() const { return freq(SuccessBin(true)); } + + /// Count the number of failure, in total. + std::size_t nbFailure() const { return numberOfObservations() - nbSuccess(); } + + /// Count the number of a particular failure. + std::size_t nbFailure(const SuccessBin::Reason& r) const { + return freq(SuccessBin(false, r)); + } + + std::string name_; + + /// If nbSuccess() * logRatio < numberOfObservations(), write to log. + std::size_t logRatio_; +}; +} // namespace statistics +} // namespace hpp + +#endif // HPP_STATISTICS_SUCCESSBIN_HH diff --git a/src/success-bin.cc b/src/success-bin.cc index 4c136ea0465ad26352b418c80315819e23a376a5..869fbcf75c13fb8834a2e56602f865fb2442759a 100644 --- a/src/success-bin.cc +++ b/src/success-bin.cc @@ -15,18 +15,20 @@ // hpp-statistics. If not, see <http://www.gnu.org/licenses/>. #ifndef HPP_STATISTICS_SUCCESSBIN_HXX -# define HPP_STATISTICS_SUCCESSBIN_HXX +#define HPP_STATISTICS_SUCCESSBIN_HXX -# include "hpp/statistics/success-bin.hh" +#include "hpp/statistics/success-bin.hh" -# include <limits.h> +#include <limits.h> namespace hpp { - namespace statistics { - std::size_t SuccessBin::reasonID_last = 0; - const SuccessBin::Reason SuccessBin::REASON_SUCCESS = SuccessBin::createReason ("Success"); - const SuccessBin::Reason SuccessBin::REASON_UNKNOWN = SuccessBin::createReason ("Unknown"); - } // namespace statistics -} // namespace hpp +namespace statistics { +std::size_t SuccessBin::reasonID_last = 0; +const SuccessBin::Reason SuccessBin::REASON_SUCCESS = + SuccessBin::createReason("Success"); +const SuccessBin::Reason SuccessBin::REASON_UNKNOWN = + SuccessBin::createReason("Unknown"); +} // namespace statistics +} // namespace hpp -#endif // HPP_STATISTICS_SUCCESSBIN_HXX +#endif // HPP_STATISTICS_SUCCESSBIN_HXX diff --git a/tests/test-distribution.cc b/tests/test-distribution.cc index 83222b14d910240a22d49fb3bc3ab41e4348c090..c78b3f47cec8b4cfe4ef29982b477a840e8a4b3d 100644 --- a/tests/test-distribution.cc +++ b/tests/test-distribution.cc @@ -14,106 +14,113 @@ // received a copy of the GNU Lesser General Public License along with // hpp-statistics. If not, see <http://www.gnu.org/licenses/>. -#include <iostream> -#include <cfloat> #include <time.h> +#include <cfloat> +#include <iostream> + #include "hpp/statistics/distribution.hh" -int test1 () -{ +int test1() { using namespace hpp::statistics; typedef int Value; - typedef DiscreteDistribution <Value> Distrib; + typedef DiscreteDistribution<Value> Distrib; Distrib dd; const int nbValues = 3; const Value values[] = {1, 2, 3}; - const Distrib::Weight_t weight[] = - {0, 1, 1}; + const Distrib::Weight_t weight[] = {0, 1, 1}; Distrib::Weight_t total_weight = 0; for (int i = 0; i < nbValues; i++) { - dd.insert (values[i], weight[i]); + dd.insert(values[i], weight[i]); total_weight += weight[i]; } - std::vector < Proba_t > p = dd.probabilities (); + std::vector<Proba_t> p = dd.probabilities(); - for (size_t i = 0; i < p.size (); i++) - if (p[i] - ((double) weight[i] / (double)total_weight) > DBL_EPSILON - || - p[i] + ((double)weight[i] / (double)total_weight) > DBL_EPSILON) { + for (size_t i = 0; i < p.size(); i++) + if (p[i] - ((double)weight[i] / (double)total_weight) > DBL_EPSILON || + -p[i] + ((double)weight[i] / (double)total_weight) > DBL_EPSILON) { std::cout << "p[" << i << "] = " << p[i] << std::endl - << "weight[" << i << "] = " << weight[i] << std::endl - << "Total weight = " << total_weight << std::endl - << "Difference = " << p[i] - ((double)weight[i] / (double)total_weight) << std::endl; + << "weight[" << i << "] = " << weight[i] << std::endl + << "Total weight = " << total_weight << std::endl + << "Difference = " + << p[i] - ((double)weight[i] / (double)total_weight) + << std::endl; return EXIT_FAILURE; } - if (dd ((Distrib::Weight_t) 0) != values[1]) { - std::cout << "dichotomy (" << 0 << ") returns " << dd ((Distrib::Weight_t) 0) << std::endl; + if (dd((Distrib::Weight_t)0) != values[1]) { + std::cout << "dichotomy (" << 0 << ") returns " << dd((Distrib::Weight_t)0) + << std::endl; return EXIT_FAILURE; } - if (dd ((Distrib::Weight_t) 1) != values[2]) { - std::cout << "dichotomy (" << 1 << ") returns " << dd ((Distrib::Weight_t) 1) << std::endl; + if (dd((Distrib::Weight_t)1) != values[2]) { + std::cout << "dichotomy (" << 1 << ") returns " << dd((Distrib::Weight_t)1) + << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; } -int test2 () -{ +int test2() { using namespace hpp::statistics; typedef int Value; - typedef DiscreteDistribution <Value> Distrib; + typedef DiscreteDistribution<Value> Distrib; Distrib dd; const int nbValues = 4; const Value values[] = {1, 3, 2, 4}; - const Distrib::Weight_t weight[] = - {1, 23, 99, 6}; + const Distrib::Weight_t weight[] = {1, 23, 99, 6}; Distrib::Weight_t total_weight = 0; - dd.insert (values[0], 9.0); + dd.insert(values[0], 9.0); for (int i = 0; i < nbValues; i++) { - dd.insert (values[i], weight[i]); + dd.insert(values[i], weight[i]); total_weight += weight[i]; } - std::vector < Proba_t > p = dd.probabilities (); + std::vector<Proba_t> p = dd.probabilities(); - for (size_t i = 0; i < p.size (); i++) - if (p[i] - ((double)weight[i] / (double)total_weight) > DBL_EPSILON - || - p[i] + ((double)weight[i] / (double)total_weight) > DBL_EPSILON) { + for (size_t i = 0; i < p.size(); i++) + if (p[i] - ((double)weight[i] / (double)total_weight) > DBL_EPSILON || + -p[i] + ((double)weight[i] / (double)total_weight) > DBL_EPSILON) { std::cout << "p[" << i << "] = " << p[i] << std::endl - << "weight[" << i << "] = " << weight[i] << std::endl - << "Total weight = " << total_weight << std::endl - << "Difference = " << p[i] - ((double)weight[i] / (double)total_weight) << std::endl; + << "weight[" << i << "] = " << weight[i] << std::endl + << "Total weight = " << total_weight << std::endl + << "Difference = " + << p[i] - ((double)weight[i] / (double)total_weight) + << std::endl; return EXIT_FAILURE; } - if (dd ((Distrib::Weight_t) 0) != values[0]) { - std::cout << "dichotomy (" << 0 << ") returns " << dd ((Distrib::Weight_t) 0) << std::endl; + if (dd((Distrib::Weight_t)0) != values[0]) { + std::cout << "dichotomy (" << 0 << ") returns " << dd((Distrib::Weight_t)0) + << std::endl; return EXIT_FAILURE; } - if (dd ((Distrib::Weight_t) 21) != values[1]) { - std::cout << "dichotomy (" << 21 << ") returns " << dd ((Distrib::Weight_t) 21) << std::endl; + if (dd((Distrib::Weight_t)21) != values[1]) { + std::cout << "dichotomy (" << 21 << ") returns " + << dd((Distrib::Weight_t)21) << std::endl; return EXIT_FAILURE; } - if (dd ((Distrib::Weight_t) 50) != values[2]) { - std::cout << "dichotomy (" << 50 << ") returns " << dd ((Distrib::Weight_t) 50) << std::endl; + if (dd((Distrib::Weight_t)50) != values[2]) { + std::cout << "dichotomy (" << 50 << ") returns " + << dd((Distrib::Weight_t)50) << std::endl; return EXIT_FAILURE; } - if (dd ((Distrib::Weight_t)125) != values[3]) { - std::cout << "dichotomy (" << 125 << ") returns " << dd ((Distrib::Weight_t) 125) << std::endl; + if (dd((Distrib::Weight_t)125) != values[3]) { + std::cout << "dichotomy (" << 125 << ") returns " + << dd((Distrib::Weight_t)125) << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; } -int main () { +int main() { /* initialize random seed: */ - srand ((unsigned int)time(NULL)); + srand((unsigned int)time(NULL)); std::cout.precision(15); - int exit_status = test1 (); + int exit_status = test1(); // exit_status |= test2 (); return exit_status; } diff --git a/tests/test-statistics.cc b/tests/test-statistics.cc index f039e6e3bb9fd2c3d4498c18617cb4214b80f988..016a35e69ad18ee5aaafb600cf3a7e31b872c3eb 100644 --- a/tests/test-statistics.cc +++ b/tests/test-statistics.cc @@ -14,9 +14,10 @@ // received a copy of the GNU Lesser General Public License along with // hpp-statistics. If not, see <http://www.gnu.org/licenses/>. -#include <iostream> -#include <time.h> #include <stdlib.h> +#include <time.h> + +#include <iostream> #include <list> #include "hpp/statistics/bin.hh" @@ -25,57 +26,50 @@ using hpp::statistics::Bin; using hpp::statistics::Statistics; class TestBin : public Bin { - public: - int val; - std::list < double > l; + public: + int val; + std::list<double> l; - TestBin (int i) : val (i) {} + TestBin(int i) : val(i) {} - std::ostream& printValue (std::ostream& os) const - { - os << val << " has :"; - for (std::list <double>::const_iterator it = l.begin (); - it != l.end (); ++it) - os << " " << *it << std::endl; - return os << std::endl; - } + std::ostream& printValue(std::ostream& os) const { + os << val << " has :"; + for (std::list<double>::const_iterator it = l.begin(); it != l.end(); ++it) + os << " " << *it << std::endl; + return os << std::endl; + } - bool operator< (const TestBin& rhs) const { - return val < rhs.val; - } + bool operator<(const TestBin& rhs) const { return val < rhs.val; } - bool operator== (const TestBin& rhs) const { - return val == rhs.val; - } + bool operator==(const TestBin& rhs) const { return val == rhs.val; } }; -class TestStatistics : public Statistics <TestBin> { - public: - void add (int n, double d) { - TestBin b(n); - TestStatistics::iterator it = insert (b); - it->l.push_back (d); - } +class TestStatistics : public Statistics<TestBin> { + public: + void add(int n, double d) { + TestBin b(n); + TestStatistics::iterator it = insert(b); + it->l.push_back(d); + } }; -int main () -{ - srand ((unsigned int)time(NULL)); +int main() { + srand((unsigned int)time(NULL)); TestStatistics t; - double *check = new double [100]; + double* check = new double[100]; int status = EXIT_SUCCESS; for (int i = 0; i < 100; i++) { - check[i] = ((double)(rand())/(double)rand()); - t.add (i, check[i]); + check[i] = ((double)(rand()) / (double)rand()); + t.add(i, check[i]); } for (int i = 0; i < 100; i++) { - TestStatistics::const_iterator it = t.find (i); - if (it == t.end ()) { + TestStatistics::const_iterator it = t.find(i); + if (it == t.end()) { status = EXIT_FAILURE; break; } - if (it->l.size () != 1 && check[i] != it->l.front()) { + if (it->l.size() != 1 && check[i] != it->l.front()) { status = EXIT_FAILURE; break; } diff --git a/tests/test-successstatistics.cc b/tests/test-successstatistics.cc index 754eaa0bfc9cec10f60ed32030c410c6d9228c1a..ea823f91015e6ae5ca600c7c6ce4ce9b4365c9bb 100644 --- a/tests/test-successstatistics.cc +++ b/tests/test-successstatistics.cc @@ -16,47 +16,48 @@ #include <stdlib.h> #include <time.h> + #include <iostream> #include "hpp/statistics/success-bin.hh" -HPP_DEFINE_REASON_FAILURE (REASON_TEST, "Fake reason for testing purpose"); +HPP_DEFINE_REASON_FAILURE(REASON_TEST, "Fake reason for testing purpose"); using namespace hpp; -int main () -{ +int main() { /* initialize random seed: */ - srand ((unsigned int)time(NULL)); + srand((unsigned int)time(NULL)); using namespace hpp::statistics; SuccessStatistics ss; std::size_t counter[3]; - counter[0]=0; counter[1]=0; counter[2]=0; + counter[0] = 0; + counter[1] = 0; + counter[2] = 0; for (int i = 0; i < 100; i++) { std::size_t nb = rand() % 3; counter[nb]++; switch (nb) { case 0: - ss.addSuccess (); + ss.addSuccess(); break; case 1: - ss.addFailure (); + ss.addFailure(); break; case 2: - ss.addFailure (REASON_TEST); + ss.addFailure(REASON_TEST); break; } } - if ( ss.nbSuccess () != counter[0] - || ss.nbFailure (SuccessBin::REASON_UNKNOWN) != counter[1] - || ss.nbFailure (REASON_TEST) != counter[2]) { + if (ss.nbSuccess() != counter[0] || + ss.nbFailure(SuccessBin::REASON_UNKNOWN) != counter[1] || + ss.nbFailure(REASON_TEST) != counter[2]) { std::cout << ss << std::endl; std::cout << "Real frequencies are: ( " << counter[0] << ", " << counter[1] - << ", " << counter [2] << ")" << std::endl; + << ", " << counter[2] << ")" << std::endl; return EXIT_FAILURE; } - if (ss.nbFailure () != counter[1] + counter[2]) - return EXIT_FAILURE; + if (ss.nbFailure() != counter[1] + counter[2]) return EXIT_FAILURE; return EXIT_SUCCESS; }