4 Defines various nose unit tests
10 from .mh
import MHSampler
11 from .ensemble
import EnsembleSampler
12 from .ptsampler
import PTSampler
17 def lnprob_gaussian(x, icov):
18 return -np.dot(x, np.dot(icov, x)) / 2.0
21 def lnprob_gaussian_nan(x, icov):
23 if not (np.array(x)).any():
26 result = -np.dot(x, np.dot(icov, x)) / 2.0
31 def log_unit_sphere_volume(ndim):
34 for i
in range(1, ndim / 2 + 1):
35 logfactorial += np.log(i)
36 return ndim / 2.0 * np.log(np.pi) - logfactorial
39 for i
in range(1, ndim + 1, 2):
40 logfactorial += np.log(i)
41 return (ndim + 1) / 2.0 * np.log(2.0) \
42 + (ndim - 1) / 2.0 * np.log(np.pi) - logfactorial
47 """Initialize a gaussian PDF with the given inverse covariance
48 matrix. If not ``None``, ``cutoff`` truncates the PDF at the
49 given number of sigma from the origin (i.e. the PDF is
50 non-zero only on an ellipse aligned with the principal axes of
51 the distribution). Without this cutoff, thermodynamic
52 integration with a flat prior is logarithmically divergent."""
57 def __call__(self, x):
58 dist2 = lnprob_gaussian(x, self.
icov)
60 if self.
cutoff is not None:
84 self.
cov = 0.5 - np.random.rand(self.
ndim ** 2) \
86 self.
cov = np.triu(self.
cov)
87 self.
cov += self.cov.T - np.diag(self.cov.diagonal())
89 self.
icov = np.linalg.inv(self.
cov)
90 self.
p0 = [0.1 * np.random.randn(self.
ndim)
92 self.
truth = np.random.multivariate_normal(self.
mean, self.
cov, 100000)
94 def check_sampler(self, N=None, p0=None):
100 for i
in self.sampler.sample(p0, iterations=N):
103 assert np.mean(self.sampler.acceptance_fraction) > 0.25
104 assert np.all(self.sampler.acceptance_fraction > 0)
106 chain = self.sampler.flatchain
107 maxdiff = 10. ** (logprecision)
108 assert np.all((np.mean(chain, axis=0) - self.
mean) ** 2 / self.
N ** 2
110 assert np.all((np.cov(chain, rowvar=0) - self.
cov) ** 2 / self.
N ** 2
113 def check_pt_sampler(self, cutoff, N=None, p0=None):
119 for i
in self.sampler.sample(p0, iterations=N):
123 assert np.mean(self.sampler.acceptance_fraction) > 0.1
124 assert np.mean(self.sampler.tswap_acceptance_fraction) > 0.1
126 maxdiff = 10.0 ** logprecision
128 chain = np.reshape(self.sampler.chain[0, ...],
129 (-1, self.sampler.chain.shape[-1]))
131 log_volume = self.
ndim * np.log(cutoff) \
132 + log_unit_sphere_volume(self.
ndim) \
133 + 0.5 * np.log(np.linalg.det(self.
cov))
134 gaussian_integral = self.
ndim / 2.0 * np.log(2.0 * np.pi) \
135 + 0.5 * np.log(np.linalg.det(self.
cov))
137 lnZ, dlnZ = self.sampler.thermodynamic_integration_log_evidence()
139 assert np.abs(lnZ - (gaussian_integral - log_volume)) < 3 * dlnZ
140 assert np.all((np.mean(chain, axis=0) - self.
mean) ** 2.0 / N ** 2.0
142 assert np.all((np.cov(chain, rowvar=0) - self.
cov) ** 2.0 / N ** 2.0
150 def test_ensemble(self):
152 lnprob_gaussian, args=[self.
icov])
155 def test_nan_lnprob(self):
170 assert False,
"We should never get here."
172 def test_inf_nan_params(self):
174 lnprob_gaussian, args=[self.
icov])
188 assert False,
"The sampler should have failed by now."
201 assert False,
"The sampler should have failed by now."
214 assert False,
"The sampler should have failed by now."
222 def test_pt_sampler(self):
227 p0 = np.random.multivariate_normal(mean=self.
mean, cov=self.
cov,
231 def test_blobs(self):
232 lnprobfn =
lambda p: (-0.5 * np.sum(p ** 2), np.random.rand())
237 assert (self.sampler.chain.shape == (self.
nwalkers, self.
N, self.
ndim)
238 and len(self.sampler.blobs) == self.
N
239 and len(self.sampler.blobs[0]) == self.
nwalkers), \
240 "The blob dimensions are wrong."
243 blobs = self.sampler.blobs
244 assert np.any([blobs[-1] != blobs[i]
for i
in range(len(blobs) - 1)])