Click here to Skip to main content
15,886,007 members
Articles / Programming Languages / C++

A Normal / Exponential Random Generator and Histogram Class

Rate me:
Please Sign up or sign in to vote.
4.73/5 (11 votes)
2 Dec 20024 min read 276.4K   8.1K   55  
A fast random generator with normal or exponential distribution + a histogram class
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.
//
//		CGDIRect
//
//
//
//		Written by Jason Hattingh
//
//		http://www.greystonefx.com
//
//		jhattingh@greystonefx.com
//
//
//
//
//		Use freely...
//
//
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_GDIRECT_H__2AC1B0EE_504D_4BF8_B567_0766B3555F88__INCLUDED_)
#define AFX_GDIRECT_H__2AC1B0EE_504D_4BF8_B567_0766B3555F88__INCLUDED_

#include <gdiplus.h>

//#pragma message("     _Adding library: gdiplus.lib" ) 
//#pragma comment(lib, "gdiplus.lib")

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

namespace Gdiplus
{

class CGDIRect
{
public:
	//
	// Construction / Destruction:
	//

	CGDIRect( int nValue = 0 )				{	Assimilate( nValue );	};

	CGDIRect( REAL fValue )					{	Assimilate( fValue );	};

	CGDIRect( Rect rcInit )					{	Assimilate( rcInit );	};

	CGDIRect( RectF rcInit )				{	Assimilate( rcInit );	};

	CGDIRect( CRect rcInit )				{	Assimilate( rcInit );	};

	CGDIRect( CPoint point, CSize size )	{	Assimilate( point.x, point.y, point.x + size.cx, point.y + size.cy );			};

	CGDIRect( Point point, Size size )		{	Assimilate( point.X, point.Y, point.X + size.Width, point.Y + size.Height );	};

	CGDIRect( PointF point, SizeF size )	{	Assimilate( point.X, point.Y, point.X + size.Width, point.Y + size.Height );	};

	CGDIRect( int nLeft, int nTop, int nRight, int nBottom )	
	{	
		Assimilate( nLeft, nTop, nRight, nBottom );
	};

	CGDIRect( REAL Left, REAL Top, REAL Right, REAL Bottom )	
	{	
		Assimilate( Left, Top, Right, Bottom );
	};

	virtual ~CGDIRect()			{							};


	//
	// Operators:
	//

	/////////////////////////////////////////////////////////////////////////////////////////// Function Header
	CGDIRect& operator=( CGDIRect& rhs )
	///////////////////////////////////////////////////////////////////////////////////////////////////////////
	{
		return Assimilate( rhs.left, rhs.top, rhs.right, rhs.bottom );
	};

	/////////////////////////////////////////////////////////////////////////////////////////// Function Header
	CGDIRect& operator|=( CGDIRect& rhs )
	///////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//	Join with rhs in holy matrimony ( Union )
	//
	{
		Rect u;

		if ( u.Union( u, *this, rhs ) )
			return Assimilate( u );
		else
			return Assimilate( 0 );
	};

	/////////////////////////////////////////////////////////////////////////////////////////// Function Header
	CGDIRect& operator&=( CGDIRect& rhs )
	///////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//	Until intersections do us part...
	//
	{
		Rect i;

		if ( i.Intersect( i, *this, rhs ) )
			return Assimilate( i );
		else
			return Assimilate( 0 );
	};

	/////////////////////////////////////////////////////////////////////////////////////////// Function Header
	CGDIRect& operator=( int nValue )
	///////////////////////////////////////////////////////////////////////////////////////////////////////////
	{
		return Assimilate( nValue );
	};

	/////////////////////////////////////////////////////////////////////////////////////////// Function Header
	CGDIRect& operator=( REAL Value )
	///////////////////////////////////////////////////////////////////////////////////////////////////////////
	{
		return Assimilate( Value );
	};

	//
	//		A d d i t i o n   O v e r l o a d s
	//

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		CGDIRect& operator+( CRect& rhs )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			return Assimilate(	top		+ (REAL)rhs.top, 
								left	+ (REAL)rhs.left,
								right	+ (REAL)rhs.right,
								bottom	+ (REAL)rhs.bottom );
		};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		CGDIRect& operator+( Rect& rhs )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			return Assimilate(	top		+ (REAL)rhs.GetTop(),
								left	+ (REAL)rhs.GetLeft(),
								right	+ (REAL)rhs.GetRight(),
								bottom	+ (REAL)rhs.GetBottom() );
		};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		CGDIRect& operator+( RectF& rhs )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			return Assimilate(	top		+ rhs.GetTop(),
								left	+ rhs.GetLeft(),
								right	+ rhs.GetRight(),
								bottom	+ rhs.GetBottom() );
		};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		CGDIRect& operator+( CGDIRect& rhs )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			return Assimilate(	top		+ rhs.top, 
								left	+ rhs.left,
								right	+ rhs.right,
								bottom	+ rhs.bottom );
		};

		CGDIRect& operator+=( CRect& rhs )		{ return Assimilate( CGDIRect(*this) + CGDIRect(rhs) );			};

		CGDIRect& operator+=( Rect& rhs )		{ return Assimilate( CGDIRect(*this) + CGDIRect(rhs) );			};
		
		CGDIRect& operator+=( RectF& rhs )		{ return Assimilate( CGDIRect(*this) + CGDIRect(rhs) );			};
		
		CGDIRect& operator+=( CGDIRect& rhs )	{ return Assimilate( CGDIRect(*this) + CGDIRect(rhs) );			};

		CGDIRect& operator+=( int nValue )		{ return Assimilate( CGDIRect(*this) + CGDIRect(nValue) );		};

		CGDIRect& operator+=( REAL fValue )		{ return Assimilate( CGDIRect(*this) + CGDIRect(fValue) );		};

	//
	//		S u b t r a c t i o n   O v e r l o a d s
	//
	
		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		CGDIRect& operator-( CRect& rhs )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			return Assimilate(	top		- (REAL)rhs.top, 
								left	- (REAL)rhs.left,
								right	- (REAL)rhs.right,
								bottom	- (REAL)rhs.bottom );
		};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		CGDIRect& operator-( Rect& rhs )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			return Assimilate(	top		- (REAL)rhs.GetTop(),
								left	- (REAL)rhs.GetLeft(),
								right	- (REAL)rhs.GetRight(),
								bottom	- (REAL)rhs.GetBottom() );
		};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		CGDIRect& operator-( RectF& rhs )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			return Assimilate(	top		- rhs.GetTop(),
								left	- rhs.GetLeft(),
								right	- rhs.GetRight(),
								bottom	- rhs.GetBottom() );
		};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		CGDIRect& operator-( CGDIRect& rhs )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			return Assimilate(	top		- rhs.top, 
								left	- rhs.left,
								right	- rhs.right,
								bottom	- rhs.bottom );
		};

		CGDIRect& operator-=( CRect& rhs )		{ return Assimilate( CGDIRect(*this) - CGDIRect(rhs) );			};

		CGDIRect& operator-=( Rect& rhs )		{ return Assimilate( CGDIRect(*this) - CGDIRect(rhs) );			};
		
		CGDIRect& operator-=( RectF& rhs )		{ return Assimilate( CGDIRect(*this) - CGDIRect(rhs) );			};
		
		CGDIRect& operator-=( CGDIRect& rhs )	{ return Assimilate( CGDIRect(*this) - CGDIRect(rhs) );			};

		CGDIRect& operator-=( int nValue )		{ return Assimilate( CGDIRect(*this) - CGDIRect(nValue) );		};

		CGDIRect& operator-=( REAL fValue )		{ return Assimilate( CGDIRect(*this) - CGDIRect(fValue) );		};

	//
	//	C o m p a r i s o n   O v e r l o a d s :
	//

		// Is Equal To?
		bool operator==( REAL Value )		{ return top == Value  && bottom == Value  && left == Value  && right == Value;				};
		bool operator==( int nValue )		{ return top == nValue && bottom == nValue && left == nValue && right == nValue;			};
		bool operator==( CGDIRect& rhs )	{ return top == rhs.top && bottom == rhs.bottom && left == rhs.left && right == rhs.right;	};
		bool operator==( CRect& rhs )		{ return CGDIRect(rhs) == *this;	};
		bool operator==( Rect&  rhs )		{ return CGDIRect(rhs) == *this;	};
		bool operator==( RectF& rhs )		{ return CGDIRect(rhs) == *this;	};

		// Is Different To?

		bool operator!=( REAL Value )		{ return top != Value && bottom != Value && left != Value && right != Value;				};
		bool operator!=( int nValue )		{ return top != nValue && bottom != nValue && left != nValue && right != nValue;			};
		bool operator!=( CGDIRect& rhs )	{ return top != rhs.top || bottom != rhs.bottom	|| left	!= rhs.left || right != rhs.right;	};
		bool operator!=( CRect& rhs )		{ return CGDIRect(rhs) != *this;	};
		bool operator!=( Rect&  rhs )		{ return CGDIRect(rhs) != *this;	};
		bool operator!=( RectF& rhs )		{ return CGDIRect(rhs) != *this;	};

	//
	//	S i z e   a n d   P o s i t i o n  :
	//

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void ReplicateBelow( CGDIRect rcSource, REAL nOffset = 0)
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			top		= rcSource.bottom + nOffset;

			left	= rcSource.left;

			SetSize( rcSource );
		};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void ReplicateAbove( CGDIRect rcSource, REAL Offset = 0)
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			top		= rcSource.top - Height() - Offset;

			left	= rcSource.left;

			SetSize( rcSource );
		};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void ReplicateLeft( CGDIRect rcSource, REAL Offset = 0)
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			top		= rcSource.top;

			left	= rcSource.left - rcSource.Width() - Offset;

			SetSize( rcSource );
		};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void ReplicateRight( CGDIRect rcSource, REAL Offset = 0)
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{
			top		= rcSource.top;

			left	= rcSource.right + rcSource.Width() + Offset;

			SetSize( rcSource );
		};

		void ReplicateBelow( CGDIRect rcSource, int nOffset = 0)	{ ReplicateBelow( rcSource, (REAL)nOffset);	};

		void ReplicateAbove( CGDIRect rcSource, int nOffset = 0)	{ ReplicateAbove( rcSource, (REAL)nOffset);	};

		void ReplicateLeft( CGDIRect rcSource, int nOffset = 0)		{ ReplicateLeft( rcSource, (REAL)nOffset);	};

		void ReplicateRight( CGDIRect rcSource, int nOffset = 0)	{ ReplicateRight( rcSource, (REAL)nOffset);	};

		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void		SetSize( CGDIRect rcSource )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{ 
			SetWidth(	rcSource.Width() );
			SetHeight(	rcSource.Height() );
		};
		
		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void		SetSize( CSize size )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{ 
			SetWidth(	size.cx );
			SetHeight(	size.cy );
		};
		
		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void		SetSize( Size size )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{ 
			SetWidth(	size.Width );
			SetHeight(	size.Height );
		};
		
		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void		SetSize( SizeF size )
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{ 
			SetWidth(	size.Width );
			SetHeight(	size.Height );
		};
		
		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void		SetWidth( REAL nValue, bool bMaintainRight=false )			
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{ 
			if (bMaintainRight)
				left	= right - nValue;
			else
				right	= left + nValue;
		};
		
		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void		SetHeight( REAL Value, bool bMaintainBottom=false )			
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{ 
			if (bMaintainBottom)
				top		= bottom - Value;
			else
				bottom	= top + Value;
		};
		
		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void		SetWidth( int nValue, bool bMaintainRight=false )			
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{ 
			SetWidth( (REAL)nValue, bMaintainRight );
		};
		
		/////////////////////////////////////////////////////////////////////////////////////////// Function Header
		void		SetHeight( int nValue, bool bMaintainBottom=false )			
		///////////////////////////////////////////////////////////////////////////////////////////////////////////
		{ 
			SetHeight( (REAL)nValue, bMaintainBottom );
		};

		REAL		Width()		{ return right - left;			};
		REAL		Height()	{ return bottom - top;			};

		int			WidthInt()	{ return (int)floor(right - left);	};
		int			HeightInt()	{ return (int)floor(bottom - top);	};

		operator	CRect()		{ return CRect( (int)left, (int)top, (int)right, (int)bottom );				};
		operator	RectF()		{ return RectF( left, top, Width(), Height() );								};
		operator	Rect()		{ return Rect(  (int)left, (int)top, (int)Width(), (int)Height() );			};

		operator	CPoint()	{ return CPoint((int)left, (int)top );										};
		operator	Point()		{ return Point((int)left, (int)top );										};
		operator	PointF()	{ return PointF((REAL)left, (REAL)top );									};

		operator	CSize()		{ return CSize( WidthInt(),	HeightInt() );									};
		operator	Size()		{ return Size(	WidthInt(),	HeightInt() );									};
		operator	SizeF()		{ return SizeF(	Width(),	Height() );										};

		//		Inflate and Deflate Methods:

		void	InflateWidth(	 REAL x )		{ left -= x;			right += x;							};
		void	InflateWidthInt( int nX )		{ left -= (REAL)nX;		right += (REAL)nX;					};

		void	InflateHeight( REAL y )			{ top -= y;				bottom += y;						};
		void	InflateHeightInt( int nY )		{ top -= nY;			bottom += (REAL)nY;					};

		void	Inflate( CSize Size )			{ InflateWidthInt( Size.cx );	  InflateHeightInt( Size.cy );	    };
		void	Inflate( Size  Size )			{ InflateWidthInt( Size.Width ); InflateHeightInt( Size.Height );	};
		void	Inflate( SizeF Size )			{ InflateWidth( Size.Width ); InflateHeight( Size.Height );	};
		void	Inflate( REAL X, REAL Y)		{ InflateWidth( X );		InflateHeight( Y );				};
		void	Inflate( REAL Val)				{ InflateWidth( Val );		InflateHeight( Val );			};
		void	InflateInt( int nX, int nY)		{ InflateWidthInt( nX );	InflateHeightInt( nY );			};
		void	InflateInt( int nVal)			{ InflateWidthInt( nVal );	InflateHeightInt( nVal );		};

		void	Deflate( CSize Size )			{ DeflateWidthInt( Size.cx ); InflateHeightInt( Size.cy );	};
		void	Deflate( Size  Size )			{ DeflateWidthInt( Size.Width ); InflateHeightInt( Size.Height );	};
		void	Deflate( SizeF Size )			{ DeflateWidth( Size.Width ); InflateHeight( Size.Height );	};
		void	Deflate( REAL X, REAL Y )		{ DeflateWidth( X );		DeflateHeight( Y );				};
		void	Deflate( REAL Val)				{ DeflateWidth( Val );		DeflateHeight( Val );			};
		void	DeflateInt( int nX, int nY )	{ DeflateWidthInt( nX );	DeflateHeightInt(nY);			};
		void	DeflateInt( int nVal)			{ DeflateWidthInt( nVal );	DeflateHeightInt(nVal);			};

		void	DeflateWidth(  REAL X )			{ left += X;			right -= X;							};
		void	DeflateWidthInt(  int nX )		{ left += (REAL)nX;		right -= (REAL)nX;					};

		void	DeflateHeight( REAL Y )			{ top += Y;				bottom -= Y;						};
		void	DeflateHeightInt( int nY )		{ top += (REAL)nY;		bottom -= (REAL)nY;					};

		//		Offset, Extend and Collapse

		void	Offset(		REAL nX, REAL nY )	{ Assimilate( top+nY, bottom+nY, left+nX, right+nX);							};
		void	OffsetInt(	int nX, int nY )	{ Assimilate( top+(REAL)nY, bottom+(REAL)nY, left+(REAL)nX, right+(REAL)nX);	};

		void	Extend(		REAL nX, REAL nY )	{ Assimilate( top, bottom+nY, left, right+nX);									};
		void	ExtendInt( int nX, int nY )		{ Assimilate( top, bottom+(REAL)nY, left, right+(REAL)nX);						};

		void	Collapse(	 REAL nX, REAL nY )	{ Assimilate( top, bottom-nY, left, right-nX);									};
		void	CollapseInt( int nX, int nY )	{ Assimilate( top, bottom-(REAL)nY, left, right-(REAL)nX);						};

	//
	//	P o i n t   R e t r i e v a l:
	//

		CPoint	TopLeftCPoint()			{ return (CPoint)(*this);							};
		Point	TopLeftPoint()			{ return (Point)(*this);							};
		PointF	TopLeftPointF()			{ return (PointF)(*this);							};

		CPoint	TopRightCPoint()		{ return CPoint((int)right, (int)top);				};
		Point	TopRightPoint()			{ return Point((int)right, (int)top);				};
		PointF	TopRightPointF()		{ return PointF(right, top);						};

		CPoint	BottomRightCPoint()		{ return CPoint((int)right, (int)bottom);			};
		Point	BottomRightPoint()		{ return Point((int)right, (int)bottom);			};
		PointF	BottomRightPointF()		{ return PointF(right, bottom);						};

		CPoint	BottomLeftCPoint()		{ return CPoint((int)left, (int)bottom);			};
		Point	BottomLeftPoint()		{ return Point((int)left, (int)bottom);				};
		PointF	BottomLeftPointF()		{ return PointF(left, bottom);						};

	//
	//		Various Others:
	//

		bool	HitTest( CPoint point )	{ return CRect(*this).PtInRect( point )==TRUE;						};
		bool	HitTest( Point  point )	{ return CRect(*this).PtInRect( CPoint(point.X, point.Y) )==TRUE;	};
		bool	HitTest( PointF point )	{ return CRect(*this).PtInRect( CPoint((int)point.X, (int)point.Y) )==TRUE;	};

		void	Dump()
		{
			TRACE0("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\nCGDIRect Values:\n");
			TRACE("\ttop:\t%.2f",		top);
			TRACE("\tleft:\t%.2f\n",	left);
			TRACE("\tright:\t%.2f\t",	right);
			TRACE("\tbottom:\t%.2f\n",	bottom);
			TRACE("\tWidth:\t%d",		WidthInt());
			TRACE("\tHeight:\t%d\n\n",	HeightInt());
			TRACE0("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
		}

	//
	//		Private Methods:
	//
private:

	CGDIRect& Assimilate( Point location, Size size)		
	{
		return Assimilate( Rect( location, size ) );
	};

	CGDIRect& Assimilate( CPoint location, CSize size)		
	{
		return Assimilate( CRect( location, size ) );
	};

	CGDIRect& Assimilate( int nValue )		
	{	
		top		= (REAL)nValue; 
		bottom	= (REAL)nValue; 
		left	= (REAL)nValue; 
		right	= (REAL)nValue; 

		return	*this;
	};

	CGDIRect& Assimilate( REAL fValue )		
	{	
		top		= fValue; 
		bottom	= fValue;
		left	= fValue;
		right	= fValue;

		return	*this;
	};

	CGDIRect& Assimilate( CRect rcData )		
	{	
		top		= (REAL)rcData.top; 
		bottom	= (REAL)rcData.bottom; 
		left	= (REAL)rcData.left; 
		right	= (REAL)rcData.right; 

		return	*this;
	};

	CGDIRect& Assimilate( REAL rleft, REAL rtop, REAL rright, REAL rbottom)		
	{	
		top		= rtop; 
		bottom	= rbottom; 
		left	= rleft; 
		right	= rright; 

		return	*this;
	};

	CGDIRect& Assimilate( int nleft, int ntop, int nright, int nbottom)		
	{	
		top		= (REAL)ntop; 
		bottom	= (REAL)nbottom; 
		left	= (REAL)nleft; 
		right	= (REAL)nright; 

		return	*this;
	};

	CGDIRect& Assimilate( Rect rcData )		
	{	
		top		= (REAL)rcData.GetTop(); 
		bottom	= (REAL)rcData.GetBottom(); 
		left	= (REAL)rcData.GetLeft(); 
		right	= (REAL)rcData.GetRight(); 

		return	*this;
	};

	CGDIRect& Assimilate( RectF rcData )		
	{	
		top		= rcData.GetTop(); 
		bottom	= rcData.GetBottom(); 
		left	= rcData.GetLeft(); 
		right	= rcData.GetRight(); 

		return	*this;
	};

	CGDIRect& Assimilate( CGDIRect& rcData )		
	{	
		top		= rcData.top; 
		bottom	= rcData.bottom; 
		left	= rcData.left; 
		right	= rcData.right; 

		return	*this;
	};

	//
	//		V a r i a b l e s
	//
public:

	REAL		top,
				bottom,
				left,
				right;
};

}

#endif // !defined(AFX_GDIRECT_H__2AC1B0EE_504D_4BF8_B567_0766B3555F88__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.


Written By
Engineer
United States United States
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).

Comments and Discussions