📄 cdbinrnk.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 + -