I have an array $v_{ijk}$ which is effectively a rank-$3$ tensor with dimensions $3\times3\times3$, and I need to contract it with $e^{ijk}$, i.e. evaluate $v_{ijk} e^{ijk}$ (see Einstein convention).
Can anyone tell me how that could be done?
-
$\begingroup$ Have a look at the docs. $\endgroup$– b.gates.you.know.whatCommented Feb 26, 2014 at 12:52
-
$\begingroup$ @b.gatessucks Would you include more details if my answer could be improved significantly? $\endgroup$– ArtesCommented Feb 27, 2014 at 12:24
2 Answers
I recommend exploiting new and powerful capabilities of Mathematica 9.
When we deal with symbolic tensors sometimes we would like to assume special properties of tensors like their specific symmetries, dimensions etc. because most of tensor equations of mathematical physics (Maxwell, Yang-Mills, Einstein etc.) involve special symmetries of underlying tensors and one would substantially simplify symbolic processing if one assumed appropriate symmetries from scratch. For this purpose one may use $Assumptions
, however there were rather few questions explicitly asking about them (see e.g. How to declare a 3D vector variable? or Can Mathematica do symbolic linear algebra?).
We can define a general tensor product of tensor v
with LeviCivitaTensor[3]
:
tp[v_]:= TensorProduct[ v, LeviCivitaTensor[3]]
and also an appropriate tensor contraction of a tensor, namely we need to contract the tensor product tp
having 6
indicies in their appropriate pairs, namely {1, 4}, {2, 5}
and {3, 6}
:
tc[v_]:= TensorContract[ TensorProduct[ v, LeviCivitaTensor[3]],
{{1, 4}, {2, 5}, {3, 6}}]
when we have defined a tensor v
. e.g.:
v = RandomInteger[{-10, 10}, {3, 3, 3}]
{{{8, 4, -4}, {2, -2, 4}, {-1, 9, -8}}, {{-9, -7, 8}, {-9, -4, 5}, {-9, 2, -7}}, {{-7, 10, -4}, {-5, 9, -9}, {-4, 6, 5}}}
tc[ v, {{1, 4}, {2, 5}, {3, 6}}]
-7
Tensor contraction of a tensor product can be performed also using Inner
or in an obvious (more procedural) way, using Sum
, Part
and Times
(see e.g. How to calculate scalar curvature Ricci tensor and Christoffel symbols in Mathematica? for more extensive usage of the latter approach) :
Sum[ v[[i, j, k]] LeviCivitaTensor[3][[i, j, k]], {i, 3}, {j, 3}, {k, 3}]
-7
A bit a simpler example of tensor contraction is e.g. a trace of a matrix (an operator in appropriate basis) m
:
m = RandomInteger[{-10, 10}, {3, 3}]
{{ 9, 3, -8}, {-2, 4, -6}, { 9, 1, -7}}
We can see that the result should be 6
. We can contract it with respect to the first and the second indicies , i.e. using { 1, 2}
as the second argument in TensorContract
or Tr
or simply computing the sum of diagonal elements:
TensorContract[ m, {1, 2}]
Tr @ m == TensorContract[ m, {1, 2}]
6 True
@Artes is right, but I have to mention also that if contracting with the Levi-Civitta tensor is something you are going to do many times, it is way more computationally efficient to use the direct summation over the coordinates. Also, it is usefull to calculate the tensor once and then use it without calling the LeveCivittaTensor[3] function:
a = RandomReal[1, {3, 3, 3}];
e = LeviCivitaTensor[3];
AbsoluteTiming[
Do[TensorContract[
TensorProduct[a, LeviCivitaTensor[3]], {{1, 4}, {2, 5}, {3, 6}}], 1000];
TensorContract[
TensorProduct[a, LeviCivitaTensor[3]], {{1, 4}, {2, 5}, {3, 6}}]]
AbsoluteTiming[
Do[TensorContract[TensorProduct[a, e], {{1, 4}, {2, 5}, {3, 6}}], 1000];
TensorContract[TensorProduct[a, e], {{1, 4}, {2, 5}, {3, 6}}]]
AbsoluteTiming[
Do[Sum[e[[i, j, k]] a[[i, j, k]], {i, 3}, {j, 3}, {k, 3}], 1000];
Sum[e[[i, j, k]] a[[i, j, k]], {i, 3}, {j, 3}, {k, 3}]]
{0.597298, 0.258979} {0.516749, 0.258979} {0.0624368, 0.258979}