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 parameters
52     *          the parameters requires to population calculation
53     * @return results the results of the calculation
54     */
55    public abstract R calculatePopulation(P parameters);
56  
57    /**
58     * Calculates survival probabilities for the first half of a year.
59     * 
60     * @param target
61     *          matrix to store results in
62     * @param deathProbInfant1half
63     *          death probabilities of infants within the first 6 months
64     * @param mortality
65     *          mortality matrix
66     * @param numOfYears
67     *          number of years to be calculated
68     * @param maxAge
69     *          the maximum age
70     */
71    protected static void getFirstHalfyearSurvProb(Matrix2D target,
72        Matrix2D deathProbInfant1half, Matrix2D mortality, int numOfYears,
73        int maxAge) {
74  
75      for (int year = 0; year < numOfYears; year++) {
76  
77        double mortCurrentYear = mortality.getQuick(year, 0);
78        double mortNextYear = mortality.getQuick(year, 1);
79  
80        // Age 0 to 0.5
81        target
82            .setQuick(
83                0,
84                year,
85                1.0 - ((deathProbInfant1half.getQuick(year, 0) * (mortCurrentYear - mortNextYear)) / mortCurrentYear));
86  
87        // Other ages
88        for (int age = 1; age < maxAge; age++) {
89          mortCurrentYear = mortNextYear;
90          mortNextYear = mortality.getQuick(year, age + 1);
91          target
92              .setQuick(
93                  age,
94                  year,
95                  1.0 - ((FORCE_MORT_INTERVAL * (mortCurrentYear - mortNextYear)) / mortCurrentYear));
96        }
97      }
98    }
99  
100   /**
101    * Calculates survival probabilities for the second half of a year.
102    * 
103    * @param target
104    *          matrix to store results in
105    * @param deathProbInfant1half
106    *          death probabilities of infants within the first 6 months
107    * @param mortality
108    *          mortality matrix
109    * @param numOfYears
110    *          number of years to be calculated
111    * @param maxAge
112    *          the maximum age
113    */
114   protected static void getSecondHalfyearSurvProb(Matrix2D target,
115       Matrix2D deathProbInfant1half, Matrix2D mortality, int numOfYears,
116       int maxAge) {
117 
118     for (int year = 0; year < numOfYears; year++) {
119 
120       double deathProbInfant = deathProbInfant1half.getQuick(year, 0);
121       double mortCurrentYear = mortality.getQuick(year, 0);
122       double mortNextYear = mortality.getQuick(year, 1);
123       double mortDiff = mortCurrentYear - mortNextYear;
124 
125       // Age 0 to 0.5
126       target
127           .setQuick(
128               0,
129               year,
130               1.0 - (((1.0 - deathProbInfant) * mortDiff) / (mortCurrentYear - deathProbInfant
131                   * mortDiff)));
132 
133       // Other ages
134       for (int age = 1; age < maxAge; age++) {
135         mortCurrentYear = mortNextYear;
136         mortNextYear = mortality.getQuick(year, age + 1);
137         mortDiff = mortCurrentYear - mortNextYear;
138         target
139             .setQuick(
140                 age,
141                 year,
142                 1.0 - ((FORCE_MORT_INTERVAL * mortDiff) / (mortCurrentYear - FORCE_MORT_INTERVAL
143                     * mortDiff)));
144       }
145     }
146 
147   }
148 
149   /**
150    * Calculate survival probabilities for both halves of the year.
151    * 
152    * @param parameters
153    *          the parameters
154    * @param results
155    *          the results
156    */
157   protected static void calculateSurvivalProbabilities(
158       BasicParameters parameters, BasicResults results) {
159 
160     // First half of the year
161     getFirstHalfyearSurvProb(results.getP1f(), parameters
162         .getDeathProbInfant1halfFemale(), parameters.getMortXf(), parameters
163         .getNumOfYears(), parameters.getMaxAge());
164     getFirstHalfyearSurvProb(results.getP1m(), parameters
165         .getDeathProbInfant1halfMale(), parameters.getMortXm(), parameters
166         .getNumOfYears(), parameters.getMaxAge());
167 
168     // Second half of the year
169     getSecondHalfyearSurvProb(results.getP2f(), parameters
170         .getDeathProbInfant1halfFemale(), parameters.getMortXf(), parameters
171         .getNumOfYears(), parameters.getMaxAge());
172     getSecondHalfyearSurvProb(results.getP2m(), parameters
173         .getDeathProbInfant1halfMale(), parameters.getMortXm(), parameters
174         .getNumOfYears(), parameters.getMaxAge());
175   }
176 
177   /**
178    * Calculates target matrix by multiplying source and the field from the
179    * multiplication matrix that correspond to the year and age (column and row)
180    * above/before (- 1).
181    * 
182    * @param startAge
183    *          start age
184    * @param endAge
185    *          end age
186    * @param year
187    *          current year
188    * @param target
189    *          target matrix
190    * @param source
191    *          source matrix
192    * @param mult
193    *          multiplication matrix
194    */
195   protected static void calculateByMultMin1(int startAge, int endAge, int year,
196       Matrix2D target, Matrix2D source, Matrix2D mult) {
197     for (int age = startAge; age < endAge; age++) {
198       target.setQuick(age, year, source.getQuick(age - 1, year - 1)
199           * mult.getQuick(age - 1, year - 1));
200     }
201   }
202 
203   /**
204    * Calculates target matrix by multiplying source and the field from the
205    * multiplication matrix at the same age and year position.
206    * 
207    * @param startAge
208    *          start age
209    * @param endAge
210    *          end age
211    * @param year
212    *          current year
213    * @param target
214    *          target matrix
215    * @param source
216    *          source matrix
217    * @param mult
218    *          multiplication matrix
219    */
220   protected static void calculateByMult(int startAge, int endAge, int year,
221       Matrix2D target, Matrix2D source, Matrix2D mult) {
222     for (int age = startAge; age < endAge; age++) {
223       target.setQuick(age, year, source.getQuick(age, year)
224           * mult.getQuick(age, year));
225     }
226   }
227 
228   /**
229    * Calculates number of children in current year.
230    * 
231    * @param meanFemalePop
232    *          mean female population
233    * @param fertility
234    *          fertility
235    * @param year
236    *          current year
237    * @return number of children in current year
238    */
239   protected static double getNumOfChilds(Matrix2D meanFemalePop,
240       Matrix2D fertility, int year) {
241 
242     double numOfChilds = 0;
243 
244     for (int age = Constants.FERT_AGE_BEGIN; age < Constants.FERT_AGE_END; age++) {
245       numOfChilds += meanFemalePop.getQuick(age + 1, year)
246           * fertility.getQuick(year, age + 1);
247     }
248 
249     return numOfChilds;
250   }
251 
252   /**
253    * Calculates the first and the last age group of the mean population.
254    * 
255    * @param target
256    *          mean population matrix
257    * @param endPopulation
258    *          end population matrix
259    * @param p2
260    *          P_2 matrix (survival probabilities of infants in second half-year
261    *          of their first year)
262    * @param survO100
263    *          survival probabilities of the over-100-years-olds
264    * @param liveBirthProp
265    *          proportions of live births belonging to this sex
266    * @param year
267    *          current year
268    * @param numberOfChilds
269    *          (overall) number of children
270    * @param maxAge
271    *          the maximal age
272    */
273   protected static void calculateRestOfMeanPopulation(Matrix2D target,
274       Matrix2D endPopulation, Matrix2D p2, Matrix2D survO100,
275       Matrix2D liveBirthProp, int year, double numberOfChilds, int maxAge) {
276 
277     target.setQuick(0, year, numberOfChilds * liveBirthProp.getQuick(year, 0));
278 
279     target
280         .setQuick(maxAge, year, endPopulation.getQuick(maxAge - 1, year - 1)
281             * p2.getQuick(maxAge - 1, year)
282             + endPopulation.getQuick(maxAge, year - 1)
283             * survO100.getQuick(year, 0));
284   }
285 
286 }