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

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

本文关键字:分布 变量 直方图 随机数生成器      更新时间:2023-10-16

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

我在这里有一个问题,我相信只需要对代码进行少量调整,但我似乎无法纠正程序。

所以,基本上我想做的是编写一个C++程序来构造一个直方图,nbin = 20(箱数),用于盖革计数器在时间间隔 dt (delta t) = 1s 的 10000 个间隔内的计数数;假设平均计数率为 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 次计数),然后,当然,随后为 hist[] 数组的所有其他元素提供 0 次"命中"。然而,我期望的输出是泊松分布,峰值"命中"为 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

我并不完全遵循你的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);

从代码中可以明显看出,t > 1时总是会出现count = 0t < 1时总是会出现运行时错误,因为您将损坏堆。

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