Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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,...)?

share|improve this question
1  
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
add comment

4 Answers 4

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.

share|improve this answer
    
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
show 1 more comment

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.

share|improve this answer
    
@Sjoerd Thanks for the edit, I guess I was writing too many comments :) –  tkott Mar 14 '12 at 18:29
add comment

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 *)
MapThread[
  Prepend,
  {Transpose@Array[Subscript[y, ##] &, {yRange, iRange}], 
   Array[Subscript[x, ##] &, {iRange}]}] // Column

All returning:

Mathematica graphics

share|improve this answer
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.