On 1/29/2019 11:50 PM, Jeff Newmiller wrote:
On Tue, 29 Jan 2019, Alan Feuerbacher wrote:
After my failed attempt at using Octave, I realized that most likely
the main contributing factor was that I was not able to figure out an
efficient data structure to model one person. But C lent itself
perfectly to my idea of how to go about programming my simulation. So
here's a simplified pseudocode sort of example of what I did:
Don't model one person... model an array of people.
To model a single reproducing woman I used this C construct:
typedef struct woman {
int isAlive;
int isPregnant;
double age;
. . .
} WOMAN;
# e.g.
Nwomen <- 100
women <- data.frame( isAlive = rep( TRUE, Nwomen )
, isPregnant = rep( FALSE, Nwomen )
, age = rep( 20, Nwomen )
)
Then I allocated memory for a big array of these things, using the C
malloc() function, which gave me the equivalent of this statement:
WOMAN women[NWOMEN]; /* An array of NWOMEN woman-structs */
After some initialization I set up two loops:
for( j=0; j<numberOfYears; j++) {
for(i=1; i< numberOfWomen; i++) {
updateWomen();
}
}
for ( j in seq.int( numberOfYears ) {
# let vectorized data storage automatically handle the other for loop
women <- updateWomen( women )
}
The function updateWomen() figures out things like whether the woman
becomes pregnant or gives birth on a given day, dies, etc.
You can use your "fixed size" allocation strategy with flags indicating
whether specific rows are in use, or you can only work with valid rows
and add rows as needed for children... best to compute a logical vector
that identifies all of the birthing mothers as a subset of the data
frame, and build a set of children rows using the birthing mothers data
frame as input, and then rbind the new rows to the updated women
dataframe as appropriate. The most clear approach for individual
decision calculations is the use of the vectorized "ifelse" function,
though under certain circumstances putting an indexed subset on the left
side of an assignment can modify memory "in place" (the
functional-programming restriction against this is probably a foreign
idea to a dyed-in-the-wool C programmer, but R usually prevents you from
modifying the variable that was input to a function, automatically
making a local copy of the input as needed in order to prevent such
backwash into the caller's context).
Hi Jeff,
I'm well along in implementing your suggestions, but I don't understand
the last paragraph. Here is part of the experimenting I've done so far:
*=======*=======*=======*=======*=======*=======*
updatePerson <- function() {
ifelse( women$isAlive,
{
# Check whether to kill off this person, if she's pregnant whether
# to give birth, whether to make her pregnant again.
women$age = women$age + timeStep
# Check if the person has reached maxAge
}
)
}
calculatePopulation <- function() {
lastDate = 0
jd = 0
while( jd < maxDate ) {
for( i in seq_len( nWomen ) ) {
updatePerson();
}
todaysDateInt = floor(jd/dpy)
NAlive[todaysDateInt] = nWomen - nDead
# Do various other things
todaysDate = todaysDate + timeStep
jd = jd + timeStep
}
}
nWomen <- 5
numberOfYears <- 30
women <- data.frame( isAlive = rep_len( TRUE, nWomen )
, isPregnant = rep_len( FALSE, nWomen )
, nChildren = rep_len( 0L, nWomen )
, ageInt = rep_len( 0L, nWomen )
, age = rep_len( 0, nWomen )
, dateOfPregnancy = rep_len( 0, nWomen )
, endDateLastPregnancy = rep_len( 0.0, nWomen )
, minBirthAge = rep_len( 0, nWomen )
, maxBirthAge = rep_len( 0, nWomen )
)
# . . .
calculatePopulation()
*=======*=======*=======*=======*=======*=======*
The above code (in its complete form) executes without errors. I don't
understand at least two things:
In the updatePerson function, in the ifelse statement, how do I change
the appropriate values in the women dataframe?
I don't understand most of your last paragraph at all.
Thanks so much for your help in learning R!
Alan
---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.