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.simulation.calculation.deterministic;
17  
18  import p3j.experiment.results.BasicResults;
19  import p3j.misc.math.Matrix2D;
20  import p3j.simulation.calculation.deterministic.parameters.BasicParameters;
21  
22  /**
23   * Base class for population calculations.
24   * 
25   * This method does not conform to ESCA-JAVA0138, but the methods that have more
26   * than 5 parameters are very short and therefore still easy to understand.
27   * 
28   * Created on July 22, 2006
29   * 
30   * @author Christina Bohk
31   * @author Roland Ewald
32   * 
33   * @param <P>
34   *          the parameter class
35   * @param <R>
36   *          the result class
37   * 
38   */
39  public abstract class AbstractPopulation<P extends BasicParameters, R extends BasicResults> {
40  
41    /**
42     * Distribution of deaths in half years of an entire single age year. First
43     * half of deaths die in first and the other half die in last half year if set
44     * to 0.5.
45     */
46    public static final double FORCE_MORT_INTERVAL = 0.5;
47  
48    /**
49     * Calculate population.
50     * 
51     * @param subPopName
52     *          the sub-population name
53     * @param generation
54     *          the generation
55     * @param parameters
56     *          the parameters requires to population calculation
57     * @return results the results of the calculation
58     */
59    public abstract R calculatePopulation(String subPopName, int generation,
60        P parameters);
61  
62    /**
63     * Calculates survival probabilities for the first half of a year.
64     * 
65     * @param target
66     *          matrix to store results in
67     * @param deathProbInfant1half
68     *          death probabilities of infants within the first 6 months
69     * @param mortality
70     *          mortality matrix
71     * @param numOfYears
72     *          number of years to be calculated
73     * @param maxAge
74     *          the maximum age
75     */
76    protected static void getFirstHalfyearSurvProb(Matrix2D target,
77        Matrix2D deathProbInfant1half, Matrix2D mortality, int numOfYears,
78        int maxAge) {
79  
80      for (int year = 0; year < numOfYears; year++) {
81  
82        double mortCurrentYear = mortality.getQuick(year, 0);
83        double mortNextYear = mortality.getQuick(year, 1);
84  
85        // Age 0 to 0.5
86        target
87            .setQuick(
88                0,
89                year,
90                1.0 - ((deathProbInfant1half.getQuick(year, 0) * (mortCurrentYear - mortNextYear)) / mortCurrentYear));
91  
92        // Other ages
93        for (int age = 1; age < maxAge; age++) {
94          mortCurrentYear = mortNextYear;
95          mortNextYear = mortality.getQuick(year, age + 1);
96          target
97              .setQuick(
98                  age,
99                  year,
100                 1.0 - ((FORCE_MORT_INTERVAL * (mortCurrentYear - mortNextYear)) / mortCurrentYear));
101       }
102     }
103   }
104 
105   /**
106    * Calculates survival probabilities for the second half of a year.
107    * 
108    * @param target
109    *          matrix to store results in
110    * @param deathProbInfant1half
111    *          death probabilities of infants within the first 6 months
112    * @param mortality
113    *          mortality matrix
114    * @param numOfYears
115    *          number of years to be calculated
116    * @param maxAge
117    *          the maximum age
118    */
119   protected static void getSecondHalfyearSurvProb(Matrix2D target,
120       Matrix2D deathProbInfant1half, Matrix2D mortality, int numOfYears,
121       int maxAge) {
122 
123     for (int year = 0; year < numOfYears; year++) {
124 
125       double deathProbInfant = deathProbInfant1half.getQuick(year, 0);
126       double mortCurrentYear = mortality.getQuick(year, 0);
127       double mortNextYear = mortality.getQuick(year, 1);
128       double mortDiff = mortCurrentYear - mortNextYear;
129 
130       // Age 0 to 0.5
131       target
132           .setQuick(
133               0,
134               year,
135               1.0 - (((1.0 - deathProbInfant) * mortDiff) / (mortCurrentYear - deathProbInfant
136                   * mortDiff)));
137 
138       // Other ages
139       for (int age = 1; age < maxAge; age++) {
140         mortCurrentYear = mortNextYear;
141         mortNextYear = mortality.getQuick(year, age + 1);
142         mortDiff = mortCurrentYear - mortNextYear;
143         target
144             .setQuick(
145                 age,
146                 year,
147                 1.0 - ((FORCE_MORT_INTERVAL * mortDiff) / (mortCurrentYear - FORCE_MORT_INTERVAL
148                     * mortDiff)));
149       }
150     }
151 
152   }
153 
154   /**
155    * Calculate survival probabilities for both halves of the year.
156    * 
157    * @param parameters
158    *          the parameters
159    * @param results
160    *          the results
161    */
162   protected static void calculateSurvivalProbabilities(
163       BasicParameters parameters, BasicResults results) {
164 
165     // First half of the year
166     getFirstHalfyearSurvProb(results.getP1f(),
167         parameters.getDeathProbInfant1halfFemale(), parameters.getMortXf(),
168         parameters.getNumOfYears(), parameters.getMaxAge());
169     getFirstHalfyearSurvProb(results.getP1m(),
170         parameters.getDeathProbInfant1halfMale(), parameters.getMortXm(),
171         parameters.getNumOfYears(), parameters.getMaxAge());
172 
173     // Second half of the year
174     getSecondHalfyearSurvProb(results.getP2f(),
175         parameters.getDeathProbInfant1halfFemale(), parameters.getMortXf(),
176         parameters.getNumOfYears(), parameters.getMaxAge());
177     getSecondHalfyearSurvProb(results.getP2m(),
178         parameters.getDeathProbInfant1halfMale(), parameters.getMortXm(),
179         parameters.getNumOfYears(), parameters.getMaxAge());
180   }
181 
182   /**
183    * Calculates target matrix by multiplying source and the field from the
184    * multiplication matrix that correspond to the year and age (column and row)
185    * above/before (- 1).
186    * 
187    * @param startAge
188    *          start age
189    * @param endAge
190    *          end age
191    * @param year
192    *          current year
193    * @param target
194    *          target matrix
195    * @param source
196    *          source matrix
197    * @param mult
198    *          multiplication matrix
199    */
200   protected static void calculateByMultMin1(int startAge, int endAge, int year,
201       Matrix2D target, Matrix2D source, Matrix2D mult) {
202     for (int age = startAge; age < endAge; age++) {
203       target
204           .setQuick(
205               age,
206               year,
207               source.getQuick(age - 1, year - 1)
208                   * mult.getQuick(age - 1, year - 1));
209     }
210   }
211 
212   /**
213    * Calculates target matrix by multiplying source and the field from the
214    * multiplication matrix at the same age and year position.
215    * 
216    * @param startAge
217    *          start age
218    * @param endAge
219    *          end age
220    * @param year
221    *          current year
222    * @param target
223    *          target matrix
224    * @param source
225    *          source matrix
226    * @param mult
227    *          multiplication matrix
228    */
229   protected static void calculateByMult(int startAge, int endAge, int year,
230       Matrix2D target, Matrix2D source, Matrix2D mult) {
231     for (int age = startAge; age < endAge; age++) {
232       target.setQuick(age, year,
233           source.getQuick(age, year) * mult.getQuick(age, year));
234     }
235   }
236 
237   /**
238    * Calculates number of children in current year.
239    * 
240    * @param meanFemalePop
241    *          mean female population
242    * @param fertility
243    *          fertility
244    * @param year
245    *          current year
246    * @return number of children in current year
247    */
248   protected static double getNumOfChilds(Matrix2D meanFemalePop,
249       Matrix2D fertility, int year) {
250 
251     double numOfChilds = 0;
252 
253     for (int age = Constants.FERT_AGE_BEGIN; age < Constants.FERT_AGE_END; age++) {
254       numOfChilds += meanFemalePop.getQuick(age + 1, year)
255           * fertility.getQuick(year, age + 1);
256     }
257 
258     return numOfChilds;
259   }
260 
261   /**
262    * Calculates the first and the last age group of the mean population.
263    * 
264    * @param target
265    *          mean population matrix
266    * @param endPopulation
267    *          end population matrix
268    * @param p2
269    *          P_2 matrix (survival probabilities of infants in second half-year
270    *          of their first year)
271    * @param survO100
272    *          survival probabilities of the over-100-years-olds
273    * @param liveBirthProp
274    *          proportions of live births belonging to this sex
275    * @param year
276    *          current year
277    * @param numberOfChilds
278    *          (overall) number of children
279    * @param maxAge
280    *          the maximal age
281    */
282   protected static void calculateRestOfMeanPopulation(Matrix2D target,
283       Matrix2D endPopulation, Matrix2D p2, Matrix2D survO100,
284       Matrix2D liveBirthProp, int year, double numberOfChilds, int maxAge) {
285 
286     target.setQuick(0, year, numberOfChilds * liveBirthProp.getQuick(year, 0));
287 
288     target.setQuick(
289         maxAge,
290         year,
291         endPopulation.getQuick(maxAge - 1, year - 1)
292             * p2.getQuick(maxAge - 1, year)
293             + endPopulation.getQuick(maxAge, year - 1)
294             * survO100.getQuick(year, 0));
295   }
296 
297 }