def test_ask_tell_flow(self): # Tests the ask-and-tell pattern # Create problem x0 = np.array([2, 4]) log_pdf = pints.toy.GaussianLogPDF([2, 4], [[1, 0], [0, 3]]) # Ask must return initial point mcmc = pints.SliceDoublingMCMC(x0) self.assertTrue(np.all(mcmc.ask() == x0)) # Ask can't be called twice self.assertRaises(RuntimeError, mcmc.ask) # Tell fx = log_pdf(x0) x1 = mcmc.tell(fx) self.assertTrue(np.all(x0 == x1)) self.assertTrue(mcmc.current_log_pdf() == fx) # Check that the new slice has been constructed appropriately self.assertTrue(mcmc.current_slice_height() < mcmc.current_log_pdf()) # Can't tell twice self.assertRaises(RuntimeError, mcmc.tell, log_pdf(x0)) # First point must be finite mcmc = pints.SliceDoublingMCMC(x0) mcmc.ask() self.assertRaises(ValueError, mcmc.tell, np.inf)
def test_run(self): # Test a short run # Create log pdf log_pdf = pints.toy.MultimodalGaussianLogPDF( modes=[[1, 1], [1, 4], [5, 4], [1, 4]]) # Create mcmc mcmc = pints.SliceDoublingMCMC(np.array([1, 2])) mcmc.set_width(2) # Run a few iterations of the sampler # But enough to hit all branches... np.random.seed(123) n = 42 chain = [] while len(chain) < n: x = mcmc.ask() fx = log_pdf(x) reply = mcmc.tell(fx) if reply is not None: y, fy, ac = reply chain.append(y) self.assertTrue(np.all(x == y)) self.assertTrue(np.all(fx == fy)) self.assertEqual(np.shape(chain), (n, 2))
def test_hyper_parameters(self): # Test the hyper parameter interface mcmc = pints.SliceDoublingMCMC(np.array([1, 2])) self.assertEqual(mcmc.n_hyper_parameters(), 2) mcmc.set_hyper_parameters([3, 100]) self.assertTrue((np.all(mcmc.width() == np.array([3, 3])))) self.assertEqual(mcmc.expansion_steps(), 100)
def test_expansion(self): # Test expansion step methods mcmc = pints.SliceDoublingMCMC(np.array([1, 2])) mcmc.set_expansion_steps(3) self.assertEqual(mcmc.expansion_steps(), 3.) with self.assertRaises(ValueError): mcmc.set_expansion_steps(-1)
def test_first_run(self): # Tests the very first run of the sampler. # Create log pdf log_pdf = pints.toy.GaussianLogPDF([2, 4], [[1, 0], [0, 3]]) # Create mcmc x0 = np.array([2., 4.]) mcmc = pints.SliceDoublingMCMC(x0) # Ask should fail if _ready_for_tell flag is True x = mcmc.ask() with self.assertRaises(RuntimeError): mcmc.ask() # Check whether _running flag becomes True when ask() is called # Check whether first iteration of ask() returns x0 self.assertTrue(np.all(x == x0)) self.assertTrue(mcmc._running) self.assertTrue(mcmc._ready_for_tell) # Calculate log pdf for x0 fx = log_pdf.evaluateS1(x0)[0] # Test first iteration of tell(). The first point in the chain # should be x0 sample = mcmc.tell(fx) self.assertTrue(np.all(sample == x0)) # We update the _current_log_pdf value used to generate the new slice self.assertEqual(mcmc.current_log_pdf(), fx) # Check that the new slice has been constructed appropriately self.assertTrue(mcmc.current_slice_height() < mcmc.current_log_pdf()) # Tell() should fail when fx is infinite mcmc = pints.SliceDoublingMCMC(x0) mcmc.ask() with self.assertRaises(ValueError): fx = np.inf mcmc.tell(fx) # Tell() should fail when _ready_for_tell is False with self.assertRaises(RuntimeError): mcmc.tell(fx)
def test_width(self): # Test width methods mcmc = pints.SliceDoublingMCMC(np.array([1, 2])) # Test set_width(), width() mcmc.set_width(2) self.assertTrue(np.all(mcmc.width() == np.array([2, 2]))) mcmc.set_width([5, 8]) self.assertTrue(np.all(mcmc.width() == np.array([5, 8]))) with self.assertRaises(ValueError): mcmc.set_width(-1) with self.assertRaises(ValueError): mcmc.set_width([3, 3, 3, 3])
def test_multimodal_run(self): # Create log pdf log_pdf = pints.toy.MultimodalGaussianLogPDF( modes=[[1, 1], [1, 4], [5, 4], [1, 4]]) # Create mcmc x0 = np.array([1, 1]) mcmc = pints.SliceDoublingMCMC(x0) mcmc.set_width(2) # Run multiple iterations of the sampler chain = [] while len(chain) < 200: x = mcmc.ask() fx = log_pdf.evaluateS1(x)[0] sample = mcmc.tell(fx) if sample is not None: chain.append(np.copy(sample)) self.assertEqual(np.shape(chain), (200, 2))
def test_run(self): # Test a short run # Create log pdf log_pdf = pints.toy.MultimodalGaussianLogPDF( modes=[[1, 1], [1, 4], [5, 4], [1, 4]]) # Create mcmc mcmc = pints.SliceDoublingMCMC(np.array([1, 2])) mcmc.set_width(2) # Run a few iterations of the sampler # But enough to hit all branches... np.random.seed(123) n = 42 chain = [] while len(chain) < n: sample = mcmc.tell(log_pdf(mcmc.ask())) if sample is not None: chain.append(np.copy(sample)) self.assertEqual(np.shape(chain), (n, 2))
def test_basic(self): # Test basic methods of the class. # Create mcmc x0 = np.array([1, 1]) mcmc = pints.SliceDoublingMCMC(x0) # Test name self.assertEqual(mcmc.name(), 'Slice Sampling - Doubling') # Test set_width(), width() mcmc.set_width(2) self.assertTrue(np.all(mcmc.width() == np.array([2, 2]))) mcmc.set_width([5, 8]) self.assertTrue(np.all(mcmc.width() == np.array([5, 8]))) with self.assertRaises(ValueError): mcmc.set_width(-1) with self.assertRaises(ValueError): mcmc.set_width([3, 3, 3, 3]) # Test set_expansion_steps(), expansion_steps() mcmc.set_expansion_steps(3) self.assertEqual(mcmc.expansion_steps(), 3.) with self.assertRaises(ValueError): mcmc.set_expansion_steps(-1) # Test current_slice height self.assertEqual(mcmc.current_slice_height(), mcmc._current_log_y) # Test number of hyperparameters self.assertEqual(mcmc.n_hyper_parameters(), 2) # Test setting hyperparameters mcmc.set_hyper_parameters([3, 100]) self.assertTrue((np.all(mcmc.width() == np.array([3, 3])))) self.assertEqual(mcmc.expansion_steps(), 100)
def test_name(self): # Tests the sampler's name mcmc = pints.SliceDoublingMCMC(np.array([1, 2])) self.assertEqual(mcmc.name(), 'Slice Sampling - Doubling')