Quickly summing matrix elements

I have a pair of rank-4 tensors, (T,V), where each index takes four values. I want to quickly contract these with the rank-4 antisymmetric tensor using the following operation:

Sum[LeviCivitaTensor[4][[i, j, q, l]] T[[i,
j, \[Mu], \[Nu]]] V[[q, l, \[Nu], \[Mu]]], {i, 1, 4}, {j, 1,
4}, {q, 1, 4}, {l, 1, 4}, {\[Nu], 1, 4}, {\[Mu], 1, 4}]]


Unfortunately this is quite slow (~0.1 seconds) and I think it should be near-instantaneous. Is there some smarter way to assemble the data and sum it up? I imagine there is something to be done with vectorization but I'm not sure exactly how to do it.

One possibility is to use TensorContract/TensorProduct, but you need to also use Inactive to prevent TensorProduct from creating an enormouse intermediate tensor:

T = RandomReal[1, {4, 4, 4, 4}];
V = RandomReal[1, {4, 4, 4, 4}];


Sum[
LeviCivitaTensor[4][[i, j, q, l]] T[[i, j, \[Mu], \[Nu]]] V[[q, l, \[Nu], \[Mu]]],
{i, 1, 4}, {j, 1, 4}, {q, 1, 4}, {l, 1, 4}, {\[Nu], 1, 4}, {\[Mu], 1, 4}
] //AbsoluteTiming


{0.091607, -0.10409}

TensorContract[
Inactive[TensorProduct][LeviCivitaTensor[4], T, V],
{{1, 5}, {2, 6}, {3, 9}, {4, 10}, {7, 12}, {8, 11}}
] //Activate //AbsoluteTiming


{0.000215, -0.10409}

Note that there are ways to improve this further by avoiding TensorContract.

• This is great, thank you. I had thought to use tensors but was put off by the construction of large intermediate objects so this is nice. Could you comment on exactly what Inactive is doing? It seems intuitive, but consulting the documentation, I'm not sure I understand - how are we managing to work with this larger tensor if we never construct it? Are we just avoiding explicit memory storage while preserving the ability to use tensor commands? Jan 27, 2023 at 14:58