Pytorch之Upper Triangular Matrix Vectorization

 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?

 

allenye0119Allen Ye

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]

 

 

 

 

本文来自于:

allenye0119samuelafritzo  : Upper Triangular Matrix Vectorization

谢谢!!!

posted @ 2018-04-25 22:35  寒杰士  阅读(715)  评论(0编辑  收藏  举报