Re: Can anyone see a faster way to compute quantities for a pair or large matrices?
- To: mathgroup at smc.vnet.net
- Subject: [mg127426] Re: Can anyone see a faster way to compute quantities for a pair or large matrices?
- From: Sseziwa Mukasa <mukasa at gmail.com>
- Date: Mon, 23 Jul 2012 19:57:12 -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: <20120723050332.C1FE768E4@smc.vnet.net>
It seems you're fighting memory allocation issues, if you think about it Mathematica doesn't know what the result of the computation will be: an array of real numbers that it can pack efficiently, so it spends a lot of time shuffling data. This is of course an assumption on my part, but making a function that does very little other than shuffle data around consumes almost as much time as computing the ArcTan on each element on my machine (Macbook Pro, Core i7, Home Edition): (Debug) In[66]:= (*Let gradfield be the gradient that I have computed and placed in two matrices.Here I will just use random numbers as a proxy:*)(*i.e.,df/dx,df/dy*)gradfield={RandomReal[{-1,1},{256,256}],RandomReal[{-1,1},{256,256}]}; (*my gradients has many zeroes,so I need to handle these*) 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]; (*examples*) Do[psiField=MapThread[myArcTan,gradfield,2],{100}]//Timing Do[magfield=MapThread[Norm[{#}]&,gradfield,2],{100}]//Timing (Debug) Out[72]= {18.9613,Null} (Debug) Out[73]= {28.6935,Null} (Debug) In[65]:= Do[MapThread[{##}&,gradfield,2],{100}]//Timing (Debug) Out[65]= {15.5384,Null} I get a factor of roughly 2.5 performance improvement using Compile, which I'm assuming allows Mathematica to know the result is numeric and allocate memory more efficiently: (Debug) In[62]:= = myCompiledArcTan=Compile[{x,y},If[x==0.0&&y==0.0,0.0,ArcTan[x,y]]]; (Debug) In[74]:= = Do[psiField2=MapThread[myCompiledArcTan,gradfield,2],{100}]//Timing (Debug) Out[74]= {7.48545,Null} (Debug) In[75]:= psiField2==psiField (Debug) Out[75]= True That's not satisfactory to me, I suspect pure C code could be nearly an order of magnitude faster still. Regards, Ssezi On Jul 23, 2012, at 1:03 AM, W Craig Carter wrote: > > Hello, > I am computing the gradient on a grid, then computing the gradient's > angle, and its magnitude. The computations below are the bottleneck for > a longer bit of code. I would be grateful for any insights on how to > speed these up. > > (* > Let gradfield be the gradient that I have computed and placed in two matrices. Here I will just use random numbers as a proxy: > *) > > (*i.e., df/dx, df/dy*) > gradfield = { RandomReal[{-1, 1}, {256, 256}], RandomReal[{-1, 1}, {256, 256}]}; > > (*my gradients has many zeroes, so I need to handle these*) > > 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]; > > > (*examples*) > Do[psiField = MapThread[myArcTan, gradfield, 2], {100}] // Timing > Do[magfield = MapThread[Norm[{#}] &, gradfield, 2], {100}] // Timing > > W Craig Carter > Professor of Materials Science, MIT
- References:
- Can anyone see a faster way to compute quantities for a pair or large matrices?
- From: W Craig Carter <ccarter@MIT.EDU>
- Can anyone see a faster way to compute quantities for a pair or large matrices?