1

Is there an elegant way to build a Torch.Tensor like this from a given set of values?

Here is an 3x3 example, but in my application I would have a matrix of any odd-size.

A function call gen_matrix([a, b, c, d, e, f]) should generate

enter image description here

Eduardo Reis
  • 1,691
  • 1
  • 22
  • 45

1 Answers1

3

You can use torch.triu_indices() to achieve this. Note that for a general N x N symmetric matrix, there can be atmost N(N+1)/2 unique elements which are distributed over the matrix.

The vals tensor here stores the elements you want to build the symmetric matrix with. You can simply use your set of values in place of vals. Only constraint is, it should have N(N+1)/2 elements in it.

Short answer:

N = 5 # your choice goes here
vals = torch.arange(N*(N+1)/2) + 1 # values

A = torch.zeros(N, N)
i, j = torch.triu_indices(N, N)
A[i, j] = vals
A.T[i, j] = vals

Example:

>>> N = 5
>>> vals = torch.arange(N*(N+1)/2) + 1
 
>>> A = torch.zeros(N, N)
>>> i, j = torch.triu_indices(N, N)
>>> A[i, j] = vals
>>> A.T[i, j] = vals
  
>>> vals
 tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13., 14.,
         15.])
>>> A
 tensor([[ 1.,  2.,  3.,  4.,  5.],
         [ 2.,  6.,  7.,  8.,  9.],
         [ 3.,  7., 10., 11., 12.],
         [ 4.,  8., 11., 13., 14.],
         [ 5.,  9., 12., 14., 15.]])
swag2198
  • 2,546
  • 1
  • 7
  • 18
  • Thank you so much. That is exactly what I was looking for. I am just having an issue trying to do it with more dimensions. like: `vals = vals.reshape((1, 1, -1)); A = torch.zeros(1, 1, N, N); A[:, :, i, j] = vals; A.T[:, :, i, j] = vals; # Colab kernel crashes on this like.`. I am getting the following log message `src/tcmalloc.cc:283] Attempt to free invalid pointer 0x7ffcedbf1818` Any idea what it could be? – Eduardo Reis Jun 18 '21 at 21:19
  • 1
    Never mind. Just noticed that it was the `A.T` operation. That changed the shape on the wrong way. I should use `A.transpose(-2, -1)` when having higher dimensions. – Eduardo Reis Jun 18 '21 at 21:30
  • I actually didn't think of tensors having dimensions > 2 while writing the answer as you didn't mention anything in the question. Nice to see it works in higher dimensions too! – swag2198 Jun 19 '21 at 00:23