S.R.
S.R.

Reputation: 41

Random Number Generator - Histogram Construction (Poisson Distribution and Counting Variables)

This Problem Has Now Been Resolved - Revised Code is Shown Below

I have a problem here which I'm sure will only require a small amount of tweaking the code but I do not seem to have been able to correct the program.

So, basically what I want to do is write a C++ program to construct a histogram with nbin = 20 (number of bins), for the number of counts of a Geiger counter in 10000 intervals of a time interval dt (delta t) = 1s; assuming an average count rate of 5 s^(-1). In order to determine the number of counts in some time interval deltat I use a while statement of the form shown below:

while((t-=tau*log(zscale*double(iran=IM*iran+IC)))<deltat)count++;

As a bit of background to this problem I should mention that the total number of counts is given by n*mu, which is proportional to the total counting time T = n*deltat. Obviously, in this problem n has been chosen to be 10000 and deltat is 1s; giving T = 10000s.

The issue I am having is that the output of my code (which will be shown below) simply gives 10000 "hits" for the element 0 (corresponding to 0 counts in the time deltat) and then, of course, 0 "hits" for every other element of the hist[] array subsequently. Whereas, the output which I am expecting is a Poisson Distribution with the peak "hits" at 5 counts (per second).

Thank you in advance for any help you can offer, and I apologise for my poor explanation of the problem at hand! My code is shown below:

#include <iostream>                                 // Pre-processor directives to include
#include <ctime>                                    //... input/output, time,
#include <fstream>                                  //... file streaming and
#include <cmath>                                    //... mathematical function headers

using namespace std;

int main(void) {

const unsigned IM = 1664525;                    // Integer constants for                
const unsigned IC = 1013904223;                 //... the RNG algorithm
const double zscale = 1.0/0xFFFFFFFF;           // Scaling factor for random double between 0 and 1
const double lambda = 5;                        // Count rate = 5s^-1
const double tau = 1/lambda;                    // Average time tau is inverse of count rate
const int deltat = 1;                           // Time intervals of 1s
const int nbin = 20;                            // Number of bins in histogram
const int nsteps = 1E4;

clock_t start, end;

int count(0);

double t = 0;                               // Time variable declaration

unsigned iran = time(0);                        // Seeds the random-number generator from the system time

int hist[nbin];                                 // Declare array of size nbin for histogram

// Create output stream and open output file

ofstream rout;
rout.open("geigercounterdata.txt");

// Initialise the hist[] array, each element is given the value of zero

for ( int i = 0 ; i < nbin ; i++ )
    hist[i] = 0;

start = clock();

// Construction of histogram using RNG process

for ( int i = 1 ; i <= nsteps ; i++ ) { 

    t = 0;
    count = 0;

    while((t -= tau*log(zscale*double(iran=IM*iran+IC))) < deltat)
        count++;        // Increase count variable by 1

    hist[count]++;          // Increase element "count" of hist array by 1

}

// Print histogram to console window and save to output file

for ( int i = 0 ; i < nbin ; i++ ) {

    cout << i << "\t" << hist[i] << endl;
    rout << i << "\t" << hist[i] << endl;

}

end = clock();

cout << "\nTime taken for process completion = "
     << (end - start)/double(CLOCKS_PER_SEC) 
     << " seconds.\n";

rout.close();

return 1;

}   // End of main() routine

Upvotes: 0

Views: 1521

Answers (1)

N A
N A

Reputation: 656

I do not entirely follow you on the mathematics of your while loop; however the problem is indeed in the condition of the while loop. I broke your while loop down as follows:

count--;
do 
{
    iran=IM * iran + IC;            //Time generated pseudo-random
    double mulTmp = zscale*iran;    //Pseudo-random double 0 to 1
    double logTmp = log(mulTmp);    //Always negative (see graph of ln(x))
    t -= tau*logTmp;                //Always more than 10^4 as we substract negative
    count++; 
}  while(t < deltat);

From the code it is apparent that you will always end up with count = 0 when t > 1 and run-time error when t < 1 as you will be corrupting your heap.

Unfortunately, I do not entirely follow you on mathematics behind your calculation and I don't understand why Poisson distribution shall to be expected. With the issue mentioned above, you should either go ahead and solve your problem (and then share your answer for the community) or provide me with more mathematical background and references and I will edit my answer with corrected code. If you decide for the earlier, keep in mind that Poisson distribution's domain is [0, infinity[ so you will need to check whether the vale of count is smaller than 20 (or your nbin for that matter).

Upvotes: 1

Related Questions