Using Extract where some indices are out of bounds (efficiently)
- To: mathgroup at smc.vnet.net
- Subject: [mg114926] Using Extract where some indices are out of bounds (efficiently)
- From: Julian Francis <julian.w.francis at gmail.com>
- Date: Thu, 23 Dec 2010 03:52:42 -0500 (EST)
Dear all, How can I arrange to use Extract to extract values from an array; but where some of the indices may be out of bounds, in which case they should be simply ignored? I wrote a simple arrayInBounds function, and then did a Select on that to retrieve only the indices which are in bounds, which are then fed into Extract. Whilst this works it seems to lead to a 150* reduction in speed. FYI: My arrayInBounds function looks like this: arrayInBounds[array_, index_] := If[index == {}, True, First[index] > 0 && First[index] < Length[array] && arrayInBounds[array[[1]], Rest[index]]] My support functions for the test are: disks = Table[ Transpose[Position[DiskMatrix[r, 2*(r + 1) + 1], 1]], {r, 1, 30}]; positions[x_, y_, r_] := Transpose[{ disks[[r, 1]] + y - (r + 2), disks[[r, 2]] + x - (r + 2)}] My timing tests are: In[291]:= Timing[lists=Table[Extract[image,Select[positions[x,y, 10],arrayInBounds[image,#]&]], {y,11,64-11}, {x,11,64-11}];] Out[291]= {17.175,Null} In[292]:= Timing[lists2=Table[Extract[image,positions[x,y,10]], {y,11,64-11}, {x,11,64-11}];] Out[292]= {0.094,Null} In[293]:= lists==lists2 Out[293]= True image is assumed to be an array of at least 64*64. In this particular case, the bounds are setup so that the checking serves no purpose and can be eliminated, but I've only done this to show the speed comparison with the no bounds checking comparison. The speed difference is a factor of over 150! This seems surprising to me. Is there a better way? I don't think I can reformulate it using partitions, or the standard imagefilter functions, because in general the functions positions will be giving a complicated list of coordinates which doesn't naturally fit into a square kernel. Any help greatly appreciated. Thanks, Julian.