Upper Triangular Matrix Vectorization
Does PyTorch has the function that would return me the vectorized upper triangular matrix?
For example, I have Tensors as [ [1, 2, 3], [4, 5, 6], [7, 8, 9]], and I want [1, 2, 3, 5, 6, 9].
numpy has triu_indices, which will return me the indices of upper triangular matrix, and use the index can easily get the elements I want from numpy matrix. but it seems that I can’t do that in PyTorch?
I don’t think that there’s a api for directly returning the vectorized upper triangular matrix, but you can still achieve that:
1 >>> a = torch.arange(1, 10).view(3, 3) 2 >>> a 3 1 2 3 4 4 5 6 5 7 8 9 6 [torch.FloatTensor of size 3x3] 7 8 >>> triu_indices = a.triu().nonzero().transpose() 9 >>> triu_indices 10 0 0 0 1 1 2 11 0 1 2 1 2 2 12 [torch.LongTensor of size 2x6] 13 14 >>> vectorized_upper_triangular_matrix = a[triu_indices[0], triiu_indices[1]] 15 >>> vectorized_upper_triangular_matrix 16 1 17 2 18 3 19 5 20 6 21 9 22 [torch.FloatTensor of size 6]
Note that this only works when there are no zeros in the upper triangular part.
Here’s another way that should work more generally:
1 In [180]: x = torch.randn(3, 3) 2 3 In [181]: x 4 Out[181]: 5 6 1.6177 0.5082 1.3817 7 -0.5801 -0.4657 0.8086 8 -0.4783 -0.3208 1.4459 9 [torch.FloatTensor of size 3x3] 10 11 In [182]: x[torch.triu(torch.ones(3, 3)) == 1] 12 Out[182]: 13 14 1.6177 15 0.5082 16 1.3817 17 -0.4657 18 0.8086 19 1.4459 20 [torch.FloatTensor of size 6]
And you can do the reverse similarly,
1 In [183]: vec = x[torch.triu(torch.ones(3, 3)) == 1] 2 3 In [184]: y = torch.zeros(3, 3) 4 5 In [185]: y[torch.triu(torch.ones(3, 3)) == 1] = vec 6 7 In [186]: y 8 Out[186]: 9 10 1.6177 0.5082 1.3817 11 0.0000 -0.4657 0.8086 12 0.0000 0.0000 1.4459 13 [torch.FloatTensor of size 3x3]
RuntimeError: can’t assign Variable to a torch.FloatTensor using a mask (only torch.FloatTensor or float are supported)
You could do this with a mask
1 def tril_mask(value): 2 n = value.size(-1) 3 coords = value.new(n) 4 torch.arange(n, out=coords) 5 return coords <= coords.view(n, 1) 6 >>> value = torch.arange(9).view(3,3) 7 >>> value[tril_mask(value)] 8 0 9 3 10 4 11 6 12 7 13 8 14 [torch.FloatTensor of size 6]
本文来自于:
allenye0119、samuela、fritzo : Upper Triangular Matrix Vectorization
谢谢!!!