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]))
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)
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 ) )
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))
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))
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))
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))
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]))
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)
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]))