@@ -690,6 +690,26 @@ def test_log_pdf_storage_in_memory_single(self):
690
690
likelihoods = [self .log_likelihood (x ) for x in chain ]
691
691
self .assertTrue (np .all (evals [i ] == likelihoods ))
692
692
693
+ # Test with a sensitivity-using method
694
+ mcmc = pints .MCMCController (
695
+ self .log_posterior , n_chains , xs , method = pints .MALAMCMC )
696
+ mcmc .set_max_iterations (n_iterations )
697
+ mcmc .set_log_to_screen (False )
698
+ mcmc .set_log_pdf_storage (True )
699
+ chains = mcmc .run ()
700
+ evals = mcmc .log_pdfs ()
701
+ self .assertEqual (len (evals .shape ), 3 )
702
+ self .assertEqual (evals .shape [0 ], n_chains )
703
+ self .assertEqual (evals .shape [1 ], n_iterations )
704
+ self .assertEqual (evals .shape [2 ], 3 )
705
+ for i , chain in enumerate (chains ):
706
+ posteriors = [self .log_posterior (x ) for x in chain ]
707
+ self .assertTrue (np .all (evals [i , :, 0 ] == posteriors ))
708
+ likelihoods = [self .log_likelihood (x ) for x in chain ]
709
+ self .assertTrue (np .all (evals [i , :, 1 ] == likelihoods ))
710
+ priors = [self .log_prior (x ) for x in chain ]
711
+ self .assertTrue (np .all (evals [i , :, 2 ] == priors ))
712
+
693
713
# Test disabling again
694
714
mcmc = pints .MCMCController (self .log_posterior , n_chains , xs )
695
715
mcmc .set_max_iterations (n_iterations )
@@ -706,7 +726,9 @@ def test_log_pdf_storage_in_memory_multi(self):
706
726
x0 = np .array (self .real_parameters ) * 1.05
707
727
x1 = np .array (self .real_parameters ) * 1.15
708
728
x2 = np .array (self .real_parameters ) * 0.95
709
- xs = [x0 , x1 , x2 ]
729
+ x3 = np .array (self .real_parameters ) * 0.95
730
+ x4 = np .array (self .real_parameters ) * 0.95
731
+ xs = [x0 , x1 , x2 , x3 , x4 ]
710
732
n_chains = len (xs )
711
733
n_iterations = 100
712
734
meth = pints .DifferentialEvolutionMCMC
@@ -737,6 +759,28 @@ def test_log_pdf_storage_in_memory_multi(self):
737
759
priors = [self .log_prior (x ) for x in chain ]
738
760
self .assertTrue (np .all (evals [i , :, 2 ] == priors ))
739
761
762
+ # Test with a sensitivity-using multi-chain method
763
+ # We don't have any of these!
764
+ mcmc = pints .MCMCController (
765
+ self .log_posterior , n_chains , xs ,
766
+ method = FakeMultiChainSamplerWithSensitivities )
767
+ mcmc .set_max_iterations (n_iterations )
768
+ mcmc .set_log_to_screen (False )
769
+ mcmc .set_log_pdf_storage (True )
770
+ chains = mcmc .run ()
771
+ evals = mcmc .log_pdfs ()
772
+ self .assertEqual (len (evals .shape ), 3 )
773
+ self .assertEqual (evals .shape [0 ], n_chains )
774
+ self .assertEqual (evals .shape [1 ], n_iterations )
775
+ self .assertEqual (evals .shape [2 ], 3 )
776
+ for i , chain in enumerate (chains ):
777
+ posteriors = [self .log_posterior (x ) for x in chain ]
778
+ self .assertTrue (np .all (evals [i , :, 0 ] == posteriors ))
779
+ likelihoods = [self .log_likelihood (x ) for x in chain ]
780
+ self .assertTrue (np .all (evals [i , :, 1 ] == likelihoods ))
781
+ priors = [self .log_prior (x ) for x in chain ]
782
+ self .assertTrue (np .all (evals [i , :, 2 ] == priors ))
783
+
740
784
# Test with a loglikelihood
741
785
mcmc = pints .MCMCController (
742
786
self .log_likelihood , n_chains , xs , method = meth )
@@ -1651,6 +1695,29 @@ def tell(self, fx):
1651
1695
return None if x is None else (x , fx , np .array ([True ] * self ._n ))
1652
1696
1653
1697
1698
+ class FakeMultiChainSamplerWithSensitivities (pints .MultiChainMCMC ):
1699
+ """
1700
+ Fake sampler that pretends to be a multi-chain method that uses
1701
+ sensitivities. At the moment (2024-12-18) we don't have these in PINTS, but
1702
+ we need to check that code potentially handling this type of sampler exists
1703
+ or raises not-implemented errors.
1704
+ """
1705
+ def ask (self ):
1706
+ self ._xs = self ._x0 + 1e-3 * np .random .uniform (
1707
+ size = (self ._n_chains , self ._n_parameters ))
1708
+ return self ._xs
1709
+
1710
+ def current_log_pdfs (self ):
1711
+ return self ._fxs
1712
+
1713
+ def tell (self , fxs ):
1714
+ self ._fxs = fxs
1715
+ return self ._xs , self ._fxs , [True ] * self ._n_chains
1716
+
1717
+ def needs_sensitivities (self ):
1718
+ return True
1719
+
1720
+
1654
1721
class TestMCMCControllerSingleChainStorage (unittest .TestCase ):
1655
1722
"""
1656
1723
Tests storage of samples and evaluations to disk, running with a
0 commit comments