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