def test_GaussianPrior(): mean = 20 sigma = 4 P1 = GaussianPrior(mean=mean, sigma=sigma, variable_indices=[0]) # Check some basic properties assert P1.mean == mean assert P1.sigma == sigma assert P1.bounds == [(None, None)] # Check that log probability is symmetric about mean log_probability = [P1(array([i])) for i in range(1, mean * 2)] assert log_probability[:mean] == log_probability[mean - 1 :][::-1] def analytic_probability(x, mu, sigma): return (1.0 / sqrt(2 * pi * sigma**2)) * exp( -((x - mu) ** 2) / (2 * sigma**2) ) test_point = mean - 2 * sigma assert isclose( exp(P1(array([test_point]))), analytic_probability(test_point, mean, sigma) ) assert isclose(exp(P1(array([-1]))), analytic_probability(-1, mean, sigma)) # Check sampling produces expected distribution sample = array([P1.sample() for _ in range(1000)]) assert isclose(sample.mean(), mean, rtol=0.2) assert isclose(sample.std(), sigma, rtol=0.2)
def test_GaussianPrior_combined(): # test combining multiple Gaussians P1 = GaussianPrior(mean=10, sigma=1, variable_indices=[0]) P2 = GaussianPrior(mean=20, sigma=2, variable_indices=[1]) P3 = GaussianPrior(mean=[30, 40], sigma=[3, 4], variable_indices=[2, 3]) combo = GaussianPrior.combine([P1, P2, P3]) # check the combined distribution has the right values assert (combo.mean == array([10.0, 20.0, 30.0, 40.0])).all() assert (combo.sigma == array([1.0, 2.0, 3.0, 4.0])).all() assert all(a == b for a, b in zip(combo.variables, [0, 1, 2, 3])) assert combo.bounds == [(None, None), (None, None), (None, None), (None, None)]
def test_GaussianPrior_gradient(): # test combining multiple Gaussians P1 = GaussianPrior(mean=10, sigma=1, variable_indices=[0]) P2 = GaussianPrior(mean=20, sigma=2, variable_indices=[1]) P3 = GaussianPrior(mean=[30, 40], sigma=[3, 4], variable_indices=[2, 3]) combo = GaussianPrior.combine([P1, P2, P3]) # evaluate the prior at a test point test_point = array([9.0, 21.0, 34.0, 35.0]) # check the analytic gradient calculation against finite difference analytic_gradient = combo.gradient(test_point) numeric_gradient = finite_difference( func=combo, x0=test_point, vectorised_arguments=True ) assert allclose(analytic_gradient, numeric_gradient)
def test_JointPrior_gradient(): P1 = ExponentialPrior(beta=10, variable_indices=[1]) P2 = GaussianPrior(mean=20, sigma=2, variable_indices=[0]) P3 = UniformPrior(lower=8, upper=16, variable_indices=[2]) JP = JointPrior(components=[P1, P2, P3], n_variables=3) test_point = array([4.0, 23.0, 12.0]) analytic_gradient = JP.gradient(test_point) numeric_gradient = finite_difference( func=JP, x0=test_point, vectorised_arguments=True ) assert allclose(analytic_gradient, numeric_gradient)
def test_JointPrior(): P1 = ExponentialPrior(beta=10, variable_indices=[1]) P2 = GaussianPrior(mean=20, sigma=2, variable_indices=[0]) P3 = UniformPrior(lower=8, upper=16, variable_indices=[2]) components = [P1, P2, P3] JP = JointPrior(components=components, n_variables=3) sample = array([JP.sample() for _ in range(1000)]) assert sample.shape[1] == len(components) assert isclose(sample[:, 0].mean(), P2.mean, rtol=0.2) assert isclose(sample[:, 0].std(), P2.sigma, rtol=0.2) for index, (lower, upper) in enumerate(JP.bounds): if lower is not None: assert all(sample[:, index] >= lower) if upper is not None: assert all(sample[:, index] <= upper)
def test_JointPrior_repeat_variable(): P1 = ExponentialPrior(beta=10, variable_indices=[0]) P2 = GaussianPrior(mean=20, sigma=2, variable_indices=[0]) P3 = UniformPrior(lower=8, upper=16, variable_indices=[2]) with pytest.raises(ValueError): JointPrior(components=[P1, P2, P3], n_variables=3)
def test_GaussianPrior_bad_sigma(): with pytest.raises(ValueError): GaussianPrior(mean=zeros(2), sigma=[1.0, 0.0], variable_indices=[0])
def test_GaussianPrior_inconsistent_dimensions(): with pytest.raises(ValueError): GaussianPrior(mean=zeros((2, 2)), sigma=ones(4), variable_indices=[0]) with pytest.raises(ValueError): GaussianPrior(mean=zeros(4), sigma=ones((2, 2)), variable_indices=[0])
def test_GaussianPrior_inconsistent_size_squeezed_dim(): with pytest.raises(ValueError): GaussianPrior(mean=zeros((2, 1, 2)), sigma=ones(2), variable_indices=[0, 1])
def test_GaussianPrior_inconsistent_size(): with pytest.raises(ValueError): GaussianPrior(mean=zeros(1), sigma=ones(2), variable_indices=[0])