# How to define some functions automatically?

I want to use Gauss-Seidel iteration to solve this problem.

$$\left\{\begin{array}{l} 8 x_{1}-3 x_{2}+2 x_{3}=20 \\ 4 x_{1}+11 x_{2}-x_{3}=33 \\ 6 x_{1}+3 x_{2}+12 x_{3}=36 \end{array}\right.$$

n = 3;
b = {20, 33, 36}; a = {{8, -3, 2}, {4, 11, -1}, {6, 3, 12}};
Δx[
i_] := (b[[i]] - Sum[a[[i, j]]*x[j, k], {j, 1, i - 1}] -
Sum[a[[i, j]]*x[j, k - 1],
{j, i + 1, n}])/a[[i, i]]
Thread[Table[x[i, k], {i, 1, n}] ==
Table[Δx[i], {i, 1, n}]]


I want to be able to use Table[Hold[x[i, k_] := x[i, k] = Δx[i]], {i, 1, n}] to automatically define functions instead of manually defining related functions as follows:

x[1, k_] := x[1, k] = (1/8)*(3*x[2, k - 1] - 2*x[3, k - 1] + 20)
x[2, k_] := x[2, k] = (1/11)*(-(4*x[1, k ]) + x[3, k - 1] + 33)
x[3, k_] := x[3, k] = (1/12)*(-(6*x[1, k ]) - 3*x[2, k ] + 36)


That is, I want to use function Table to automatically define some functions.

So that the following operations can be carried out automatically:

x[1, 0] = 1.;
x[2, 0] = 1.;
x[3, 0] = 1.;
Table[{x[1, i], x[2, i], x[3, i]}, {i, 0, 10}]
LinearSolve[( {
{8, -3, 2},
{4, 11, -1},
{6, 3, 12}
} ), {20, 33, 36}]


What can I do to get the custom functions directly in the result?

Update 1:

The following code can implement batch custom functions:

Table[With[{i = i}, Hold[x[i, k_] := x[i, k] = i*k]], {i, 1, 3}]
ReleaseHold[%]
Table[{x[1, i], x[2, i], x[3, i]}, {i, 0, 3}]


But I don't know why the following code doesn't work in the same way:

n = 3;
b = {20, 33, 36}; a = {{8, -3, 2}, {4, 11, -1}, {6, 3, 12}};
Δx[i_] := (b[[i]] - Sum[a[[i, j]]*x[j, k], {j, 1, i - 1}] -
Sum[a[[i, j]]*x[j, k - 1], {j, i + 1, n}])/a[[i, i]]
Table[With[{i = i},
Hold[x[i, k_] := x[i, k] = Δx[i]]], {i, 1, 3}]
ReleaseHold[%]
Table[{x[1, m], x[2, m], x[3, m]}, {m, 0, 1}]


I guess the local assignment of k may cause this problem, but I don't know how to solve this problem. Please help me.

• Maybe it’s not exactly clear what you’re asking? At least to me it is not clear. If you define all of those expressions as you have written them, does it not run? What is the issue with it? Do errors appear? If so, what are they? Sep 20, 2020 at 4:51
• Table[With[{i = i}, Hold[...i...]], {i, n}] maybe. See docs for With, under Scope. Sep 20, 2020 at 20:19
• IDK, and please understand I don't have time to figure out what you want to do this evening. All I saw was Table and Hold, and you need With to insert the value of i, as I showed. It does exactly what I would want it to do. If it doesn't work for you, I can only think you don't know what Hold does and decided to stick it in for no reason. What happens if you leave it out or use ReleaseHold? Sep 21, 2020 at 2:11
• @Alittlemouseonthepampas is what I posted not what you are looking for? It does it automatically. If you’re asking to perform the initial conditions/values automatically, that is something that does not work from an algorithmic standpoint, if I’m using the correct terminology. You would need to redefine your function definitions if that’s what you want to do, which is quite outside the scope of this question & would involve the use not of Mathematica, but pen & paper to derive the proper expression so as to not need to define x[1, 0], x[2, 0], and x[3, 0] yourself. Sep 21, 2020 at 4:06
• @CATrevillian Thank you for your answer. I have posted a feasible method below. I hope you can provide more methods. Sep 21, 2020 at 5:26

I think this is what you’re looking for:

ClearAll[n,b,x,Δx];
n = 3;
b = {20, 33, 36}; a = {{8, -3, 2}, {4, 11, -1}, {6, 3, 12}};
x[i_,k_]:=x[i,k]=Δx[i,k];
x[1,0]=1.;
x[2,0]=1.;
x[3,0]=1.;
Δx[
i_,k_] := (b[[i]] - Sum[a[[i, j]]*x[j, k], {j, 1, i - 1}] -
Sum[a[[i, j]]*x[j, k - 1],
{j, i + 1, n}])/a[[i, i]];
Table[{x[1,i],x[2,i],x[3,i]},{i,0,10}]


{{1.,1.,1.},{2.625,2.13636,1.15341},{3.01278,2.0093,0.991284},{3.00567,1.99715,0.99788},{2.99946,2.,1.00027},{2.99993,2.00005,1.00002},{3.00001,2.,0.999994},{3.,2.,1.},{3.,2.,1.},{3.,2.,1.},{3.,2.,1.}}

Where the trick seems to be to define the initial conditions of the function x[i, k] after it is defined. In this way, you overwrite the definitions you defined previously, or you are defining the results that the function needs to access that will never be defined by it to start.

If this is not what you are after, please further clarify what you are interested in obtaining?

• If only the Gauss-Seidel iterates are desired, this is more straightforward: With[{mat = {{8, -3, 2}, {4, 11, -1}, {6, 3, 12}}, vec = N[{20, 33, 36}], init = N[{1, 1, 1}]}, Block[{lf = LinearSolve[N[LowerTriangularize[mat]]], su = UpperTriangularize[mat, 1]}, FixedPointList[lf[vec - su.#] &, init]]] Sep 21, 2020 at 8:55

A simple method:

n = 3;
b = {20, 33, 36}; a = {{8, -3, 2}, {4, 11, -1}, {6, 3, 12}};
x[1, 0] = 1.;
x[2, 0] = 1.;
x[3, 0] = 1.;
Δx[
i_] := (b[[i]] - Sum[a[[i, j]]*x[j, k], {j, 1, i - 1}] -
Sum[a[[i, j]]*x[j, k - 1], {j, i + 1, n}])/a[[i, i]]
Table[Hold[x[m1, k_] := x[m1, k] = c] /. m1 -> m /.
c -> Δx[m], {m, 1, 3}]
ReleaseHold[%]
Table[{x[1, m], x[2, m], x[3, m]}, {m, 0, 3}]