Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm currently trying to consistently define rules for extending D[] to four-derivatives. As 'backend' I'm using the package TRACER (, which can perform contractions with metric tensors, Dirac algebra, etc. Derivatives, however, are not implemented in this package. The rules here are independent of TRACER, but I adapted it's syntax, so

  • S[k, {σ}] is the four-vector $k_\sigma$
  • S[{μ}, {ν}] is the metric tensor $g_{\mu\nu}$

The basic assumption is that $\frac{\partial}{\partial k^\sigma}k^\rho=g^{\sigma\rho}$.

So far, I have

D[S[notk_Symbol, idx_List], S[k_Symbol, derividx_List]] := 
    0 /; FreeQ[notk, k];
D[S[k_Symbol, index_List], S[k_Symbol, derividx_List]] := 
   S[index, derividx];
D[S[param1__]^n_Integer, S[deriv_, derividx_]] := 
   n S[param1]^(n - 1) D[S[param1], S[deriv, derividx]]

For multiplication and addition, I have

D[S[param1__] + S[param2__], S[deriv_, derividx_]] := 
    D[S[param1], S[deriv, derividx]] + D[S[param2], S[deriv, derividx]];
D[S[param1__] * S[param2__], S[deriv_, derividx_]] := 
      S[deriv, derividx]]*S[param2] + S[param1] * D[S[param2],
      S[deriv, derividx]]];

And for scalar products:

D[S[k1_Symbol, k2_Symbol], S[k_, derividx_List]] := 
    D[S[k1, {dummy}],
      S[k, derividx]] S[k2, {dummy}] + S[k1, {dummy}] D[S[k2, {dummy}],
      S[k, derividx]];

These, however, do not deliver the correct results (the result is in fact 0) when trying to derive a product or sum with more than two terms. //Trace confirms that Mathematica does not know what to do.

Does anyone have a pointer?

share|improve this question
The result is 0 because you use D, you should define a new function rather than modify D. – unstable Feb 28 '13 at 6:51
Great suggestion! I just realized Mathematica will leave unknown expressions unevaluated, instead of setting them equal to zero. – Ulrik Guenther Feb 28 '13 at 10:29
up vote 4 down vote accepted

We can define a function called partialD for your purpose.

General definitions:

(* For addition*)    
a : partialD[_Plus, ___] := Thread[Unevaluated[a], Plus, 1]
(* For multiplication *)
partialD[a_Times, x___] := Plus @@ (MapAt[partialD[#, x] &, a, #] & /@ Range[Length[a]])
(* For power *)
partialD[a_ ^b_, x___] := b a^(b - 1) partialD[a, x]

Specific to your problem:

partialD[S[notk_Symbol, idx_List], S[k_Symbol, derividx_List]] := 0 /; FreeQ[notk, k]
partialD[S[k_Symbol, idx_List], S[k_Symbol, derividx_List]] := S[idx, derividx]
(* for scalar product *)
partialD[S[k1_Symbol, k2_Symbol], S[k_Symbol, derividx_List]] := Module[{i}, 
    partialD[S[k1, {i}], S[k, derividx]] S[k2, {i}] + S[k1, {i}] partialD[S[k2, {i}], S[k, derividx]] /. 
    S[a_Symbol, j_List] (S[j_List, l_List] | S[l_List, j_List]) :> S[a, l]]

Defining the format of your S function for a nice-looking output

Format[S[k_Symbol, {i_}]] := DisplayForm@SubscriptBox[k, i]
Format[S[{i_}, {j_}]] := DisplayForm@SubscriptBox[g, RowBox[{i, j}]]


partialD[S[k, k] + S[p, k] + S[k, {b}], S[k, {a}]]
(* its FullForm is: Plus[Times[2,S[k,List[a]]],S[p,List[a]],S[List[b],List[a]]] *)
share|improve this answer
I added the definitions PartialD[a_, S[var_, idx_List]] := 0 /; NumericQ[a] and PartialD[S[idx1_List, idx2_List], S[var_, derividx_]] := 0; to define the derivative for numbers as well as for the metric tensor. Works quite nicely now :) – Ulrik Guenther Feb 28 '13 at 21:39

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.