mcpele  1.0.0
The Monte Carlo Python Energy Landscape Explorer
mcpele/histogram.h
00001 #ifndef _MCPELE_HISTOGRAM_H
00002 #define _MCPELE_HISTOGRAM_H
00003 
00004 #include <cmath>
00005 #include <algorithm>
00006 #include <list>
00007 #include <iostream>
00008 #include <limits>
00009 
00010 #include "pele/array.h"
00011 
00012 namespace mcpele{
00013 
00014 /*Dynamic histogram class that expand if energies outside of the initial bounds are found.
00015  * Being generous on the initial bounds saves a lot of time in reallocation of memory, at
00016  * the cost of memory preallocation.
00017  * Notes:
00018  * ->floor always casts towards minus infinity
00019  * ->a list is used instead of a vector because more efficient at pushing forward
00020  * ->begin and end return list iterators point to the beginning and the end of the
00021  *   histogram respectively.
00022  * -> the most basic test that histogram must satisfy is that there must be as many
00023  *      beads as the number of iterations (commented out at the end of the script)
00024  * */
00025 
00026 class Moments {
00027 public:
00028     typedef double data_t;
00029     typedef size_t index_t;
00030 private:
00031     data_t m_mean;
00032     data_t m_mean2;
00033     index_t m_count;
00034 public:
00035     Moments()
00036         : m_mean(0),
00037           m_mean2(0),
00038           m_count(0)
00039     {}
00040     void update(const data_t input)
00041     {
00042         m_mean = (m_mean * m_count + input) / (m_count + 1);
00043         m_mean2 = (m_mean2 * m_count + (input * input)) / (m_count + 1);
00044         if (m_count == std::numeric_limits<index_t>::max()) {
00045             throw std::runtime_error("Moments: update: integer overflow");
00046         }
00047         ++m_count;
00048     }
00052     void replace(const data_t old_data, const data_t new_data)
00053     {
00054         m_mean += (new_data - old_data) / m_count;
00055         m_mean2 += (new_data * new_data - old_data * old_data) / m_count;
00056     }
00057     void operator() (const data_t input) { update(input); }
00058     index_t count() const { return m_count; }
00059     data_t mean() const { return m_mean; }
00060     data_t variance() const { return (m_mean2 - m_mean * m_mean); }
00061     data_t std() const { return sqrt(variance()); }
00062 };
00063 
00064 class Histogram{
00065 private:
00066     double m_max;
00067     double m_min;
00068     double m_bin;
00069     double m_eps;
00070     int m_N;
00071     std::vector<double> m_hist;
00072     int m_niter;
00073     Moments m_moments;
00074 public:
00075     Histogram(const double min, const double max, const double bin);
00076     ~Histogram() {}
00077     void add_entry(double entry);
00078     double max() const { return m_max; }
00079     double min() const { return m_min; }
00080     double bin() const { return m_bin; }
00081     size_t size() const { return m_N; }
00082     int entries() const { return m_niter; }
00083     double get_mean() const { return m_moments.mean(); }
00084     double get_variance() const { return m_moments.variance(); }
00085     std::vector<double>::iterator begin(){return m_hist.begin(); }
00086     std::vector<double>::iterator end(){return m_hist.end(); }
00087     double get_position(const size_t bin_index) const { return m_min + (0.5 + bin_index) * m_bin; }
00088     std::vector<double> get_vecdata() const {return m_hist; }
00089     double get_entry(const size_t bin_index) const { return m_hist.at(bin_index); }
00090     std::vector<double> get_vecdata_error() const;
00091     std::vector<double> get_vecdata_normalized() const;
00092     void print_terminal() const;
00093     void resize(const double E, const int i);
00094 };
00095 
00096 }//namespace mcpele
00097 
00098 #endif
 All Classes Namespaces Functions Variables Typedefs