// Read the documentation to learn more about C++ code generator // versioning. // %X% %Q% %Z% %W% #ifndef HISTOGRAM_H #define HISTOGRAM_H 1 #include #include #include namespace Numerics { class LinearBinning { public: template static int calcIndex(const T& min, const T& max, const T& val, const int nSteps, const bool parIsLog = false) { // parIsLog flag is ignored for this case Real delta = (max - min)/static_cast(nSteps); return static_cast(floor((val - min)/delta)); } template static void calcBoundaries(const T& min, const T& max, const int idx, const int nSteps, std::pair& boundaries, const bool parIsLog = false) { Real delta = (max - min)/static_cast(nSteps); boundaries.first = min + idx*delta; boundaries.second = min + (idx+1.0)*delta; } template static int verify(const std::vector& mins, const std::vector& maxes, const BoolArray& isLog = BoolArray()) { for (size_t i=0; i static int calcIndex(const T& min, const T& max, const T& val, const int nSteps, const bool parIsLog = true) { // parIsLogflag is ignored for this case using namespace std; const int BAD = -9999; if (val <= .0) return BAD; Real delta = (log(max) - log(min))/static_cast(nSteps); return static_cast(floor((log(val) - log(min))/delta)); } template static void calcBoundaries(const T& min, const T& max, const int idx, const int nSteps, std::pair& boundaries, const bool parIsLog = true) { using namespace std; Real delta = (log(max) - log(min))/static_cast(nSteps); boundaries.first = min*exp(idx*delta); boundaries.second = min*exp((idx+1.0)*delta); } template static int verify(const std::vector& mins, const std::vector& maxes, const BoolArray& isLog = BoolArray()) { for (size_t i=0; i static int calcIndex(const T& min, const T& max, const T& val, const int nSteps, const bool parIsLog = false) { if (parIsLog) return LogBinning::calcIndex(min, max, val, nSteps); else return LinearBinning::calcIndex(min, max, val, nSteps); } template static void calcBoundaries(const T& min, const T& max, const int idx, const int nSteps, std::pair& boundaries, const bool parIsLog = false) { if (parIsLog) LogBinning::calcBoundaries(min, max, idx, nSteps, boundaries); else LinearBinning::calcBoundaries(min, max, idx, nSteps, boundaries); } template static int verify(const std::vector& mins, const std::vector& maxes, const BoolArray& isLog = BoolArray()) { if (isLog.size()) { for (size_t i=0; i class Histogram { public: Histogram (const std::vector& minRanges, const std::vector& maxRanges, const IntegerArray& nSteps, const BoolArray& isLog = BoolArray()); ~Histogram(); size_t nDim () const; bool addToHist (const std::vector& entry); void calcBoundaries (int index, std::vector& boundaries) const; const std::vector& minRanges () const; const std::vector& maxRanges () const; const IntegerArray& nSteps () const; long totalEntries () const; const std::valarray& counts () const; const BoolArray& isLog () const; long totalAttempts () const; // Additional Public Declarations protected: // Additional Protected Declarations private: Histogram(const Histogram< T,Policy > &right); Histogram< T,Policy > & operator=(const Histogram< T,Policy > &right); // Additional Private Declarations private: //## implementation // Data Members for Class Attributes const size_t m_nDim; std::vector m_minRanges; std::vector m_maxRanges; IntegerArray m_nSteps; long m_totalEntries; std::valarray m_counts; BoolArray m_isLog; long m_totalAttempts; // Additional Implementation Declarations }; // Parameterized Class Numerics::Histogram template inline size_t Histogram::nDim () const { return m_nDim; } template inline const std::vector& Histogram::minRanges () const { return m_minRanges; } template inline const std::vector& Histogram::maxRanges () const { return m_maxRanges; } template inline const IntegerArray& Histogram::nSteps () const { return m_nSteps; } template inline long Histogram::totalEntries () const { return m_totalEntries; } template inline const std::valarray& Histogram::counts () const { return m_counts; } template inline const BoolArray& Histogram::isLog () const { return m_isLog; } template inline long Histogram::totalAttempts () const { return m_totalAttempts; } // Parameterized Class Numerics::Histogram template Histogram::Histogram (const std::vector& minRanges, const std::vector& maxRanges, const IntegerArray& nSteps, const BoolArray& isLog) : m_nDim(minRanges.size()), m_minRanges(minRanges), m_maxRanges(maxRanges), m_nSteps(nSteps), m_totalEntries(0), m_counts(), m_isLog(), m_totalAttempts(0) { const string msg("Histogram construction error."); if (!m_nDim || m_maxRanges.size() != m_nDim || m_nSteps.size() != m_nDim) { throw RedAlert(msg); } if (isLog.size()) { if (isLog.size() != m_nDim) throw RedAlert(msg); m_isLog = isLog; } else { m_isLog.resize(m_nDim, false); } size_t nGridPoints = 1; for (size_t i=0; i Histogram::~Histogram() { } template bool Histogram::addToHist (const std::vector& entry) { size_t idxTot = 0; size_t parIncr = 1; ++m_totalAttempts; // LOWEST parameter number varies fastest in counts array. // Example: if 2 pars, par1 = 2 steps, par2 = 2 steps, // counts = [(par1=0,par2=0),(par1=1,par2=0),(par1=0,par2=1),(par1=1,par2=1)] for (size_t i=0; i= nStep_i) { // If ANY indices are out of bounds, point will not get binned. return false; } else { idxTot += idxPar*parIncr; parIncr *= nStep_i; } } m_counts[idxTot] += 1; ++m_totalEntries; return true; } template void Histogram::calcBoundaries (int index, std::vector& boundaries) const { boundaries.resize(m_nDim*2, .0); int accum = 1; for (size_t i=0; i= nSteps_i) { throw YellowAlert("Out of bounds error in Histogram::calcBoundaries\n"); } std::pair parBnd; Policy::calcBoundaries(m_minRanges[i], m_maxRanges[i], parIdx, nSteps_i, parBnd, m_isLog[i]); boundaries[2*i] = parBnd.first; boundaries[2*i+1] = parBnd.second; accum *= m_nSteps[i]; } } // Additional Declarations } // namespace Numerics #endif