# Creating a table/Matrix during a For loop

I have a For loop (with i as a counter), which calculates different values (y1, y2, y3,...) as a function of the variable x. How can I create a table/matrix which contains i lines, each line containing the variable x_i and the values (y1_i, y2_i, y3_i,...)?

-
Hi @Solarboy, welcome to MMA.SE. In the future, it would be helpful to have a minimal example of what you've tried. That way the answers can be more specific. –  tkott Mar 14 '12 at 10:24
A relevant doc page here‌​. –  Sjoerd C. de Vries Mar 14 '12 at 18:30

Try using Table, assuming x is an array of values you could try:

matrix = Table[{xi, y1[xi], y2[xi], ..}, {xi, x}]


Table will "do the For loop" while building matrix, in this case xi will take each value of x.

And if y functions is also an array, you can use a nested Table:

matrix = Table[{xi, Sequence@@Table[y[xi,j], {j, n}]}, {xi, x}]


Here j is the index for the second table, which will run from 1 to n.

-

Typically the best way to accumulate results from an arbitrary process is to use Sow and Reap.

I picked four functions of i as an example. Since there are four, I Partition at the end into subsets of four:

Reap[
For[i = 1, i < 10, i++, Sow[i]; Sow[i^2]; Sow[i!]; Sow[N@Log@i]];
][[2, 1]] ~Partition~ 4

{{1, 1, 1, 0.},
{2, 4, 2, 0.693147},
{3, 9, 6, 1.09861},
{4, 16, 24, 1.38629},
{5, 25, 120, 1.60944},
{6, 36, 720, 1.79176},
{7, 49, 5040, 1.94591},
{8, 64, 40320, 2.07944},
{9, 81, 362880, 2.19722}}


If you can formulate your code to do a single Sow for each row it will be cleaner:

Reap[
For[i = 1, i < 10, i++, Sow[{i, i^2, i!, N@Log@i}]];
][[2, 1]]


Brett Champion recommended that I show the two argument from of Sow, which groups results according to explicit tags.

Sow[e, tag]
specifies that e should be collected by the nearest enclosing Reap whose pattern matches tag.

Sow[e, {tag1, tag2, ...}]
specifies that e should be collected once for each pattern that matches a tagi.

(See this answer for a powerful use of the multiple tag form.)

Here is an example using this in place of Partition in the case of separate Sow expressions per loop.

Reap[
For[i = 1, i < 10, i++, Sow[i, i]; Sow[i^2, i]; Sow[i!, i]; Sow[N@Log@i, i]];
][[2]]


Also, with a few exceptions it is better to avoid For in Mathematica and use constructs such as Table, Do, Array, Map, NestWhile, FixedPointList and others. I chose to answer your direct question rather than to answer with what I think you should use instead. If you are interested in alternative ways to write your program you should post a new question to that effect with an example For loop you wish to optimize.

-
Glad someone brought up Sow and Reap... You should mention the two-argument form, though, since otherwise you can run into problems down the road. (Like needing to resort to Partition.) –  Brett Champion Mar 14 '12 at 21:04
Why didn't you use Do instead of For? For these cases (doing simple tests) it shows as a faster solution. –  FJRA Mar 15 '12 at 1:12
@FJRA you already showed a "better" way using Table. István references Array. I wanted to answer the OP's question directly and show best how results may be accumulated from within For or any other construct. –  Mr.Wizard Mar 15 '12 at 7:54
@Brett I'll add an example. –  Mr.Wizard Mar 15 '12 at 7:55
@Mr.Wizard your last comment points out what István started saying: there are a million ways to do this! –  FJRA Mar 15 '12 at 13:03

Now this is the kind of question that can be answered in a million ways:

yRange = 4;
iRange = 6;

(* using Table & Map *)
Table[{Subscript[x, i],
Sequence @@ Map[Subscript[y, #, i] &, Range[yRange]]}, {i,
6}] // Column

(* using Map & Table *)
Map[Prepend[Table[Subscript[y, j, #], {j, yRange}],
Subscript[x, #]] &, Range[iRange]] // Column

(* using MapThread & Array *)
Prepend,
{Transpose@Array[Subscript[y, ##] &, {yRange, iRange}],
Array[Subscript[x, ##] &, {iRange}]}] // Column


All returning:

-

Without having your for loop in hand, you could also do something like the following:

myMatrix = {}; (* Initialize the list *)

For[i=0, i<Something, i++,
(* ... you do something here *)
AppendTo[myMatrix,{xi, y1[xi], y2[xi], ..}]

(* ... do other things .. *)
]


Or you could combine the a call to Table as @FJRA suggests for the "inner loop" j with the For loop like above.

-
@Sjoerd Thanks for the edit, I guess I was writing too many comments :) –  tkott Mar 14 '12 at 18:29