Suppose we have a tensor product basis, say of dimensions lengths={2,3,2}
.
Every element in such basis can be represented as a triplet of numbers $(i,j,k)$ with $i=1,2$, $j=1,2,3$, and $k=1,2$.
The natural way to enumerate all the elements in such basis using a single index is doing a mapping like the following:
1 -> (1, 1, 1),
2 -> (1, 1, 2),
3 -> (1, 2, 1),
4 -> (1, 2, 2),
5 -> (1, 3, 1),
6 -> (1, 3, 2),
7 -> (2, 1, 1),
8 -> (2, 1, 2),
9 -> (2, 2, 1),
10 -> (2, 2, 2),
11 -> (2, 3, 1),
12 -> (2, 3, 2)
My question is: how can we implement such a mapping in Mathematica (for arbitrary dimensions of the basis)?
Two solutions I found for this are the following:
indexToTensorIndices[idx_Integer, lengths_] := Table[
Mod[idx, Times @@ lengths[[k ;;]], 1] / Apply[
Times,
lengths[[k + 1 ;;]]
] // Ceiling,
{k, Length@lengths}
]
and
indexToTensorIndices2[idx_Integer, lengths_] := Position[#, idx] &[
ArrayReshape[Range[Times @@ lengths], lengths]
] // First
which do both produce the intended result:
However, I find these methods kind of unsatisfactory: the first one is rather convoluted and not that easy to read, while the second one is slow for larger bases as it computes the mapping of all possible numbers while we may be interested in only a single one.
Is there a better, cleaner way to solve this problem?
Flatten[Outer[List, {1, 2}, {1, 2, 3}, {1, 2}], 2]
? $\endgroup$