Problem 7 simulates the growth of a virus in a subject. Due to odds of multiplying or self healing, the virus population varies greatly up and down. In this simulation, the graph shows that this virus does not exceed 15% of host cells. This is due to the inverse relationship between the number of virus cells and their likelihood to reproduce: self.maxBirthProb * (1 – popDensity). This would not be so bad for the virus if it were not for the probability of virus cells to cleanse themselves (5%).
Problem 7b computationally shows the odds of rolling a Yahtzee, five six-sided die landing on the same number. Mathematically we know this is 6/7776, the number of desired outcomes over the number of possible outcomes. By simulating a number of trials (20) with increasing numbers of dice rolls, we can see that as our rolls exceed 100K and grow to 2^20, the mean of the resulting ratios becomes very close to the number we expect, 0.00077.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# Problem Set 7: Simulating the Spread of Disease and Virus Population Dynamics # Name: Casey # Collaborators: # Time: 2hr import numpy import random import pylab ''' Begin helper code ''' class NoChildException(Exception): """ NoChildException is raised by the reproduce() method in the SimpleVirus and ResistantVirus classes to indicate that a virus particle does not reproduce. You can use NoChildException as is, you do not need to modify/add any code. """ ''' End helper code ''' # # PROBLEM 1 # class SimpleVirus(object): """ Representation of a simple virus (does not model drug effects/resistance). """ def __init__(self, maxBirthProb, clearProb): """ Initialize a SimpleVirus instance, saves all parameters as attributes of the instance. maxBirthProb: Maximum reproduction probability (a float between 0-1) clearProb: Maximum clearance probability (a float between 0-1). """ # TODO assert isinstance(maxBirthProb, float) and 0 <= maxBirthProb <= 1 assert isinstance(clearProb, float) and 0 <= maxBirthProb <= 1 self.maxBirthProb = maxBirthProb self.clearProb = clearProb def doesClear(self): """ Stochastically determines whether this virus particle is cleared from the patient's body at a time step. returns: True with probability self.clearProb and otherwise returns False. """ # TODO if random.random() < self.clearProb: return True else: return False def reproduce(self, popDensity): """ Stochastically determines whether this virus particle reproduces at a time step. Called by the update() method in the SimplePatient and Patient classes. The virus particle reproduces with probability self.maxBirthProb * (1 - popDensity). If this virus particle reproduces, then reproduce() creates and returns the instance of the offspring SimpleVirus (which has the same maxBirthProb and clearProb values as its parent). popDensity: the population density (a float), defined as the current virus population divided by the maximum population. returns: a new instance of the SimpleVirus class representing the offspring of this virus particle. The child should have the same maxBirthProb and clearProb values as this virus. Raises a NoChildException if this virus particle does not reproduce. """ # TODO if random.random() < self.maxBirthProb * (1 - popDensity): return SimpleVirus(self.maxBirthProb, popDensity) else: NoChildException() class SimplePatient(object): """ Representation of a simplified patient. The patient does not take any drugs and his/her virus populations have no drug resistance. """ def __init__(self, viruses, maxPop): """ Initialization function, saves the viruses and maxPop parameters as attributes. viruses: the list representing the virus population (a list of SimpleVirus instances) maxPop: the maximum virus population for this patient (an integer) """ # TODO assert isinstance(viruses, list) assert isinstance(maxPop, int) self.viruses = viruses self.maxPop = maxPop def getTotalPop(self): """ Gets the current total virus population. returns: The total virus population (an integer) """ # TODO return len(self.viruses) def update(self): """ Update the state of the virus population in this patient for a single time step. update() should execute the following steps in this order: - Determine whether each virus particle survives and updates the list of virus particles accordingly. - The current population density is calculated. This population density value is used until the next call to update() - Determine whether each virus particle should reproduce and add offspring virus particles to the list of viruses in this patient. returns: The total virus population at the end of the update (an integer) """ # TODO # need: a list of virus particles # already exists as var viruses # loop and survive or clear survive_list = [] for i in range(0, len(self.viruses)): if not self.viruses[i].doesClear(): survive_list.append(self.viruses[i]) self.viruses = survive_list # update the pop density now_density = self.getTotalPop() / float(self.maxPop) # for each virus particle, reproduce or not new_viruses = [] for i in range(0, len(self.viruses)): virus = self.viruses[i] a = virus.reproduce(now_density) if a: new_viruses.append(a) self.viruses = self.viruses + new_viruses # return total virus pop as an int # # PROBLEM 2 # def simulationWithoutDrug(): """ Run the simulation and plot the graph for problem 2 (no drugs are used, viruses do not have any drug resistance). Instantiates a patient, runs a simulation for 300 timesteps, and plots the total virus population as a function of time. """ # TODO a = SimpleVirus(0.1, 0.05) disease = [a]*100 patient = SimplePatient(disease, 1000) pop_over_time = [] for i in range(0, 300): patient.update() pop_over_time.append(patient.getTotalPop()) pylab.plot(pop_over_time) pylab.ylabel("Virus cells") pylab.xlabel("Time") pylab.title("Virus population in patient") pylab.show() simulationWithoutDrug() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# Monte Carlo Simulation Yahtzee! # Casey # 3hr import pylab import random import time ''' def stdDev(X): mean = sum(X)/float(len(X)) tot = 0.0 for x in X: tot += (x - mean)**2 return (tot/len(X))**0.5 ''' def roll(num_rolls): yahtzee = 0 for i in range(0, num_rolls): result = [] for j in range(0, 5): result.append(random.choice([1,2,3,4,5,6])) if len(set(result)) == 1: yahtzee += 1 not_yahtzee = num_rolls - yahtzee return (yahtzee/float(not_yahtzee)) # for some number exponent, that becomes the number of rolls # the number of trials to turn into mean stays the same ie. 20 def yahtzee(minExp, maxExp, numTrials): mean_ratios = [] xAxis = [] for exp in range(minExp, maxExp + 1): xAxis.append(2**exp) for num_rolls in xAxis: ratios = [] for trial in range(numTrials): ratios.append(roll(num_rolls)) mean_ratios.append(sum(ratios)/numTrials) print num_rolls pylab.plot(xAxis, mean_ratios, 'bo') pylab.title("Mean ratio of rolling Yahtzee given increasing rolls") pylab.xlabel("Number of rolls") pylab.ylabel("Yahtzees over all other") pylab.semilogx() pylab.show() yahtzee(10, 20, 20) |