⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdbinrnk.c

📁 diehard随机数测试套件的C程序代码
💻 C
字号:
/*******Test ranks of 100,000 6x8 binary matrices************** *******Each row a byte from a RNG, overlapping rows*************/#include "header.h"#include "macro.h"/* define a binary matrix */typedef struct binmatrix {  uniform *row;  int no_row, no_col;  unsigned long mask;} binmatrix;/*print the title*/void rnk_ttl(char *fn, char *test){ if( test[0]=='6' ){  puts("\n\t|-------------------------------------------------------------|");  puts("\t|This is the BINARY RANK TEST for 6x8 matrices.  From each of |");  puts("\t|six random 32-bit integers from the generator under test, a  |");  puts("\t|specified byte is chosen, and the resulting six bytes form a |");  puts("\t|6x8 binary matrix whose rank is determined.  That rank can be|");  puts("\t|from 0 to 6, but ranks 0,1,2,3 are rare; their counts are    |");  puts("\t|pooled with those for rank 4. Ranks are found for 100,000    |");  puts("\t|random matrices, and a chi-square test is performed on       |");  puts("\t|counts for ranks 6,5 and (0,...,4) (pooled together).        |");  puts("\t|-------------------------------------------------------------|\n"); } if( test[1]=='1' ){  puts("\n\t|-------------------------------------------------------------|");  puts("\t|This is the BINARY RANK TEST for 31x31 matrices. The leftmost|");  puts("\t|31 bits of 31 random integers from the test sequence are used|");  puts("\t|to form a 31x31 binary matrix over the field {0,1}. The rank |");  puts("\t|is determined. That rank can be from 0 to 31, but ranks< 28  |");  puts("\t|are rare, and their counts are pooled with those for rank 28.|");  puts("\t|Ranks are found for 40,000 such random matrices and a chisqu-|");  puts("\t|are test is performed on counts for ranks 31,30,28 and <=28. |");  puts("\t|-------------------------------------------------------------|"); } if( test[1]=='2' ){  puts("\n\t|-------------------------------------------------------------|");  puts("\t|This is the BINARY RANK TEST for 32x32 matrices. A random 32x|");  puts("\t|32 binary matrix is formed, each row a 32-bit random integer.|");  puts("\t|The rank is determined. That rank can be from 0 to 32, ranks |");  puts("\t|less than 29 are rare, and their counts are pooled with those|");  puts("\t|for rank 29.  Ranks are found for 40,000 such random matrices|");  puts("\t|and a chisquare test is performed on counts for ranks  32,31,|");  puts("\t|30 and <=29.                                                 |");  puts("\t|-------------------------------------------------------------|"); }  printf("\t\tRank test for binary matrices (%s) from %s\n", test, fn);  return;}/*compute the rank of a binary matrix*/int rkbm(binmatrix bm){  register int i, j, k, rt=0;  int rank=0;  uniform tmp;  for(k=0; k<bm.no_row; ++k){    i=k;    while( ( (bm.row[i]>>rt)&1 ) == 0 ){      ++i;      if( i<bm.no_row ){        continue;      }      else {        ++rt;        if( rt<bm.no_col ){          i=k;          continue;        }      }      return rank;    }    ++rank;    if( i!=k ){      tmp=bm.row[i];      bm.row[i]=bm.row[k];      bm.row[k]=tmp;    }    for(j=i+1; j<bm.no_row; ++j){      if( ( (bm.row[j] >> rt) & 1 ) == 0 ) continue;      else  bm.row[j] ^= bm.row[k];     }    ++rt;  }  return rank;  } /* perform the test and calculate test-stat */real rnk_stat(char *fn, counter no_mtr, char *test, int rt){  real p6[]={.009443, 0.217439, 0.773118};  real  p30[]={.0052854502, .1283502644, .5775761902, .2887880952};  binmatrix bm;  register counter i, j;  register int cls, llim;  char cat[2][4]={ {"r<="}, {"r="} };   counter *f;   short df=3;  real pvalue, *p;  real Ef, chsq=0, tmp;  switch(test[1]){    case '1': bm.no_row=bm.no_col=31;bm.mask=pow(2,31)-1;llim=28;p=p30;break;    case '2': bm.no_row=bm.no_col=32;bm.mask=pow(2,32)-1;llim=29; p=p30; break;    default: {       df=2;       bm.no_row=6;       bm.no_col=8;        bm.mask=pow(2,8)-1;       llim=4;       p=p6;       printf("\n\t\t\t      bits %2d to %2d\n", 25-rt, 32-rt);       break;    }  }  bm.row=(uniform*)malloc(bm.no_row*sizeof(uniform));  f=(counter*)calloc( (df+1), sizeof(counter));  puts("\n\tRANK\tOBSERVED\tEXPECTED\t(O-E)^2/E\tSUM\n");  for( i=1; i<=no_mtr; ++i ){   /* get the rows of a matrix */    for(j=0; j<bm.no_row; ++j){      switch(test[1]){         case '1': bm.row[j]=( uni(fn)>>1 ); break;        case '2': bm.row[j]=uni(fn); break;        default: bm.row[j]=( uni(fn)>>rt ); break;      }      bm.row[j] &= bm.mask;    }         cls=rkbm(bm);    cls=MAX(llim,cls)-llim;    ++f[cls];  } /* compute chi-square */  for(i=0; i<=df; ++i){    Ef=no_mtr* ( *(p+i) );    tmp=(f[i]-Ef)*(f[i]-Ef)/Ef;    chsq+=tmp;    printf("\t%s%d\t%-12d\t%-12.1f", cat[MIN(1,i)], i+llim, f[i], Ef);    printf("\t%-12.3f\t%-12.3f\n", tmp, chsq);  }  uni("close");/*  cfree(f, (df+1), sizeof(counter));*/  free(bm.row);  pvalue=1-Chisq( df, chsq );  printf("\n\t\tchi-square = %.3f with df = %d;", chsq, df);  printf("  p-value = %.3f\n", pvalue);  printf("\t--------------------------------------------------------------\n");   return pvalue; }/* type "6x8", "31x31" or "32x32" (including the quotation mark) to call    each test.*/void binrnk(char *filename, char *test){  counter no_matrices=100000;  short rt=24, not6x8=strncmp(test, "6 x 8", 1);  real *p;    if( not6x8 ){    rt=0;    no_matrices=40000;  }     rnk_ttl(filename, test);  p=(real*)malloc( (rt+1)*sizeof(real) );  do{    p[rt]=rnk_stat(filename, no_matrices, test, rt);    --rt;   }while(rt>=0);  if( not6x8 ) return;  puts("\t    TEST SUMMARY, 25 tests on 100,000 random 6x8 matrices");  puts("\t    These should be 25 uniform [0,1] random variates:");  for(rt=24; rt>=0; --rt){    if( (rt+1)%5==0 ) puts(" ");    printf("\t%-12.6f", p[rt]);  }      printf("\n\t\tThe KS test for those 25 supposed UNI's yields\n");  printf("\t\t\tKS p-value = %.6f\n", KStest(p,25));     free(p);   return;}    /*main(){  binrnk("binc", "6 x 8");  binrnk("binc", "32 x 32");  return;}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -