2

I am trying to get an output of the following kind

Out = Do[Evaluate[f[x,y]],{x,table1},{y,table2}]

Here Out is a N-times-1 dimensional array/list and N is the size of table1 and table2.

I have been trying Do/For loops with various errors. Could anyone please help me on how to go about this ?

user21
  • 39,710
  • 8
  • 110
  • 167
P_0frF67
  • 31
  • 4
  • Possible duplicate: https://mathematica.stackexchange.com/questions/134609/why-should-i-avoid-the-for-loop-in-mathematica/134610#134610 – Michael E2 Apr 18 '18 at 13:04
  • I'd like to add that the use of Evaluate in this code snippet is most likely not necessary or even desirable. Evaluate is a symbol you should only start using when you get a good feel for how the Mathematica evaluator works and understand how attributes like HoldAll work. – Sjoerd Smit Apr 18 '18 at 13:32

2 Answers2

5

Do returns Null. Do is used for its side effect. Instead, use the sister function Table:

Table[f[x, y], {x, {1, 2, 3, 4}}, {y, {10, 20, 30}}]
{{f[1, 10], f[1, 20], f[1, 30]}, {f[2, 10], f[2, 20], 
  f[2, 30]}, {f[3, 10], f[3, 20], f[3, 30]}, {f[4, 10], f[4, 20], 
  f[4, 30]}}
user21
  • 39,710
  • 8
  • 110
  • 167
  • Thank you. How does the above get modified if my requirement is to create out[i] = [f[x[i],y[i]]], where i varies from {1,Length[x]} ? – P_0frF67 Apr 18 '18 at 14:26
  • Okay. I just used something like the following list = {}; For[i = 1, i <= Length[x], ++i, list = Append[list, f[x,y] /. {x ->x[[i]], y -> y[[i]]}]]. And this seems to work. Please let me know if there is a better way of doing this. Thanks. – P_0frF67 Apr 18 '18 at 14:31
  • @Prag, you should ask a new question for that. – user21 Apr 18 '18 at 14:44
4

I suggest that you use Outer, which enables you to get rid of dummy indexes. By just using @user21 's table1 and table2,

table1 = {1, 2, 3, 4};
table2 = {10, 20, 30};
Outer[f, table1, table2]

returns

{{f[1, 10], f[1, 20], f[1, 30]},
{f[2, 10], f[2, 20], f[2, 30]},
{f[3, 10], f[3, 20], f[3, 30]},
{f[4, 10], f[4, 20], f[4, 30]}}

Pay attention to how Outer distributes table1 and table2; and I think this is one of the typical examples to avoid explicit loops in Wolfram language.

If you want a 1D vector output rather than a 2D matrix, check Tuples (or just Transpose) and Apply to level one (shorthanded as @@@).


Update

In the previous last paragraph, I mean, if your two tables have equal length and you want just to pick corresponding entries from them as the function's arguments, you could use:

tables = {{a, b, c}, {x, y, z}};
f @@@ Transpose@tables

returns

{f[a, x], f[b, y], f[c, z]}

But I find a better alternative, MapThread:

MapThread[f, tables]