Abstract
The models developed in the three previous chapters are “cohort” models, in which all the actors in the simulation are born at the same time. This cohort approach is the principle behind life tables. Although this type of modelling is interesting and very useful for analytical purposes, it cannot be used for simulating real populations exposed to the full range of demographic forces such as immigration and fertility.
Access this chapter
Tax calculation will be finalised at checkout
Purchases are for personal use only
Notes
- 1.
The file code is not shown at the end of the chapter.
- 2.
This argument is also valid for the mobility event we added in Chap. 3. We assumed there that the exit rates were real rates (rather than annual rates or probabilities). In fact the inputs are almost always annual rates, so we have to take the necessary precautions to avoid double counting of repeatable events. Having said this, where rates are low the probability of double counting is very small and the corresponding impact on the results is negligible.
- 3.
- 4.
Not to be confused with the definition of an event in the actor Person.
Author information
Authors and Affiliations
Appendices
Appendices
4.1.1 Appendix 4.1 PersonCore.mpp
Code Sections: Header, Parameters, Actor Person and functions
1 classification SEX{ S_FEM, S_MAL }; 2 3 range AGE{ 0, 110 }; 4 5 partition AGE_GROUP{ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 6 70, 75, 80, 85 }; 7 8 partition YEAR5{ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 9 75, 80, 85, 90, 95, 100 }; 10 11 parameters 12 { 13 //EN Annual hazard of death according to sex and age 14 double MortalityHazard[SEX][AGE][PROV]; 15 int AgeMax; // Maximum lifespan 16 double ProbabilityMale; // Probability of male birth 17 int horizon; // Maximum duration of simulation 18 19 }; 20 21 actor Person //EN Individual 22 { 23 24 //EN Alive 25 logical alive = {TRUE}; 26 27 SEX sex; // Sex state variable 28 29 // Age state variable, auto-increment 30 AGE age_int = COERCE(AGE, self_scheduling_int(age)); 31 32 // Year state variable, auto-increment 33 int year_int = self_scheduling_int(time); 34 35 36 event timeMortalityEvent, MortalityEvent; //ENMortality event 37 38 //LABEL(Person.Start, EN) Starts the actor 39 // The start function now takes three arguments: 40 // 1) dTimeStart is the exact time at which a simulation starts 41 // 2) ActorType tells if the simulated actor is part of the 42 // starting cohort or born in the model 43 // 3) prMother is a pointer to the actor who gave birth to the 44 // new actor 45 void Start(double dTimeStart, int ActorType, Person *prMother); 46 47 //LABEL(Person.Finish, EN) Finishes the actor 48 void Finish(); 49 }; 50 51 // The time function of MortalityEvent 52 TIME Person::timeMortalityEvent() 53 { 54 TIME tEventTime = TIME_INFINITE; 55 56 // If max age or horizon is reached, death event occurs immediately 57 if (age_int == AgeMax | year_int >= horizon) 58 { 59 tEventTime = WAIT(0); 60 } 61 else { 62 // Draw a random waiting time to death from 63 // an exponential distribution based on the 64 // constant hazard MortalityHazard. 65 tEventTime = WAIT(-TIME(log(RandUniform(1)) / 66 MortalityHazard[sex][age_int][prov])); 67 } 68 69 return tEventTime; 70 } 71 72 // The implement function of MortalityEvent 73 void Person::MortalityEvent() 74 { 75 if (year_int<Horizon) {alive = FALSE;}; 76 77 // Remove the actor from the simulation. 78 Finish(); 79 } 80 81 // The start function now takes three arguments: 82 // 1) dTimeStart is the exact time at which a simulation starts 83 // 2) ActorType tells if the simulated actor is part of the 84 // starting cohort or born in the model 85 // 3) prMother is a pointer to the actor who gave birth to the 86 // new actor 87 void Person::Start(double dTimeStart, int ActorType, Person *prMother) 88 { 89 // Modgen initializes all actor variables 90 // before the code in this function is executed. 91 92 age = 0; 93 // Sets continuous time. time>0 if actor is born during simulation 94 time = dTimeStart; 95 96 // Sex is randomly attributed according to parameter ProbabilityMale 97 if (RandUniform(2) < ProbabilityMale) 98 { 99 sex = S_MAL; 100 } 101 else 102 { 103 sex = S_FEM; 104 }; 105 106 // ActorType = 0 (actor from the starting cohort) 107 // ActorType = 1 (actor born in the simulation) 108 109 if (ActorType == 0) { 110 111 // The following lines attribute province of birth 112 // and province of residence to the actor 113 114 // A temporary variable to store the province value 115 int prov_temp = { 0 }; 116 // Lookup picks a random province 117 // according to cumrate distribution 118 Lookup_ProvBirth(RandUniform(5), &prov_temp); 119 // Casts the (integer) prov_temp value into the 120 // prov state variable (of PROV type) 121 prov = (PROV)prov_temp; 122 // Province of residence at birth is the province of birth 123 prov_birth = prov; 124 } 125 126 else { 127 128 if (prMother != NULL) { 129 130 lMother = prMother; 131 prov = lMother->prov; 132 prov_birth = prov; 133 134 }; 135 136 }; 137 138 } 139 140 /*NOTE(Person.Finish, EN) 141 The Finish function terminates the simulation of an actor. 142 */ 143 void Person::Finish() 144 { 145 // After the code in this function is executed, 146 // Modgen removes the actor from tables and from the simulation. 147 // Modgen also recuperates any memory used by the actor. 148 }
4.1.2 Appendix 4.2 Fertility.mpp
Code Sections: Header, Parameters, Actor Person and functions
1 /* 2 This module contains the fertility event and related parameters 3 In the fertility event, a Modgen link is created between the 4 parent and the actor 5 */ 6 7 link Person.lMother; // Link to the mother 8 range AGE_FERTILE{ 15, 49 }; // Fertile ages 9 10 parameters 11 { 12 13 double FertilityHazard[AGE_FERTILE][PROV]; // Fertility hazard 14 15 }; 16 17 actor Person // Individual 18 { 19 20 int last_age_fertile = { 0 }; // Age of actor at last birth 21 22 event TimeFertilityEvent, FertilityEvent; // Fertility event (birth) 23 24 }; 25 26 // Fertility event 27 TIME Person::TimeFertilityEvent() 28 { 29 TIME tEventTime = TIME_INFINITE; 30 31 // A birth can take place if actor is female and fertile (between 32 // 15 and 49 years old) 33 // An actor cannot give birth twice in the same year 34 35 if (age_int >= MIN(AGE_FERTILE) && age_int <= MAX(AGE_FERTILE) && 36 sex == S_FEM && last_age_fertile != age_int) 37 { 38 39 tEventTime = WAIT(-TIME(log(RandUniform(6)) / (-log(1 – 40 FertilityHazard[RANGE_POS(AGE_FERTILE, age_int)][prov] 41 - 0.0000000001)))); 42 43 }; 44 45 return tEventTime; 46 47 } 48 49 void Person::FertilityEvent() 50 { 51 52 Person *prChild = { NULL }; // Creates a new actor 53 prChild = new Person(); // Instantiation of the class Person 54 prChild->Start(time, 1, this); // Starts simulating the new actor 55 last_age_fertile = age_int; // Indicates age of actor at last birth 56 57 }
4.1.3 Appendix 4.3 Tables.mpp
1 table Person FertilityBirths // Births and age-specific fertility rates 2 [age_int >= MIN(AGE_FERTILE) && age_int <= MAX(AGE_FERTILE)] 3 { 4 { 5 // Number of births 6 changes(last_age_fertile), 7 // Annual fertility rates decimals=4 8 changes(last_age_fertile) / duration(sex, S_FEM) 9 } 10 11 *split(year_int, YEAR5) + // Year 12 *age_int + // Age 13 *prov + // Province 14 }; 15 16 table Person AvAgeCB // Average age at childbirth 17 { 18 { 19 // Average age at childbirth decimals=4 20 value_at_changes(last_age_fertile, age) 21 / changes(last_age_fertile) 22 } 23 24 *prov + //Province 25 }; 26 27 table Person Demography // Population 28 { 29 { 30 // Population size at the end of period 31 value_at_changes(split(year_int, YEAR5), alive), 32 entrances(alive, FALSE), // Deaths 33 changes(last_age_fertile), // Births 34 changes(prov), // Exits 35 event(changes(prov)) // Entrances 36 } 37 38 *prov + //Province 39 *split(age_int, AGE_GROUP) + // Age 40 *split(year_int, YEAR5) // Year 41 42 };
4.1.4 Appendix 4.4 ModgenExample.mpp
1 //LABEL(ModgenExample, EN) Core simulation functions 2 3 /* NOTE(ModgenExample, EN) 4 This module contains core simulation functions and definitions. 5 */ 6 7 // The model version number 8 version 1, 0, 0, 0; 9 10 // The model type 11 model_type case_based; 12 13 // The data type used to represent time 14 time_type double; 15 16 // Supported languages 17 languages { 18 EN // English 19 }; 20 21 // The CaseSimulation function simulates a single case, 22 // and is called by the Simulation function declared later 23 // in this module. 24 25 void CaseSimulation( ) 26 { 27 // Initialize the first actor in the case. 28 Person *poFirstActor = new Person(); 29 poFirstActor->Start(0, 0, NULL ); 30 31 // Continue processing events until there are no more. 32 // Model code is responsible for ending the case by calling 33 // Finish on all existant actors. 34 35 // The Modgen run-time implements the global 36 // event queue gpoEventQueue. 37 while ( !gpoEventQueue->Empty() ) 38 { 39 // The global variables gbCancelled and gbErrors 40 // are maintained by the Modgen run-time. 41 if ( gbCancelled || gbErrors ) 42 { 43 // The user cancelled the simulation, 44 // or run-time errors occurred. 45 // Terminate the case immediately. 46 gpoEventQueue->FinishAllActors(); 47 } 48 else 49 { 50 // Age all actors to the time of the next event. 51 gpoEventQueue->WaitUntil( gpoEventQueue->NextEvent() ); 52 53 // Implement the next event. 54 gpoEventQueue->Implement(); 55 } 56 } 57 58 // Note that Modgen handles memory cleanup when 59 // Finish is called on an actor. 60 } 61 62 63 // The Simulation function is called by Modgen to simulate a set of cases. 64 void Simulation() 65 { 66 // counter for cases simulated 67 long lCase = 0; 68 69 // The Modgen run-time implements CASES (used below), 70 // which supplies the number of cases to simulate in a particular thread. 71 // 72 // The following loop for cases is stopped if 73 // - the simulation is cancelled by the user, 74 // with partial reports (gbInterrupted) 75 // - the simulation is cancelled by the user, 76 // with no partial reports (gbCancelled) 77 // - a run-time error occurs (gbErrors) 78 // 79 // The global variables gbInterrupted, gbCancelled and gbErrors 80 // are maintained by the Modgen run-time. 81 for ( lCase = 0; lCase < CASES() && !gbInterrupted && !gbCancelled 82 && !gbErrors; lCase++ ) 83 { 84 // Simulate a case. 85 86 // Tell the Modgen run-time to prepare to simulate a new case. 87 StartCase(); 88 89 // Call the CaseSimulation function defined earlier in this module. 90 CaseSimulation(); 91 92 // Tell the Modgen run-time that the case has been completed. 93 SignalCase(); 94 } 95 }
Rights and permissions
Copyright information
© 2017 Springer International Publishing Switzerland
About this chapter
Cite this chapter
Bélanger, A., Sabourin, P. (2017). Modelling Fertility. In: Microsimulation and Population Dynamics. The Springer Series on Demographic Methods and Population Analysis, vol 43. Springer, Cham. https://doi.org/10.1007/978-3-319-44663-9_4
Download citation
DOI: https://doi.org/10.1007/978-3-319-44663-9_4
Published:
Publisher Name: Springer, Cham
Print ISBN: 978-3-319-44662-2
Online ISBN: 978-3-319-44663-9
eBook Packages: Social SciencesSocial Sciences (R0)