Click here to Skip to main content
15,879,474 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.2K   8.1K   55   35
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.

Sample Image - zigurat.png

Introduction

Random Variable Generator

This article presents a fast generator for Random Variable, namely normal and exponential distributions. The algorithm is due to George Marsaglia and Wai Wan Tsang in [1]. Here's the abstract of their paper:

We provide a new version of our ziggurat method for generating a random variable from a given decreasing density. It is faster and simpler than the original, and will produce, for example, normal or exponential variates at the rate of 15 million per second with a C version on a 400MHz PC. It uses two tables, integers ki and reals wi. Some 99% of the time, the required x is produced by: Generate a random 32-bit integer j and let i be the index formed from the rightmost 8 bits of j. If j < ki return x = j . wi.

They did 99,9% of the work, I just encapsulated their C code in a class wrapper.

Histogram

In order to illustrate the generator, a Histogram template class, THistogram is provided.

A Little Bit of Mathematical Background

The normal distribution holds an honored role in probability and statistics, mostly because of the central limit theorem, one of the fundamental theorems that forms a bridge between the two subjects.

The normal distribution is also called the Gaussian distribution, in honor of Carl Friedrich Gauss, who was among the first to use the distribution.

There are plenty of tutorials and demo applets on normal distributions on the web so I won't go into mathematical details here. A very nice web site on this topic can be found at Virtual Laboratories in Probability and Statistics.

The algorithm used to compute the mean, variance and other statistical properties are taken from the numerical recipies (see [2]).

Using the Generator

The CRandomGenerator provides two types of random variables: normal and exponential. These are computed by two static functions, RNOR and REXP:

  • Standard normal variable:
    C++
    float var = CRandomGenerator::RNOR();
    You can also modify the mean and standard deviation of the generator:
    C++
    float fMean=...;
    float fSdev=...;
    float var = CRandomGenerator::RNOR(fMean, fSdev);	
  • Exponential variable:
    C++
    float var = CRandomGenerator::REXP();	

Initializing the Generator

Like any random generator, it has to be initialized with a "seed". Classically, one uses the current time to seed the generator. This is done implicitly in the default constructor of CRandomGenerator, so what you have to do is to build one and only one CRandomGenerator object in your application thread before using the generator. Doing that in your CWinApp::InitInstance function is a good idea.

C++
CWinApp::InitInstance
{
   ...
   // build a CRandomGenerator to seed the generator
   CRandomGenerator randn;
}

Using the Histogram

THistogram is a templated histogram class.

Template Parameters

  • T, input data type: can be float or double
  • TOut, result data type: can be float or double, by default set to double

Characteristics

The histogram is characterized by:

  • a region, defined by a minimum and maximum spectrum value (see Get/SetMinSpectrum,Get/SetMaxSpectrum)
  • a step size (see GetStep)

Histogram diagram

Computing the Histogram

You can feed the histogram with data by different manners:

  • Feeding a vector of data:
    C++
    vector< float > vData;
    ...  // computing the data
    	 
    // Creating an histogram with 101 regions
    THistogram< float > histo(101);
    // Computing the histogram, min and max values are automatically computed... 
    histo.Compute( vData , true /* compute min, max */);
  • Updating with a vector of data:
    C++
    vector< float > vData;
    ... 
    // updating the histogram 
    histo.Update( vData );
  • Updating with a single data entry:
    C++
    float fData;
    ... 
    // updating the histogram 
    histo.Update( fData );
  • Computing the statistical characteristics of a data set: you can compute the moments of a data sets (mean, standard deviation, variance, etc.) by using the static method GetMoments:
    C++
    float fMean, fAdev, fSdev,  fVar, fSkew,fKurt;
    // Computing successively the mean, absolute mean, 
    // standard deviation, variance, skewness and kurtosis
    THistogram<float,float>::GetMoments(vData, fAdev, fSdev,fVar, fSkew, fKurt);
    This method is used in the demo to compare the normal distribution generated by CRandomGenerator and the theoretical probability density function.

Retrieving Results

  • Get the histogram results by using GetHistogram.
  • Get a normalized histogram (such that it's area is 1) by calling GetNormalizedHistogram.
  • Get the coordinates of the regions can be accessed by using GetLeftContainers and GetCenterContainers.

    The code to generate the plots looks like this:

    C++
    vector < double > vDistribution ( histo.GetNormalizedHistogram() );
    vector < double > vLeftPositions ( histo.GetLeftContainers() );
    CPGLLine2D* pLine;
    ...
    pLine->SetDatas(vLeftPositions, vDistributions);

Demo Application

The demo application shows the normal and exponential distribution. The red curve represents the histogram of the random values and the blue curve represent the theoretical probability density function.

There are two projects in the demo application:

  • HistogramDemo uses the Plot Graphic Library for visualization. There is another article on the PGL here. You will need the GDI+ binaries to make the demo application work! (gdiplus.dll)
  • HistogramMatlab uses the Matlab engine for visualization. You will need Matlab installed to make the demo application work!

Note that the source code is documented using Doxygen syntax.

References

Update History

  • 26th November, 2002
    • Added theoretical distribution in CRandomGenerator
    • Added histogram area computation
    • Fixed normalized histogram, added
  • 13th September, 2002
    • Added a new demo project using Matlab
  • 11th September, 2002
    • Fixed demo project and added binary in demo

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


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

 
GeneralBug? Pin
typke23-May-11 3:27
typke23-May-11 3:27 
QuestionCan open in microsoft vc10 or vc08 Pin
Member 76545647-Feb-11 23:42
Member 76545647-Feb-11 23:42 
Generalmultivariate normal Pin
hamidreza_buddy21-Jul-08 19:10
hamidreza_buddy21-Jul-08 19:10 
QuestionProblems implementing in VC++6 Pin
Paul S Ganney10-Aug-07 7:00
Paul S Ganney10-Aug-07 7:00 
Generalsimpler algorithm Pin
andrewgs738-Oct-05 4:29
andrewgs738-Oct-05 4:29 
GeneralAnother one Histogram Template. Pin
rbid14-Sep-04 6:31
rbid14-Sep-04 6:31 
GeneralRandom Generator object should always be GLOBAL Pin
Alex Chirokov13-Jul-04 14:09
Alex Chirokov13-Jul-04 14:09 
GeneralRe: Random Generator object should always be GLOBAL Pin
Anonymous13-Jul-04 20:25
Anonymous13-Jul-04 20:25 
GeneralRe: Random Generator object should always be GLOBAL Pin
Alex Chirokov14-Jul-04 1:46
Alex Chirokov14-Jul-04 1:46 
GeneralNon-members Pin
JoeSox23-Dec-02 7:44
JoeSox23-Dec-02 7:44 
GeneralRe: Non-members Pin
Jonathan de Halleux24-Dec-02 2:29
Jonathan de Halleux24-Dec-02 2:29 
Generalmissing files Pin
zhshshen9-Dec-02 13:41
zhshshen9-Dec-02 13:41 
GeneralGDI+ Pin
Jonathan de Halleux10-Dec-02 19:20
Jonathan de Halleux10-Dec-02 19:20 
GeneralRe: GDI+ Pin
JoeSox23-Dec-02 7:35
JoeSox23-Dec-02 7:35 
GeneralGDI+ Pin
Jonathan de Halleux24-Dec-02 2:32
Jonathan de Halleux24-Dec-02 2:32 
GeneralRe: missing files Pin
ronc12-Feb-03 4:14
ronc12-Feb-03 4:14 
GeneralRe: missing files Pin
Jonathan de Halleux4-Mar-03 8:02
Jonathan de Halleux4-Mar-03 8:02 
QuestionMissing DLL? Pin
Jim A. Johnson2-Dec-02 10:46
Jim A. Johnson2-Dec-02 10:46 
AnswerFix... Pin
Jonathan de Halleux2-Dec-02 22:27
Jonathan de Halleux2-Dec-02 22:27 
GeneralThe page you requested cannot be found Pin
Logan Dugenoux17-Sep-02 4:38
sussLogan Dugenoux17-Sep-02 4:38 
GeneralProblem when moving Pin
Jonathan de Halleux17-Sep-02 4:47
Jonathan de Halleux17-Sep-02 4:47 
Generaldoesn't compile Pin
deepsea200213-Sep-02 19:13
deepsea200213-Sep-02 19:13 
GeneralVC7 problem Pin
Jonathan de Halleux2-Oct-02 2:47
Jonathan de Halleux2-Oct-02 2:47 
GeneralVery nice! Pin
Gary McHale11-Sep-02 18:40
Gary McHale11-Sep-02 18:40 
GeneralWon't build on VC6 Pin
Jim A. Johnson9-Sep-02 12:21
Jim A. Johnson9-Sep-02 12:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.