Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I want to define a "prefix" (D_i) covariant derivative operator CD[] for symbolic tensors in form of a function, i.e. for




should be made an assumption, an additional slot is created on the left. So far the only way I found to make this possible is defining a function

$Assumptions = {Element[v,Vectors[3, Reals]]}

CDdef[a_] := (AppendTo[$Assumptions, 
      TensorSymmetry[TensorProduct[v, a]]]];
      $Assumptions =  DeleteDuplicates[$Assumptions]; CD[a])

and effectively writing all the assumption by hand into $Assumptions. But this could generate a huge list in bigger calculations. All my attempts of the kind

$Assumptions={Element[CD[a_?SomeSymmetryQ],Arrays["one more slot"]]}

to use pattern that are at least valid for all tensors with the same symmetries have failed. Is there any effective way to proceed?

Many thanks, Hendrik

share|improve this question
Syntax! for starters: not $Assumptions={Element[g,Arrays[{3,3},Reals],Symmetric[{1,2}]]} but $Assumptions = Element[g, Arrays[{3, 3}, Reals, Symmetric[{1, 2}]]] –  Wouter Mar 31 at 12:59
I think this depends on if you are planning to add further assumptions later on. Or do you think starters can only use one assumption at a time? ;-) –  Hendrik Mar 31 at 13:36
that's not it, rather the closed bracket after Reals : the argument Symmetric belongs inside Arrays. –  Wouter Mar 31 at 14:20
sorry, this was just a typo that does not appear in my actual code, i will correct –  Hendrik Mar 31 at 14:54

1 Answer 1

up vote 5 down vote accepted

Good question; the notion of a tensorial (covariant) derivative is something that is missing in Mathematica AFAIK. I can think of two ways to proceed:

Option 1

One way is to overload the TensorRank, TensorDimensions, and TensorSymmetry functions for patterns that have head CD:

CD /: TensorRank[CD[tensor_]] := TensorRank[tensor] + 1

CD /: TensorDimensions[CD[tensor_]] := Join[{First[#]}, #]& @ TensorDimensions[tensor]

CD /: TensorSymmetry[CD[tensor_]] := TensorSymmetry[tensor] /.
  (h : (Cycles | Symmetric | Antisymmetric))[list_List] :> h[list + 1]

Note that this is a bit rough on the edges and gives incorrect results if tensor hasn't been defined as a tensor or is a scalar, but it shouldn't be too hard to improve the code.

The following then works as expected:

$Assumptions = m ∈ Matrices[{4, 4}, Reals, Symmetric[{1, 2}]];

{4, 4, 4}
TensorReduce@TensorTranspose[CD@m, {1, 3, 2}]

Option 2

However, if your covariant derivatives is commutative (like for instance the partial derivative), a better way would be to simply define it as a vector:

$Assumptions = CD ∈ Vectors[4, Reals] && m ∈ Matrices[{4, 4}, Reals, Symmetric[{1, 2}]]

If you like the CD[tensor] notation, you may even define

CD[tensor_] := TensorProduct[CD, tensor]

All the above commands then give the same result. In addition, multiple derivatives are symmetric:

{{Cycles[{{1, 2}}], 1}, {Cycles[{{3, 4}}], 1}}

So only use this if your derivatives actually commute!

share|improve this answer
Since I want to consider non-commuting derivatives I favour option one. Many thanks for this very useful solution!!! Any details about exceptions I will hopefully be able to figure out on my own. –  Hendrik Jul 22 at 13:40
I think there is an issue with option 2, even if the derivative can be assumed commutative: It will always act on everything on the right. This is because the tensor product is associative, and brackets have no effect. So there is no way to distinguish between D_i A_j B_k = (D_i A_j) B_k + A_j (D_i B_k) and (D_i A_j) B_k –  Hendrik Aug 7 at 13:24
@Hendrik Yes, that's indeed an issue with option 2. So you can't write CD*T*CD*T (where * is the TensorProduct) to mean (CD@T)*(CD@T) -- yet another reason to opt for option 1! –  Teake Nutma Aug 7 at 13:36

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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