# Elegant way to get a symmetric Torch Tensor over diagonal

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 EDIT: As of now, I implemented the following solution. A more elegant way is desirable without a `for` loop. Using plain `torch` operations is desirable.

``````def weights_to_symmetric(weights, N):
assert(weights.ndim == 3)
tensor = torch.zeros((*weights.shape[:2], N, N))

idx = 0
for diag in range(N):
size = N - diag
w = weights[:, :, idx:idx+size]

tensor += torch.diag_embed(w, offset=diag)
if diag > 0:
tensor += torch.diag_embed(w, offset=-diag)

idx += size

return tensor
``````

I’m not sure about pytorch, but gpytorch has something called toeplitz. Maybe that’s what you are looking for ? (look into sym_toeplitz)

Thank you for the suggestion. `sym_toeplitz` is a resembles want, but it is not quite the same thing.

``````from gpytorch import utils
c = torch.tensor([1, 6, 4, 5], dtype=torch.float)
res = utils.toeplitz.sym_toeplitz(c)
res
# tensor([[1., 6., 4., 5.],
#        [6., 1., 6., 4.],
#        [4., 6., 1., 6.],
#        [5., 4., 6., 1.]])
``````

Here is a solution by swag2198 from stackoverflow.

``````>>> 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.]])
``````