随机数发生器 - 直方图构造(泊松分布和计数变量)

时间:2013-10-17 19:40:37

标签: c++ random

此问题现已解决 - 修改后的代码如下所示

我在这里遇到问题,我确信只需要对代码进行少量调整,但我似乎无法纠正该程序。

所以,基本上我想做的是编写一个C ++程序来构建一个nbin = 20(bin的数量)的直方图,用于一个时间间隔dt的10000个间隔内的Geiger计数器的计数数量(delta t )= 1s;假设平均计数率为5 s ^( - 1)。为了确定某个时间间隔deltat中的计数数量,我使用下面显示的表格的while语句:

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

作为这个问题的一些背景,我应该提到计数的总数由n * mu给出,其与总计数时间T = n * deltat成比例。显然,在这个问题中,n被选择为10000并且deltat是1s;给T = 10000s。

我遇到的问题是我的代码输出(将在下面显示)简单地为元素0提供10000次“命中”(对应于时间deltat中的0次计数)然后,当然,0“随后命中“对于hist []数组的每个其他元素。然而,我期待的输出是泊松分布,峰值“命中”为5个计数(每秒)。

提前感谢您提供的任何帮助,对于我对手头问题的不良解释,我深表歉意!我的代码如下所示:

#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

1 个答案:

答案 0 :(得分:1)

我并不完全关注你的while循环数学;但问题确实是在while循环的条件下。我打破你的while循环如下:

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);

从代码中可以看出,count = 0t > 1总是t < 1[0, infinity[时运行时错误,因为您将破坏堆。

不幸的是,我并没有完全跟随你的计算背后的数学,我不明白为什么泊松分布应该是预期的。对于上面提到的问题,您应该继续解决您的问题(然后分享您对社区的回答)或者为我提供更多的数学背景和参考资料,我将使用更正后的代码编辑我的答案。如果你决定更早,请记住泊松分布的域名为count,因此你需要检查nbin的值是否小于20(或者你的{{1}} )。