//  [python]
def check_equivariance_(self, atol: float = 0.1, rtol: float = 0.1, assertion: bool = True, verbose: bool = True, device: str = 'cpu'):
        
        # np.set_printoptions(precision=5, threshold=30 *self.in_type.size**2, suppress=False, linewidth=30 *self.in_type.size**2)

        feature_map_size = 5
        last_downsampling = 5
        first_downsampling = 5

        initial_size = (feature_map_size * last_downsampling + 1 - self.kernel_size) * first_downsampling

        c = self.in_type.size
    
        # x = torch.randn(3, c, 10, 10, 10)

        from tqdm import tqdm
        import matplotlib.image as mpimg
        from skimage.measure import block_reduce
        from skimage.transform import resize


        import scipy
        x = scipy.datasets.face().transpose((2, 0, 1))[np.newaxis, 0:c, :, :]

        x = resize(
            x,
            (x.shape[0], x.shape[1], initial_size, initial_size, initial_size),
            anti_aliasing=True
        )
        
        x = x / 255.0 - 0.5
        
        if x.shape[1] < c:
            to_stack = [x for i in range(c // x.shape[1])]
            if c % x.shape[1] > 0:
                to_stack += [x[:, :(c % x.shape[1]), ...]]
    
            x = np.concatenate(to_stack, axis=1)

        assert x.shape[0] == 1, x.shape

        x = torch.FloatTensor(x)
        x = self.in_type(x)

        # def shrink(t: GeometricTensor, s) -> GeometricTensor:
        #     return GeometricTensor(torch.FloatTensor(block_reduce(t.tensor.detach().numpy(), s, func=np.mean)), t.type)
        shrink1 = escnn.nn.PointwiseAvgPoolAntialiased3D(self.in_type, sigma=first_downsampling / 3., stride=first_downsampling, padding=first_downsampling//2+1)
        shrink2 = escnn.nn.PointwiseAvgPoolAntialiased3D(self.out_type, sigma=last_downsampling / 3., stride=last_downsampling, padding=last_downsampling//2+1)

        errors = []
    
        for el in self.space.testing_elements:
            
            # out1 = self(shrink(x, (1, 1, 5, 5, 5))).transform(el).tensor.detach().numpy()
            # out2 = self(shrink(x.transform(el), (1, 1, 5, 5, 5))).tensor.detach().numpy()
            #
            # out1 = block_reduce(out1, (1, 1, 5, 5, 5), func=np.mean)
            # out2 = block_reduce(out2, (1, 1, 5, 5, 5), func=np.mean)

            out1 = self(shrink1(x)).transform(el)
            out2 = self(shrink1(x.transform(el)))

            out1 = shrink2(out1).tensor.detach().numpy()
            out2 = shrink2(out2).tensor.detach().numpy()

            b, c, w1, w2, w3 = out2.shape

            assert w1 == w2 == w3 == feature_map_size, (w1, w2, w3, feature_map_size)

            # center_mask = np.zeros((3, w1, w2, w3))
            # center_mask[2, ...] = np.arange(0, w3) - w3 // 2
            # center_mask[1, ...] = np.arange(0, w2) - w2 // 2
            # center_mask[0, ...] = np.arange(0, w1) - w1 // 2
            # center_mask[0, ...] = center_mask[0, ...].T
            center_mask = np.stack(np.meshgrid(*[np.arange(0, w) - w//2 for w in [w1, w2, w3]]), axis=0)
            assert center_mask.shape == (3, w1, w2, w3), (center_mask.shape, w1, w2, w3)
            center_mask = (center_mask ** 2).sum(0) < (w1 / 4) ** 2

            out1 = out1[..., center_mask]
            out2 = out2[..., center_mask]
            
            out1 = out1.reshape(-1)
            out2 = out2.reshape(-1)
            
            errs = np.abs(out1 - out2)

            esum = np.maximum(np.abs(out1), np.abs(out2))
            esum[esum == 0.0] = 1

            relerr = errs / esum
    
            if verbose:
                print(el, relerr.max(), relerr.mean(), relerr.var(), errs.max(), errs.mean(), errs.var())
        
            # tol = rtol*(np.abs(out1) + np.abs(out2)) + atol
            tol = rtol * esum + atol
            
            if np.any(errs > tol) and verbose:
                # print(errs[errs > tol])
                print(out1[errs > tol])
                print(out2[errs > tol])
                print(tol[errs > tol])
            
            if assertion:
                assert np.all(errs < tol), 'The error found during equivariance check with element "{}" is too high: max = {}, mean = {} var ={}'.format(el, errs.max(), errs.mean(), errs.var())
        
            errors.append((el, errs.mean()))
    
        return errors