def test_pdf(self, distribution_test): # 1d case x = [1, 2, -1] means = [0, 2] weights = normalize_weights([.4, .1]) d = GMDistribution.pdf(x, means, weights=weights) d_true = weights[0] * ss.norm.pdf(x, loc=means[0]) + \ weights[1] * ss.norm.pdf(x, loc=means[1]) assert np.allclose(d, d_true) # Test with a single observation # assert GMDistribution.pdf(x[0], means, weights=weights).ndim == 0 # Distribution_test with 1d means distribution_test(GMDistribution, means, weights=weights) # 2d case x = [[1, 2, -1], [0, 0, 2]] means = [[0, 0, 0], [-1, -.2, .1]] d = GMDistribution.pdf(x, means, weights=weights) d_true = weights[0] * ss.multivariate_normal.pdf(x, mean=means[0]) + \ weights[1] * ss.multivariate_normal.pdf(x, mean=means[1]) assert np.allclose(d, d_true) # Test with a single observation assert GMDistribution.pdf(x[0], means, weights=weights).ndim == 0 # Distribution_test with 3d means distribution_test(GMDistribution, means, weights=weights)
def _compute_weights_and_cov(self, pop): params = np.column_stack(tuple([pop.outputs[p] for p in self.parameter_names])) if self._populations: q_logpdf = GMDistribution.logpdf(params, *self._gm_params) p_logpdf = self._prior.logpdf(params) w = np.exp(p_logpdf - q_logpdf) else: w = np.ones(pop.n_samples) if np.count_nonzero(w) == 0: raise RuntimeError("All sample weights are zero. If you are using a prior " "with a bounded support, this may be caused by specifying " "a too small sample size.") # New covariance cov = 2 * np.diag(weighted_var(params, w)) if not np.all(np.isfinite(cov)): logger.warning("Could not estimate the sample covariance. This is often " "caused by majority of the sample weights becoming zero." "Falling back to using unit covariance.") cov = np.diag(np.ones(params.shape[1])) return w, cov
def prepare_new_batch(self, batch_index): """Prepare values for a new batch. Parameters ---------- batch_index : int next batch_index to be submitted Returns ------- batch : dict or None Keys should match to node names in the model. These values will override any default values or operations in those nodes. """ if self.state['round'] == 0: # Use the actual prior return # Sample from the proposal, condition on actual prior params = GMDistribution.rvs(*self._gm_params, size=self.batch_size, prior_logpdf=self._prior.logpdf, random_state=self._round_random_state) batch = arr2d_to_batch(params, self.parameter_names) return batch
def test_rvs_prior_ok(self): means = [0.8, 0.5] weights = [.3, .7] N = 10000 prior_logpdf = ss.uniform(0, 1).logpdf rvs = GMDistribution.rvs(means, weights=weights, size=N, prior_logpdf=prior_logpdf) # Ensure prior pdf > 0 for all samples assert np.all(np.isfinite(prior_logpdf(rvs)))
def prepare_new_batch(self, batch_index): if self.state['round'] == 0: # Use the actual prior return # Sample from the proposal params = GMDistribution.rvs(*self._gm_params, size=self.batch_size, random_state=self._round_random_state) batch = arr2d_to_batch(params, self.parameter_names) return batch
def test_rvs(self): means = [[1000, 3], [-1000, -3]] weights = [.3, .7] N = 10000 random = np.random.RandomState(12042017) rvs = GMDistribution.rvs(means, weights=weights, size=N, random_state=random) rvs = rvs[rvs[:, 0] < 0, :] # Test correct proportion of samples near the second mode assert np.abs(len(rvs) / N - .7) < .01 # Test that the mean of the second mode is correct assert np.abs(np.mean(rvs[:, 1]) + 3) < .1