I am trying to use mathematica to generate explicitely a tensor. I know multiple thing about it. Let's call it $C_{\mu\nu\lambda\sigma}$. This guy has to be symmetric in the two first indices ${\mu,\nu}$ are well as in the two indices ${\lambda\sigma}$. To build this tensor, I have at my disposal the Kronecker symbol $\delta_{\mu\nu}$ that is symmetric as well as a vector, call it $s_{\lambda}$. It is then clear that we will have three possible structures : 2 Kronecker deltas, 1 Kronecker delta and two s, or 4 s. I worked it out explicitely on paper and manage to find the most general tensor of this type can be written as

\begin{align} C_{\mu\nu\lambda\sigma} =& C_1s^2(\delta_{\mu\nu}\delta_{\lambda\sigma}) +C_2s^2(\delta_{\mu\lambda}\delta_{\nu\sigma}+\delta_{\mu\sigma}\delta_{\nu\lambda} )+C_3\delta_{\mu\nu}s_{\lambda}s_{\sigma} + C_4\delta_{\lambda\sigma}s_{\mu}s_{\nu}\nonumber\\ & + C_5(\delta_{\lambda\nu}s_{\mu}s_{\sigma}+\delta_{\sigma\nu}s_{\mu}s_{\lambda}+\delta_{\lambda\mu}s_{\nu}s_{\sigma}+\delta_{\sigma\mu}s_{\nu}s_{\lambda})+C_6\frac{s_{\mu}s_{\nu}s_{\lambda}s_{\sigma}}{s^2}, \end{align} where the $s^2$ are just here because of dimensionality and the structure of constants in the one needed for the symmetry to be the one I described. I will have to generalize this type of construction to tensors with more indices, so I would like to be able to do it in Mathematica. My best guess at the moment in that the easiest way to do it would be to generate all the possible tensors and then erase the one that are the same due to the symmetry in place, nevertheless, I really don't know how to deal with the two different structures $s_{\lambda}$ and $\delta_{\mu\nu}$. I would really appreciate any solution.

  • $\begingroup$ Having constructed it, what do you plan to do with it? $\endgroup$
    – mikado
    Nov 4, 2018 at 8:18
  • $\begingroup$ Map it to an expansion of a quantity that I know to fix the 6 constants. $\endgroup$
    – Ezareth
    Nov 4, 2018 at 12:17
  • $\begingroup$ If you want to do anything but the most basic calculations, you may want to look into the (free) expansion package xAct. I think that plain-vanilla Mathematica can do what you're asking here, though. $\endgroup$ Nov 4, 2018 at 17:24
  • $\begingroup$ One question, to make sure: Do you know for certain that you cannot use any other objects to construct the tensor other than the Kronecker and a 3-vector s? Because a tensor with four indices that is symmetric in the first pair and separately symmetric in the second pair has 36 freedoms in dimension 3, not just 6. Just want to confirm. $\endgroup$
    – jose
    Nov 5, 2018 at 20:29

3 Answers 3


There are multiple ways in which this could be done in xAct, and perhaps there is even a function to do something like this in one of the xAct packages SymManipulator or xTras (you could ask in the xAct forum), but I'm going to give you here a simple brute way of doing this for tensors with a few indices.

Load xTensor:

<< xAct`xTensor`

Define a manifold M of dimension 3, and declare that every lowercase Latin letter is an index:

DefManifold[M, 3, IndexRange[a, z]]

Hence we will use S for your vector, instead of s, which has been used as index already. The notation S[a] means contravariant vector. We could use S[-a] for a covariant vector, but your problem does not depend on that:

DefTensor[S[a], M]

Equally, your problem does not depend on the properties of the delta or a metric, so we just introduce a general symmetric two-tensor that I'll call G:

DefTensor[G[a, b], M, Symmetric[{1, 2}]]

Now I'll define these functions (sorry for not explaining...):

makeGSTensor[list_List] := Apply[Times, Replace[list, {{a_, b_} -> G[a, b], {a_} -> S[a]}, 2]]

makeSeeds[inds_List] := makeGSTensor /@ Flatten[Outer[TakeList, Permutations[inds], Cases[IntegerPartitions[Length[inds]], {(1 | 2) ..}], 1], 1]

makeSymmetricTensors[inds_List, sym_] := DeleteDuplicates[ToCanonical[ImposeSymmetry[#, IndexList @@ inds, sym] & /@ makeSeeds[inds]] /. _Rational -> 1]

The last function creates the list of independent symmetrized tensors you need, for a given list of indices and a given symmetry (in xAct notation!).

For example for your problem you want four indices and pair-symmetry:

makeSymmetricTensors[{a, b, c, d}, GenSet[Cycles[{1, 2}], Cycles[{3, 4}]]]

That returns your six tensors:

 G[a, b] G[c, d],
 G[a, b] S[c] S[d],
 S[a] S[b] S[c] S[d], 
 G[a, d] G[b, c] + G[a, c] G[b, d], 
 G[b, d] S[a] S[c] + G[a, d] S[b] S[c] + G[b, c] S[a] S[d] + G[a, c] S[b] S[d], 
 G[c, d] S[a] S[b]

Imagine that you wanted the same thing for a tensor of six indices which is independently symmetric in each of its three pairs. Then you need

makeSymmetricTensors[{a, b, c, d, e, f}, GenSet[Cycles[{1, 2}], Cycles[{3, 4}], Cycles[{5, 6}]]]

That returns, after almost a minute, 24 combinations.

Or imagine that you wanted also six indices, but symmetric in the first triple and symmetric in the second triple. Then you need

makeSymmetricTensors[{a, b, c, d, e, f}, GenSet[Cycles[{1, 2}], Cycles[{2, 3}], Cycles[{4, 5}], Cycles[{5, 6}]]]

That returns, after three minutes, 10 combinations.

This could all be done a lot faster using a bit of group theory, or implementing some clever organization. But if your cases do not go beyond 6 indices, then this should be enough.

  • $\begingroup$ I managed to make it works. Thank you very much. $\endgroup$
    – Ezareth
    Nov 6, 2018 at 16:38

Let's assume for the sake of argument that the dimension of your underlying space is $d = 3$. The code below constructs a $3 \times 3 \times 3 \times 3$ array whose components are the components of $C_{\mu \nu \lambda \sigma}$. Define:

d = 3;
delta = IdentityMatrix[d];
svec = Array[s, d]

(* {s[1], s[2], s[3]} *)

Label the tensor slots $\mu, \nu, \lambda, \sigma$ as 1–4. To construct the first tensor $\delta_{\mu \nu} \delta_{\lambda \sigma}$, we use TensorProduct. For any two tensors $t_{a_1 \dots a_n}$ and $u_{b_1 \dots b_n}$, TensorProduct creates the tensors $v_{a_1 \dots a_n b_1 \dots b_n} = t_{a_1 \dots a_n} u_{b_1 \dots b_n}$. The order of the indices is always in the order of the input tensors.

tensor1base = svec.svec TensorProduct[delta, delta];
tensor1 = Symmetrize[tensor1base, {{{2, 1, 3, 4}, 1}, {{1, 2, 4, 3}, 1}}] 

This returns a StructuredArray object, which can be turned into a normal array via Normal. The Symmetrize command causes this to be symmetrized over the first two pair of indices and the second pair of indices. But since the tensor $\delta_{\mu \nu} \delta_{\lambda \sigma}$ already has this symmetry, it doesn't have a net effect other than changing the data structure in which the result is stored (which is necessary if you'll be adding them all together in the end.)

For the second tensor $\frac{1}{2} s^2 (\delta_{\mu \lambda } \delta_{\nu \sigma} + \delta_{\nu \lambda } \delta_{\mu \sigma})$ (note the change in normalization), we use the following code:

tensor2base = TensorTranspose[tensor1base, {1, 3, 2, 4}]
tensor2 = Symmetrize[tensor2base, {{{2, 1, 3, 4}, 1}, {{1, 2, 4, 3}, 1}}]  

The first line constructs the tensor $\delta_{\mu \lambda} \delta_{\nu \sigma}$; the second line then symmetrizes it over $\{\mu, \nu\}$ and $\{ \lambda, \sigma \}$.

The third tensor can be constructed via

tensor3base = TensorProduct[delta, svec, svec]
tensor3 = Symmetrize[tensor3base, {{{2, 1, 3, 4}, 1}, {{1, 2, 4, 3}, 1}}]

The remaining three tensors can be constructed similarly via the appropriate combinations of TensorProduct and Symmetrize. (I don't think that TensorTranspose is strictly required for any of the other four tensors, though you could use it if you wanted to.) Note that the tensor associated with $C_5$ will end up with an overall factor of $\frac{1}{4}$ in front of it. Finally, the overall tensor can be constructed simply by adding

C[1] tensor1 + C[2] tensor2 + ...
  • $\begingroup$ Thank you very much for your answer. It still requires a fair amount of work to know which kind of term can be written and how to symmetrize them, but it already helps a lot. $\endgroup$
    – Ezareth
    Nov 4, 2018 at 21:57
  • $\begingroup$ @Ezareth: Yeah, this is why I suggested looking into xAct (and xCoba, if you're wanting component-wise calculations) in the comments above. The syntax is a bit more "natural" if you're used to index-based notation. On the other hand, there's a very steep learning curve, and it's rather overpowered for the task you've described here. Choose your poison. $\endgroup$ Nov 5, 2018 at 13:04
DefTensor[C[-a, -b,-c,-d], M4, Symmetric[{-a, -b},{-c, -d}]];
  • $\begingroup$ Showing a specific example of your code usage would be helpful. $\endgroup$
    – bbgodfrey
    Aug 16, 2023 at 12:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.