Re: Counting list elements above/below a given value
- To: mathgroup at smc.vnet.net
- Subject: [mg17375] Re: Counting list elements above/below a given value
- From: colin at tri.org.au (Colin Rose)
- Date: Thu, 6 May 1999 02:44:02 -0400
- Organization: Theoretical Research Institute
- References: <7g0qv1$drj@smc.vnet.net> <7gbkto$l17@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
The problem here is to *efficiently* count the number of elements in a list above a given value. The list is of form: In[1]:= m = Table[Random[], {280}, {280}]; and the solutions offered to date take form: In[2]:= Count[Flatten[m], x_ /; x > 0.5] // Timing Out[2]= {1.21667 Second, 38905} In[3]:= Length[Select[Flatten[m], # > .5 &]] // Timing Out[3]= {0.983333 Second, 38905} In[4]:= Count[m - .5, _?Positive, {2}] // Timing Out[4]= {0.85 Second, 38905} In[5]:= Length[Select[Flatten[m] - .5, Positive]] // Timing Out[5]= {0.566667 Second, 38905} __________________________________________ This can be improved upon in two respects: *1* COMPILING: The last solution can still be compiled: In[6]:= MrSpeedy = Compile[{{m, _Real, 1}, {val, _Real}}, Length[Select[m - val, Positive]]] In[7]:= MrSpeedy[Flatten[m], 0.5] // Timing Out[7]= {0.366667 Second, 38905} *2* BINARY SEARCH: In contrast to the approaches above, one can Sort the list, and then use a binary search algorithm to find the first element in this sorted list that is larger than VAL. Here, I adapt the BinarySearch algorithm provided in the AddOns -> Extra Packages -> ProgramminginMma directory for our purposes: BinarySearchCount[list_, elem_] := Module[{lis, n0 = 1, n1, v}, lis = Flatten[list]; lis = If[OrderedQ[lis], lis, Sort[lis]]; n1 = Length[lis]; While[n0 <= n1, v = Floor[(n0 + n1)/2]; If[ lis[[v]] == elem, Return[Length[lis]-v] ]; If[ lis[[v]] < elem, n0 = v+1, n1 = v-1 ] ]; Length[lis]-(n0-1) ] Let's try it out: In[8]:= BinarySearchCount[m, 0.5] // Timing Out[8]= {0.2 Second, 38905} Moreover, almost ALL the 'search' time goes into just sorting the list. In fact, given a SORTED list, the search time is close to zero here: In[9]:= lis = Sort[Flatten[m]]; In[10]:= BinarySearchCount[lis, 0.5] // Timing Out[10]= {0. Second, 38905} Cheers Colin PS: Timings are on a PowerMac Blue G3/400. -- Colin Rose tr(I) - Theoretical Research Institute __________________________________________ colin at tri.org.au http://www.tri.org.au/