Define a rule of derivative in NonCommutativeMultiply?

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

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

Drv[f[i],j]=f[i,j]
Drv[f[i,j],k]=f[i,j,k]
Drv[f[i]**g[j],k]=f[i,k]**g[j]+f[i]**g[j,k]


UPDATE

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].$$

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.

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.

• @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? – van abel Oct 5 '14 at 15:21
• 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. – van abel Oct 5 '14 at 15:37
• @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. – ybeltukov Oct 5 '14 at 15:38
• @vanabel Downloading the NCAlgebra is mush easy then implementing any non-commutative rules. It is a really useful and convenient package! – ybeltukov Oct 5 '14 at 15:44
• thanks, I will have a try! Your answer seems work for me, but can I take more examination before I approve it? – van abel Oct 5 '14 at 15:50

Update

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

Unprotect[Plus, NonCommutativeMultiply];
NCM := NonCommutativeMultiply;
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];


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]

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]

ClearAll[c]
Drv[c ** f, i]


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

Original

Deleted

• 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? – van abel Oct 3 '14 at 14:34
• 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? – van abel Oct 3 '14 at 14:47