001 /*
002 Galois, a framework to exploit amorphous data-parallelism in irregular
003 programs.
004
005 Copyright (C) 2010, The University of Texas at Austin. All rights reserved.
006 UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING THIS SOFTWARE
007 AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR ANY
008 PARTICULAR PURPOSE, NON-INFRINGEMENT AND WARRANTIES OF PERFORMANCE, AND ANY
009 WARRANTY THAT MIGHT OTHERWISE ARISE FROM COURSE OF DEALING OR USAGE OF TRADE.
010 NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH RESPECT TO THE USE OF THE
011 SOFTWARE OR DOCUMENTATION. Under no circumstances shall University be liable
012 for incidental, special, indirect, direct or consequential damages or loss of
013 profits, interruption of business, or related expenses which may arise from use
014 of Software or Documentation, including but not limited to those resulting from
015 defects in Software and/or Documentation, or loss or inaccuracy of data of any
016 kind.
017
018 File: Statistics.java
019
020 */
021
022 package util;
023
024 import java.io.PrintStream;
025 import java.util.ArrayList;
026 import java.util.Collection;
027 import java.util.Collections;
028 import java.util.List;
029
030 import util.fn.FnIterable;
031 import util.fn.Lambda;
032
033 /**
034 * Abstract class for encapsulating statistics collected by the
035 * runtime system.
036 *
037 *
038 */
039 public abstract class Statistics {
040 /**
041 * Prints a summary of the statistics. The output should be short and,
042 * in most cases, at most one line long.
043 *
044 * @param out output stream
045 */
046 public abstract void dumpSummary(PrintStream out);
047
048 /**
049 * Prints the full results for the statistics.
050 *
051 * @param out output stream
052 */
053 public abstract void dumpFull(PrintStream out);
054
055 /**
056 * Merge two of the same type of statistics together. Used to aggregate
057 * statistics together.
058 *
059 * @param other another statistics object of the same type to be merged with
060 */
061 public abstract void merge(Object other);
062
063 /**
064 * Prints out appropriately formatted header for {@link #dumpFull(PrintStream)} output.
065 *
066 * @param out output stream
067 * @param header header to print
068 */
069 protected final void printFullHeader(PrintStream out, String header) {
070 out.printf("==== %s ====\n", header);
071 }
072
073 /**
074 * Prints out appropriately formatted for {@link #dumpSummary(PrintStream)} output.
075 *
076 * @param out
077 * @param header
078 */
079 protected final void printSummaryHeader(PrintStream out, String header) {
080 out.printf("%s: ", header);
081 }
082
083 /**
084 * Prints out mean, min, max, and stdev of a collection of integers.
085 *
086 * @param out output stream
087 * @param list collection of integers
088 * @param prefix string to prefix the output
089 */
090 protected final void summarizeInts(PrintStream out, Collection<Integer> list, String prefix) {
091 summarizeInts(out, list, 0, prefix);
092 }
093
094 /**
095 * Prints out mean, min, max, and stdev of a collection of integers.
096 *
097 * @param out output stream
098 * @param list collection of integers
099 * @param drop exclude the first <code>drop</code> integers from the output
100 * @param prefix string to prefix the output
101 */
102 protected final void summarizeInts(PrintStream out, Collection<Integer> list, int drop, String prefix) {
103 float[] stats = summarizeInts(list, drop);
104 if (stats == null) {
105 return;
106 }
107
108 if (stats[4] != list.size()) {
109 prefix = String.format("%sDrop first %.0f: ", prefix, list.size() - stats[4]);
110 }
111
112 out.printf("%smean: %.2f min: %.0f max: %.0f stdev: %.2f\n", prefix, stats[0], stats[1], stats[2], Math
113 .sqrt(stats[3]));
114 }
115
116 /**
117 * Returns mean, min, max, and variance of a collection of integers. This method
118 * takes a drop parameter that drops the first <i>N</i> integers before computing
119 * the summary statistics.
120 *
121 * @param list collection of integers
122 * @param drop exclude the first <code>drop</code> integers from the results
123 * @return an array of {mean, min, max, variance, number of dropped integers}
124 */
125 protected final float[] summarizeInts(Collection<Integer> list, int drop) {
126 if (list.isEmpty()) {
127 return null;
128 }
129
130 if (list.size() <= 1 + drop) {
131 drop = 0;
132 }
133
134 List<Integer> retain = new ArrayList<Integer>(list).subList(drop, list.size());
135 final float mean = CollectionMath.sumInteger(retain) / (float) retain.size();
136 int min = Collections.min(retain);
137 int max = Collections.max(retain);
138
139 float var = CollectionMath.sumFloat(FnIterable.from(retain).map(new Lambda<Integer, Float>() {
140 @Override
141 public Float call(Integer x) {
142 return (x - mean) * (x - mean);
143 }
144 })) / (retain.size() - 1);
145
146 float[] retval = new float[] { mean, min, max, var, retain.size() };
147
148 return retval;
149 }
150
151 /**
152 * Prints out mean, min, max, and stdev of a collection of longs.
153 *
154 * @param out output stream
155 * @param list collection of longs
156 * @param prefix string to prefix the output
157 */
158 protected final void summarizeLongs(PrintStream out, Collection<Long> list, String prefix) {
159 summarizeLongs(out, list, 0, prefix);
160 }
161
162 /**
163 * Prints out mean, min, max, and stdev of a collection of longs.
164 *
165 * @param out output stream
166 * @param list collection of longs
167 * @param drop exclude the first <code>drop</code> longs from the output
168 * @param prefix string to prefix the output
169 */
170 protected final void summarizeLongs(PrintStream out, Collection<Long> list, int drop, String prefix) {
171 summarizeLongs(out, list, drop, prefix, false);
172 }
173
174 /**
175 * Prints out mean, min, max, and stdev of a collection of longs.
176 *
177 * @param out output stream
178 * @param list collection of longs
179 * @param drop exclude the first <code>drop</code> longs from the output
180 * @param prefix string to prefix the output
181 * @param newLine suppress trailing newline
182 */
183 protected final void summarizeLongs(PrintStream out, Collection<Long> list, int drop, String prefix,
184 boolean suppressNewline) {
185 float[] stats = summarizeLongs(list, drop);
186 if (stats == null) {
187 return;
188 }
189
190 if (stats[4] != list.size()) {
191 prefix = String.format("%sDrop first %.0f: ", prefix, list.size() - stats[4]);
192 }
193
194 out.printf("%smean: %.2f min: %.0f max: %.0f stdev: %.2f", prefix, stats[0], stats[1], stats[2], Math
195 .sqrt(stats[3]));
196
197 if (!suppressNewline)
198 out.println();
199 }
200
201 /**
202 * Returns mean, min, max, and variance of a collection of longs. This method
203 * takes a drop parameter that drops the first <i>N</i> longs before computing
204 * the summary statistics.
205 *
206 * @param list collection of longs
207 * @param drop exclude the first <code>drop</code> longs from the results
208 * @return an array of {mean, min, max, variance, number of dropped longs}
209 */
210 protected final float[] summarizeLongs(Collection<Long> list, int drop) {
211 if (list.isEmpty()) {
212 return null;
213 }
214
215 if (list.size() <= 1 + drop) {
216 drop = 0;
217 }
218
219 List<Long> retain = new ArrayList<Long>(list).subList(drop, list.size());
220 final float mean = CollectionMath.sumLong(retain) / (float) retain.size();
221 long min = Collections.min(retain);
222 long max = Collections.max(retain);
223
224 float var = CollectionMath.sumFloat(FnIterable.from(retain).map(new Lambda<Long, Float>() {
225 @Override
226 public Float call(Long x) {
227 return (x - mean) * (x - mean);
228 }
229 })) / (retain.size() - 1);
230
231 float[] retval = new float[5];
232 retval[0] = mean;
233 retval[1] = min;
234 retval[2] = max;
235 retval[3] = var;
236 retval[4] = retain.size();
237
238 return retval;
239 }
240
241 /**
242 * Prints out mean, min, max, and stdev of a collection of floats.
243 *
244 * @param out output stream
245 * @param list collection of floats
246 * @param prefix string to prefix the output
247 */
248 protected final void summarizeFloats(PrintStream out, Collection<Float> list, String prefix) {
249 summarizeFloats(out, list, 0, prefix);
250 }
251
252 /**
253 * Prints out mean, min, max, and stdev of a collection of floats.
254 *
255 * @param out output stream
256 * @param list collection of floats
257 * @param drop exclude the first <code>drop</code> floats from the output
258 * @param prefix string to prefix the output
259 */
260 protected final void summarizeFloats(PrintStream out, Collection<Float> list, int drop, String prefix) {
261 float[] stats = summarizeFloats(list, drop);
262 if (stats == null) {
263 return;
264 }
265
266 if (stats[4] != list.size()) {
267 prefix = String.format("%sDrop first %d: ", prefix, list.size() - stats[4]);
268 }
269
270 out.printf("%smean: %.4f min: %.4f max: %.4f stdev: %.3f\n", prefix, stats[0], stats[1], stats[2], Math
271 .sqrt(stats[3]));
272 }
273
274 /**
275 * Returns mean, min, max, and variance of a collection of floats. This method
276 * takes a drop parameter that drops the first <i>N</i> floats before computing
277 * the summary statistics.
278 *
279 * @param list collection of floats
280 * @param drop exclude the first <code>drop</code> floats from the results
281 * @return an array of {mean, min, max, variance, number of dropped floats}
282 */
283 protected final float[] summarizeFloats(Collection<Float> list, int drop) {
284 if (list.isEmpty()) {
285 return null;
286 }
287
288 if (list.size() <= 1 + drop) {
289 drop = 0;
290 }
291
292 List<Float> retain = new ArrayList<Float>(list).subList(drop, list.size());
293 final float mean = CollectionMath.sumFloat(retain) / (float) retain.size();
294 float min = Collections.min(retain);
295 float max = Collections.max(retain);
296
297 float var = CollectionMath.sumFloat(FnIterable.from(retain).map(new Lambda<Float, Float>() {
298 @Override
299 public Float call(Float x) {
300 return (x - mean) * (x - mean);
301 }
302 })) / (retain.size() - 1);
303
304 float[] retval = new float[5];
305 retval[0] = mean;
306 retval[1] = min;
307 retval[2] = max;
308 retval[3] = var;
309 retval[4] = retain.size();
310
311 return retval;
312 }
313 }