[英]Plotting random numbers in a historgram in C language
我使用“C 書中的數字食譜”中的代碼生成一個統一的隨機數,該數命名為函數float ran1(long *idum)
。 它產生一個介於0 and 1
之間的均勻隨機數。 我正在嘗試對這些統一的隨機數進行分類並制作直方圖。 我寫了下面的代碼,但是當我繪制 bin 與頻率的關系時,我沒有得到均勻分布。
有人可以幫我知道問題是什么嗎?
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define IA 16807
#define IM 2147483647
#define AM (1.0/IM)
#define IQ 127773
#define IR 2836
#define NTAB 32
#define NDIV (1+(IM-1)/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
float ran1(long *idum);
int main(){
double delta, x;
int i , ibin ;
long idum ;
int histog[500] ;
delta=0.02 ;
idum=-1 ;// necessary to generate the uniform random number, must be negative integer
FILE *file1;
file1=fopen("guassians.dat","w") ;
for (i=0 ; i<=10000 ; ++i) {
x=ran1(&idum) ; // here ran1(&idum) returns a uniform random number
ibin=round(x/delta);
if ( abs(ibin) < 250 ) {
histog[ibin]=histog[ibin] + 1 ;
}
}
for (ibin=-250 ; ibin <= 250 ; ++ibin){
fprintf(file1, "%0.10lf \t %d \n", ibin*delta , histog[ibin]);
}
fclose(file1);
}
float ran1(long *idum){
int j ;
long k;
static long iy=0;
static long iv[NTAB];
float temp ;
if (*idum <= 0 || !iy) {
if (-(*idum) < 1) *idum=1 ;
else *idum = -(*idum) ;
for (j=NTAB+7 ; j>=0 ; j--) {
k=(*idum)/IQ ;
*idum=IA*(*idum-k*IQ)-IR*k ;
if (*idum < 0) *idum += IM;
if (j < NTAB) iv[j] = *idum;
}
iy=iv[0] ;
}
k=(*idum)/IQ ;
*idum=IA*(*idum-k*IQ)-IR*k ;
if (*idum < 0) *idum += IM ;
j=iy/NDIV ;
iy=iv[j] ;
iv[j] = *idum ;
if ((temp=AM*iy) > RNMX) return RNMX ;
else return temp;
}
至少這些問題
int histog[500]
未初始化。
用負值索引histog[ibin]
是未定義的行為。
我發現我應該使用指針而不是數組。 現在,以下代碼生成均勻分布的 [0:1](不包括)之間的隨機數,
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define IA 16807
#define IM 2147483647
#define AM (1.0/IM)
#define IQ 127773
#define IR 2836
#define NTAB 32
#define NDIV (1+(IM-1)/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
float ran1(long *idum){
int j ;
long k;
static long iy=0;
static long iv[NTAB];
float temp ;
if (*idum <= 0 || !iy) {
if (-(*idum) < 1) *idum=1 ;
else *idum = -(*idum) ;
for (j=NTAB+7 ; j>=0 ; j--) {
k=(*idum)/IQ ;
*idum=IA*(*idum-k*IQ)-IR*k ;
if (*idum < 0) *idum += IM;
if (j < NTAB) iv[j] = *idum;
}
iy=iv[0] ;
}
k=(*idum)/IQ ;
*idum=IA*(*idum-k*IQ)-IR*k ;
if (*idum < 0) *idum += IM ;
j=iy/NDIV ;
iy=iv[j] ;
iv[j] = *idum ;
if ((temp=AM*iy) > RNMX) return RNMX ;
else return temp;
}
int main(){
double delta ,x ;
int i , ibin, maxbin;
long idum=-1 ;
int *p ;
maxbin=100 ;
delta=1.0/maxbin ;
p= calloc(maxbin,sizeof(int)) ;
FILE *myfile1 ;
myfile1 = fopen("gs.dat","w") ;
for (i=0; i<500000 ; ++i) {
x=ran1(&idum) ;
ibin=round(x/delta);
if ( ibin >= 0 && ibin< 100){
*(p+ibin)=*(p+ibin) + 1 ;
}
}
for (ibin=0 ; ibin < 100 ; ++ibin){
fprintf(myfile1, "%lf \t %lf \n", ibin*delta , *(p+ibin)/(500000*delta));
}
free(p);
fclose(myfile1) ;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.