Re: Can anyone see a faster way to compute quantities for a pair or
- To: mathgroup at smc.vnet.net
- Subject: [mg127460] Re: Can anyone see a faster way to compute quantities for a pair or
- From: Sseziwa Mukasa <mukasa at gmail.com>
- Date: Thu, 26 Jul 2012 03:35:25 -0400 (EDT)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- Delivered-to: mathgroup-newout@smc.vnet.net
- Delivered-to: mathgroup-newsend@smc.vnet.net
- References: <juim0j$k9a$1@smc.vnet.net> <20120724081538.B3AF16802@smc.vnet.net> <20120725063235.C36766858@smc.vnet.net>
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
result.
- 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.
Regards,
Sseziwa
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
original
> method (pasted again below) using MapThread so inefficient compared
to
> 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
very
> 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]]}
>
>
>
- References:
- Re: Can anyone see a faster way to compute quantities for a pair or
- From: Ray Koopman <koopman@sfu.ca>
- Re: Can anyone see a faster way to compute quantities for a pair or
- From: W Craig Carter <ccarter@MIT.EDU>
- Re: Can anyone see a faster way to compute quantities for a pair or