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}. 29 * 30 * 2) Select the variable of interest from the {@link BasicResults} object, i.e. 31 * which aspect of the given sub-population's results are of interest (e.g. the 32 * year-end numbers of males). The result of this selection is a matrix. 33 * 34 * 3) The actual aggregation of the matrices to some result; this is the only 35 * aspect that cannot be re-used and has to be implemented for any kind of 36 * aggregation. 37 * 38 * @see BasicResults 39 * @see ResultsOfTrial 40 * 41 * @author Christina Bohk 42 * @author Roland Ewald 43 */ 44 public abstract class AbstractAggregationSelector implements 45 IAggregationSelector { 46 47 /** The basic results selector. */ 48 private final IOutputVariableSelector basicResultsSelector; 49 50 /** The trial results selector. */ 51 private final ISubPopulationSelector trialResultsSelector; 52 53 /** The generation. */ 54 private final int generation; 55 56 /** The aggregated data. */ 57 protected double[][] aggregation; // NOSONAR 58 59 /** 60 * Instantiates a new abstract aggregation selector. 61 * 62 * @param resultsSelector 63 * the results selector 64 * @param trialSelector 65 * the trial selector 66 * @param generationForSelection 67 * the generation for selection 68 */ 69 public AbstractAggregationSelector(IOutputVariableSelector resultsSelector, 70 ISubPopulationSelector trialSelector, int generationForSelection) { 71 basicResultsSelector = resultsSelector; 72 trialResultsSelector = trialSelector; 73 generation = generationForSelection; 74 } 75 76 /** 77 * Select the result of interest. 78 * 79 * @param resultsOfTrial 80 * the results of trial 81 * 82 * @return the matrix2 d 83 */ 84 protected Matrix2D select(ResultsOfTrial resultsOfTrial) { 85 return basicResultsSelector.select(trialResultsSelector.select( 86 resultsOfTrial, generation)); 87 } 88 89 /** 90 * Gets the file name. 91 * 92 * @return the file name 93 */ 94 protected String getFileName() { 95 return trialResultsSelector.getPrefix() 96 + (generation == -1 ? "" : "_gen_" + generation) + "_" 97 + basicResultsSelector.getSuffix(); 98 } 99 100 /** 101 * Reorders results according to list of indices. 102 * 103 * @param indexOrdering 104 * the index ordering 105 * @param orderedResults 106 * the ordered results 107 * 108 * @return the reordered results 109 */ 110 protected double[][] reorderResults(List<Integer> indexOrdering, 111 double[][] orderedResults) { 112 double[][] results = new double[indexOrdering.size()][orderedResults[0].length]; 113 for (int i = 0; i < indexOrdering.size(); i++) { 114 results[i] = orderedResults[indexOrdering.get(i)]; 115 } 116 return results; 117 } 118 119 /** 120 * Cuts off unused lines in data. This is necessary for any conditional 121 * results, i.e. where not all trial results are considered. 122 * 123 * @param aggregatedData 124 * the aggregation 125 * @param numOfLines 126 * the size 127 * 128 * @return the trimmed results 129 */ 130 protected double[][] cutOffUnused(double[][] aggregatedData, int numOfLines) { 131 double[][] results = new double[numOfLines][aggregatedData[0].length]; 132 System.arraycopy(aggregatedData, 0, results, 0, numOfLines); 133 return results; 134 } 135 136 /** 137 * Gets a copy of an array. 138 * 139 * @param selArray 140 * the array of selectors 141 * 142 * @return the copy of the array 143 */ 144 protected static AbstractAggregationSelector[] getCopy( 145 AbstractAggregationSelector[] selArray) { 146 if (selArray == null) { 147 return new AbstractAggregationSelector[0]; 148 } 149 AbstractAggregationSelector[] copy = new AbstractAggregationSelector[selArray.length]; 150 System.arraycopy(selArray, 0, copy, 0, selArray.length); 151 return copy; 152 } 153 154 /** 155 * Sum to array by element-wise adding all array in the first list to one 156 * another, and then subtracting all arrays in the second list. 157 * 158 * @param additionArrays 159 * the addition arrays 160 * @param subtractionArrays 161 * the subtraction arrays 162 * 163 * @return the double[] 164 */ 165 protected double[] sumPerElement(List<double[]> additionArrays, 166 List<double[]> subtractionArrays) { 167 // (additionArrays.size() > 0 ? additionArrays.get(0).length : 168 // subtractionArrays.get(0).length) 169 double[] sum = new double[aggregation[0].length]; 170 for (double[] additionData : additionArrays) { 171 for (int j = 0; j < sum.length; j++) { 172 sum[j] += additionData[j]; 173 } 174 } 175 for (double[] subtrData : subtractionArrays) { 176 for (int j = 0; j < sum.length; j++) { 177 sum[j] -= subtrData[j]; 178 } 179 } 180 return sum; 181 } 182 183 } 184 185 /** 186 * Selector for a certain element of the basic results. 187 * 188 * @see BasicResults 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 * Selector for a basic result set from the overall results of a trial. 215 * 216 * @see ResultsOfTrial 217 * @see BasicResults 218 * 219 * @author Christina Bohk 220 * @author Roland Ewald 221 */ 222 interface ISubPopulationSelector { 223 224 /** 225 * Select a {@link BasicResults} from the {@link ResultsOfTrial}, given a 226 * certain generation number. 227 * 228 * @param resultsOfTrial 229 * the results of trial 230 * @param generation 231 * the generation 232 * 233 * @return the basic results 234 */ 235 BasicResults select(ResultsOfTrial resultsOfTrial, int generation); 236 237 /** 238 * Gets the prefix describing the kind of selection. 239 * 240 * @return the prefix 241 */ 242 String getPrefix(); 243 }