package stat; import java.awt.*; import java.io.*; import parameters.Parameter; import parameters.ParameterSet; import parameters.ParameterSetArray; import iterators.MultiFloatReturn; import main.GlobalIO; import main.MoreMath; /** Calculates a number of summary statistics for the parameter sets, including average, std. dev, min, and max values of each parameter; proportion of total range covered by each parameter; maximum distance between parameter sets. The last statistic can take a little while to calculate (goes as square of num sets). */ public class SummaryStat extends Stat implements Runnable { public SummaryStat() {} public void calculateStat() { int i; if(paramSets == null) { GlobalIO.printlnGeneral("No Cam loaded - Stat did nothing"); return; } try { makeOutputFile(); if(paramSets.getNumSets() > 100) GlobalIO.printlnGeneral("Starting summary - this may take a while", false); else GlobalIO.printlnGeneral("Starting summary", false); prototype = paramSets.getPrototype(); if(prototype == null) prototype = paramSets.goToBeginning(); if(prototype == null) { closeOutputFile(); return; } // Nothing in cam file // five slots for each param = num_values, sum, sum_sqr, min, max double [] avgs = new double[prototype.getNumParams() * 5]; for(i = 0; i < prototype.getNumParams(); i++) { avgs[i*5+0] = avgs[i*5+1] = avgs[i*5+2] = avgs[i*5+4] = 0; avgs[i*5+3] = 987654321; // Something big that's unlikely to ever be a real value } // four slots for overall averages = proportion_min, proportion_max, proportion, max_ratio double [] cross_param_avgs = new double[9]; for(i = 0; i < 9; i++) cross_param_avgs[i] = 0; // Go through all the param sets and accumulate stats ParameterSet set = paramSets.goToBeginning(); while(set != null) { for(i = 0; i < set.getNumParams(); i++) { try { int pos = prototype.getPosition(set.getName(i)); float val = set.getValue(i); avgs[pos*5+0]++; avgs[pos*5+1] += val; avgs[pos*5+2] += val * val; if(val < avgs[pos*5+3]) avgs[pos*5+3] = val; if(avgs[pos*5+4] < val) avgs[pos*5+4] = val; } catch(Exception e) {} // Missing from prototype, so don't do anything } set = paramSets.getNextSet(); } printlnToFile("Parameter\tAverage\tStdDev\tMin\tMax\tProportionMin\tProportionMax\tProportion\tMaxRatio"); // Print headings for(i = 0; i < prototype.getNumParams(); i++) { if(avgs[i*5+0] > 0) { // an instance of this parameter had a value if(avgs[i*5+3] == avgs[i*5+4]) avgs[i*5+2] = 0; // If there was no variation, this can be screwy because of round-off error else avgs[i*5+2] = getStdDev(avgs[i*5+1], avgs[i*5+2], avgs[i*5+0]); avgs[i*5+1] /= avgs[i*5+0]; // Print the average, std. dev., min, and max for this parameter printToFile(prototype.getName(i) + "\t" + avgs[i*5+1] + "\t" + avgs[i*5+2] + "\t" + avgs[i*5+3] + "\t" + avgs[i*5+4]); // Print min and max as proportions of total range for this parameter if(prototype.getUpperBound(i) == prototype.getLowerBound(i)) printToFile("\t1\t1"); else { printToFile("\t" + ((avgs[i*5+3] - prototype.getLowerBound(i)) / (prototype.getUpperBound(i) - prototype.getLowerBound(i)))); printToFile("\t" + ((avgs[i*5+4] - prototype.getLowerBound(i)) / (prototype.getUpperBound(i) - prototype.getLowerBound(i)))); cross_param_avgs[0] ++; // Num params with upperbound != lowerbound cross_param_avgs[1] += (avgs[i*5+3] - prototype.getLowerBound(i)) / (prototype.getUpperBound(i) - prototype.getLowerBound(i)); cross_param_avgs[2] += MoreMath.sqr((avgs[i*5+3] - prototype.getLowerBound(i)) / (prototype.getUpperBound(i) - prototype.getLowerBound(i))); cross_param_avgs[3] += (avgs[i*5+4] - prototype.getLowerBound(i)) / (prototype.getUpperBound(i) - prototype.getLowerBound(i)); cross_param_avgs[4] += MoreMath.sqr((avgs[i*5+4] - prototype.getLowerBound(i)) / (prototype.getUpperBound(i) - prototype.getLowerBound(i))); } if(avgs[i*5+3] == avgs[i*5+4]) printToFile("\t0"); else if(avgs[i*5+3] <= 0 || avgs[i*5+4] <= 0) printToFile("\tUndefined"); else if(prototype.getUpperBound(i) == prototype.getLowerBound(i)) printToFile("\t0"); else { printToFile("\t" + (avgs[i*5+4] / avgs[i*5+3]) / (prototype.getUpperBound(i) / prototype.getLowerBound(i))); cross_param_avgs[5] += (avgs[i*5+4] / avgs[i*5+3]) / (prototype.getUpperBound(i) / prototype.getLowerBound(i)); cross_param_avgs[6] += MoreMath.sqr((avgs[i*5+4] / avgs[i*5+3]) / (prototype.getUpperBound(i) / prototype.getLowerBound(i))); } if(avgs[i*5+3] == 0) printlnToFile("\tUndefined"); else { printlnToFile("\t" + (avgs[i*5+4] / avgs[i*5+3])); cross_param_avgs[7] += (avgs[i*5+4] / avgs[i*5+3]); cross_param_avgs[8] += MoreMath.sqr((avgs[i*5+4] / avgs[i*5+3])); } } } printlnToFile(""); printToFile("Averages\t-\t-\t-\t-"); printToFile("\t" + (cross_param_avgs[1] / cross_param_avgs[0]) + "\t" + getStdDev(cross_param_avgs[1], cross_param_avgs[2], cross_param_avgs[0])); printToFile("\t" + (cross_param_avgs[3] / cross_param_avgs[0]) + "\t" + getStdDev(cross_param_avgs[3], cross_param_avgs[4], cross_param_avgs[0])); printToFile("\t" + (cross_param_avgs[5] / cross_param_avgs[0]) + "\t" + getStdDev(cross_param_avgs[5], cross_param_avgs[6], cross_param_avgs[0])); printlnToFile("\t" + (cross_param_avgs[7] / cross_param_avgs[0]) + "\t" + getStdDev(cross_param_avgs[7], cross_param_avgs[8], cross_param_avgs[0])); printlnToFile(""); // Calculate the max distance between two param sets printlnToFile("Maximum distance between sets = " + paramSets.calculateDistancesToSet(paramSets).f2); closeOutputFile(); } catch(Exception e) { System.out.println("Error in AveragesStat: " + e.toString()); } System.out.println("Finished making summary"); } }