mcpele
1.0.0
The Monte Carlo Python Energy Landscape Explorer
|
00001 #include "mcpele/histogram.h" 00002 00003 namespace mcpele{ 00004 00005 Histogram::Histogram(const double min, const double max, const double bin) 00006 : m_max(floor((max / bin) + 1) * bin), 00007 m_min(floor((min / bin)) * bin), 00008 m_bin(bin), 00009 m_eps(std::numeric_limits<double>::epsilon()), 00010 m_N((m_max - m_min) / bin), 00011 m_hist(m_N, 0), 00012 m_niter(0) 00013 { 00014 #ifdef DEBUG 00015 std::cout << "histogram is of size " << m_N << "\n"; 00016 #endif 00017 } 00018 00019 void Histogram::add_entry(double E) 00020 { 00021 m_moments(E); 00022 int i; 00023 E = E + m_eps; //this is a dirty hack, not entirely sure of its generality and possible consequences, tests seem to be fine 00024 i = floor((E - m_min) / m_bin); 00025 if (i < m_N && i >= 0) { 00026 m_hist[i] += 1; 00027 ++m_niter; 00028 } 00029 else 00030 this->resize(E, i); 00031 00032 /*THIS IS A TEST*/ 00033 /*int renorm = 0; 00034 * for(vector<size_t>::iterator it = _hist.begin();it != _hist.end();++it) 00035 { 00036 renorm += *it; 00037 } 00038 00039 if (renorm != _niter) 00040 { 00041 std::cout<<" E "<<E<<"\n niter "<<_niter<<"\n renorm "<<renorm<<"\n min "<<_min<<"\n max "<<_max<<"\n i "<<i<<"\n N "<<_N<< "\n"; 00042 assert(renorm == _niter); 00043 }*/ 00044 } 00045 00046 void Histogram::resize(const double E, const int i) 00047 { 00048 int newlen; 00049 if (i >= m_N) { 00050 newlen = (i + 1) - m_N; 00051 m_hist.insert(m_hist.end(), (newlen - 1), 0); 00052 m_hist.push_back(1); 00053 ++m_niter; 00054 m_max = floor((E / m_bin) + 1) * m_bin; //round to nearest increment 00055 m_N = round((m_max - m_min) / m_bin); //was round 00056 if (static_cast<int>(m_hist.size()) != m_N) { 00057 std::cout<< " E " << E << "\n niter " << m_niter<< "\n size " << m_hist.size() << "\n min " << m_min << "\n max " << m_max << "\n i " << i << "\n N " << m_N << "\n"; 00058 assert(static_cast<int>(m_hist.size()) == m_N); 00059 exit (EXIT_FAILURE); 00060 } 00061 std::cout<< "resized above at niter " << m_niter << "\n"; 00062 } 00063 else if (i < 0) { 00064 newlen = -1 * i; 00065 m_hist.insert(m_hist.begin(), (newlen - 1), 0); 00066 m_hist.insert(m_hist.begin(),1); 00067 ++m_niter; 00068 m_min = floor((E / m_bin)) * m_bin; //round to nearest increment 00069 m_N = round((m_max - m_min) / m_bin); //was round 00070 if ( (int) m_hist.size() != m_N) { 00071 std::cout<<" E "<< E << "\n niter " << m_niter << "\n size " << m_hist.size() << "\n min " << m_min << "\n max " << m_max << "\n i " << i << "\n N " << m_N << "\n"; 00072 assert(static_cast<int>(m_hist.size()) == m_N); 00073 exit (EXIT_FAILURE); 00074 } 00075 std::cout<< "resized below at niter " << m_niter << "\n"; 00076 } 00077 else { 00078 std::cerr << "histogram encountered unexpected condition" << "\n"; 00079 std::cout << " E " << E << "\n niter " << m_niter << "\n min " << m_min << "\n max " << m_max << "\n i " << i << "\n N " << m_N << "\n"; 00080 } 00081 } 00082 00083 /* 00084 * Note: This gives the error bar on a bin of width _bin, under the assumption that the sum of all bin areas is 1. 00085 * */ 00086 std::vector<double> Histogram::get_vecdata_error() const 00087 { 00088 std::vector<double> result(m_hist.size(), 0); 00089 for (size_t i = 0; i < result.size(); ++i) { 00090 const double this_fraction = static_cast<double>(m_hist.at(i)) / static_cast<double>(entries()); 00091 result.at(i) = sqrt(this_fraction * (1 - this_fraction) / m_bin) / sqrt(entries()); 00092 } 00093 return result; 00094 } 00095 00096 std::vector<double> Histogram::get_vecdata_normalized() const 00097 { 00098 std::vector<double> result(m_hist.size(), 0); 00099 for (size_t i = 0; i < m_hist.size(); ++i) { 00100 const double this_fraction = static_cast<double>(m_hist.at(i)) / static_cast<double>(m_niter); 00101 result.at(i) = this_fraction / m_bin; 00102 } 00103 return result; 00104 } 00105 00106 void Histogram::print_terminal() const 00107 { 00108 for(size_t i = 0; i < m_hist.size(); ++i) { 00109 std::cout << i << "-" << (i + 1) << ": "; 00110 std::cout << std::string(m_hist[i] * 10000 / m_niter, '*') << "\n"; 00111 } 00112 } 00113 00114 00115 }//namespace mcpele