C++ 随机数生成器-直方图构造(泊松分布和计数变量)
此问题现已解决-修订后的代码如下所示 我这里有一个问题,我肯定只需要少量的代码调整,但我似乎无法纠正程序 < >基本上,我要做的是写一个C++程序,构造一个具有NBN=20(BIN)的直方图,用于盖革计数器在一个时间间隔DT(ΔT)=1s的10000个间隔中计数的数目;假设平均计数率为5秒^(-1)。为了确定某个时间间隔deltat中的计数数,我使用了如下形式的while语句:C++ 随机数生成器-直方图构造(泊松分布和计数变量),c++,random,C++,Random,此问题现已解决-修订后的代码如下所示 我这里有一个问题,我肯定只需要少量的代码调整,但我似乎无法纠正程序 < >基本上,我要做的是写一个C++程序,构造一个具有NBN=20(BIN)的直方图,用于盖革计数器在一个时间间隔DT(ΔT)=1s的10000个间隔中计数的数目;假设平均计数率为5秒^(-1)。为了确定某个时间间隔deltat中的计数数,我使用了如下形式的while语句: while((t-=tau*log(zscale*double(iran=IM*iran+IC)))<delta
while((t-=tau*log(zscale*double(iran=IM*iran+IC)))<deltat)count++;
#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((t-=tau*log(zscale*double(iran=IM*iran+IC))我并不完全理解您的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);
计数--;
做
{
iran=IM*iran+IC;//时间生成伪随机
double mulTmp=zscale*iran;//伪随机双精度0到1
double logTmp=log(mulTmp);//始终为负(参见ln(x)的图表)
t-=tau*logTmp;//当我们减去负数时,总是大于10^4
计数++;
}而(t
从代码中可以明显看出,当t>1
时,您将始终得到count=0
,当t<1
时,您将得到运行时错误,因为这将损坏堆
不幸的是,我并不完全理解你计算背后的数学原理,我也不明白为什么泊松分布是可以预期的。对于上述问题,你要么继续解决你的问题(然后向社区分享你的答案)或者给我提供更多的数学背景和参考资料,我会用更正后的代码编辑我的答案。如果你决定更早,请记住泊松分布的域是[0,无穷大[
,因此你需要检查计数的值是否小于20(或者你的nbin
).我认为问题可能与我对变量t的初始化有关,但是如果我将t更改为大于1的任何值,则会产生相同的输出,如果我将t更改为小于1,则程序会在运行时崩溃。您可能想看看std::poisson\u分布
。我基本上使用的是方程t=-tauln(z),来自放射性衰变方程dN/dt的解析解=-lambdaN;给出N=N(0)*exp(-lambda*t).以平均速率lambda发生的事件由平均时间tau=1/lambda分隔。然后可通过转换z=exp(-t/tau)以所需的指数分布生成随机时间t;其中,随机数z均匀分布在0和1之间。每次单击盖革计数器之间的时间延迟可以模拟为t=-taulog(zscaledouble(iran=IMiran+IC))。但如我的代码所示,在while循环中使用时,需要将其更改为t-=taulog(zscaledouble(iran=IMiran+IC))z=exp(-t/tau)
“变换”,你可能指的是它。通过使用这个方程,你基本上是在说:好的,这是粒子衰减的随机概率,我想要粒子有这个概率的时间。我知道你现在在做什么。首先,你要设置你的双t=1E4;
我并不完全相信这是正确的。在我看来,你应该从t=0
开始每一次试验。然后你要增加t
,直到它达到deltat
。你以这样的方式激励,你每个周期都要加上盖革计数器记录粒子所用的随机时间,这样你的过程看起来会有些什么像这样t=0,t+=0.1,t+=0.3,
当t>=deltat
你计算激励的数量并相应地将其添加到直方图中。另一个问题是你应该在每一个模拟秒后重置计数器。我仍然认为z=exp(-t/tau)有问题
transformation,因为它产生非常小的随机数,所以每秒都会得到大量粒子。这就是我目前得到的结果。