# Tensors with mixed symmetry

I want to work with tensors of mixed symmetry, for example with a rank 3 tensor $A_{ijk}$ that is symmetric under the exchange of $i$ and $j$ and antisymmetric with respect to $i$ and $k$.

I was trying to describe this by

$Assumptions = {a \[Element] Arrays[{3, 3, 3}, Reals, {Symmetric[{1, 2}], Antisymmetric[{1, 3}]}]}  but this gives the message Arrays::symm0: Symmetry specification {Symmetric[{1,2}],Antisymmetric[{1,3}]} is only compatible with the zero tensor. >> and everything like TensorTranspose[a, {2, 1, 3}] // TensorReduce  evaluates to zero. Why does my example not work as expected and how can I fix it? • Mathematica is right that no such tensor exists. Alternately permuting the {1,2} and {1,3} indices, flipping signs when performing the latter, we get$A_{ijk} = A_{jik} = - A_{kij} = - A_{ikj} = A_{jki} = A_{kji} = -A_{ijk}$. Hence,$A_{ijk} = 0$. Apr 24, 2015 at 20:38 • Ok, this is probably not the behaviour I want. I want$A$to behave like$A_{ijk}=a_{ijk}+a_{jik}-a_{kji}-a_{jki}$, where$a$doesn't have any symmetry properties. In this case$A_{ijk} =-A_{kij}$does not hold and$A$does not vanish. Apr 24, 2015 at 20:59 • Yeah, Mathematica assumes that the components of the tensor have the symmetry property you specify. However, applying a mixed-symmetry symmetrizer to an arbitrary tensor does not in general yield a tensor whose components have that particular symmetry property. (And just to confuse things, the components do have the symmetry property of the symmetrizer for completely symmetric and completely antisymmetric tensors, which is why one's intuition about these things rapidly fails for higher-rank tensors.) Apr 24, 2015 at 21:03 • I think I was indeed a bit confused. But how can I implement that$A$has the desired properties, e.g. that TensorTranspose[a, {2, 1, 3}] // TensorReduce gives a and TensorTranspose[a, {3, 2, 1}] // TensorReduce gives -a? Apr 24, 2015 at 21:28 • But if you define$A_{ijk}$as you did above, then$A_{jik} = a_{jik} + a_{ijk} - a_{kij} - a_{ikj} \neq A_{ijk}$. (The last two terms differ.) So the first of your two conditions shouldn't hold for a tensor of this symmetry type. Apr 24, 2015 at 21:57 ## 1 Answer What follows is a partial answer at best; a complete answer would depend on what sorts of things you're going to want to do with your tensor, and what native Mathematica functionality you want to mimic. But I figured I would post the progress I've made thus far. The short answer is that Mathematica really only seems to be equipped to deal with simple symmetries that can be expressed as permutations of the tensor slots: something like$A_{abc...} = \phi A_{\sigma(a) \sigma(b) \sigma(c) ...}$, where$\phi$is a root of unity and$\sigma$is a permutation on the letters$a, b, c, ...$. Unfortunately, tensors of mixed symmetry, as you have above, cannot in general be written in terms of slot permutations alone. For example, you do have$A_{ijk} = - A_{kji}$, which is a slot permutation that Mathematica can handle. However, you also have$A_{ijk} + A_{kij} + A_{jki} = 0$automatically, which is a symmetry Mathematica doesn't have built-in support for (so far as I can tell.) How you choose to deal with this is going to depend on what, exactly, you want to do with the tensors. For instance, you can explicitly construct a tensor of mixed symmetry by taking a tensor of arbitrary symmetry, and then symmetrizing it: array = Array[Subscript[a, ##] &, {3, 3, 3}] symarray = TensorTranspose[array, {Cycles[{{}}], 1}] + TensorTranspose[array, {Cycles[{{1, 2}}], 1}] + TensorTranspose[array, {Cycles[{{1, 3}}], -1}] + TensorTranspose[array, {Cycles[{{1, 2, 3}}], -1}]  I'll leave off the output, since it's rather complex and unilluminating; but the result is that symarray is a tensor of mixed symmetry type as you're requesting. Mathematica recognizes that the resulting tensor is antisymmetric between indices 1 and 3, but nothing else: In[10]:= TensorSymmetry[symarray] Out[10]= Antisymmetric[{1, 3}]  However, there are certain combinations of the components that automatically vanish, despite being individually non-zero: symarray + TensorTranspose[symarray, {2, 3, 1}] + TensorTranspose[symarray, {3, 1, 2}] {{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}  To get the proper number of independent components of the symmetrized tensor, you can use GroebnerBasis to construct a set of polynomials in the components of the original tensor that span the components of the symmetrized tensor: basis = GroebnerBasis[Flatten[symarray], Flatten[array]]  $$\left\{a_{2,3,3}+a_{3,2,3}-2 a_{3,3,2},2 a_{2,2,3}-a_{2,3,2}-a_{3,2,2},a_{1,3,3}+a_{3,1,3}-2 a_{3,3,1}, \\ a_{1,3,2}-a_{2,3,1}+a_{3,1,2}-a_{3,2,1},a_{1,2,3}+a_{2,1,3}-a_{2,3,1}-a_{3,2,1},a_{1,2,2}+a_{2,1,2}-2 a_{2,2,1}, \\2 a_{1,1,3}-a_{1,3,1}-a_{3,1,1},2 a_{1,1,2}-a_{1,2,1}-a_{2,1,1}\right\}$$ Note that this list only has eight elements, as opposed the nine independent components that the tensor would have if it was truly "just" antisymmetric in the first and third components. We can then use PolynomialReduce to express each component of symarray in terms of one of these canonical components, which we can express as$aa_1$,$aa_2$, and so on: indepcomplist = Array[Subscript[aa, ##] &, {Length[basis]}]; compidentify[x_] := First[PolynomialReduce[x, basis, Flatten[array]]] Map[(#.indepcomplist) &, Map[compidentify, symarray, 3]]  $$\left( \begin{array}{ccc} \left\{0,\text{aa}_8,\text{aa}_7\right\} & \left\{0,\text{aa}_6,\text{aa}_5\right\} & \left\{0,\text{aa}_4,\text{aa}_3\right\} \\ \left\{-\text{aa}_8,0,\text{aa}_5-\text{aa}_4\right\} & \left\{-\text{aa}_6,0,\text{aa}_2\right\} & \left\{-\text{aa}_4,0,\text{aa}_1\right\} \\ \left\{-\text{aa}_7,\text{aa}_4-\text{aa}_5,0\right\} & \left\{-\text{aa}_5,-\text{aa}_2,0\right\} & \left\{-\text{aa}_3,-\text{aa}_1,0\right\} \\ \end{array} \right)$$ You could use this form of the tensor to create, say, a "random" tensor of this symmetry type for test purposes: just assign values to the components$aa_1$through$aa_8\$ via a Rule.

(The PolynomialReduce calls in last bit of code throws a bunch of errors, BTW, and I'm not quite sure why. Any comments or suggestions would be helpful here.)