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}. 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 }