6
$\begingroup$

I have two expressions and three loops as

    f[x_, y_, z_] := (y + z^2) Exp[-I x] + (x + z^2) Exp[-I y];
    g[x_, y_, z_] := Abs[Conjugate[f[x, y, z]]*f[x + 1, y + 1, z + 2]];

list = {};
Do[
 Do[
  Do[
   AppendTo[list, {x, g[x, y, z]}];
   
   , {x, 0, 10, 0.05}]
  , {y, 1, 10}]
 , {z, -50, 50, 10}]

Bu I wish to use Reap and Sow instead of AppendTo and three loops. However I have seen the document and help of Mathematica about this subject, I did not understand very well how I can exploit of Reap because of few examples in the help.

$\endgroup$
3
  • 1
    $\begingroup$ Have you seen Henrik's explanation? I think it's very helpful. $\endgroup$
    – bmf
    Mar 27 at 8:21
  • $\begingroup$ I have not seen that post. I think it is good $\endgroup$ Mar 27 at 8:24
  • $\begingroup$ If you just want to build up a list, wouldn't Table or some other structure-building function be simpler (and faster)? $\endgroup$
    – lericr
    Mar 27 at 15:11

2 Answers 2

7
$\begingroup$

The following works and reproduces precisely the result of the OP.

f[x_, y_, z_] := (y + z^2) Exp[-I x] + (x + z^2) Exp[-I y];
g[x_, y_, z_] := Abs[Conjugate[f[x, y, z]]*f[x + 1, y + 1, z + 2]];

Code from OP

list = {};
Do[
 Do[
  Do[
   AppendTo[
     list, {x, g[x, y, z]}];,
   {x, 0, 10, 0.05}],
  {y, 1, 10}],
 {z, -50, 50, 10}]

Using Sow + Reap

rslist = Reap[
    Do
     [Do
      [Do
       [Sow[{x, g[x, y, z]}], {x, 0, 10, 0.05}],
      {y, 1, 10}],
     {z, -50, 50, 10}]][[-1, 1]];

Checking they are precisely the same

LinearAlgebra`Private`ZeroArrayQ[list - rslist]

True

The following also tests if the Array is zero

test = Statistics`Library`ConstantVectorQ[#] && #[[1]] == 0 &;


test@(Flatten[Rationalize[list - rslist, 0]])

True

$\endgroup$
9
$\begingroup$

why not

f[x_, y_, z_] = (y + z^2) Exp[-I x] + (x + z^2) Exp[-I y];
g[x_, y_, z_] = Abs[Conjugate[f[x, y, z]]*f[x + 1, y + 1, z + 2]];
Table[{x, g[x, y, z]}, {z, -50, 50, 10}, {y, 1, 10}, {x, 0, 10, 0.05}]//Flatten[#,2]&

if you do want reap and sow

f[x_, y_, z_] = (y + z^2) Exp[-I x] + (x + z^2) Exp[-I y];
g[x_, y_, z_] = Abs[Conjugate[f[x, y, z]]*f[x + 1, y + 1, z + 2]];
Reap[Do[
  Sow[{x, g[x, y, z]}]
, {z, -50, 50, 10}
, {y, 1, 10}
, {x, 0, 10, 0.05}
 ]][[-1,1]]
$\endgroup$
1
  • 1
    $\begingroup$ (+1) for elegance and simplicity!!! $\endgroup$
    – bmf
    Mar 27 at 8:22

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