Hi Alpha!



 AlphaBetaGamma96:

I’m trying to figure out a way to set the diagonal of a 3-dimensional Tensor (along 2 given dims) equal to 0.


In the case that you want to zero out the 1-2 diagonal of all three
dim = 0 slices, you can use broadcasting, together with element-wise
multiplication by a two-dimensional zero-diagonal matrix:
>>> data = torch.randn ((3, 3, 3))
>>> print (data)
tensor([[[-0.0236, -0.3462, -0.3220],
         [ 0.3032,  1.3593, -1.1444],
         [-0.0366, -0.4146,  0.7503]],

        [[ 1.3535,  1.0488,  1.1539],
         [-0.2239,  0.3035, -1.6576],
         [-0.3756,  1.4249,  0.6928]],

        [[-0.0917,  2.4133,  0.0379],
         [-0.0485, -0.5681, -0.3200],
         [-0.5743, -2.4652, -0.2874]]])
>>> dataz = (1 - torch.eye (3)) * data
>>> print (dataz)
tensor([[[-0.0000, -0.3462, -0.3220],
         [ 0.3032,  0.0000, -1.1444],
         [-0.0366, -0.4146,  0.0000]],

        [[ 0.0000,  1.0488,  1.1539],
         [-0.2239,  0.0000, -1.6576],
         [-0.3756,  1.4249,  0.0000]],

        [[-0.0000,  2.4133,  0.0379],
         [-0.0485, -0.0000, -0.3200],
         [-0.5743, -2.4652, -0.0000]]])



In short, is there a way to mask a given diagonal over 2 arbitrary dimensions for a 3D-tensor?


You can either transpose() your data matrix so that your desired
dimensions become your 1-2 dimensions, use broadcasting, as above,
and then transpose() it back, or you can build a three-dimensional
“mask” tensor using a two-dimensional zero-diagonal matrix with
repeat(), transpose it to put the zero-diagonals along the desired
dimensions, and then element-wise multiply your three-dimensional
“mask” tensor with your three-dimensional data tensor:
>>> mask01 = (1 - torch.eye (3)).repeat (3, 1, 1).transpose (0, 2)
>>> print (mask01)
tensor([[[0., 0., 0.],
         [1., 1., 1.],
         [1., 1., 1.]],

        [[1., 1., 1.],
         [0., 0., 0.],
         [1., 1., 1.]],

        [[1., 1., 1.],
         [1., 1., 1.],
         [0., 0., 0.]]])
>>> dataz01 = mask01 * data
>>> print (dataz01)
tensor([[[-0.0000, -0.0000, -0.0000],
         [ 0.3032,  1.3593, -1.1444],
         [-0.0366, -0.4146,  0.7503]],

        [[ 1.3535,  1.0488,  1.1539],
         [-0.0000,  0.0000, -0.0000],
         [-0.3756,  1.4249,  0.6928]],

        [[-0.0917,  2.4133,  0.0379],
         [-0.0485, -0.5681, -0.3200],
         [-0.0000, -0.0000, -0.0000]]])



I need to repeat this `zeroing’ along 2 different pairs of dimensions (e.g. dim=(1,2) then dim=(0,1) ) to get the required masking I need.


You could apply either of the above techniques multiple times, once for
each of your pairs of dimensions, or, if you reuse the same set of pairs
of dimensions, you could make a “multi-pair” mask tensor by multiplying
together the respective “single-pair” mask tensors, and use that
multi-pair mask tensor every time you need to zero out that particular
set of diagonals.
Best.
K. Frank