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