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 }