' ----------------------------------------------------------------------------- ' CryoCare Death Rate Simulation ' Charles Platt, 4/98 ' ----------------------------------------------------------------------------- defint a-z 'All variables integers EXCEPT variable names ending 'with & character, which are long integers. randomize timer 'Reseed random number generator from system clock. orgsize=80 'Initial number of members in organization; their 'birthdates must be listed in dates: section below. thisyear=1999 'Simulation begins Jan 1, 1999; this may be changed. dim day(365) 'Random-selected day of death. dim members(101) 'Stores number of members in each age group, 0-100. '101 subscript is used for deceased members. dim chance(100) 'Chance of death in each year of a person's life; 'these figures are from 1996 but are assumed constant. restore chances 'Prepare to read actuarial table... for year=0 to 99 read chance(year) next gosub variables 'Establish initial values for all simulation runs. ' ------------------------------------------------------------- ' User inputs to establish parameters start: cls print"Cryonics Death Rate Simulation" print"by Charles Platt, 4/98" print print"This program simulates the death rate in a cryonics organization." print"Press Enter to accept default values in the list below," print"or type in your choice of values and then press Enter." print print"Number of years to look ahead:";maxyears scrnlin=9:mn=5:mx=40:gosub getinput:if k$<>"" then maxyears=v print print"Growth rate (percent) per year:";growthrate scrnlin=12:mn=0:mx=20:gosub getinput:if k$<>"" then growthrate=v print print"Median age of new members:";medianage scrnlin=15:mn=30:mx=50:gosub getinput:if k$<>"" then medianage=v print print"By repeating the simulation, we can enhance its accuracy." print"Number of times to repeat the simulation:";numruns scrnlin=19:mn=1:mx=100:gosub getinput:if k$<>"" then numruns=v print print"The year-by-year option shows a complete breakdown of each simulation." print"The summary-only option shows averaged figures from all the repeats." print"1:Show year-by-year 2:Summary only: "; k$="" while k$<>"1" and k$<>"2" locate 23,40 line input k$ wend automode$="OFF" if k$="2" then automode$="ON" ' ------------------------------------------------------------- ' Control sequence cls if automode$="ON" then locate 1,1:print"Run number:"; gosub accuvariables 'reset variables that accumulate thru many runs for runs=1 to numruns 'we will average the results of many runs gosub runvariables 'reset variables for each single run for year=1 to maxyears 'examine death rate in each year of projection gosub chancedeath 'figure chance of death for each member this year gosub yearsummary 'show what happened in this year next gosub runsummary 'summarize results of the entire simulation run if k$=chr$(27) then runs=numruns 'user-abort via the Escape key next cls if k$<>chr$(27) then gosub postmortem 'show results of all runs, averaged print"Press Enter for a new series of projections, Esc to quit: "; locate,,1 k$="" while k$<>chr$(13) and k$<>chr$(27) k$=input$(1) wend locate,,0 if k$=chr$(13) then goto start cls end ' ------------------------------------------------------------- ' Establish zero values for variables that accumulate during multiple runs accuvariables: accudied&=0 accumaxdied&=0 accumembers&=0 accuproblem&=0 return ' ------------------------------------------------------------- ' Establish default values at start of each simulation run runvariables: totalmembers&=orgsize totaldied=0 maxdied=0 totalproblem=0 for age=1 to 100 members(age)=0 next restore dates 'reload initial ages of all members for person=1 to totalmembers& read year,month age=thisyear-year 'age relative to Jan 1 of current year if month>6 then age=age-1 'round to nearest year members(age)=members(age)+1 next if automode$="OFF" then cls print" Year/Number of members dying during each year" locate 1,58:print"Simultaneous deaths" scrnlin=3 else locate 1,12 print runs end if return ' ------------------------------------------------------------- ' Choose members to die randomly during one year chancedeath: died=0 problem=0 for a=1 to 365 day(a)=0 next for age=100 to 0 step -1 'note: chance of death for age 100 alive=members(age) 'has been set to total certainty for person=1 to members(age) if rnd(1) < chance(age)/10000 then 'this selects death or no-death died=died+1 alive=alive-1 p=0 'problem detector a=1+int(365*rnd(1)) 'choose a day of death at random for b=a-2 to a+2 c=b if c<1 then c=c+365 'this messy little routine "wraps" if c>365 then c=c-365 'around from end of year to if day(c)=1 then p=1 'beginning of year where necessary next problem=problem+p 'increment number of simul deaths day(a)=1 'mark this as a death day end if next members(age+1)=alive 'surviving members are copied into next 'the next year's age group totalmembers&=totalmembers&-died members(0)=0 return ' ------------------------------------------------------------- ' Show how many members died in each year; and add new members yearsummary: totaldied=totaldied+died if maxdied0 then locate scrnlin,7 print left$(string$(died,"X"),67); if died>69 then print">"; end if locate scrnlin,75 print problem scrnlin=scrnlin+1 if scrnlin=24 then gosub newpage end if newmembers=totalmembers&*(growthrate/100) 'the rnd division fakes an approx for person=1 to newmembers 'bell curve around median age, with a=(rnd(1)*17)/(1+(rnd(1)*3)) 'a spread of +/- 16 years. if rnd(1)<.5 then age=medianage+a else age=medianage-a members(age)=members(age)+1 next totalmembers&=totalmembers&+newmembers return newpage: locate 25,1 print"Press Enter to continue..."; while input$(1)<>chr$(13) wend locate 3,1 print space$(1839); scrnlin=3 return ' ------------------------------------------------------------- ' Conclusions from this simulation runsummary: accumembers&=accumembers&+totalmembers& accumaxdied&=accumaxdied&+maxdied accudied&=accudied&+totaldied accuproblem&=accuproblem&+totalproblem if automode$="OFF" then locate 24,1 print"Number of members left alive:";totalmembers&;" "; print"Maximum deaths in one year:";maxdied; locate 25,1 print"Press Enter to continue, Esc to abort."; k$=input$(1) end if return ' ------------------------------------------------------------- ' Conclusions by averaging this whole series of simulations postmortem: print"Looking ahead";maxyears;"years, assuming";orgsize;"members in 1999" print"and a growth rate of";growthrate;"percent per year, with new members" print"sharing a median age of";medianage;"years, we should expect:" print avmembers&=accumembers&/numruns print"Number of living members at the end of the period:";avmembers& print avtotaldied=accudied&/numruns print"Number of new patients entering cryopreservation:";avtotaldied print avdied=avtotaldied/maxyears print"Average number of cryopreservations per year:";avdied print avmaxdied=accumaxdied&/numruns print"MAXIMUM number of cryopreservations in any one year:";avmaxdied print avproblem&=100*(accuproblem&/numruns) print"Of the";avtotaldied;"patients entering cryopreservation during" print"the";maxyears;"year period, on average";avproblem&/100;"case"; if avproblem&<>1 then print"s were"; else print" was"; print" simultaneous" print"(separated by less than 3 days from another case)." print pcproblem=100*(accuproblem&/accudied&) print"When dealing with any one case during this period, the chance of" print"another case occurring less than 3 days later was";pcproblem;"percent." print return ' ------------------------------------------------------------- ' User input control getinput: range$=mid$(str$(mn),2)+"-"+mid$(str$(mx),2) v=-1:k$="dummytext" while (vmx) and k$<>"" locate scrnlin,1 print"Press Enter to accept current value, or type new value (";range$;"): "; line input k$ if k$<>"" then v=val(k$) wend return '------------------------------------------------------------- ' Chance of death in each year of life, from birth (year 0) to 99, ' expressed in number of deaths per 10,000 people, rounded to nearest 5. ' Figures above age 85 were extrapolated by curve-fitting. ' Chance of death in the year following age 100 is arbitrarily 100 percent. ' Source: Statistical Abstract of the United States, 1997. chances: data 80, 5, 5, 5, 5, 0, 0, 0, 0, 0 data 0, 0, 0, 5, 5, 5, 10, 10, 10, 10 data 10, 10, 10, 10, 10, 10, 10, 10, 15, 15 data 15, 15, 15, 15, 20, 20, 20, 20, 20, 25 data 25, 25, 25, 30, 30, 30, 35, 35, 40, 45 data 50, 50, 55, 60, 65, 75, 80, 85, 95, 105 data 115, 130, 140, 150, 160, 175, 190, 205, 220, 240 data 265, 290, 310, 330, 360, 390, 425, 460, 500, 550 data 600, 650, 700, 760, 850, 920, 1050, 1170, 1300, 1450 data 1600, 1770, 1950, 2150, 2400, 2680, 3000, 3450, 4000, 4900 data 10000 ' ------------------------------------------------------------- ' CryoCare member birth dates in year,month format (80 members) dates: data 1914,06, 1915,10, 1916,11, 1922,03, 1925,10, 1926,09, 1928,09, 1929,09 data 1930,04, 1932,08, 1933,07, 1934,05, 1936,04, 1936,10, 1936,11, 1939,07 data 1941,04, 1941,12, 1942,01, 1942,07, 1942,12, 1943,05, 1943,11, 1944,07 data 1945,01, 1945,04, 1945,04, 1945,08, 1945,09, 1946,05, 1946,08, 1946,11 data 1946,12, 1947,04, 1947,07, 1948,03, 1948,12, 1949,01, 1949,05, 1949,07 data 1949,08, 1949,09, 1949,10, 1950,03, 1950,04, 1950,04, 1951,05, 1951,05 data 1951,08, 1952,01, 1954,01, 1954,02, 1954,07, 1954,09, 1954,11, 1954,11 data 1955,04, 1956,02, 1956,03, 1957,03, 1957,05, 1957,05, 1958,03, 1959,03 data 1960,07, 1960,12, 1961,03, 1961,05, 1962,08, 1963,05, 1963,06, 1963,07 data 1965,02, 1965,12, 1967,05, 1967,06, 1967,10, 1968,07, 1972,12, 1994,10 ' ------------------------------------------------------------- ' Explanation of variables in this program variables: k$="" 'all-purpose user-input string automode$="" 'if OFF, program shows detailed data; else just summaries chartbar$="" 'for graphical display of number of deaths per year range$="" 'to display range of min/max acceptable input values a=0:b=0 'all-purpose loop variables age=0 'figures age from birthdates in data table maxyears=20 'number of years we will look ahead in the simulation growthrate=3 'percent growth per year during each run of simulation year=0 'counts years from 1 to maxyears; also reads year from data month=0 'reads month from data newmembers=0 'number of new members we expect to add, per year numruns=10 'number of times to run the simulation runs=0 'counts iterations of simulation, from 1 to numrums totalmembers&=0 'the number of living members at end of each year accumembers&=0 'accumulates number of members from ALL simulation runs avmembers&=0 'final number of members averaged from ALL simulation runs member=0 'identifies each member in turn maxdied=0 'maximum number of members who died in any year of a simulation accumaxdied&=0 'accumulates maximum annual deaths through ALL simulation runs avmaxdied=0 'maximum deaths in any year averaged from ALL simulation runs scrnlin=0 'counts printed screen lines, starts new screen if necessary v=0 'value for variable obtained via user input died=0 'counts people who died in each year of a simulation alive=0 'number of people at a certain age alive at start of one year totaldied=0 'total number of patients dying in each simulation run accudied&=0 'accumulates number of patients from ALL simulation runs avtotaldied=0 'averaged total number of members dying during a simulation avdied=0 'averaged number of cases per year, from all simulations problem=0 'number of problem cases (simultaneous death) in each year totalproblem=0 'total number of problem cases in each simulation run accuproblem&=0 'accumulates number of problem cases through ALL simulation runs avproblem&=0 'average number of problem (simultaneous) cases per year avmaxproblem=0 'maximum problem cases per year, averaged from ALL simulations medianage=40 'median age of new members, allowing a spread of +/- 16 years return