mcpele  1.0.0
The Monte Carlo Python Energy Landscape Explorer
histogram.cpp
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
 All Classes Namespaces Functions Variables Typedefs