MathGroup Archive 2012

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Can anyone see a faster way to compute quantities for a pair or

I can only guess as to what's under the hood, but I suspect it's 
something like this:

- MapThread can't know the depth of the result, since the function being 
mapped may return a non-atomic result.  So it can't allocate the space 
to contain the result, or it allocates space to the depth it knows about 
from its second and third arguments, then uses a pointer to hold the 

- It then computes the values by mapping the function across the second 
argument of MapThread.  If it did not pre-allocate the space then every 
result has to be inserted into the result using a Join like operation 
which is known to be slow.  Otherwise it still has to allocate space to 
hold the result and each allocation takes time.

To demonstrate this idea I ran the following test for which it takes 
several seconds to do 100 iterations of MapThread on a 256x256x2 array:

(Debug) In[49]:= data = RandomReal[{-1., 1}, {2, 256, 256}];

(Debug) In[61]:= Do[MapThread[0. &, data, 2], {100}] // Timing

(Debug) Out[61]= {11.5296, Null}

Ray's solution is faster because the interpreter is optimized to handle 
the case of threading ArcTan.  Making a user defined listable, numeric 
function is not as efficient:

(Debug) In[62]:= returnZero[x_, y_] := 0.
SetAttributes[returnZero, {Listable, NumericFunction}];

(Debug) In[64]:= Do[returnZero @@ data, {100}] // Timing
Do[ArcTan @@ data, {100}] // Timing

(Debug) Out[64]= {10.4257, Null}

(Debug) Out[65]= {0.191412, Null}

If there's a teachable moment in this I suppose it's use the built-in 
listable numeric functions instead of Map, Apply etc. whenever possible.


On Jul 25, 2012, at 2:32 AM, W Craig Carter wrote:

> Thanks to Ray, Dan, Sseziwa, Andre, and David Park (offline response)

> for their suggestions which improve computation time by about a factor

> of 100.
> I am very curious what is going on under the hood that makes my 
> method (pasted again below) using MapThread so inefficient  compared 
> the better solutions (i.e., using Apply and Map solutions not the
> Compile solution).  This seems a good learning--and
> teaching--opportunity.
> (*original posting, the myArcTan is not the real culprit (btw, I am 
> impressed with Ray's UnitStep trick*)
> (* original inefficient posted method*)
> gradfield =  { RandomReal[{-1, 1}, {256, 256}], RandomReal[{-1, 1},

> {256, 256}]};
> SetAttributes[myArcTan, {Listable, NumericFunction}];
> myArcTan[0.0, 0.0] = 0.0;
> myArcTan[x_, y_] := ArcTan[x, y]
> (*the angles, this is slow*)
> psiField = MapThread[myArcTan, gradfield, 2];
> (*the magnitudes, this is slower*)
> magfield =  MapThread[Norm[{#}] &, gradfield, 2];
>>  psifield2 = ArcTan@@{gradfield[[1]] + UnitStep[-magfield2],
>>                       gradfield[[2]]}

  • Prev by Date: Re: Countur/Density plot on sphere
  • Next by Date: Putting a Test or Condition on the Right-Hand Side of a Function
  • Previous by thread: Re: Can anyone see a faster way to compute quantities for a pair or
  • Next by thread: Re: Can anyone see a faster way to compute quantities for a pair or