1 /* 2 * Copyright 2006 - 2012 Christina Bohk and Roland Ewald 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package p3j.experiment.results; 17 18 import java.util.List; 19 20 import p3j.misc.math.Matrix2D; 21 22 /** 23 * An abstract class containing functionality all aggregation selectors may 24 * share. The basic idea here is that, for the given structure in 25 * {@link ResultsOfTrial}, aggregation is essentially a three-step process: 26 * 27 * 1) Select the sub-population and generation of interest: this means to select 28 * a {@link BasicResults} object from the lists in {@link ResultsOfTrial}. This 29 * is handled by an {@link ISubPopulationSelector}. 30 * 31 * 2) Select the variable of interest from the {@link BasicResults} object, i.e. 32 * which aspect of the given sub-population's results are of interest (e.g. the 33 * year-end numbers of males). The result of this selection is a matrix. This is 34 * handled by an {@link IOutputVariableSelector}. 35 * 36 * 3) The actual aggregation of the matrices to some result; this is the only 37 * aspect that cannot be re-used and has to be implemented for any kind of 38 * aggregation. This is handled by a sub-class of 39 * {@link AbstractAggregationSelector}. 40 * 41 * @see BasicResults 42 * @see ResultsOfTrial 43 * 44 * @author Christina Bohk 45 * @author Roland Ewald 46 */ 47 public abstract class AbstractAggregationSelector implements 48 IAggregationSelector { 49 50 /** The basic results selector. */ 51 private final IOutputVariableSelector outputVariableSelector; 52 53 /** The trial results selector. */ 54 private final ISubPopulationSelector subPopulationSelector; 55 56 /** The generation. */ 57 private final int generation; 58 59 /** The aggregated data. */ 60 protected double[][] aggregation; // NOSONAR 61 62 /** 63 * Instantiates a new abstract aggregation selector. 64 * 65 * @param outputVarSelector 66 * the results selector 67 * @param subPopSelector 68 * the trial selector 69 * @param generationForSelection 70 * the generation for selection 71 */ 72 public AbstractAggregationSelector(IOutputVariableSelector outputVarSelector, 73 ISubPopulationSelector subPopSelector, int generationForSelection) { 74 outputVariableSelector = outputVarSelector; 75 subPopulationSelector = subPopSelector; 76 generation = generationForSelection; 77 } 78 79 /** 80 * Select the result of interest. 81 * 82 * @param resultsOfTrial 83 * the results of trial 84 * 85 * @return the matrix2 d 86 */ 87 protected Matrix2D select(ResultsOfTrial resultsOfTrial) { 88 return outputVariableSelector.select(subPopulationSelector.select( 89 resultsOfTrial, generation)); 90 } 91 92 /** 93 * Gets the file name. 94 * 95 * @return the file name 96 */ 97 protected String getFileName() { 98 return subPopulationSelector.getPrefix() 99 + (generation == -1 ? "" : "_gen_" + generation) + "_" 100 + outputVariableSelector.getSuffix(); 101 } 102 103 /** 104 * Reorders results according to list of indices. 105 * 106 * @param indexOrdering 107 * the index ordering 108 * @param orderedResults 109 * the ordered results 110 * 111 * @return the reordered results 112 */ 113 protected double[][] reorderResults(List<Integer> indexOrdering, 114 double[][] orderedResults) { 115 double[][] results = new double[indexOrdering.size()][orderedResults[0].length]; 116 for (int i = 0; i < indexOrdering.size(); i++) { 117 results[i] = orderedResults[indexOrdering.get(i)]; 118 } 119 return results; 120 } 121 122 /** 123 * Cuts off unused lines in data. This is necessary for any conditional 124 * results, i.e. where not all trial results are considered. 125 * 126 * @param aggregatedData 127 * the aggregation 128 * @param numOfLines 129 * the size 130 * 131 * @return the trimmed results 132 */ 133 protected double[][] cutOffUnused(double[][] aggregatedData, int numOfLines) { 134 double[][] results = new double[numOfLines][aggregatedData[0].length]; 135 System.arraycopy(aggregatedData, 0, results, 0, numOfLines); 136 return results; 137 } 138 139 /** 140 * Gets a copy of an array. 141 * 142 * @param selArray 143 * the array of selectors 144 * 145 * @return the copy of the array 146 */ 147 protected static AbstractAggregationSelector[] getCopy( 148 AbstractAggregationSelector[] selArray) { 149 if (selArray == null) { 150 return new AbstractAggregationSelector[0]; 151 } 152 AbstractAggregationSelector[] copy = new AbstractAggregationSelector[selArray.length]; 153 System.arraycopy(selArray, 0, copy, 0, selArray.length); 154 return copy; 155 } 156 157 /** 158 * Sum to array by element-wise adding all array in the first list to one 159 * another, and then subtracting all arrays in the second list. 160 * 161 * @param additionArrays 162 * the addition arrays 163 * @param subtractionArrays 164 * the subtraction arrays 165 * 166 * @return the double[] 167 */ 168 protected double[] sumPerElement(List<double[]> additionArrays, 169 List<double[]> subtractionArrays) { 170 double[] sum = new double[aggregation[0].length]; 171 for (double[] additionData : additionArrays) { 172 for (int j = 0; j < sum.length; j++) { 173 sum[j] += additionData[j]; 174 } 175 } 176 for (double[] subtrData : subtractionArrays) { 177 for (int j = 0; j < sum.length; j++) { 178 sum[j] -= subtrData[j]; 179 } 180 } 181 return sum; 182 } 183 184 } 185 186 /** 187 * Selects a certain element (variable) from {@link BasicResults}. Used by 188 * {@link AbstractAggregationSelector}. 189 * 190 * @author Christina Bohk 191 * @author Roland Ewald 192 */ 193 interface IOutputVariableSelector { 194 195 /** 196 * Selects a certain element of the basic results. 197 * 198 * @param basicResults 199 * the basic results 200 * 201 * @return the selected data (as a matrix) 202 */ 203 Matrix2D select(BasicResults basicResults); 204 205 /** 206 * Gets the suffix describing the kind of selection. 207 * 208 * @return the suffix 209 */ 210 String getSuffix(); 211 } 212 213 /** 214 * Selects a {@link BasicResults} instance from a {@link ResultsOfTrial} 215 * instance. User by {@link AbstractAggregationSelector}. 216 * 217 * @author Christina Bohk 218 * @author Roland Ewald 219 */ 220 interface ISubPopulationSelector { 221 222 /** 223 * Select a {@link BasicResults} from the {@link ResultsOfTrial}, given a 224 * certain generation number. 225 * 226 * @param resultsOfTrial 227 * the results of trial 228 * @param generation 229 * the generation 230 * 231 * @return the basic results 232 */ 233 BasicResults select(ResultsOfTrial resultsOfTrial, int generation); 234 235 /** 236 * Gets the prefix describing the kind of selection. 237 * 238 * @return the prefix 239 */ 240 String getPrefix(); 241 }