In tensor calculation, I need to do the following thing:

Define a derivative operator Drv[fun,i], such that



I think this question in fact is quite important to me, and the answer, however is not quite complete, thus I will try to make the question more clearly.

The basic setting is that we want to define a derivative rule for the operator NonCommutativeMultiply, recall what's a derivative, call Drv:

  1. To do the derivation, we must know who is/isn't a function with respect to the derivative variable, since Drv acts on them differently. Thus as first step, it should be declare a set of functions that are real functions, let's say f, g, h.
  2. The basic rule for a derivative is that:

    • Linearity: Drv[c**f]=c**Drv[f] and Drv[f+g]=Drv[f]+Drv[g];
    • Distributive: Drv[f**g]=Drv[f]**g+f**Drv[g];
  3. for multivariable functions, we just write $Drv[f(x_1,x_2,...,x_n),x_k]$ as $f[k]$, and $Drv[Drv[f(x_1,x_2,...,x_n),x_i],x_j]$ as $f[i,j]$ and so on. For example: $$ Drv[f,i]=f[i]\\ Drv[f[i],j]=f[i,j]\\ Drv[f[i,j],k]=f[i,j,k] $$ the properties of derivative is just reads:

linearity $$ Drv[c**f,i]=c**Drv[f,i]=c**f[i], Drv[f[i]+g,j]=f[i,j]+g[j] $$ for c is a function which is independent on $x_i$. But when $c$ is a real number, $$ Drv[2 f,i]=2f[i] $$ distributive $$ Drv[f**g[i]**h[j,k],l]=f[l]**g[i]**h[j,k]+f**g[i,l]**h[j,k]+f**g[i]**h[j,k,l]. $$

UPDATE FOR 1st Answer

  1. could you just make some explanation for your code?
  2. I want drv[f[i,j],j] output f[i,j,j] rather than f[i,{j,2}]. I think this is easy to do by flatten, but since I don't understand your code, I can't do it myself.

2 Answers 2


The build-in D do almost what you want with NonConstants. I just add converters from f[i,j] format to D format and vice versa.

$drvFunctions = {f, g, h};

fromD[expr_] := expr /. HoldPattern@D[f_[ind__] | f_, i_, _Rule] :> f[ind, i]
drv[expr_, i_] := fromD@D[expr, i, NonConstants -> $drvFunctions]
drv[expr_, ind__] := Fold[drv, expr, {ind}]

drv[f, i]
(* f[i] *)

drv[f[i], j]
(* f[i, j] *)

drv[f[i, j], k]
(* f[i, j, k] *)

drv[c ** f, i]
(* c ** f[i]   <--- with NCAlgebra package *)
(* 0 ** f + c ** f[i] *)

drv[2 ** f, i]
(* 2 f[i]   <--- with NCAlgebra package *)
(* 0 ** f + 2 ** f[i] *)

drv[f[i] + g, j]
(* f[i, j] + g[j] *)

drv[f ** g[i] ** h[j, k], l]
(* f ** g[i] ** h[j, k, l] + f ** g[i, l] ** h[j, k] + f[l] ** g[i] ** h[j, k] *)

I also recommend you to load the NCAlgebra package. It helps a lot to work with noncommutative algebras.

  • $\begingroup$ @ybelltukov Thanks, I will just test it step by step, so there maybe some more problems will enconter. I think, I just update my original question at the end? $\endgroup$
    – van abel
    Oct 5, 2014 at 15:21
  • $\begingroup$ By the way, say my this post is linked to my another question, (see the left sidebar: Linked), and there are the rules I need to simplify the expression, I believe it is enough, thus I don't try NCAlgebra. $\endgroup$
    – van abel
    Oct 5, 2014 at 15:37
  • $\begingroup$ @vanabel Now it returns f[i,j,j]. For better understanding please read the docs for NonConstants and pattern-matching and investigate the output of toD, fromD. $\endgroup$
    – ybeltukov
    Oct 5, 2014 at 15:38
  • $\begingroup$ @vanabel Downloading the NCAlgebra is mush easy then implementing any non-commutative rules. It is a really useful and convenient package! $\endgroup$
    – ybeltukov
    Oct 5, 2014 at 15:44
  • $\begingroup$ thanks, I will have a try! Your answer seems work for me, but can I take more examination before I approve it? $\endgroup$
    – van abel
    Oct 5, 2014 at 15:50


I did not fully understand your question at first. I have tried like this.

Unprotect[Plus, NonCommutativeMultiply];
NCM := NonCommutativeMultiply;
constQ[t_] := If[TrueQ[Head[t] == Symbol],
  MemberQ[Attributes[t], Constant], NumberQ[t]]

Drv[n_?constQ, i_] := 0
Drv[f_, i_] := f[i]
Drv[n_?constQ f_, i_] := n f[i]

Drv[f_[i__], j_] := f[i, j]
Drv[NCM[f__], k_] := Sum[MapAt[Drv[#, k] &, NCM[f], n],
   {n, Length[{f}]}] /.
  {NCM[a___, 0, b___] :> 0,
   NCM[a_?constQ , b_] :> a b,
   NCM[b_ , a_?constQ] :> a b}

Plus /: Drv[p_ + q_] := Drv[p] + Drv[q]
Plus /: Drv[p_ + q_, k_] := Drv[p, k] + Drv[q, k]
Protect[Plus, NonCommutativeMultiply];

This is your example.

Drv[2 ** f, i]

2 f[i]

Drv[2 f, i]

2 f[i]

Drv[f[i] + g, j]

f[i, j] + g[j]

Drv[f ** g[i] ** h[j, k], l]

f ** g[i] ** h[j, k, l] + f ** g[i, l] ** h[j, k] + f[l] ** g[i] ** h[j, k]

And these are additional examples.

Drv[c ** f, i]

c ** f[i] + c[i] ** f

SetAttributes[c, Constant]
Drv[c ** f, i]

c f[i]

Drv[2 ** f ** g[i], k]

2 f ** g[i, k] + 2 f[k] ** g[i]

Drv[f ** g[i] ** c, l]

c f ** g[i, l] + c f[l] ** g[i]

Drv[c ** f, i]

c ** f[i] + c[i] ** f



  • $\begingroup$ Thanks, is there any way to make Drv[f_[i_], j_] := f[i, j] and Drv[f_[i_, j_], k_] := f[i, j, k] more general, such that Drv[f_[i_, j_,k_], l_] := f[i, j, k,l] and so on holds? $\endgroup$
    – van abel
    Oct 3, 2014 at 14:34
  • $\begingroup$ Drv[f_[i__],j_]:=f[i,j] works! But it seems that the basic rule of Drv[f[i]**h[l]+g[j],k]=f[i,k]**h[l]+f[i]**h[l,k]+g[j,k] is not holds, can you help me again? $\endgroup$
    – van abel
    Oct 3, 2014 at 14:47

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.