# Evaluate function of two variables using nested Do loops

Is there a more efficient way of evaluating a function of two variables on a rectangular grid the the following nested Do loops?

fonGrid[x_, y_, f_] := Module[{n, m, fvals},
(* x is an n-by-1 vector *)
(* y is an n-by-1 vector *)
(* f is a scalar function of two variables *)
(* fvals is an m-by-
n matirx where fVals[[i,j]]=f[ x[[j]], y[[i]] ] *)
n = Length[x];
m = Length[y];
fvals = Table[0, {m}, {n}]; (* preallocate fvals *)
Do[
Do[
fvals[[i, j]] = f[x[[j]], y[[i]]];,
{i, 1, m}];,
{j, 1, n}];
fvals]

-
Welcome to Mathematica.SE! Please edit your question and format the code as a 'code block' for readability. Use the (?) button at the top right corner of the editor for formatting help. – Szabolcs Mar 6 '14 at 23:57
Also note the differences between vectors and matrices in Mathematica. The way you wrote this code suggests to me that you are used to MATLAB. MATLAB doesn't support vectors at all, only matrices. You can have 1 by n or n by 1 "row vector" or "column vectors". Don't use these in Mathematica. Use true one-dimensional vectors such as {1,2,3} instead of a matrix such as {{1,2,3}} or {{1},{2},{3}}. – Szabolcs Mar 7 '14 at 0:02
p.s. special case: Array[f, {4, 3}] – Kuba Mar 7 '14 at 0:07

Generally, for good performance, avoid Do loops in favour of Table and functional constructs.

In this case there's a simpler way than Table:

Outer[f, x, y]


Outer is a generalization of the outer product (or Kronecker product) in that it gives you the freedom to choose the operation used in place of the multiplication.

Example:

Outer[f, Range[3], Range[5]]

{{f[1, 1], f[1, 2], f[1, 3], f[1, 4], f[1, 5]},
{f[2, 1], f[2, 2], f[2, 3], f[2, 4], f[2, 5]},
{f[3, 1], f[3, 2], f[3, 3], f[3, 4], f[3, 5]}}


If you wanted to use Table for some reason, you could directly use

Table[f[a,b], {a, x}, {b, y}]


where x and y are vectors and a and b are iterators that take elements from the vector one-by-one. I recommend that as a beginner you get familiar with Table first. It's a very commonly used and very general function that'll be useful in many cases.

-
Latter does not produce results same as OP, you need e.g.fonGrid2[x_, y_, f_] := Table[f[a, b], {b, y}, {a, x}] – ciao Mar 7 '14 at 0:11
@rasher Neither does the Outer-version I posted, but I wrote it this way on purpose (instead of transposing). I believe the OP wrote his function this way because he is used to MATLAB which encourages column-major thinking, while Mathematica encourages row-major thinking. In Mathematica a matrix is a list of rows, not a list of columns, so it's typically (not always) more advantageous to work with rows. – Szabolcs Mar 7 '14 at 0:15
Of course, I'm just a stickler for giving OPs what they want, even if goofy, and the noting it as such. – ciao Mar 7 '14 at 0:19