def test_logging(self): # Tests logging to screen and file. # No logging with StreamCapture() as c: sampler = pints.NestedController(self.log_likelihood, self.log_prior) sampler.set_n_posterior_samples(2) sampler.set_iterations(10) sampler.set_log_to_screen(False) sampler.set_log_to_file(False) samples, margin = sampler.run() self.assertEqual(c.text(), '') # Log to screen with StreamCapture() as c: sampler = pints.NestedController(self.log_likelihood, self.log_prior) sampler.set_n_posterior_samples(2) sampler.set_iterations(20) sampler.set_log_to_screen(True) sampler.set_log_to_file(False) samples, margin = sampler.run() lines = c.text().splitlines() self.assertEqual(lines[0], 'Running Nested ellipsoidal sampler') self.assertEqual(lines[1], 'Number of active points: 400') self.assertEqual(lines[2], 'Total number of iterations: 20') self.assertEqual(lines[3], 'Total number of posterior samples: 2') self.assertEqual( lines[4], ('Iter. Eval. Time m:s Delta_log(z) ' + 'Acceptance rate')) pattern = re.compile('[0-9]+[ ]+[0-9]+[ ]+[0-9]{1}:[0-9]{2}.[0-9]{1}') for line in lines[5:]: self.assertTrue(pattern.match(line)) self.assertEqual(len(lines), 28) # Log to file with StreamCapture() as c: with TemporaryDirectory() as d: filename = d.path('test.txt') sampler = pints.NestedController(self.log_likelihood, self.log_prior) sampler.set_n_posterior_samples(2) sampler.set_iterations(10) sampler.set_log_to_screen(False) sampler.set_log_to_file(filename) samples, margin = sampler.run() with open(filename, 'r') as f: lines = f.read().splitlines() self.assertEqual(c.text(), '') self.assertEqual(len(lines), 23) self.assertEqual( lines[0], ('Iter. Eval. Time m:s Delta_log(z) ' + 'Acceptance rate')) pattern = re.compile('[0-9]+[ ]+[0-9]+[ ]+[0-9]{1}:[0-9]{2}.[0-9]{1}') for line in lines[5:]: self.assertTrue(pattern.match(line))
def test_construction_errors(self): # Tests if invalid constructor calls are picked up. # First arg must be a log likelihood self.assertRaisesRegex(ValueError, 'must extend pints.LogLikelihood', pints.NestedController, 'hello', self.log_prior) # First arg must be a log prior self.assertRaisesRegex(ValueError, 'must extend pints.LogPrior', pints.NestedController, self.log_likelihood, self.log_likelihood) # Both must have same number of parameters log_prior = pints.UniformLogPrior([0.01, 400, 1], [0.02, 600, 3]) self.assertRaisesRegex(ValueError, 'same number of parameters', pints.NestedController, self.log_likelihood, log_prior) # test that ellipsoidal sampling used by default sampler = pints.NestedController(self.log_likelihood, self.log_prior) self.assertEqual(sampler._sampler.name(), 'Nested ellipsoidal sampler') self.assertRaisesRegex( ValueError, 'Given method must extend pints.NestedSampler.', pints.NestedController, self.log_likelihood, self.log_prior, pints.DifferentialEvolutionMCMC) self.assertRaisesRegex( ValueError, 'Given method must extend pints.NestedSampler.', pints.NestedController, self.log_likelihood, self.log_prior, 0.0)
def test_settings_check(self): # Tests the settings check at the start of a run. sampler = pints.NestedController(self.log_likelihood, self.log_prior) sampler.set_n_posterior_samples(2) sampler.set_iterations(10) sampler.set_log_to_screen(False) sampler.run()
def test_sensitivities(self): # tests whether sensitivities bit runs sampler = pints.NestedController(self.log_likelihood, self.log_prior) # hacky but currently no samplers need sensitivities sampler._needs_sensitivities = True sampler._initialise_callable()
def test_parallel(self): # Test running sampling with parallisation. sampler = pints.NestedController(self.log_likelihood, self.log_prior) # Test with auto-detected number of worker processes self.assertFalse(sampler.parallel()) sampler.set_parallel(True) self.assertTrue(sampler.parallel()) sampler.set_iterations(10) sampler.set_log_to_screen(False) sampler.run() # Test with fixed number of worker processes sampler = pints.NestedController(self.log_likelihood, self.log_prior) sampler.set_parallel(4) sampler.set_log_to_screen(False) self.assertEqual(sampler.parallel(), 4) sampler.run()
def test_dynamic_enlargement_factor(self): # tests dynamic enlargement factor runs sampler = pints.NestedController(self.log_likelihood, self.log_prior) sampler._sampler.set_dynamic_enlargement_factor(1) sampler.set_log_to_screen(False) ef1 = sampler._sampler.enlargement_factor() sampler.run() ef2 = sampler._sampler.enlargement_factor() self.assertTrue(ef2 < ef1)
def test_quick_run(self): # Test a single run. sampler = pints.NestedController(self.log_likelihood, self.log_prior) sampler.set_n_posterior_samples(10) sampler.set_iterations(50) sampler.set_log_to_screen(False) samples = sampler.run() # Check output: Note n returned samples = n posterior samples self.assertEqual(samples.shape, (10, 2))
def test_exception_on_multi_use(self): # Controller should raise an exception if use multiple times sampler = pints.NestedController(self.log_likelihood, self.log_prior) sampler.set_n_posterior_samples(2) sampler.set_iterations(10) sampler.set_log_to_screen(False) sampler.run() with self.assertRaisesRegex(RuntimeError, 'Controller is valid for single use only'): sampler.run()
def _run(self, result): import pints import pints.toy # Allow slightly older pints versions to be tested try: from pints.toy import TwistedGaussianLogPDF except ImportError: from pints.toy import TwistedNormalLogPDF as TwistedGaussianLogPDF try: from pints import MultivariateGaussianLogPrior except ImportError: from pints import MultivariateNormalLogPrior \ as MultivariateGaussianLogPrior log = logging.getLogger(__name__) DEBUG = False # Show method name log.info('Using method: ' + self._method) # Get method class method = getattr(pints, self._method) # Create a log pdf (use multi-modal, but with a single mode) log_pdf = TwistedGaussianLogPDF(dimension=2, b=0.1) # Create a log prior log_prior = MultivariateGaussianLogPrior( [0, 0], [[10, 0], [0, 10]]) # Create a nested sampler sampler = pints.NestedController(log_pdf, log_prior, method=method) # Log to file if not DEBUG: sampler.set_log_to_screen(False) # Set max iterations sampler.set_iterations(4000) sampler.set_n_posterior_samples(1000) # Run samples = sampler.run() # Store kullback-leibler divergence result['kld'] = log_pdf.kl_divergence(samples) # Store status result['status'] = 'done'
def test_early_termination(self): # tests that nested sampling terminates early with a large # threshold sampler = pints.NestedController(self.log_likelihood, self.log_prior) # Test with auto-detected number of worker processes self.assertFalse(sampler.parallel()) sampler.set_parallel(True) self.assertTrue(sampler.parallel()) sampler.set_iterations(200) sampler.set_log_to_screen(False) sampler.set_marginal_log_likelihood_threshold(100000) sampler.run() m_inactive = sampler.inactive_points() self.assertTrue(m_inactive.shape[0] < 200)
def _run(self, result): import pints import pints.toy import numpy as np import logging log = logging.getLogger(__name__) DEBUG = False # Show method name log.info('Using method: ' + self._method) # Get method class method = getattr(pints, self._method) # Create a log pdf xtrue = np.array([2, 4]) sigma = np.diag(np.array([1, 3])) log_pdf = pints.toy.GaussianLogPDF(xtrue, sigma) # Create a log prior log_prior = pints.MultivariateGaussianLogPrior(xtrue + 1, sigma * 2) # Create a nested sampler sampler = pints.NestedController(log_pdf, log_prior, method=method) # Log to file if not DEBUG: sampler.set_log_to_screen(False) # Set max iterations sampler.set_iterations(4000) sampler.set_n_posterior_samples(1000) # Run samples = sampler.run() # Store kullback-leibler divergence result['kld'] = log_pdf.kl_divergence(samples) # Store status result['status'] = 'done'
def _run(self, result): import pints import pints.toy log = logging.getLogger(__name__) DEBUG = False # Show method name log.info('Using method: ' + self._method) # Get method class method = getattr(pints, self._method) # Create a log pdf sigma = 2 r = 4 log_pdf = pints.toy.SimpleEggBoxLogPDF(sigma=sigma, r=r) # Create a log prior d = 2 * 6 * r * sigma log_prior = pints.MultivariateGaussianLogPrior([0, 0], [[d, 0], [0, d]]) # Create a nested sampler sampler = pints.NestedController(log_pdf, log_prior, method=method) # Log to file if not DEBUG: sampler.set_log_to_screen(False) # Set max iterations sampler.set_iterations(4000) sampler.set_n_posterior_samples(1000) # Run samples = sampler.run() # Store kullback-leibler-based score result['kld'] = log_pdf.kl_divergence(samples) # Store status result['status'] = 'done'
def test_quick_run(self): # Test a single run. sampler = pints.NestedController(self.log_likelihood, self.log_prior) sampler.set_n_posterior_samples(10) sampler.set_iterations(50) sampler.set_log_to_screen(False) # Time before run is None self.assertIsNone(sampler.time()) t = pints.Timer() samples = sampler.run() t_upper = t.time() # Check output: Note n returned samples = n posterior samples self.assertEqual(samples.shape, (10, 2)) # Time after run is greater than zero self.assertIsInstance(sampler.time(), float) self.assertGreater(sampler.time(), 0) self.assertGreater(t_upper, sampler.time())
def test_getters_and_setters(self): # Tests various get() and set() methods. sampler = pints.NestedController(self.log_likelihood, self.log_prior) # Iterations x = sampler.iterations() + 1 self.assertNotEqual(sampler.iterations(), x) sampler.set_iterations(x) self.assertEqual(sampler.iterations(), x) self.assertRaisesRegex(ValueError, 'negative', sampler.set_iterations, -1) # Posterior samples x = sampler.n_posterior_samples() + 1 self.assertNotEqual(sampler.n_posterior_samples(), x) sampler.set_n_posterior_samples(x) self.assertEqual(sampler.n_posterior_samples(), x) self.assertRaisesRegex(ValueError, 'greater than zero', sampler.set_n_posterior_samples, 0) self.assertRaises(ValueError, sampler.sample_from_posterior, 0) # Marginal likelihood threshold self.assertRaises(ValueError, sampler.set_marginal_log_likelihood_threshold, 0) sampler.set_marginal_log_likelihood_threshold(3.0) self.assertEqual(sampler.marginal_log_likelihood_threshold(), 3.0) # Acive points sampler.set_iterations(100) sampler.set_log_to_screen(False) sampler.run() active_points = sampler.active_points() self.assertEqual(active_points.shape[0], 400) # effective sample size and log-likelihood vector ess1 = sampler.effective_sample_size() logLikelihood1 = sampler.log_likelihood_vector() self.assertEqual(len(logLikelihood1), 400 + 100) self.assertTrue(ess1 > 0) iter = 2000 sampler.set_iterations(iter) sampler.set_n_posterior_samples(100) sampler.set_log_to_screen(False) sampler.run() ess2 = sampler.effective_sample_size() self.assertTrue(ess2 > ess1) logLikelihood2 = sampler.log_likelihood_vector() self.assertEqual(len(logLikelihood2), 400 + iter) # marginal likelihood ess_sd1 = sampler.marginal_log_likelihood_standard_deviation() self.assertTrue(ess_sd1 > 0) sampler._log_Z_called = False ess_sd2 = sampler.marginal_log_likelihood_standard_deviation() self.assertEqual(ess_sd1, ess_sd2) # number of posterior samples m_posterior_samples = sampler.posterior_samples() self.assertEqual(m_posterior_samples.shape[0], 100) # prior space prior_space = sampler.prior_space() self.assertEqual(len(prior_space), iter + 1) for elem in prior_space: self.assertTrue(elem >= 0) self.assertTrue(elem <= 1) # Acive points sampler.set_iterations(100) sampler.set_log_to_screen(False) sampler.set_parallel(2) sampler.run() active_points = sampler.active_points() self.assertEqual(active_points.shape[0], 400) inactive_points = sampler.inactive_points() self.assertEqual(inactive_points.shape[0], 100)