# Define Matrix Function in a For loop

Let $$g\in\mathcal R^{3\times 3}$$ be a given known rank 2 tensor function, $$gInv$$ its inverse, and $$dg\in\mathcal R^{3\times 3\times 3}$$ its gradiant:

g[x_,y_,z_] = {{g11[x,y,z],g12[x,y,z],g13[x,y,z]},
{g21[x,y,z],g22[x,y,z],g23[x,y,z]},
{g31[x,y,z],g32[x,y,z],g33[x,y,z]}};
dg[x_,y_,z_] = Grad[g[x, y, z], {x, y, z}];


I want to define a rank 3 tensor function componentwise by looping over each entry. Ideally like this:

G[x_, y_, z_][[k, i, j]] = 0;
For[i = 1, i <= 3, i++, For[j = 1, j <= 3, j++, For[k = 1, k <= 3, k++, For[d = 1, d <= 3, d++,
G[x_, y_, z_][[k, i, j]] +=  0.5 gInv[x, y, z][[k, d]]
(dg[x, y, z][[i, d, j]] + dg[x, y, z][[d, j, i]] - dg[x, y, z][[i, j, d]]);
]]]]


or maybe like this if the += is not suitable for a function definition:

For[i = 1, i <= 3, i++, For[j = 1, j <= 3, j++, For[k = 1, k <= 3, k++,
G[x_, y_, z_][[k, i, j]] =
0.5 gInv[x, y, z][[k, 1]](dg[x, y, z][[i, 1, j]] + dg[x, y, z][[1, j, i]] - dg[x, y, z][[i, j, 1]])
+0.5 gInv[x, y, z][[k, 2]](dg[x, y, z][[i, 2, j]] + dg[x, y, z][[2, j, i]] - dg[x, y, z][[i, j, 2]])
+0.5 gInv[x, y, z][[k, 3]](dg[x, y, z][[i, 3, j]] + dg[x, y, z][[3, j, i]] - dg[x, y, z][[i, j, 3]]);
]]]


However this notation does not work and unrolling all 4 For loops will most centainly introduce typos.

I am rather new to mathematica. Maybe there is a completely different solution which is much better. Feel free correct my approach or advice me something completely different. I might learn something.

Physics Background:

G are the Christoffel symbols from general relativity/differential geometry, and g the spatial 3-metric of a spatial hypersurface.

• You might be better off doing something like g[1,2][x_, y_, z_] and G[k_,i_,j_][x_,y_,z_] = ... (note that the first set of brackets are not [[double]]). Aug 12, 2021 at 10:21
• There are numerous questions about Christoffel Symbols on this site. Do any meet your needs? Aug 12, 2021 at 14:34
• TensorProduct-TensorContract combo. Aug 13, 2021 at 8:35
• And I suggest using a specific $g$ as an example. Aug 13, 2021 at 12:26

With the help of ebanb's comment I managed to solve my issue. Here is the solution for anybody who has a similar problem. By reversing the brakets and basicly defining one function for each tensor entry it it possible to loop over them the way I want to,

For[i = 1, i <= 3, i++, For[j = 1, j <= 3, j++, For[k = 1, k <= 3, k++,
G[k, i, j][x_, y_, z_] =
0.5 gInv[k, 1][x, y, z](dg[i, 1, j][x, y, z] + dg[1, j, i][x, y, z] - dg[i, j, 1][x, y, z])
+0.5 gInv[k, 2][x, y, z](dg[i, 2, j][x, y, z] + dg[2, j, i][x, y, z] - dg[i, j, 2][x, y, z])
+0.5 gInv[k, 3][x, y, z](dg[i, 3, j][x, y, z] + dg[3, j, i][x, y, z] - dg[i, j, 3][x, y, z]);
]]]


This way also gInv and dg need to be defined in that manner. Finally I still need to be able to do Matrix operations on some of these tensors (e.g. inverting the 3x3 metric). For this I just create a Matrix and give it the corresponding entries,

g[x_,y_,z_] =
{{g[1,1][x,y,z],g[1,2][x,y,z],g[1,3][x,y,z]},
{g[2,1][x,y,z],g[2,2][x,y,z],g[2,3][x,y,z]},
{g[3,1][x,y,z],g[3,2][x,y,z],g[3,3][x,y,z]}};
gInv[x_,y_,z_] = Inverse[g[x,y,z]];


and then reextract them if needed for the loop.

For[i = 1, i <= 3, i++, For[j = 1, j <= 3, j++,
gInv'[i, j][x_, y_, z_] = gInv[x, y, z][[i, j]];
]]

• nice! but note that you'd have an easier time using Do here with nested indices! check out Do[Print["i = ", i, ", j = ", j, ", k = ", k], {i, 3}, {j, 3}, {k, 3}] to see how it loops over all values—then substitute your i,j,k-dependent assignment for Print[...]. Aug 13, 2021 at 0:22
• however, i do wonder why you perform all assignments individually—why not simply evaluate one statement, G[k_, i_, j_][x_, y_, z_] := 0.5 gInv[k, 1][x, y, z](dg[i, 1, j][x, y, z] + dg[1, j, i][x, y, z] - dg[i, j, 1][x, y, z]) +0.5 gInv[k, 2][x, y, z](dg[i, 2, j][x, y, z] + dg[2, j, i][x, y, z] - dg[i, j, 2][x, y, z]) +0.5 gInv[k, 3][x, y, z](dg[i, 3, j][x, y, z] + dg[3, j, i][x, y, z] - dg[i, j, 3][x, y, z]), which allows generic i,j,k? Aug 13, 2021 at 0:25
• I didn't think of i,j,k as variables which then can be assigned later. For me in my mind there are already fixed, so it made more sense to me to do it this way. Thanks for the hint, ill keep it in mind for the next time!
– Tom
Aug 13, 2021 at 11:04