Issue
I wish to create a random symmetric tensor such that for each permutation of indices i1, i2,...,ik
i will have:
a[i1][i2]...[ik] = a[pi(i1)][pi(i2)]...[pi(ik)]
Where pi
is a permutation function. For example:
a[1][2][3][4] = a[1][3][2][4] = a[4][2][1][3] = ...
In the 2 dim setting its the normal symmetry but i am unsure how implement this (without iterating over permutations) or if there is an automatic way of doing this using numpy / pytorch.
Solution
AFAIK there is no function for that in either torch
nor numpy
, but one might add all dimensionality permutated tensors to make it symmetric across every dimension.
This has:
O(size^dims)
- memory complexity (as generators are used)O(dims! * size^dims)
- runtime complexity (althoughsize^dims
is vectorized and should be reasonably quick)
No idea how to improve runtime complexity though, sorry. Here is the code:
import functools
import itertools
import operator
import torch
def symmetricND(size: int, dims: int) -> torch.Tensor:
data = torch.randn(*[size] * dims)
return functools.reduce(
operator.add,
(
torch.permute(data, permutation)
for permutation in itertools.permutations(range(dims))
),
)
And example usage (4x4x4
symmetrical tensor):
symmetric = symmetricND(4, 3)
print(symmetric[0][1][2])
print(symmetric[2][1][0])
print(symmetric[1][2][0])
print(symmetric[1][0][2])
In general: will run as long as you can hold single tensor in your memory, but might take a lot of time ((3, 7)
is instant on my laptop, (3, 9)
takes around 1 minute though, not sure if this is satisfactory for your case).
You could also precompute these tensors (or even use multiple machines for that), save them and load as needed.
Answered By - Szymon Maszke
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.