def test_clone(self): """ Check that cloned transformations contain different _matrix objects. Also, the clone of a composed translation and rotation has to be the same as composition of clones of translation and rotation. """ tr = Translate(torch.FloatTensor([[1.0, 2.0, 3.0]])) R = torch.FloatTensor([[0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]]) R = Rotate(R) # check that the _matrix property of clones of # both transforms are different for t in (R, tr): self.assertTrue(t._matrix is not t.clone()._matrix) # check that the _transforms lists of composition of R, tr contain # different objects t1 = Transform3d().compose(R, tr) for t, t_clone in (t1._transforms, t1.clone()._transforms): self.assertTrue(t is not t_clone) self.assertTrue(t._matrix is not t_clone._matrix) # check that all composed transforms are numerically equivalent t2 = Transform3d().compose(R.clone(), tr.clone()) t3 = t1.clone() for t_pair in ((t1, t2), (t1, t3), (t2, t3)): matrix1 = t_pair[0].get_matrix() matrix2 = t_pair[1].get_matrix() self.assertTrue(torch.allclose(matrix1, matrix2))
def test_inverse(self, batch_size=5): device = torch.device("cuda:0") log_rot = torch.randn((batch_size, 3), dtype=torch.float32, device=device) R = so3_exp_map(log_rot) t = Rotate(R) im = t.inverse()._matrix im_2 = t._matrix.inverse() im_comp = t.get_matrix().inverse() self.assertTrue(torch.allclose(im, im_comp, atol=1e-4)) self.assertTrue(torch.allclose(im, im_2, atol=1e-4))
def test_inverse(self, batch_size=5): device = torch.device("cuda:0") # generate a random chain of transforms for _ in range(10): # 10 different tries # list of transform matrices ts = [] for i in range(10): choice = float(torch.rand(1)) if choice <= 1.0 / 3.0: t_ = Translate( torch.randn((batch_size, 3), dtype=torch.float32, device=device), device=device, ) elif choice <= 2.0 / 3.0: t_ = Rotate( so3_exponential_map( torch.randn( (batch_size, 3), dtype=torch.float32, device=device, )), device=device, ) else: rand_t = torch.randn((batch_size, 3), dtype=torch.float32, device=device) rand_t = rand_t.sign() * torch.clamp(rand_t.abs(), 0.2) t_ = Scale(rand_t, device=device) ts.append(t_._matrix.clone()) if i == 0: t = t_ else: t = t.compose(t_) # generate the inverse transformation in several possible ways m1 = t.inverse(invert_composed=True).get_matrix() m2 = t.inverse(invert_composed=True)._matrix m3 = t.inverse(invert_composed=False).get_matrix() m4 = t.get_matrix().inverse() # compute the inverse explicitly ... m5 = torch.eye(4, dtype=torch.float32, device=device) m5 = m5[None].repeat(batch_size, 1, 1) for t_ in ts: m5 = torch.bmm(torch.inverse(t_), m5) # assert all same for m in (m1, m2, m3, m4): self.assertTrue(torch.allclose(m, m5, atol=1e-3))
def test_to(self): tr = Translate(torch.FloatTensor([[1.0, 2.0, 3.0]])) R = torch.FloatTensor([[0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]]) R = Rotate(R) t = Transform3d().compose(R, tr) for _ in range(3): t.cpu() t.cuda() t.cuda() t.cpu()
def test_single_matrix(self): R = torch.eye(3) t = Rotate(R) matrix = torch.tensor( [[ [1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0], ]], dtype=torch.float32, ) self.assertTrue(torch.allclose(t._matrix, matrix))
def test_to(self): tr = Translate(torch.FloatTensor([[1.0, 2.0, 3.0]])) R = torch.FloatTensor([[0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]]) cpu_points = torch.rand(9, 3) cuda_points = cpu_points.cuda() R = Rotate(R) t = Transform3d().compose(R, tr) for _ in range(3): t = t.cpu() t.transform_points(cpu_points) t = t.cuda() t.transform_points(cuda_points) t = t.cuda() t = t.cpu()
def test_invalid_dimensions(self): R = torch.eye(4) with self.assertRaises(ValueError): Rotate(R)
def test_to(self): tr = Translate(torch.FloatTensor([[1.0, 2.0, 3.0]])) R = torch.FloatTensor([[0.0, 1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0, 0.0]]) R = Rotate(R) t = Transform3d().compose(R, tr) cpu_device = torch.device("cpu") cpu_t = t.to("cpu") self.assertEqual(cpu_device, cpu_t.device) self.assertEqual(cpu_device, t.device) self.assertEqual(torch.float32, cpu_t.dtype) self.assertEqual(torch.float32, t.dtype) self.assertIs(t, cpu_t) cpu_t = t.to(cpu_device) self.assertEqual(cpu_device, cpu_t.device) self.assertEqual(cpu_device, t.device) self.assertEqual(torch.float32, cpu_t.dtype) self.assertEqual(torch.float32, t.dtype) self.assertIs(t, cpu_t) cpu_t = t.to(dtype=torch.float64, device=cpu_device) self.assertEqual(cpu_device, cpu_t.device) self.assertEqual(cpu_device, t.device) self.assertEqual(torch.float64, cpu_t.dtype) self.assertEqual(torch.float32, t.dtype) self.assertIsNot(t, cpu_t) cuda_device = torch.device("cuda:0") cuda_t = t.to("cuda:0") self.assertEqual(cuda_device, cuda_t.device) self.assertEqual(cpu_device, t.device) self.assertEqual(torch.float32, cuda_t.dtype) self.assertEqual(torch.float32, t.dtype) self.assertIsNot(t, cuda_t) cuda_t = t.to(cuda_device) self.assertEqual(cuda_device, cuda_t.device) self.assertEqual(cpu_device, t.device) self.assertEqual(torch.float32, cuda_t.dtype) self.assertEqual(torch.float32, t.dtype) self.assertIsNot(t, cuda_t) cuda_t = t.to(dtype=torch.float64, device=cuda_device) self.assertEqual(cuda_device, cuda_t.device) self.assertEqual(cpu_device, t.device) self.assertEqual(torch.float64, cuda_t.dtype) self.assertEqual(torch.float32, t.dtype) self.assertIsNot(t, cuda_t) cpu_points = torch.rand(9, 3) cuda_points = cpu_points.cuda() for _ in range(3): t = t.cpu() t.transform_points(cpu_points) t = t.cuda() t.transform_points(cuda_points) t = t.cuda() t = t.cpu()