예제 #1
0
    def test_truncated_gaussian_prior_cdf_icdf(self):
        mean = 10.0
        std = 2.0
        a = -1.0
        b = 14.0
        p = pints.TruncatedGaussianLogPrior(mean, std, a, b)

        ndtr = scipy.special.ndtr
        x = 3.0
        theoretical_cdf = (ndtr((x - mean) / std) - ndtr((a - mean) / std)) \
            / (ndtr((b - mean) / std) - ndtr((a - mean) / std))
        self.assertAlmostEqual(p.cdf(x), theoretical_cdf)

        mean = 0.0
        std = 2.0
        a = -4.0
        b = 4.0
        p = pints.TruncatedGaussianLogPrior(mean, std, a, b)
        self.assertAlmostEqual(p.icdf(0.5), 0.0)
        self.assertTrue(2.0 < p.icdf(0.99) < 4.0)
        self.assertTrue(-4.0 < p.icdf(0.01) < -2.0)
예제 #2
0
    def test_truncated_gaussian_prior_sampling(self):
        mean = 10.0
        std = 2.0
        a = -1.0
        b = 14.0
        p = pints.TruncatedGaussianLogPrior(mean, std, a, b)

        # Check number of samples
        d = 1
        n = 1
        x = p.sample(n)
        self.assertEqual(x.shape, (n, d))
        n = 10
        x = p.sample(n)
        self.assertEqual(x.shape, (n, d))

        # Check that the positions of samples are within truncation limits
        np.random.seed(1)
        x = p.sample(10000)
        self.assertTrue(np.max(x) <= 14.0)
        self.assertTrue(np.min(x) >= -1.0)
예제 #3
0
    def test_truncated_gaussian_prior(self):
        mean = 10
        std = 2
        a = -1.0
        b = 14.0
        p = pints.TruncatedGaussianLogPrior(mean, std, a, b)

        n = 10000

        # Test left half of distribution
        x = np.linspace(mean - 5.5 * std, mean, n)
        px = [p([i]) for i in x]
        self.assertTrue(np.all(px[1:] >= px[:-1]))

        # Test right half of distribution
        y = np.linspace(mean, mean + 2 * std, n)
        py = [p([i]) for i in y]
        self.assertTrue(np.all(py[1:] <= py[:-1]))

        # Test means
        mean = 1.0
        std = 1.5
        a = 2.0
        b = 11.0
        p = pints.TruncatedGaussianLogPrior(mean, std, a, b)

        phi = scipy.stats.norm.pdf
        ndtr = scipy.special.ndtr
        theoretical_mean = \
            mean + std / (ndtr((b - mean) / std) - ndtr((a - mean) / std)) \
            * (phi((a - mean) / std) - phi((b - mean) / std))
        self.assertAlmostEqual(p.mean(), theoretical_mean)

        # Test derivatives
        x = [4.5]
        y, dy = p.evaluateS1(x)
        self.assertEqual(y, p(x))
        self.assertEqual(dy.shape, (1, ))

        dx = 1e-6
        self.assertAlmostEqual(dy[0], (p([x[0] + dx]) - p(x)) / dx, places=4)

        # Test inputs outside the truncation limits
        x = [11.5]
        y, dy = p.evaluateS1(x)
        self.assertTrue(np.isneginf(p(x)))
        self.assertTrue(np.isneginf(y))
        self.assertTrue(np.isnan(dy))

        x = [-1.0]
        y, dy = p.evaluateS1(x)
        self.assertTrue(np.isneginf(p(x)))
        self.assertTrue(np.isneginf(y))
        self.assertTrue(np.isnan(dy))

        # Test specific points
        mean = 5.0
        std = 2.5
        a = 0.0
        b = 10.0
        p = pints.TruncatedGaussianLogPrior(mean, std, a, b)
        self.assertAlmostEqual(
            p([5.0]),
            scipy.stats.truncnorm.logpdf(5.0, -2, 2, loc=mean, scale=std)
        )

        self.assertAlmostEqual(
            p([0.1]),
            scipy.stats.truncnorm.logpdf(0.1, -2, 2, loc=mean, scale=std)
        )

        # Test input at each bound, this should return a finite number
        x = [b]
        self.assertTrue(np.isfinite(p(x)))

        x = [a]
        self.assertTrue(np.isfinite(p(x)))

        # Test n_parameters
        self.assertEqual(p.n_parameters(), 1)

        # Test one sided truncation
        mean = 5.0
        std = 2.5
        a = 0.0
        b = np.inf
        p = pints.TruncatedGaussianLogPrior(mean, std, a, b)
        result = p([1e5])
        self.assertTrue(np.isfinite(result))

        mean = 5.0
        std = 2.5
        a = -np.inf
        b = 10.0
        p = pints.TruncatedGaussianLogPrior(mean, std, a, b)
        result = p([-1e5])
        self.assertTrue(np.isfinite(result))

        # Test bad truncation
        self.assertRaises(
            ValueError, pints.TruncatedGaussianLogPrior, 0.0, 1.0, 10.0, 9.0)

        self.assertRaises(
            ValueError, pints.TruncatedGaussianLogPrior, 0.0, 1.0, 10.0, 10.0)