-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathugdist.c
119 lines (98 loc) · 3.56 KB
/
ugdist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/****************************************************
* Uniform to Gaussian Distribution *
* Uses Box-Muller transform *
* Ref: http://bit.ly/2GIs0mn *
* *
* Chris K Cockrum *
* https://cockrum.net *
* 02/03/2018 *
* *
* Infile: binary uniform distribution file *
* (i.e. from TrueRNG binary mode capture) *
* OutFile: ASCII text file of floating point values *
* Output will have Gaussian distribution with mean *
* and standard deviation as defined below or input *
* conversion if the INPUT_ONLY is set *
****************************************************/
#include<stdio.h>
#include<math.h>
#define two_pi 2*3.14159265358979323846264338327
#define mean 0.0
#define stddev 10.0
#define INPUT_ONLY 0
int main(int argc, char** argv)
{
FILE *infile; /* Input File Pointer */
FILE *outfile; /* Output File Pointer */
FILE *outfile2; /* Output File Pointer */
int x_in,y_in; /* Variables to read input binary values */
double x,y; /* Variables for input values as floats */
double g0,g1; /* Variables to hold Gaussian distributed values */
size_t xbytesread; /* Number of bytes read */
size_t ybytesread; /* Number of bytes read */
/* If we don't have 2 command line inputs */
if (argc !=3 )
{
printf("Usage:\n ugdist infile outfile\n");
printf("Infile: binary uniform distribution file (i.e. from TrueRNG binary mode capture)\n");
printf("OutFile: ASCII text file of floating point values\n");
return 0;
}
/* Open the Input File */
infile=fopen(argv[1],"rb");
if(infile<=0)
{
printf("Can't open %s\n",argv[1]);
return 0;
}
/* Open the Output File */
outfile=fopen(argv[2],"w+");
if(outfile<=0)
{
printf("Can't open %s\n",argv[2]);
fclose(infile);
return 0;
}
/* Print output file comment */
fprintf(outfile,"%% Gaussian Distribution Random Numbers\n");
while(1)
{
/* Read 4 bytes to each int */
xbytesread=fread(&x_in,1,4,infile);
ybytesread=fread(&y_in,1,4,infile);
/* If we are out of data then exit this loop */
if((xbytesread!=4)||(ybytesread!=4))
break;
/* Scale to +/- 1 */
x=(double)x_in / (double)(1<<31);
y=(double)y_in / (double)(1<<31);
#if INPUT_ONLY
/* Only print converted and scaled input values */
fprintf(outfile,"%f\n",x);
fprintf(outfile,"%f\n",y);
#else
/* If x != 0 -- prevent discontinuity in log at 0 */
if(x!=0)
{
/* change sign for -log since the log function doesn't support complex numbers */
if(x>0)
{
g0=sqrt(-2.0*log(x))*cos(two_pi*y);
g1=sqrt(-2.0*log(x))*sin(two_pi*y);
}
else
{
g0=-sqrt(-2.0*log(-x))*cos(two_pi*y);
g1=-sqrt(-2.0*log(-x))*sin(two_pi*y);
}
/* Apply mean and standard deviation then print to output file */
fprintf(outfile,"%f\n",g0*stddev+mean);
fprintf(outfile,"%f\n",g1*stddev+mean);
}
#endif
};
/* Close Files */
fclose(infile);
fclose(outfile);
return 0;
}