1 /******************************************************************************
2  *
3  *   Copyright © International Business Machines  Corp., 2006, 2008
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * NAME
20  *       libstats.h
21  *
22  * DESCRIPTION
23  *      Some basic statistical analysis convenience tools.
24  *
25  *
26  * USAGE:
27  *      To be included in test cases
28  *
29  * AUTHOR
30  *        Darren Hart <dvhltc@us.ibm.com>
31  *
32  * HISTORY
33  *      2006-Oct-17: Initial version by Darren Hart
34  *
35  * TODO: the save routine for gnuplot plotting should be more modular...
36  *
37  *****************************************************************************/
38 
39 #ifndef LIBSTATS_H
40 #define LIBSTATS_H
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <errno.h>
46 #include <unistd.h>
47 #include <math.h>
48 
49 #define MIN(A,B) ((A)<(B)?(A):(B))
50 #define MAX(A,B) ((A)>(B)?(A):(B))
51 
52 typedef struct stats_record {
53 	long x;
54 	long y;
55 } stats_record_t;
56 
57 typedef struct stats_container {
58 	long size;
59 	long index;
60 	stats_record_t *records;
61 } stats_container_t;
62 
63 enum stats_sort_method {
64 	ASCENDING_ON_X,
65 	ASCENDING_ON_Y,
66 	DESCENDING_ON_X,
67 	DESCENDING_ON_Y
68 };
69 
70 typedef struct stats_quantiles {
71 	int nines;
72 	long *quantiles;
73 } stats_quantiles_t;
74 
75 extern int save_stats;
76 
77 /* function prototypes */
78 
79 /* stats_container_init - allocate memory for a new container
80  * size: number of records to allocate
81  * data: stats_container_t destination pointer
82  */
83 int stats_container_init(stats_container_t *data, long size);
84 
85 /* stats_container_resize - resize a container
86  * data: container to resize
87  * size: new number of records
88  */
89 int stats_container_resize(stats_container_t *data, long size);
90 
91 /* stats_container_free - free the records array
92  * data: stats_container_t to free records
93  */
94 int stats_container_free(stats_container_t *data);
95 
96 /* stats_sort - sort a container according to method
97  * data: stats_container_t to sort
98  * method: which field and which order to sort
99  */
100 int stats_sort(stats_container_t *data, enum stats_sort_method method);
101 
102 /* stats_stddev - return the standard deviation of the y values in data
103  * data: stats_container_t data with y values for use in the calculation
104  */
105 float stats_stddev(stats_container_t *data);
106 
107 /* stats_avg - return the average (mean) of the y values in data
108  * data: stats_container_t data with y values for use in the calculation
109  */
110 float stats_avg(stats_container_t *data);
111 
112 /* stats_min - return the minimum of the y values in data
113  * data: stats_container_t data with y values for use in the calculation
114  */
115 long stats_min(stats_container_t *data);
116 
117 /* stats_max - return the maximum of the y values in data
118  * data: stats_container_t data with y values for use in the calculation
119  */
120 long stats_max(stats_container_t *data);
121 
122 /* stats_container_init - allocate memory for new quantiles
123  * nines: int number of nines in most inclusive quantile
124  * quantiles: stats_quantiles_t destination pointer
125  */
126 int stats_quantiles_init(stats_quantiles_t *quantiles, int nines);
127 
128 /* stats_quantiles_free - free the quantiles array
129  * data: stats_quantiles_t to free
130  */
131 int stats_quantiles_free(stats_quantiles_t *quantiles);
132 
133 /* stats_quantiles_calc - calculate the quantiles of the supplied container
134  * data: stats_container_t data with y values for use in the calculation
135  * quantiles: stats_quantiles_t structure for storing the results
136  */
137 int stats_quantiles_calc(stats_container_t *data, stats_quantiles_t *quantiles);
138 
139 /* stats_quantiles_print - print the quantiles stored in quantiles
140  * quantiles: stats_quantiles_t structure to print
141  */
142 void stats_quantiles_print(stats_quantiles_t *quantiles);
143 
144 /* stats_hist - calculate a histogram with hist->size divisions from data
145  * hist: the destination of the histogram data
146  * data: the source from which to calculate the histogram
147  */
148 int stats_hist(stats_container_t *hist, stats_container_t *data);
149 
150 /* stats_hist_print - print out a histogram in human readable format
151  * hist: the stats_container containing the histogram data
152  */
153 void stats_hist_print(stats_container_t *hist);
154 
155 /* stats_container_save - save the x,y data to a file and create a gnuplot
156  * runnable script.
157  * filename: the filename to save the data as without an extension. A .dat
158  * and a .plt file will be created.
159  * title: the title of the graph
160  * labelx: the x-axis label
161  * labely: the y-axis label
162  * mode: "points" "lines" "steps" etc, see gnuplot help for plotting types
163  */
164 int stats_container_save(char *filename, char *title, char *labelx, char *labely, stats_container_t *data, char *mode);
165 
166 /* stats_container_append - appends stats_record_t to data
167  * data: stats_container_t structure for holding the records list, index of
168  *       min and max elements in records list and the sum
169  * rec: stats_record_t to be appended to the records list in data
170  * Returns the index of the appended record on success and -1 on error
171  */
172 int stats_container_append(stats_container_t *data, stats_record_t rec);
173 #endif /* LIBSTAT_H */
174