mcpele
1.0.0
The Monte Carlo Python Energy Landscape Explorer
|
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