class PmcAbc(object): def __init__(self, data, simulator, prior_dict = {}, N = 1000, eps0 = 0.01, T = 20, Nthreads = 10): """ Class taht describes PMC-ABC """ self.data = data self.N = N self.eps0 = eps0 self.T = T self.Nthreads = Nthreads # simulator function has to be a function of theta_star self.simz = simulator self.prior_param(param_dict = prior_dict) # first run prior parameters def prior_param(self, param_dict={}): """ Pass priors of parameters in theta """ self.param_obj = Params(param_dict) # parameter object self.param_names = param_dict.keys() self.n_params = len(param_dict.keys()) # number of parameters in theta def priors_sample(self): """ Sample from priors derived from parameter object """ theta_star = np.zeros(self.n_params) for i in xrange(self.n_params): np.random.seed() theta_star[i] = self.param_obj.prior()[i].rvs(size=1)[0] return theta_star def prior_of_priors(self, tt): """ Multiply priors of multile dimensions p(theta) = p(theta_0) * p(theta_1) * ... * p(theta_n_params) """ for i in xrange(self.n_params): try: p_theta *= self.param_obj.prior()[i].pdf(tt[i]) except UnboundLocalError: p_theta = self.param_obj.prior()[i].pdf(tt[i]) return p_theta def initial_sampling(self, params): """Wrapper for parallelized initial pool sampling """ i = params theta_star = self.priors_sample() model = self.simz( theta_star ) rho = test_dist(self.data, model) while rho > self.eps0: theta_star = self.priors_sample() model = self.simz( theta_star ) rho = test_dist(self.data, model) data_list = [np.int(i)] for i_param in xrange(self.n_params): data_list.append(theta_star[i_param]) data_list.append(1./np.float(self.N)) data_list.append(rho) return np.array(data_list) def initial_pool(self): """ Creating the initial pool """ self.t = 0 self.theta_t = np.zeros((self.n_params, self.N)) self.w_t = np.zeros((self.N)) self.rhos = np.zeros((self.N)) #pool = InterruptiblePool(self.Nthreads) #mapfn = pool.map args_list = [(i) for i in xrange(self.N)] results = [] for arg in args_list: print self.initial_sampling(arg) results.append(self.initial_sampling(arg)) #unwrap_self_initial_sampling(zip([self]*len(args_list), args_list)[0]) #results = mapfn(unwrap_self_initial_sampling, zip([self]*len(args_list), args_list)) #pool.close() #pool.terminate() #pool.join() print 'Initial Pool Complete' pars = np.array(results).T self.theta_t = pars[1:self.n_params+1,:] self.w_t = pars[self.n_params+1,:] self.rhos = pars[self.n_params+2,:] self.sig_t = 2.0 * np.cov( self.theta_t ) # covariance matrix self.writeout() self.plotout() return np.array(self.rhos) def importance_sampling(self, params): """ Wrapper for parallelized importance sampling """ i_part = params theta_star = weighted_sampling( self.theta_t_1, self.w_t_1 ) np.random.seed() theta_starstar = multivariate_normal( theta_star, self.sig_t_1 ).rvs(size=1) model_starstar = self.simz( theta_starstar ) rho = test_dist(self.data, model_starstar) while rho > self.eps_t: theta_star = weighted_sampling( self.theta_t_1, self.w_t_1 ) theta_starstar = multivariate_normal(theta_star, self.sig_t_1).rvs(size=1) model_starstar = self.simz( theta_starstar ) rho = test_dist(self.data, model_starstar) p_theta = self.prior_of_priors(theta_starstar) pos_t = np.dstack(self.theta_t_1) tmp_w_t = p_theta / np.sum(self.w_t_1 * multivariate_normal(self.theta_t[:,i_part], self.sig_t_1).pdf(pos_t)) data_list = [np.int(i_part)] for i_param in xrange(self.n_params): data_list.append(theta_starstar[i_param]) data_list.append(tmp_w_t) data_list.append(rho) return np.array(data_list) def pmc_abc(self): """ """ self.rhos = self.initial_pool() while self.t < self.T: self.eps_t = np.percentile(self.rhos, 75) print 'Epsilon t', self.eps_t self.theta_t_1 = self.theta_t.copy() self.w_t_1 = self.w_t.copy() self.sig_t_1 = self.sig_t.copy() pool = InterruptiblePool(self.Nthreads) mapfn = pool.map args_list = [ i for i in xrange(self.N) ] results = mapfn(unwrap_self_importance_sampling, zip([self]*len(args_list), args_list)) pool.close() pool.terminate() pool.join() pars = np.array(results).T self.theta_t = pars[1:self.n_params+1,:].copy() self.w_t = pars[self.n_params+1,:].copy() self.rhos = pars[self.n_params+2,:].copy() self.sig_t = 2.0 * np.cov(self.theta_t) self.t += 1 self.writeout() self.plotout() return None def writeout(self): """ Write out theta_t and w_t """ out_file = ''.join(['theta_w_t', str(self.t), '.dat']) data_list = [] for i in xrange(self.n_params): data_list.append( self.theta_t[i,:] ) data_list.append(self.w_t) np.savetxt( out_file, (np.vstack(np.array(data_list))).T, delimiter='\t' ) return None def plotout(self, plot_type = 'seabreeze'): """ Triangle plot the things """ if plot_type == 'seabreeze': figure = sns.jointplot(x = self.theta_t[0,:], y = self.theta_t[1,:], kind = 'kde', style = 'white', weights = self.w_t, xlim = [-1.0, 1], ylim = [0.0, 2.0] ) plt.savefig("seabreeze_theta_t"+str(self.t)+".png") plt.close() elif plot_type == 'triangle': # Clunky based on which version of corner.py you have # Clunky based on which version of corner.py you have # Clunky based on which version of corner.py you have # Clunky based on which version of corner.py you have figure = triangle.corner( (self.theta_t).T, labels = self.param_names, weights = self.w_t, show_titles=True, title_args={"fontsize": 12}, smooth=False ) figure.gca().annotate( str(self.t), xy=(0.5, 1.0), xycoords="figure fraction", xytext=(0, -5), textcoords="offset points", ha="center", va="top" ) figure.savefig("triangle_theta_t"+str(self.t)+".png") plt.close() elif plot_type == 'scatter': if len(self.theta_t[:,0]) != 2: warnings.warn("Can only plot two axes on scatter plot. No plot generated") return figure = plt.figure(1) sub = figure.add_subplot(111) sub.scatter(self.theta_t[0,:], self.theta_t[1,:]) sub.set_xlim([-1.0, 1.0]) sub.set_ylim([0.8, 1.5]) figure.savefig("scatter_theta_t"+str(self.t)+".png") plt.close()
def pmc_abc(data, N = 1000, eps0 = 0.01, T = 20 ): start_time = time.time() toolz = Params({ 'mu': {'shape': 'gauss', 'mean': .0, 'stddev': 1.0}, 'sigma': { 'shape': 'uniform', 'min': 0.0, 'max': 2.0} }) t = 0 theta_t = np.zeros((2, N)) w_t = np.zeros((N)) for i in xrange(N): theta_star = np.zeros(2) theta_star[0] = toolz.prior()[0].rvs(size=1)[0] theta_star[1] = toolz.prior()[1].rvs(size=1)[0] #print theta_star model = toolz.simulator( theta_star ) rho = test_dist(data[1], model(data[0])) while rho > eps0: theta_star[0] = toolz.prior()[0].rvs(size=1)[0] theta_star[1] = toolz.prior()[1].rvs(size=1)[0] model = toolz.simulator( theta_star ) rho = test_dist(data[1], model(data[0])) theta_t[:,i] = theta_star w_t[i] = 1.0/np.float(N) sig_t = 2.0 * np.cov( theta_t ) # covariance matrix print sig_t # write out np.savetxt( ''.join(['theta_w_t', str(t), '.dat']), np.c_[theta_t[0,:], theta_t[1,:], w_t ] ) print 'Initial Pool ', time.time() - start_time fig = plt.figure(1) sub = fig.add_subplot(111) sub.scatter( theta_t[0,:], theta_t[1,:], alpha = 1. , color = 'b' ) #s = 10.**10.*w_t/w_t.sum() , sub.set_xlim([-2. , 2.]) sub.set_ylim([ 0. , 2.]) sub.set_xlabel(r'$\mu$') sub.set_ylabel(r'$\sigma$') plt.savefig("theta_scatter"+str(t)+".png") plt.close() start_time = time.time() while t < T: eps_t = np.percentile(rho, 75) print 'Epsilon t', eps_t theta_t_1 = theta_t.copy() w_t_1 = w_t.copy() sig_t_1 = sig_t.copy() for i in xrange(N): start_time = time.time() theta_star = weighted_sampling( theta_t_1, w_t_1 ) theta_starstar = multivariate_normal( theta_star, sig_t_1 ).rvs(size=1) while theta_starstar[1] < 0 : theta_star = weighted_sampling( theta_t_1, w_t_1 ) theta_starstar = multivariate_normal(theta_star, sig_t_1).rvs(size=1) #print theta_starstar model_starstar = toolz.simulator( theta_starstar ) rho = test_dist(data[1], model_starstar(data[0])) while rho > eps_t: theta_star = weighted_sampling( theta_t_1, w_t_1 ) theta_starstar = multivariate_normal(theta_star, sig_t_1).rvs(size=1) while theta_starstar[1] < 0 : theta_star = weighted_sampling( theta_t_1, w_t_1 ) theta_starstar = multivariate_normal(theta_star, sig_t_1).rvs(size=1) #print theta_starstar model_starstar = toolz.simulator( theta_starstar ) rho = test_dist(data[1], model_starstar(data[0])) #print theta_star, theta_starstar theta_t[:,i] = theta_starstar #print sig_t_1 p_theta = toolz.prior()[0].pdf(theta_t[0,i]) * toolz.prior()[1].pdf(theta_t[1,i]) #print p_theta pos_t = np.dstack((theta_t_1[0,:],theta_t_1[1,:])) #print multivariate_normal(theta_t[:,i], sig_t_1).pdf(pos_t).shape , w_t_1.shape w_t[i] = p_theta / np.sum(w_t_1 * multivariate_normal(theta_t[:,i], sig_t_1).pdf(pos_t)) #print test_dist(data[1], model_starstar(data[0])), w_t[i] #print 'For loop ', time.time() - start_time sig_t = 2.0 * np.cov(theta_t) t += 1 fig = plt.figure(1) sub = fig.add_subplot(111) sub.scatter( theta_t[0,:], theta_t[1,:], alpha = 0.5 ) # s = w_t/w_t.sum() , sub.set_xlim([-2. , 2.]) sub.set_ylim([ 0. , 2.]) sub.set_xlabel(r'$\mu$') sub.set_ylabel(r'$\sigma$') plt.savefig("theta_scatter"+str(t)+".png") plt.close() np.savetxt( ''.join(['theta_w_t', str(t), '.dat']), np.c_[theta_t[0,:], theta_t[1,:], w_t ] ) print t, ' ;D'