示例#1
0
 def test_MultivariateNormalQMCEngineDegenerate(self):
     for dtype in (torch.float, torch.double):
         # X, Y iid standard Normal and Z = X + Y, random vector (X, Y, Z)
         mean = torch.zeros(3, device=self.device, dtype=dtype)
         cov = torch.tensor(
             [[1, 0, 1], [0, 1, 1], [1, 1, 2]], device=self.device, dtype=dtype
         )
         engine = MultivariateNormalQMCEngine(mean=mean, cov=cov, seed=12345)
         samples = engine.draw(n=4096)
         self.assertEqual(samples.dtype, dtype)
         self.assertEqual(samples.device.type, self.device.type)
         self.assertTrue(torch.all(torch.abs(samples.mean(dim=0)) < 1e-2))
         self.assertTrue(torch.abs(torch.std(samples[:, 0]) - 1) < 1e-2)
         self.assertTrue(torch.abs(torch.std(samples[:, 1]) - 1) < 1e-2)
         self.assertTrue(torch.abs(torch.std(samples[:, 2]) - math.sqrt(2)) < 1e-2)
         for i in (0, 1, 2):
             _, pval = shapiro(samples[:, i].cpu().numpy())
             self.assertGreater(pval, 0.9)
         cov = np.cov(samples.cpu().numpy().transpose())
         self.assertLess(np.abs(cov[0, 1]), 1e-2)
         self.assertLess(np.abs(cov[0, 2] - 1), 1e-2)
         # check to see if X + Y = Z almost exactly
         self.assertTrue(
             torch.all(
                 torch.abs(samples[:, 0] + samples[:, 1] - samples[:, 2]) < 1e-5
             )
         )
示例#2
0
 def test_MultivariateNormalQMCEngineInvTransform(self):
     for d, dtype in itertools.product((1, 2, 3), (torch.float, torch.double)):
         mean = torch.rand(d, device=self.device, dtype=dtype)
         cov = torch.eye(d, device=self.device, dtype=dtype)
         engine = MultivariateNormalQMCEngine(mean=mean, cov=cov, inv_transform=True)
         samples = engine.draw()
         self.assertEqual(samples.dtype, dtype)
         self.assertEqual(samples.device.type, self.device.type)
         self.assertEqual(samples.shape, torch.Size([1, d]))
         samples = engine.draw(n=5)
         self.assertEqual(samples.shape, torch.Size([5, d]))
示例#3
0
 def test_MultivariateNormalQMCEngineSymmetric(self):
     for dtype in (torch.float, torch.double):
         # try with non-symmetric cov and expect an error
         mean = torch.zeros(2, device=self.device, dtype=dtype)
         cov = torch.tensor([[1, 0], [2, 1]], device=self.device, dtype=dtype)
         with self.assertRaises(ValueError):
             MultivariateNormalQMCEngine(mean=mean, cov=cov)
示例#4
0
 def test_MultivariateNormalQMCEngineNonPSD(self, cuda=False):
     device = torch.device("cuda") if cuda else torch.device("cpu")
     for dtype in (torch.float, torch.double):
         # try with non-psd, non-pd cov and expect an assertion error
         mean = torch.zeros(2, device=device, dtype=dtype)
         cov = torch.tensor([[1, 2], [2, 1]], device=device, dtype=dtype)
         with self.assertRaises(ValueError):
             MultivariateNormalQMCEngine(mean=mean, cov=cov)
示例#5
0
 def test_MultivariateNormalQMCEngineNonPD(self):
     for dtype in (torch.float, torch.double):
         mean = torch.zeros(3, device=self.device, dtype=dtype)
         cov = torch.tensor(
             [[1, 0, 1], [0, 1, 1], [1, 1, 2]], device=self.device, dtype=dtype
         )
         # try with non-pd but psd cov; should work
         engine = MultivariateNormalQMCEngine(mean=mean, cov=cov)
         self.assertTrue(engine._corr_matrix is not None)
示例#6
0
    def test_MultivariateNormalQMCEngineShapiroInvTransform(self, cuda=False):
        device = torch.device("cuda") if cuda else torch.device("cpu")
        for dtype in (torch.float, torch.double):
            # test the standard case
            mean = torch.zeros(2, device=device, dtype=dtype)
            cov = torch.eye(2, device=device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean,
                                                 cov=cov,
                                                 seed=12345,
                                                 inv_transform=True)
            samples = engine.draw(n=250)
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, device.type)
            self.assertTrue(torch.all(torch.abs(samples.mean(dim=0)) < 1e-2))
            self.assertTrue(
                torch.all(torch.abs(samples.std(dim=0) - 1) < 1e-2))
            # perform Shapiro-Wilk test for normality
            samples = samples.cpu().numpy()
            for i in (0, 1):
                _, pval = shapiro(samples[:, i])
                self.assertGreater(pval, 0.9)
            # make sure samples are uncorrelated
            cov = np.cov(samples.transpose())
            self.assertLess(np.abs(cov[0, 1]), 1e-2)

            # test the correlated, non-zero mean case
            mean = torch.tensor([1.0, 2.0], device=device, dtype=dtype)
            cov = torch.tensor([[1.5, 0.5], [0.5, 1.5]],
                               device=device,
                               dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean,
                                                 cov=cov,
                                                 seed=12345,
                                                 inv_transform=True)
            samples = engine.draw(n=250)
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, device.type)
            self.assertTrue(
                torch.all(torch.abs(samples.mean(dim=0) - mean) < 1e-2))
            self.assertTrue(
                torch.all(
                    torch.abs(samples.std(dim=0) - math.sqrt(1.5)) < 1e-2))
            # perform Shapiro-Wilk test for normality
            samples = samples.cpu().numpy()
            for i in (0, 1):
                _, pval = shapiro(samples[:, i])
                self.assertGreater(pval, 0.9)
            # check covariance
            cov = np.cov(samples.transpose())
            self.assertLess(np.abs(cov[0, 1] - 0.5), 1e-2)
示例#7
0
    def test_MultivariateNormalQMCEngineSeededInvTransform(self, cuda=False):
        device = torch.device("cuda") if cuda else torch.device("cpu")
        for dtype in (torch.float, torch.double):
            # test even dimension
            with manual_seed(54321):
                a = torch.randn(2, 2)
                cov = a @ a.transpose(-1, -2) + torch.rand(2).diag()

            mean = torch.zeros(2, device=device, dtype=dtype)
            cov = cov.to(device=device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean,
                                                 cov=cov,
                                                 seed=12345,
                                                 inv_transform=True)
            samples = engine.draw(n=2)
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, device.type)
            samples_expected = torch.tensor(
                [[-0.560064316, 0.629113674], [-1.292604208, -0.048077226]],
                device=device,
                dtype=dtype,
            )
            self.assertTrue(torch.allclose(samples, samples_expected))

            # test odd dimension
            with manual_seed(54321):
                a = torch.randn(3, 3)
                cov = a @ a.transpose(-1, -2) + torch.rand(3).diag()

            mean = torch.zeros(3, device=device, dtype=dtype)
            cov = cov.to(device=device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean,
                                                 cov=cov,
                                                 seed=12345,
                                                 inv_transform=True)
            samples = engine.draw(n=2)
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, device.type)
            samples_expected = torch.tensor(
                [
                    [-2.388370037, 3.071142435, -0.319439292],
                    [-0.282978594, -4.350236893, -1.085214734],
                ],
                device=device,
                dtype=dtype,
            )
            self.assertTrue(torch.allclose(samples, samples_expected))
示例#8
0
    def test_MultivariateNormalQMCEngineSeeded(self, cuda=False):
        device = torch.device("cuda") if cuda else torch.device("cpu")
        for dtype in (torch.float, torch.double):

            # test even dimension
            with manual_seed(54321):
                a = torch.randn(2, 2)
                cov = a @ a.transpose(-1, -2) + torch.rand(2).diag()

            mean = torch.zeros(2, device=device, dtype=dtype)
            cov = cov.to(device=device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean,
                                                 cov=cov,
                                                 seed=12345)
            samples = engine.draw(n=2)
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, device.type)
            samples_expected = torch.tensor(
                [[-0.849047422, -0.713852942], [0.398635030, 1.350660801]],
                device=device,
                dtype=dtype,
            )
            self.assertTrue(torch.allclose(samples, samples_expected))

            # test odd dimension
            with manual_seed(54321):
                a = torch.randn(3, 3)
                cov = a @ a.transpose(-1, -2) + torch.rand(3).diag()

            mean = torch.zeros(3, device=device, dtype=dtype)
            cov = cov.to(device=device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean, cov, seed=12345)
            samples = engine.draw(n=2)
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, device.type)
            samples_expected = torch.tensor(
                [
                    [3.113158941, -3.262257099, -0.819938779],
                    [0.621987879, 2.352285624, -1.992680788],
                ],
                device=device,
                dtype=dtype,
            )
            self.assertTrue(torch.allclose(samples, samples_expected))
示例#9
0
 def test_MultivariateNormalQMCEngineSeededOut(self):
     for dtype in (torch.float, torch.double):
         # test even dimension
         a = torch.randn(2, 2)
         cov = a @ a.transpose(-1, -2) + torch.rand(2).diag()
         mean = torch.zeros(2, device=self.device, dtype=dtype)
         cov = cov.to(device=self.device, dtype=dtype)
         engine = MultivariateNormalQMCEngine(mean=mean, cov=cov, seed=12345)
         out = torch.zeros(2, 2, device=self.device, dtype=dtype)
         self.assertIsNone(engine.draw(n=2, out=out))
         self.assertTrue(torch.all(out != 0))
         # test odd dimension
         a = torch.randn(3, 3)
         cov = a @ a.transpose(-1, -2) + torch.rand(3).diag()
         mean = torch.zeros(3, device=self.device, dtype=dtype)
         cov = cov.to(device=self.device, dtype=dtype)
         engine = MultivariateNormalQMCEngine(mean, cov, seed=12345)
         out = torch.zeros(2, 3, device=self.device, dtype=dtype)
         self.assertIsNone(engine.draw(n=2, out=out))
         self.assertTrue(torch.all(out != 0))
示例#10
0
    def test_MultivariateNormalQMCEngineSeededOut(self):
        for dtype in (torch.float, torch.double):

            # test even dimension
            with manual_seed(54321):
                a = torch.randn(2, 2)
                cov = a @ a.transpose(-1, -2) + torch.rand(2).diag()

            mean = torch.zeros(2, device=self.device, dtype=dtype)
            cov = cov.to(device=self.device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean,
                                                 cov=cov,
                                                 seed=12345)
            out = torch.empty(2, 2, device=self.device, dtype=dtype)
            self.assertIsNone(engine.draw(n=2, out=out))
            samples_expected = torch.tensor(
                [[-0.849047422, -0.713852942], [0.398635030, 1.350660801]],
                device=self.device,
                dtype=dtype,
            )
            self.assertTrue(torch.allclose(out, samples_expected))

            # test odd dimension
            with manual_seed(54321):
                a = torch.randn(3, 3)
                cov = a @ a.transpose(-1, -2) + torch.rand(3).diag()

            mean = torch.zeros(3, device=self.device, dtype=dtype)
            cov = cov.to(device=self.device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean, cov, seed=12345)
            out = torch.empty(2, 3, device=self.device, dtype=dtype)
            self.assertIsNone(engine.draw(n=2, out=out))
            samples_expected = torch.tensor(
                [
                    [3.113158941, -3.262257099, -0.819938779],
                    [0.621987879, 2.352285624, -1.992680788],
                ],
                device=self.device,
                dtype=dtype,
            )
            self.assertTrue(torch.allclose(out, samples_expected))
示例#11
0
    def test_MultivariateNormalQMCEngineSeeded(self):
        for dtype in (torch.float, torch.double):

            # test even dimension
            a = torch.randn(2, 2)
            cov = a @ a.transpose(-1, -2) + torch.rand(2).diag()
            mean = torch.zeros(2, device=self.device, dtype=dtype)
            cov = cov.to(device=self.device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean, cov=cov, seed=12345)
            samples = engine.draw(n=2)
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, self.device.type)

            # test odd dimension
            a = torch.randn(3, 3)
            cov = a @ a.transpose(-1, -2) + torch.rand(3).diag()
            mean = torch.zeros(3, device=self.device, dtype=dtype)
            cov = cov.to(device=self.device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean, cov, seed=12345)
            samples = engine.draw(n=2)
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, self.device.type)
示例#12
0
 def test_MultivariateNormalQMCEngineShapeErrors(self):
     with self.assertRaises(ValueError):
         MultivariateNormalQMCEngine(mean=torch.zeros(2), cov=torch.zeros(2, 1))
     with self.assertRaises(ValueError):
         MultivariateNormalQMCEngine(mean=torch.zeros(1), cov=torch.eye(2))
示例#13
0
    def test_MultivariateNormalQMCEngineInvTransform(self, cuda=False):
        device = torch.device("cuda") if cuda else torch.device("cpu")
        for dtype in (torch.float, torch.double):

            # d = 1 scalar
            mean = torch.tensor([0], device=device, dtype=dtype)
            cov = torch.tensor([[5]], device=device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean, cov=cov, inv_transform=True)
            samples = engine.draw()
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, device.type)
            self.assertEqual(samples.shape, torch.Size([1, 1]))
            samples = engine.draw(n=5)
            self.assertEqual(samples.shape, torch.Size([5, 1]))

            # d = 2 list
            mean = torch.tensor([0, 1], device=device, dtype=dtype)
            cov = torch.eye(2, device=device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean, cov=cov, inv_transform=True)
            samples = engine.draw()
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, device.type)
            self.assertEqual(samples.shape, torch.Size([1, 2]))
            samples = engine.draw(n=5)
            self.assertEqual(samples.shape, torch.Size([5, 2]))

            # d = 3 Tensor
            mean = torch.tensor([0, 1, 2], device=device, dtype=dtype)
            cov = torch.eye(3, device=device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean, cov=cov, inv_transform=True)
            samples = engine.draw()
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, device.type)
            self.assertEqual(samples.shape, torch.Size([1, 3]))
            samples = engine.draw(n=5)
            self.assertEqual(samples.shape, torch.Size([5, 3]))
示例#14
0
    def test_MultivariateNormalQMCEngine(self):
        for dtype in (torch.float, torch.double):

            # d = 1 scalar
            mean = torch.tensor([0], device=self.device, dtype=dtype)
            cov = torch.tensor([[5]], device=self.device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean, cov=cov)
            samples = engine.draw()
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, self.device.type)
            self.assertEqual(samples.shape, torch.Size([1, 1]))
            samples = engine.draw(n=5)
            self.assertEqual(samples.shape, torch.Size([5, 1]))

            # d = 2 list
            mean = torch.tensor([0, 1], device=self.device, dtype=dtype)
            cov = torch.eye(2, device=self.device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean, cov=cov)
            samples = engine.draw()
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, self.device.type)
            self.assertEqual(samples.shape, torch.Size([1, 2]))
            samples = engine.draw(n=5)
            self.assertEqual(samples.shape, torch.Size([5, 2]))

            # d = 3 Tensor
            mean = torch.tensor([0, 1, 2], device=self.device, dtype=dtype)
            cov = torch.eye(3, device=self.device, dtype=dtype)
            engine = MultivariateNormalQMCEngine(mean=mean, cov=cov)
            samples = engine.draw()
            self.assertEqual(samples.dtype, dtype)
            self.assertEqual(samples.device.type, self.device.type)
            self.assertEqual(samples.shape, torch.Size([1, 3]))
            samples = engine.draw(n=5)
            self.assertEqual(samples.shape, torch.Size([5, 3]))