Skip to content
Snippets Groups Projects
Commit 500f618e authored by Guilhem Saurel's avatar Guilhem Saurel
Browse files

format

parent 8729b9c4
No related branches found
No related tags found
No related merge requests found
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......@@ -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;
}
......@@ -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;
}
......
......@@ -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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment