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.simulation;
17  
18  import java.util.List;
19  
20  import junit.framework.TestCase;
21  
22  import org.jamesii.SimSystem;
23  import org.jamesii.core.util.misc.CSVReader;
24  import org.jamesii.core.util.misc.Strings;
25  
26  import p3j.misc.MatrixDimension;
27  import p3j.misc.math.Matrix;
28  import p3j.misc.math.Matrix2D;
29  import p3j.pppm.parameters.Parameter;
30  import p3j.pppm.parameters.ParameterAssignment;
31  import p3j.pppm.parameters.ParameterInstance;
32  import p3j.pppm.parameters.ParameterType;
33  import p3j.pppm.parameters.Population;
34  
35  /**
36   * Simple test for deviation calculation.
37   * 
38   * @author Christina Bohk
39   * @author Roland Ewald
40   * 
41   */
42  public class CheckDeviationCalculator extends TestCase {
43  
44    /** The number of years for the test matrix. */
45    static final int YEARS = 50;
46  
47    /** The number of ages for the test matrix. */
48    static final int AGES = 99;
49  
50    /** The value with which the original matrix shall be filled. */
51    static final int FIXED_AMOUNT = 100000;
52  
53    /**
54     * A large deviation, to check corner cases.
55     */
56    static final double LARGE_DEVIATION = 10.;
57  
58    /**
59     * The default standard deviation.
60     */
61    static final double DEFAULT_DEVIATION = 0.01;
62  
63    /**
64     * The file that contains the test data.
65     */
66    static final String FILE_TEST_DATA = "./p3j/simulation/surv_assumption_natives_male_blue.txt";
67  
68    /**
69     * The original matrix.
70     */
71    Matrix2D originalMatrix;
72  
73    /**
74     * The parameter assignment to pass.
75     */
76    ParameterAssignment assignment;
77  
78    /*
79     * (non-Javadoc)
80     * 
81     * @see junit.framework.TestCase#setUp()
82     */
83    @Override
84    public void setUp() {
85      originalMatrix = new Matrix2D(YEARS, AGES);
86      for (int i = 0; i < YEARS; i++) {
87        for (int j = 0; j < AGES; j++) {
88          originalMatrix.setQuick(i, j, FIXED_AMOUNT);
89        }
90      }
91  
92      assignment = new ParameterAssignment(new ParameterInstance(0,
93          new Parameter(0, true, "Some parameter", MatrixDimension.YEARS,
94              MatrixDimension.AGES, Population.NATIVES)), "test", "", 1.0, 0.0,
95          new Matrix(originalMatrix));
96      assignment.setDeviation(DEFAULT_DEVIATION);
97    }
98  
99    /**
100    * Tests case when there is no deviation calculation (because deviation is 0).
101    */
102   public void testNoDeviationCalculation() {
103     assignment.setDeviation(0.);
104     Matrix2D deviationMatrix = DeviationCalculator
105         .calculateAssignmentDeviation(assignment, SimSystem.getRNGGenerator()
106             .getNextRNG());
107     for (int i = 0; i < YEARS; i++) {
108       for (int j = 0; j < AGES; j++) {
109         assertEquals(originalMatrix.get(i, j), deviationMatrix.get(i, j));
110       }
111     }
112   }
113 
114   /**
115    * Test deviation calculation.
116    */
117   public void testDeviationCalculation() {
118     assignment.setDeviation(0.2);
119 
120     Matrix2D deviationMatrix = DeviationCalculator
121         .calculateAssignmentDeviation(assignment, SimSystem.getRNGGenerator()
122             .getNextRNG());
123 
124     // First year should always stay the same
125     for (int j = 0; j < AGES; j++) {
126       assertEquals(originalMatrix.get(0, j), deviationMatrix.get(0, j));
127     }
128 
129     // Everything else should be different
130     for (int i = 1; i < YEARS; i++) {
131       for (int j = 0; j < AGES; j++) {
132         assertFalse(Double.compare(originalMatrix.get(i, j),
133             deviationMatrix.get(i, j)) == 0);
134       }
135     }
136 
137     // Just for manual checks
138     System.out.println(Strings.displayMatrix(deviationMatrix.toArray()));
139   }
140 
141   /**
142    * Tests calculation with large standard deviation.
143    */
144   public void testLargeDeviationCalculation() {
145     assignment.setDeviation(LARGE_DEVIATION);
146     Matrix2D deviationMatrix = DeviationCalculator
147         .calculateAssignmentDeviation(assignment, SimSystem.getRNGGenerator()
148             .getNextRNG());
149 
150     // Results should never be negative.
151     for (int i = 1; i < YEARS; i++) {
152       for (int j = 0; j < AGES; j++) {
153         assertTrue(deviationMatrix.get(i, j) >= 0);
154       }
155     }
156 
157     // Just for manual checks
158     System.out.println(Strings.displayMatrix(deviationMatrix.toArray()));
159   }
160 
161   /**
162    * Test mortality deviation.
163    */
164   public void testMortalityDeviation() {
165 
166     Matrix mortMatrix = new Matrix(getTestMatrixForMortality());
167     Matrix2D mortalityMatrix = mortMatrix.getValue();
168 
169     ParameterAssignment mortAssignment = new ParameterAssignment(
170         new ParameterInstance(0, new Parameter(0, true,
171             "Some parameter regarding " + ParameterType.SURVIVORS_AGE_X,
172             MatrixDimension.YEARS, MatrixDimension.AGES, Population.NATIVES)),
173         "test", "", 1.0, 0.0, mortMatrix);
174     mortAssignment.setDeviation(DEFAULT_DEVIATION);
175 
176     Matrix2D deviationMatrix = DeviationCalculator
177         .calculateAssignmentDeviation(mortAssignment, SimSystem
178             .getRNGGenerator().getNextRNG());
179 
180     // First year should stay the same
181     for (int age = 0; age < mortAssignment.getMatrix().getValue().columns(); age++) {
182       assertEquals(mortalityMatrix.get(0, age), deviationMatrix.get(0, age));
183     }
184 
185     // 0-aged should always stay the same
186     for (int year = 0; year < mortAssignment.getMatrix().getValue().rows(); year++) {
187       assertEquals(mortalityMatrix.get(year, 0), deviationMatrix.get(year, 0));
188     }
189 
190     // Everything else should be different
191     for (int year = 1; year < mortAssignment.getMatrix().getValue().rows(); year++) {
192       for (int age = 1; age < mortAssignment.getMatrix().getValue().columns(); age++) {
193         assertFalse(Double.compare(mortalityMatrix.getQuick(year, age),
194             deviationMatrix.getQuick(year, age)) == 0);
195       }
196     }
197 
198     System.out.println(Strings.displayMatrix(deviationMatrix.toArray()));
199   }
200 
201   /**
202    * Gets the test matrix for mortality. Is transposed while being read.
203    * 
204    * @return the test matrix for mortality
205    */
206   private Matrix2D getTestMatrixForMortality() {
207 
208     List<String[]> data = (new CSVReader()).read(FILE_TEST_DATA, false);
209     int years = data.get(0).length - 1;
210     int ages = data.size();
211 
212     double[][] matrix = new double[years][ages];
213     for (int age = 0; age < data.size(); age++) {
214       for (int year = 0; year < years; year++) {
215         matrix[year][age] = Double.parseDouble(data.get(age)[year + 1]);
216       }
217     }
218 
219     System.out.println(Strings.displayMatrix(matrix));
220 
221     return new Matrix2D(matrix, "", "");
222   }
223 }