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.

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] 
share|improve this question
    
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 at 23:57
1  
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 at 0:02
    
p.s. special case: Array[f, {4, 3}] –  Kuba Mar 7 at 0:07
add comment

1 Answer 1

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.

share|improve this answer
    
Latter does not produce results same as OP, you need e.g.fonGrid2[x_, y_, f_] := Table[f[a, b], {b, y}, {a, x}] –  rasher Mar 7 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 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. –  rasher Mar 7 at 0:19
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.