def __init__(self, a, b, K): from operator import mul self._a = a self._b = b self._K = K theta = 1. / b self.gamma_dist = gamma_dist(a, 0, theta)
def produce_gomes_exfig1(coeffs: list, add_hist=False, n_bins=3, x_values=50, plot_upper_limit=3.0): """ Produce figure equivalent to Extended Data Fig 1 of Aguas et al pre-print as a check """ # Prelims x_values = np.linspace(0.1, plot_upper_limit, x_values) # Can't go to zero under some coeffs gamma_plot = plt.figure() axis = gamma_plot.add_subplot(111) # For each requested coefficient of variation for coeff in coeffs: gamma_distri = gamma_dist(coeff ** -2.0, scale=coeff ** 2.0) # Line graph of the raw function y_values = [gamma_distri.pdf(i) for i in x_values] axis.plot(x_values, y_values, color="k") # Numeric integration over parts of the function domain if add_hist: lower_terminals, _, _, normalised_heights, bin_width = get_gamma_data( plot_upper_limit, n_bins, coeff ) axis.bar(lower_terminals, normalised_heights, width=bin_width, align="edge") # Return the figure return gamma_plot
def get_gamma_data(tail_start_point, n_bins, coeff): """ Compute a discretised version of a gamma distribution with mean 1 and a given coefficient of variation (sd/mean). The discretisation involves numerical solving to ensure the coefficient of variation is preserved. However, the mean of the discrete ditribution may be different to 1. :param tail_start_point: the last lower terminal :param n_bins: number of bins (including tail) :param coeff: requested coefficient of variation :return: """ # First address a few singular scenarios if n_bins == 1 and coeff > 0.0: raise ValueError("Cannot compute a positive coefficient of variation using a single bin") elif n_bins > 1 and coeff == 0.0: raise ValueError("Cannot compute a null coefficient of variation using multiple bins") elif n_bins == 1: return [0.0], [float("inf")], 1.0, 1.0, float("inf") n_finite_bins = n_bins - 1 # Prelims lower_terminal, lower_terminals, upper_terminals, heights = 0.0, [], [], [] bin_width = tail_start_point / n_finite_bins for i_bin in range(n_finite_bins): # Record the upper and lower terminals lower_terminals.append(lower_terminal) upper_terminals.append(lower_terminal + bin_width) gamma_distri = gamma_dist(coeff ** -2.0, scale=coeff ** 2.0) heights.append( gamma_distri.cdf(upper_terminals[-1]) - gamma_distri.cdf(lower_terminals[-1]) ) # Move to the next value lower_terminal = upper_terminals[-1] # the last height is the remaining area under the curve (tail) heights.append(1.0 - sum(heights)) # Find mid-points as the representative values mid_points = [(lower + upper) / 2.0 for lower, upper in zip(lower_terminals, upper_terminals)] # add the last representative point such that modelled_CV = input_CV last_point, last_height = find_last_representative_point(mid_points, heights, coeff) mid_points.append(last_point) heights[-1] = last_height # rescale heights heights = [h / sum(heights) for h in heights] lower_terminals.append(upper_terminals[-1]) upper_terminals.append(float("inf")) # Return everything just in case return lower_terminals, upper_terminals, mid_points, heights, bin_width
# Model Parameters to sample from Gamma Distributions gamma_inv, gamma_inv_shape = 7, 0.1 # From report (mean, shape) sigma_inv, sigma_inv_shape = 5.1, 0.1 # From report (mean, shape) r0, r0_shape = 2.28, 0.1 # From report (mean, shape) # For gamma pdf plots x = np.linspace(1E-6, 10, 1000) num_samples = 1000 #### Gamma distributed samples for gamma_inv #### #### --> This might be wrong?!?!? k = 1 loc = gamma_inv theta = gamma_inv_shape gamma_inv_dist = gamma_dist(k, loc, theta) gamma_inv_samples = gamma_inv_dist.rvs(num_samples) # Plot gamma samples and pdf count, bins, ignored = plt.hist(gamma_inv_samples, 50, density=True) plt.plot(x, gamma_inv_dist.pdf(x), 'r', label=r'$k=%.1f,\ \theta=%.1f$' % (k, theta)) #### Gamma distributed samples for sigma_inv #### k = 1 loc = sigma_inv theta = sigma_inv_shape sigma_inv_dist = gamma_dist(k, loc, theta) sigma_inv_samples = sigma_inv_dist.rvs(num_samples)
def plotSIR_sampledParams(beta_samples, gamma_inv_samples, filename, *prob_params): fig, (ax1,ax2) = plt.subplots(1,2, constrained_layout=True) ########################################################### ################## Plot for Beta Samples ################## ########################################################### count, bins, ignored = ax1.hist(beta_samples, 30, density=True) if prob_params[0] == 'uniform': ax1.set_xlabel(r"$\beta \sim \mathcal{N}$", fontsize=15) if prob_params[0] == 'gaussian': mu = prob_params[1] sigma = prob_params[2] + 0.00001 ax1.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) * np.exp( - (bins - mu)**2 / (2 * sigma**2) ), linewidth=2, color='r') ax1.set_xlabel(r"$\beta \sim \mathcal{N}$", fontsize=15) if prob_params[0] == 'gamma': g_dist = gamma_dist(prob_params[2], prob_params[1], prob_params[3]) # Plot gamma samples and pdf x = np.arange(0,1,0.001) ax1.plot(x, g_dist.pdf(x), 'r',label=r'$k = 1, \mu=%.1f,\ \theta=%.1f$' % (prob_params[1], prob_params[2])) for tick in ax1.xaxis.get_major_ticks(): tick.label.set_fontsize(15) for tick in ax1.yaxis.get_major_ticks(): tick.label.set_fontsize(15) plt.xlim(0, 1.0) ax1.grid(True, alpha=0.3) ax1.set_title(r"Histogram of $\beta$ samples", fontsize=20) ############################################################### ################## Plot for Gamma^-1 Samples ################## ############################################################### count, bins, ignored = ax2.hist(gamma_inv_samples, 30, density=True) if prob_params[0] == 'gaussian': mu = prob_params[3] sigma = prob_params[4] + 0.00001 ax2.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) * np.exp( - (bins - mu)**2 / (2 * sigma**2) ), linewidth=2, color='r') ax2.set_xlabel(r"$\gamma^{-1} \sim \mathcal{N}$", fontsize=15) if prob_params[0] == 'uniform': ax2.set_xlabel(r"$\gamma^{-1} \sim \mathcal{U}$", fontsize=15) if prob_params[0] == 'gamma': g_dist = gamma_dist(prob_params[5], prob_params[4], prob_params[6]) # Plot gamma samples and pdf x = np.arange(1,15,0.1) ax2.plot(x, g_dist.pdf(x), 'r',label=r'$k = 1, \mu=%.1f,\ \theta=%.1f$' % (prob_params[3], prob_params[4])) for tick in ax2.xaxis.get_major_ticks(): tick.label.set_fontsize(15) for tick in ax2.yaxis.get_major_ticks(): tick.label.set_fontsize(15) plt.xlim(1, 17) ax2.grid(True, alpha=0.3) plt.title(r"Histogram of $\gamma^{-1}$ samples", fontsize=20) fig.subplots_adjust(left=.12, bottom=.14, right=.93, top=0.93) fig.set_size_inches(20/2, 8/2, forward=True) # Store plot plt.savefig(filename + ".png", bbox_inches='tight')
def rollout_SIR_sim_stoch(*prob_params, **kwargs): ''' Run a single simulation of stochastic SIR dynamics ''' verbose = kwargs['verbose'] N = kwargs['N'] days = kwargs['days'] # Sample from Uniform Distributions if prob_params[0] == 'uniform': if prob_params[1] == prob_params[2]: beta = prob_params[1] else: beta = np.random.uniform(prob_params[1],prob_params[2]) if prob_params[3] == prob_params[4]: gamma_inv = prob_params[3] else: gamma_inv = np.random.uniform(prob_params[3],prob_params[4]) # Sample from Gaussian Distributions if prob_params[0] == 'gaussian': beta_mean = prob_params[1] beta_std = prob_params[2] gamma_inv_mean = prob_params[3] gamma_inv_std = prob_params[4] # Sample from Gaussian Distributions beta = 0 while beta < 0.02: beta = np.random.normal(beta_mean, beta_std) gamma_inv = 0 while gamma_inv < 0.1: gamma_inv = np.random.normal(gamma_inv_mean, gamma_inv_std) # Sample from Gaussian Distributions if prob_params[0] == 'gamma': beta_loc = prob_params[1] beta_scale = prob_params[2] beta_shape = prob_params[3] gamma_inv_loc = prob_params[4] gamma_inv_scale = prob_params[5] gamma_inv_shape = prob_params[6] # Sample from Gamma Distributions if beta_scale == 0: beta = beta_loc else: beta_dist = gamma_dist(beta_scale, beta_loc, beta_shape) beta = beta_dist.rvs(1)[0] if gamma_inv_scale == 0: gamma_inv = gamma_inv_loc else: gamma_inv_dist = gamma_dist(gamma_inv_scale, gamma_inv_loc, gamma_inv_shape) gamma_inv = gamma_inv_dist.rvs(1)[0] # Derived values gamma = 1.0 / gamma_inv r0 = beta * gamma_inv if verbose: print('***** SIMULATING SIR MODEL DYNAMICS *****') print('***** Hyper-parameters *****') print('N=',N,'days=', days, 'r0=',r0, 'gamma_inv (days) = ',gamma_inv) print('***** Model-parameters *****') print('beta=',beta, 'gamma=',gamma) # Create Model model_kwargs = {} model_kwargs['r0'] = r0 model_kwargs['inf_period'] = gamma_inv model_kwargs['I0'] = kwargs['I0'] model_kwargs['R0'] = kwargs['R0'] model = SIR(N,**model_kwargs) S,I,R,t = model.project(days,'ode_int') return S, I, R, t, beta, gamma_inv