1#include <fcntl.h>
2#include <sys/ioctl.h>
3#include <stdio.h>
4#include <sys/time.h>
5#include <sys/types.h>
6#include <sys/mman.h>
7#include <unistd.h>
8#include <stdlib.h>
9#include <math.h>
10
11char *pname;
12char *in_file;
13
14#define DATA_COUNT	(1024*1024)
15double data_items[DATA_COUNT];
16
17int num_data_items = 0;
18
19#define BUFSIZE		1024
20char in_buf[BUFSIZE];
21
22static int
23compare_double(const void *p1, const void *p2)
24{
25	double val1 = *(u_int64_t *)p1;
26	double val2 = *(u_int64_t *)p2;
27
28	if (val1 == val2)
29		return 0;
30	if (val1 < val2)
31		return -1;
32	return 1;
33}
34
35int
36main(int argc, char **argv)
37{
38	FILE *in_fp;
39	double sum_x = 0;
40	double sum_sq_x = 0;
41	double mean;
42	double std_dev;
43	int i;
44	int one_sd = 0;
45	int two_sd = 0;
46	int three_sd = 0;
47	double one_sd_low, one_sd_high;
48	double two_sd_low, two_sd_high;
49	double three_sd_low, three_sd_high;
50
51	pname = argv[0];
52	if (argc == 1)
53		in_fp = stdin;
54	else {
55		in_file = argv[1];
56		in_fp = fopen(in_file, "r");
57	}
58	while (fgets(in_buf, BUFSIZE, in_fp)) {
59		if (num_data_items == DATA_COUNT) {
60			fprintf(stderr,
61				"DATA overflow, increase size of data_items array\n");
62			exit(1);
63		}
64		sscanf(in_buf, "%lf", &data_items[num_data_items]);
65#if 0
66		printf("%lf\n", data_items[num_data_items]);
67#endif
68		num_data_items++;
69	}
70	if (num_data_items == 0) {
71		fprintf(stderr, "Empty input file ?\n");
72		exit(1);
73	}
74#if 0
75	printf("Total items %lu\n", num_data_items);
76#endif
77	for (i = 0 ; i < num_data_items ; i++) {
78		sum_x += data_items[i];
79		sum_sq_x += data_items[i] * data_items[i];
80	}
81	mean = sum_x / num_data_items;
82	printf("\tMean %.4f\n", mean);
83	std_dev = sqrt((sum_sq_x / num_data_items) - (mean * mean));
84	printf("\tStd Dev %.4f (%.4f%% of mean)\n",
85	       std_dev, (std_dev * 100.0) / mean);
86	one_sd_low = mean - std_dev;
87	one_sd_high = mean + std_dev;
88	two_sd_low = mean - (2 * std_dev);
89	two_sd_high = mean + (2 * std_dev);
90	three_sd_low = mean - (3 * std_dev);
91	three_sd_high = mean + (3 * std_dev);
92	for (i = 0 ; i < num_data_items ; i++) {
93		if (data_items[i] >= one_sd_low &&
94		    data_items[i] <= one_sd_high)
95			one_sd++;
96		if (data_items[i] >= two_sd_low &&
97		    data_items[i] <= two_sd_high)
98			two_sd++;
99		if (data_items[i] >= three_sd_low &&
100			 data_items[i] <= three_sd_high)
101			three_sd++;
102	}
103	printf("\tWithin 1 SD %.2f%%\n",
104	       ((double)one_sd * 100) / num_data_items);
105	printf("\tWithin 2 SD %.2f%%\n",
106	       ((double)two_sd * 100) / num_data_items);
107	printf("\tWithin 3 SD %.2f%%\n",
108	       ((double)three_sd* 100) / num_data_items);
109	printf("\tOutside 3 SD %.2f%%\n",
110	       ((double)(num_data_items - three_sd) * 100) / num_data_items);
111	/* Sort the data to get percentiles */
112	qsort(data_items, num_data_items, sizeof(u_int64_t), compare_double);
113	printf("\t50th percentile %lf\n", data_items[num_data_items / 2]);
114	printf("\t75th percentile %lf\n", data_items[(3 * num_data_items) / 4]);
115	printf("\t90th percentile %lf\n", data_items[(9 * num_data_items) / 10]);
116	printf("\t99th percentile %lf\n", data_items[(99 * num_data_items) / 100]);
117}
118
119