MathGroup Archive 2011

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

Search the Archive

Re: Using Extract where some indices are out of bounds (efficiently)

  • To: mathgroup at smc.vnet.net
  • Subject: [mg115219] Re: Using Extract where some indices are out of bounds (efficiently)
  • From: Ray Koopman <koopman at sfu.ca>
  • Date: Tue, 4 Jan 2011 04:28:24 -0500 (EST)
  • References: <iev2kf$4mq$1@smc.vnet.net>

On Dec 23 2010, 12:52 am, Julian Francis <julian.w.fran... at gmail.com>
wrote:
> 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.

Is this the sort of thing you're looking for?

myExtract[array_,indices_] := With[{m = Dimensions@array}, Extract[
  array, Select[indices, And@@Positive@# && And@@Thread[# <= m]&]]]

a = Array[FromDigits@{##}&,{2,3,4}]

{{{111,112,113,114},{121,122,123,124},{131,132,133,134}},
 {{211,212,213,214},{221,222,223,224},{231,232,233,234}}}

myExtract[a,{{0,1,2},{1,2,3},{2,3,4},{3,4,5}}]

{123,234}

myExtract[a[[2,2]],Transpose@{Range[0,5]}]

{221,222,223,224}


  • Prev by Date: Re: Import, ReadList, and Unicode
  • Next by Date: Re: WAV Import[] and Integer16 Issue
  • Previous by thread: Re: Mathematica daily WTF (programming everything functionally?)
  • Next by thread: Re: Using Extract where some indices are out of bounds (efficiently)