       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[], 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:= Timing[lists=Table[Extract[image,Select[positions[x,y,
> 10],arrayInBounds[image,#]&]],
> {y,11,64-11},
> {x,11,64-11}];]
> Out= {17.175,Null}
> In:= Timing[lists2=Table[Extract[image,positions[x,y,10]],
> {y,11,64-11},
> {x,11,64-11}];]
> Out= {0.094,Null}
> In:= lists==lists2
> Out= 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)