In this article, you will find a fast generator for Random Variable, namely normal and exponential distributions. It is based on George Marsaglia's and Wai Wan Tsang's work.
|
// Histogram.h: interface for the CHistogram class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_HISTOGRAM_H__DF74A789_2878_4CB0_BAA9_125272F0E7E1__INCLUDED_)
#define AFX_HISTOGRAM_H__DF74A789_2878_4CB0_BAA9_125272F0E7E1__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <valarray>
/*! \brief A histogram class
This class computes the histogram of a vector.
Moment function taken from Numerical recipies...
*/
template<class T>
class CHistogram
{
public:
//! \name Constructors
//@{
/*! Default constructor
\param nCounters the number of histogram containers (default value is 10)
*/
CHistogram<T>(UINT nCounters = 10);
virtual ~CHistogram<T>() { Clear();};
//@}
//! \name Histogram computation, update
//@{
/*! Computes histogram of vector v
\param v vector to compute histogram
\param bComputeMinMax set to true if min/max of v have to be used to get the histogram limits
This function computes the histogram of v and stores it internally.
\sa Update, GetHistogram
*/
void Compute( const std::vector<T>& v, bool bComputeMinMax = true);
//! Update histogram with the vector v
void Update( const std::vector<T>& v);
//! Update histogram with t
void Update( const T& t);
//@}
//! \name Resetting functions
//@{
//! Resize the histogram. Warning this function clear the histogram.
void Resize( UINT nCounters );
//! Clears the histogram
void Clear() { m_vCounters.clear();};
//@}
//! \name Setters
//@{
/*! This function sets the minimum of the histogram spectrum.
The spectrum is not recomputed, use it with care
*/
void SetMinSpectrum( const T& tMin ) { m_tMin = tMin; ComputeStep();};
/*! This function sets the minimum of the histogram spectrum.
The spectrum is not recomputed, use it with care
*/
void SetMaxSpectrum( const T& tMax ) { m_tMax = tMax; ComputeStep();};
//@}
//! \name Getters
//@{
//! return minimum of histogram spectrum
const T& GetMinSpectrum() const { return m_tMin;};
//! return maximum of histogram spectrum
const T& GetMaxSpectrum() const { return m_tMax;};
//! return step size of histogram containers
double GetStep() const { return m_dStep;};
//! return number of points in histogram
UINT GetSum() const;
//! return number of containers
UINT GetSize() const { return m_vCounters.size();};
//! returns i-th counter
UINT operator [] (UINT i) const { ASSERT( i < m_vCounters.size() ); return m_vCounters[i];};
//! return the computed histogram
const std::vector<UINT>& GetHistogram() const { return m_vCounters;};
//! return the computed histogram, in doubles
std::vector<double> GetHistogramD() const;
//! return the computed histogram normalized to 1
std::vector<double> GetNormalizedHistogram() const;
//! returns left containers position
std::vector<double> GetLeftContainers() const;
//! returns center containers position
std::vector<double> GetCenterContainers() const;
//@}
private:
//! Computes the step
void ComputeStep() { m_dStep = (double)(((double)(m_tMax-m_tMin)) / (m_vCounters.size()-1));};
protected:
std::vector<UINT> m_vCounters;
T m_tMin;
T m_tMax;
double m_dStep;
};
template<class T>
CHistogram<T>::CHistogram<T>(UINT nCounters)
: m_vCounters(nCounters,0), m_tMin(0), m_tMax(0), m_dStep(0)
{
}
template<class T>
void CHistogram<T>::Resize( UINT nCounters )
{
Clear();
m_vCounters.resize(nCounters,0);
ComputeStep();
}
template<class T>
void CHistogram<T>::Compute( const std::vector<T>& v, bool bComputeMinMax)
{
using namespace std;
UINT i;
int index;
if (m_vCounters.empty())
return;
if (bComputeMinMax)
{
m_tMax = m_tMin = v[0];
for (i=1;i<v.size();i++)
{
m_tMax = __max( m_tMax, v[i]);
m_tMin = __min( m_tMin, v[i]);
}
}
ComputeStep();
for (i = 0;i < v.size() ; i++)
{
index=(int) floor( ((double)(v[i]-m_tMin))/m_dStep ) ;
if (index >= m_vCounters.size() || index < 0)
return;
m_vCounters[index]++;
}
}
template<class T>
void CHistogram<T>::Update( const std::vector<T>& v)
{
if (m_vCounters.empty())
return;
ComputeStep();
double uSize = m_vCounters.size();
int index;
for (UINT i = 0;i < uSize ; i++)
{
index = (int)floor(((double)(v[i]-m_tMin))/m_dStep);
if (index >= m_vCounters.size() || index < 0)
return;
m_vCounters[index]++;
}
}
template<class T>
void CHistogram<T>::Update( const T& t)
{
int index=(int) floor( ((double)(t-m_tMin))/m_dStep ) ;
if (index >= m_vCounters.size() || index < 0)
return;
m_vCounters[index]++;
};
template<class T>
std::vector<double> CHistogram<T>::GetHistogramD() const
{
std::vector<double> v(m_vCounters.size());
for (UINT i = 0;i<m_vCounters.size(); i++)
v[i]=(double)m_vCounters[i];
return v;
}
template <class T>
std::vector<double> CHistogram<T>::GetLeftContainers() const
{
std::vector<double> vX( m_vCounters.size());
for (UINT i = 0;i<m_vCounters.size(); i++)
vX[i]= m_tMin + i*m_dStep;
return vX;
}
template <class T>
std::vector<double> CHistogram<T>::GetCenterContainers() const
{
std::vector<double> vX( m_vCounters.size());
for (UINT i = 0;i<m_vCounters.size(); i++)
vX[i]= m_tMin + (i+0.5)*m_dStep;
return vX;
}
template <class T>
UINT CHistogram<T>::GetSum() const
{
UINT uSum = 0;
for (UINT i = 0;i<m_vCounters.size(); i++)
uSum+=m_vCounters[i];
return uSum;
}
template <class T>
std::vector<double> CHistogram<T>::GetNormalizedHistogram() const
{
std::vector<double> vNormCounters( m_vCounters.size());
double dSum = (double)GetSum();
for (UINT i = 0;i<m_vCounters.size(); i++)
{
vNormCounters[i]= (double)m_vCounters[i]/dSum;
}
return vNormCounters;
}
#endif // !defined(AFX_HISTOGRAM_H__DF74A789_2878_4CB0_BAA9_125272F0E7E1__INCLUDED_)
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Jonathan de Halleux is Civil Engineer in Applied Mathematics. He finished his PhD in 2004 in the rainy country of Belgium. After 2 years in the Common Language Runtime (i.e. .net), he is now working at Microsoft Research on Pex (http://research.microsoft.com/pex).