View Javadoc

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 }