Extending D for four-derivatives

I'm currently trying to consistently define rules for extending D[] to four-derivatives. As 'backend' I'm using the package TRACER (http://library.wolfram.com/infocenter/MathSource/2987/), 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_]] :=
D[S[param1],
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?

• 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. – skalarproduktraum Feb 28 '13 at 10:29

We can define a function called partialD for your purpose.

General definitions:

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}]]

Test:

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]]] *)
• 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 :) – skalarproduktraum Feb 28 '13 at 21:39