Mathematica 9 is now available
Services & Resources / Wolfram Forums / MathGroup Archive
-----

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: [mg115339] Re: Using Extract where some indices are out of bounds (efficiently)
  • From: Julian Francis <julian.w.francis at gmail.com>
  • Date: Sat, 8 Jan 2011 03:37:54 -0500 (EST)
  • References: <iev2kf$4mq$1@smc.vnet.net> <ifup7d$cog$1@smc.vnet.net>

On Jan 7, 9:07 am, Ray Koopman <koop... at sfu.ca> wrote:
> On Jan 5, 11:01 pm, Ray Koopman <koop... at sfu.ca> wrote:
>
>
>
>
>
>
>
>
>
> > On Jan 4, 1:28 am, Ray Koopman <koop... at sfu.ca> wrote:
> >> 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, 3=
0}];
>
> >>> 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}
>
> > If the array from which you are extracting elements is two-dimensional
> > and square then this will be much faster than my previous suggestion:
>
> > myExtract2[array_,indices_] := With[{m = Length@array},
> > Extract[array, Part[indices,
> >   SparseArray[Times@@UnitStep[(#-1)*(m-#)&@Transpose@indices]] /.
> >   SparseArray[_,_,_,d_] :> Flatten@d[[2,2]] ]]]
>
> To remove the restriction on myExtract2 to two-dimensional square
> arrays, just change Length@array to Dimensions@array. This will make
> it as general as myExtract, without slowing it for two-dimensional
> square arrays.

Thank you very much; that is excellent. My timings indicates your
version is approximately 40 times faster than my original extract with
arrayInBounds version.

Thank you and kind regards,
Julian.


  • Prev by Date: Re: I'm puzzled by drastic truncation of y-axis in DateListLogPlot
  • Next by Date: Re: How to change the directory for the docs?
  • Previous by thread: Re: Using Extract where some indices are out of bounds (efficiently)
  • Next by thread: Re: Using Extract where some indices are out of bounds (efficiently)