# Pattern matching with two variables - derivatives on 4-vectors

I am interested in pattern matching with two variables and not just one, and more specifically implementing derivatives on 4-vectors. In the case of interest the 4-vectors have two indices; one is in Euclidean spacetime and the other is just such that it counts sites.

So, for the raising and lowering of the spacetime indices we have: \begin{aligned} x^{\mu} &= \delta^{\mu \nu} x_{\nu} \, , \\ x_{\mu} &= \delta_{\mu \nu} x^{\nu} \end{aligned} where in the above $$\delta$$ denotes the Kronecker delta. Greek indices are Euclidean spacetime indices, and latin indices correspond to site-counting.

In practice, the derivatives in which I am interested obey the following rules \begin{aligned} \partial^{\mu}_k x^{\nu}_1 &= \delta^{\mu \nu} \delta_{k ~ 1} \, , \\ \partial^{\mu}_1 x^{\nu}_1 &= \delta^{\mu \nu} \delta_{1 ~ 1} = \delta^{\mu \nu} \, , \\ \partial^{\mu}_2 x^{\nu}_1 &= \delta^{\mu \nu} \delta_{2 ~ 1} = 0 \, , \\ \partial_{k,\mu} x^2_1 &= \partial_{k,\mu}(x^{\nu}_1 x_{1,\nu}) = 2 x_{1,\mu} \delta_{k ~ 1} \, . \end{aligned} Site counting indices are never raised, they are always downstairs as they only serve for counting.

There is a wonderful approach here on how to implement derivatives on four-vectors, when the pattern matching is only in one variable. A sample code is given below

First we implement some rules:

(*---addtn---*)
a : pD[_Plus, ___] := Thread[Unevaluated[a], Plus, 1]
(*---mltplctn---*)

pD[a_Times, x___] :=
Plus @@ (MapAt[pD[#, x] &, a, #] & /@ Range[Length[a]])
(*---prs---*)
pD[a_^b_, x___] := b a^(b - 1) pD[a, x]
(*---cnstnts---*)
pD[a_, fvd[var_, idx_List]] := 0
(*---sclr prdcts---*)

pD[fvd[k1_Symbol, k2_Symbol], fvd[k_Symbol, derividx_List]] :=
Module[{i},
pD[fvd[k1, {i}], fvd[k, derividx]] fvd[k2, {i}] +
fvd[k1, {i}] pD[fvd[k2, {i}], fvd[k, derividx]] /.
fvd[a_Symbol,
j_List] (fvd[j_List, l_List] | fvd[l_List, j_List]) :> fvd[a, l]]
(*---mtrc drvtv---*)

pD[fvd[idx1_List, idx2_List], fvd[var_, derividx_]] := 0;
(*---4-vctrs drvtvs---*)

pD[fvd[notk_Symbol, idx_List], fvd[k_Symbol, derividx_List]] :=
0 /; FreeQ[notk, k]
pD[fvd[k_Symbol, idx_List], fvd[k_Symbol, derividx_List]] :=
fvd[idx, derividx]
(*---dspl---*)
(*---4-vctrs---*)

Format[fvd[k_Symbol, {i_}]] := Subscript[k, i]
(*---mtrc---*)
Format[fvd[{i_}, {j_}]] := Subscript[\[Delta], {i, j}]
(*---sclr prdct---*)

Format[fvd[k1_Symbol, k2_Symbol]] := DisplayForm@(k1 k2)


And the above works fine in cases where we have only the spacetime index. Examples:

1. 4-vector display $$x_{\alpha}$$:

for which we write

fvd[x, {α}]

1. Euclidean metric display $$\delta_{\alpha ~ \beta}$$:

we need to run

fvd[{α}, {β}]

1. $$\partial_b x_a = \delta_{a ~ b}$$

for which we write

pD[fvd[x, {α}], fvd[x, {β}]]

1. $$\partial_{\mu} x^2 = 2 x_{\mu}$$

for which we run:

pD[fvd[x, x], fvd[x, {μ}]]

1. Sums and differences $$\partial_{\mu}(x_{\alpha} \pm x_{\beta})=\delta_{\alpha \mu} \pm \delta_{\beta \mu}$$

for which we have

pD[fvd[x, {α}] + fvd[x, {β}], fvd[x, {μ}]]
pD[fvd[x, {α}] - fvd[x, {β}], fvd[x, {μ}]]


And it works fine. How can I generalize the above to include the second index?

After replacing SubscriptBox by Subscript and getting rid of the RowBox, which was suggested in the comments, the formatting is just fine; see below.

1. $$x_{\alpha,i}$$ and $$x_{\alpha,1}$$

are given by:

fvd[x, {α}, {i}]
fvd[x, {α}, {1}]


Then I tried to implement the derivative rule as follows, in order to account for both indices:

pD[fvd[k_Symbol, idx1_List, idx2_List],
fvd[k_Symbol, derividx1_List, derividx2_List]] :=
fvd[idx1, derividx1] fvd[idx2, derividx2]


The above works correctly in a simple example:

1. $$\partial_{2,\beta} x_{1, \alpha} = \delta_{1,2} \delta_{\alpha,\beta}$$

we run

pD[fvd[x, {1}, {α}], fvd[x, {2}, {β}]]


and when I perform the sum

1. $$\partial_{1,\beta}(x_{1,\alpha}+x_{0,\alpha})=\delta_{0,1} \delta_{\alpha, \beta} + \delta_{1,1} \delta_{\alpha, \beta}$$

it works without any issues

pD[(fvd[x, {1}, {α}] + fvd[x, {0}, {α}]),
fvd[x, {1}, {β}]]


However, when I tried to compute the difference it returned an un-evaluated expression:

1. $$\partial_{1,\beta}(x_{1,\alpha}-x_{0,\alpha})=-\delta_{0,1} \delta_{\alpha, \beta} + \delta_{1,1} \delta_{\alpha, \beta}$$

which should be computable by:

pD[(fvd[x, {1}, {α}] - fvd[x, {0}, {α}]),
fvd[x, {1}, {β}]]


causes errors.

Question: what is the proper way of implementing the derivative rules (sums, differences, products) in the case of these two parameters?

Final question: The main quantity of interest would be the following:

$$$$\partial_{k,\nu}(x^2_{1,0}) = 2 (\delta_{k,1}-\delta_{k,0})x_{1,0,\nu}$$$$

where $$x_{1,0,\nu}=x_{1,\nu}-x_{0,\nu}$$ with its inverse that would be:

$$$$\partial_{k,\nu}(\frac{1}{x^2_{1,0}}) = - \frac{2}{x^4_{1,0}} (\delta_{k,1}-\delta_{k,0})x_{1,0,\nu}$$$$

• SubscriptBox works with two arguments. You could just use Subscript, which takes the tail of the argument list and displays it as a comma-separated subscript. Or you could figure out your own way of combining the two subscript arguments and pass that structure to SubscriptBox. Commented Feb 14, 2022 at 22:29
• As for the "strange result" that shows products in the subscripts, I don't see any definition for how fvd structures should be multiplied. What you're looking at is the display form as you've defined it, but the "real" expression is still just Times[fvd[{1}, {2}], fvd[{[Alpha]}, {[Beta]}]]. Commented Feb 14, 2022 at 22:40
• @lericr thanks for your input. I got what you pointed about SubscriptBox and it works now. I still don't get the second comment about multiplication. The $\delta$ are coming from the rules in the code for the derivative, so I don't understand what multiplication has to do with them. And there's another issue, so maybe you could have a look at the edited post.
– user49048
Commented Feb 15, 2022 at 16:04
• @lericr generally people here prefer copy-pastable code rather than attached notebooks. I have put all the rules and displays in one box, then provided some examples and described the issue. hopefully is better organized
– user49048
Commented Feb 15, 2022 at 16:51
• Thanks, that'll make it a bit easier. I'll try to circle back to this later. For now, I'll just comment on the Subscript thing. DisplayForm was needed when you were using SubscriptBox. Subscript already displays with subscripts, so you don't need DisplayForm@Subscript, you can just use Subscript. I was trying to avoid dealing with box expressions, which can get complicated and difficult to parse. So, if you don't need raw boxes, it's best to avoid them. Subscript also deals with multiple subscripted elements naturally, so you don't need the RowBox stuff either. Commented Feb 15, 2022 at 20:30

It seems to me that the issue with the difference is a matter of not being able to handle scalar multiples.

Adding an additional rule for scalar products for an arbitrary number of indices is not too difficult. I used:

pD[(k_ /; FreeQ[k, fvd[_]]) v_fvd, l__] := k pD[v, l]


In this case, k_ is a pattern to capture multiples which do not contain an fvd[_] pattern, v_ is a pattern capture groups which are 4-vectors, and l__ is a pattern capture of all subsequent indices of derivation.

The resulting pattern moves the non-4-vector terms outside of the derivative. You can be more precise if you only want to consider specific types of scalar values (perhaps k_?NumericQ instead?).

Evaluating:

pD[(fvd[x, {1}, {α}] - fvd[x, {0}, {α}]), fvd[x, {1}, {β}]]


$$-\delta_{(0,1)} \delta_{(\alpha,\beta)} + \delta_{(1,1)} \delta_{(\alpha,\beta)}$$

Seems to be reasonable.

• (+1) thanks a lot for your input. It's pretty late here, so let me have a look first thing in the morning and I will make a comment :)
– user49048
Commented Feb 18, 2022 at 7:41
• I just wanted to ask you, do you understand why this happened? The reason I am asking is that essentially I would like to be able to also write the (*---sclr prdcts---*) rule using a squared 4-vector with an extra index; something the partial derivative of $x^2_1$. This is just out of curiosity in case you have a quick fix.
– user49048
Commented Feb 18, 2022 at 22:21
• The reason this scalar product rule is necessary is just because Mathematica automatically converts differences to sums, inserting factors of -1 as necessary. I'm willing to take a look at the rest of the rules, but I'm not entirely convinced I fully understand the requirements. Commented Feb 18, 2022 at 22:23
• Thanks for that. I will add the main quantity of interest in the OP. Thanks for that in advance :)
– user49048
Commented Feb 18, 2022 at 22:24
• I have added the -perhaps- more peculiar rule that I have not been able to implement. If you manage to do that, it would be great. Thanks again for your answer!
– user49048
Commented Feb 18, 2022 at 22:41