# Computing Christoffel symbols of the first kind

I am trying to compute the Christoffel symbols of the first kind. To keep the question short I am only computing the second term:

$$\Gamma _{\text{ijk}}=\partial \text{Mg}_{\text{ik}}/\partial q_j$$ where q = (x, y, psi, theta). I have done the computation as shown below, but is there an easier way to do this? I suspect that I can just use the partial derivative function but I have run into syntax errors when I tried it in the past.

In the computation below, I have followed the steps I would have followed if I did this by hand. It is easier to follow the code if you run the Mathematica notebook. In my example, Mg is not symmetric or invertible, but let's ignore that. It doesn't matter for this example.

Mg = {{x, 2 x, 3 x, 4 x},
{y, 2 y, 3 y, 4 y},
{psi, 2 psi, 3 psi, 4 psi},
{theta, 2 theta, 3 theta, 4 theta}}


Take partial derivatives with respect to x, y, theta, and psi.

δMgδx=D[Mg,{x}]     (* don't have better notation for partial derivative *)


 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 

δMgδy=D[Mg,{y}]


( 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0 )

δMgδpsi=D[Mg,{psi}]


( 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0 )

δMgδtheta=D[Mg,{theta}]


( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4 )

Compute the second term of the Christoffel symbol Gamma_ijk ('ij' dropped in variable name). Take the k'th column of each of the above matrices and line them up left to right.

Γ[k_] :=
Module[{},
col1 = ArrayReshape[δMgδx[[All, k]], {4, 1}];
col2 = ArrayReshape[δMgδy[[All, k]], {4, 1}];
col3 = ArrayReshape[δMgδpsi[[All, k]], {4, 1}];
col4 = ArrayReshape[δMgδtheta[[All, k]], {4, 1}];
ArrayFlatten[{{col1, col2, col3, col4}}]
]


Display outputs

Γ[1]


( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 )

Γ[2]


( 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2 )

Γ[3]


( 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3 )

Γ[4]


( 4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4 )

• Very related: math.stackexchange.com/questions/24294/… (with a reference to some Mathematica packages).
– JimB
Jul 19, 2017 at 2:27
• The entity you want to use as Riemannian metric is neither symmetric nor invertible... Jul 19, 2017 at 5:48
• There is a package called GR at library.wolfram.com/infocenter/MathSource/8847 which might be helpful for your problem. Jul 19, 2017 at 7:46

Much simpler, assuming you're using the coordinated basis:

firstChristofell[g_, x_] := With[{dG = Grad[g, x]},
1/2 (dG + TensorTranspose[dG, {3, 1, 2}] - TensorTranspose[dG, {2, 3, 1}])
]


Grad[g,x] gives us $$\partial_3 g_{12}$$, where I have used numbers rather than letters for the indices to indicate which slot we're looking at. In particular, it adds the slot at the end. Comparing with the formula for 2nd Christoffel, that's the 1st term in the formula. The second term in that formula has the derivative in the 2nd slot, so we must move level 3 to level 2 cyclically, leading to the TensorTranspose with {3,1,2} in the function body. The third term (with the minus) has the derivative in the first slot, explaining the other permutation.

### Update: re question 1) from the comments

You may find tutorial/Permutations helpful. But here's another way to look at the problem. First, let's write

$$\Gamma_{mno} = \partial_o g_{mn} + \partial_n g_{om} - \partial_m g_{no}.$$

Since o is the third slot and Grad adds slots at the end, the first term is the output from Grad. For the 2nd term, you want to get nom from omn which is

In[76]:= PermutationList[FindPermutation[{n, o, m}, {o, m, n}]]
Out[76]= {3, 1, 2}


For the third term, you want to get mno from omn, which is

In[77]:= PermutationList[FindPermutation[{m, n, o}, {o, m, n}]]
Out[77]= {2, 3, 1}


Note that the arguments to FindPermuation may appear reversed relative to the documentation. This is because FindPermutation gives the permutation to permute the labels, i.e.,

In[78]:= Permute[{n, o, m}, {3, 1, 2}]
Out[78]= {o, m, n}


But we want to permute the tensor itself, which is the inverse permutation.

• Few questions. 1) I don't fully understand why we are doing the transpose this way. I get that the index of the derivative should be last. For the first term, dg_ij/dx_k, we use {i,j,k}. For the second term, dg_ik/dx_j, we use {k,i,j}, and so on. But this seems like a black-box procedure. Can you provide more intuition for why this works or suggest a resource? 2) It looks like you are computing the Christoffel symbol of the first kind. Why are you referring to it as the second kind?
– Leo
Jul 19, 2017 at 13:51
• 2) Because I don't use this terminology and I was confused when I wrote it down. :) (I call the 2nd kind the "Levi-Civita connection", which for me is the real object, and the 1st kind the "lowered connection", which is a derived object) I have fixed the name. Jul 19, 2017 at 17:25