# Define-Produce function from a loop?

Consider the following code:

L = 4;
sind = Range[-π, (2 π/L)*(L/2 - 1), 2 π/L]
Clear[len]; len = Length[sind];
ix1 = Flatten[Table[sind[[i]], {i, len}, len]]
iy1 = Flatten[Table[Table[sind[[i]], {i, 1, len}], len]]

(* sind={-π, -(π/2), 0, π/2}
ix1={-π, -π, -π, -π, -(π/2), -(π/2), -(π/2), -(π/2), 0, 0, 0, 0, π/2, π/2, π/2, π/2}
iy1={-π, -(π/2), 0, π/2, -π, -(π/2), 0, π/2, -π, -(π/2), 0, π/2, -π, -(π/2), 0, π/2} *)


Now we do a loop over the elements of ix1,iy1 in order to evaluate jnum:

k = 0;
For[i = 1, i <= Length[ix1], i += len, For[j = 1, j <= len, j++,
jnum = k len + Mod[j, len + 1];
Print[i, " , ", j, " , ", ix1[[i]], " , ", iy1[[j]], " , ", jnum]
]; k = k + 1;]

(*  1 , 1 , -π , -π , 1
1 , 2 , -π , -(π/2) , 2
1 , 3 , -π , 0 , 3
1 , 4 , -π , π/2 , 4
5 , 1 , -(π/2) , -π , 5
5 , 2 , -(π/2) , -(π/2) , 6
5 , 3 , -(π/2) , 0 , 7
5 , 4 , -(π/2) , π/2 , 8
9 , 1 , 0 , -π , 9
9 , 2 , 0 , -(π/2) , 10
9 , 3 , 0 , 0 , 11
9 , 4 , 0 , π/2 , 12
13 , 1 , π/2 , -π , 13
13 , 2 , π/2 , -(π/2) , 14
13 , 3 , π/2 , 0 , 15
13 , 4 , π/2 , π/2 , 16 *)


I want to create a function f: f[-π ,-π]=1, f[-π ,-(π/2)]=2, ...,f[π/2,π/2] = 16, i.e I need the x, y arguments of f[x_,y_] be given by the third and fourth columns and the output be the last column (which is given by jnum inside the loop). A piecewise definition for every x,y pair is obviously not the answer. Can it be done using Block or Module?

Instead of printing the data, we create a list dat, whereby we only need columns 3..5. Then we map an expression that defines our function fun onto the list elements:

L = 4;
sind = Range[-\[Pi], (2 \[Pi]/L)*(L/2 - 1), 2 \[Pi]/L];
Clear[len]; len = Length[sind];
ix1 = Flatten[Table[sind[[i]], {i, len}, len]];
iy1 = Flatten[Table[Table[sind[[i]], {i, 1, len}], len]];

k = 0;
dat = Reap[
For[i = 1, i <= Length[ix1], i += len,
For[j = 1, j <= len, j++, jnum = k len + Mod[j, len + 1];
Sow[{ix1[[i]], iy1[[j]], jnum}]
]; k = k + 1;]
][[2, 1]];

Clear[fun];
(fun[#1, #2] = #3) & @@@ dat;
?? fun


– geom
Commented Jan 21, 2021 at 13:34

Daniel's answer using Reap and Sow is better. An alternative to Reap and Sow is what I was working with and it is the following:

 R1 = {};
For[i = 1, i <= len, i++, a = sind[[i]];
For[j = 1, j <= len, j++, b = sind[[j]]; R = {}; R = {a, b};
R1 = Append[R1, R]];
];
R1
(*=> {{-π, -π}, {-π, -(π/2)}, {-π, 0}, {-π, π/2}, {-(π/2), -π},
{-(π/2), -(π/2)}, {-(π/2), 0}, {-(π/2), π/2}, {0, -π}, {0, -(π/2)}, {0, 0},
{0, π/2}, {π/2, -π}, {π/2, -(π/2)}, {π/2, 0}, {π/2, π/2}} *)

k = 0; R2 = {};
For[i = 1, i <= Length[R1], i++, k = k + 1; R = {}; R = {R1[[i]], k};
R = Flatten[R, 2]; R2 = Append[R2, R]]
R2

(*=> {{-π, -π, 1}, {-π, -(π/2), 2}, {-π, 0, 3}, {-π, π/2, 4},
(π/2), -π, 5},  {-(π/2), -(π/2), 6}, {-(π/2), 0, 7}, {-(π/2), π/2, 8},
{0, -π, 9}, {0, -(π/2), 10}, {0, 0, 11}, {0, π/2, 12}, {π/2, -π, 13},
{π/2, -(π/2), 14}, {π/2, 0, 15}, {π/2, π/2, 16}} *)


and then you define the function as in Daniel's answer

Clear[fun];
(fun[#1, #2] = #3) & @@@ R2;
?? fun