[Date Index]
[Thread Index]
[Author Index]
Re: Re: Pattern problem: How to count from a long list of numbers
*To*: mathgroup at smc.vnet.net
*Subject*: [mg87476] Re: [mg87427] Re: [mg87393] Pattern problem: How to count from a long list of numbers
*From*: DrMajorBob <drmajorbob at att.net>
*Date*: Fri, 11 Apr 2008 01:46:09 -0400 (EDT)
*References*: <200804090956.FAA25006@smc.vnet.net> <2514503.1207820602171.JavaMail.root@m08>
*Reply-to*: drmajorbob at longhorns.com
For those of you, like me, who need a little help understanding Carl's
always brilliant code, here's a cheat-sheet of sorts.
First, the original:
pairCount[data_, p1_, p2_] :=
Total@BitAnd[
Clip[Clip[Most@data, {p1, p1}, {p1 - 2, p1 - 2}], {p1 - 1,
p1 - 1}, {0, 1}],
Clip[Clip[Rest@data, {p2, p2}, {p2 - 2, p2 - 2}], {p2 - 1,
p2 - 1}, {0, 1}]]
Next, a parsing of that. straddle[data,p] changes everything that's NOT p
to p-2, binaryMark changes that to 0s and 1s, and pairCount2 uses Total
and BitAnd to compare binaryMark for Most@data to binaryMark for Rest@data.
straddle[data_, p_] := Clip[data, {p, p}, {p - 2, p - 2}]
binaryMark2[data_, p_] :=
Clip[straddle[data, p], {p - 1, p - 1}, {0, 1}]
pairCount2[data_, p1_, p2_] :=
Total@BitAnd[binaryMark2[Most@data, p1], binaryMark2[Rest@data, p2]]
That's exactly the same as Carl's solution, except for the
compartmentalization of code.
Third, here's my initial solution to the same problem, with a simpler
binaryMark:
binaryMark3[data_, p_] := 1 - Unitize@Sign[data - p]
pairCount3[data_, p1_, p2_] :=
Total@BitAnd[binaryMark3[Most@data, p1], binaryMark3[Rest@data, p2]]
A one-liner version of that:
pairCount4[data_, p1_, p2_] :=
Total@BitAnd[1 - Unitize@Sign[Most@data - p1],
1 - Unitize@Sign[Rest@data - p2]]
And a faster one-liner:
pairCount5[data_, p1_, p2_] :=
Length@data - 1 -
Total@BitOr[Unitize@Sign[Most@data - p1],
Unitize@Sign[Rest@data - p2]]
Finally, some timings:
sample[n_] := RandomInteger[{1, 5}, n]
times[n_, p1_, p2_] :=
With[{data = sample@n}, {Timing@pairCount[data, p1, p2],
Timing@pairCount2[data, p1, p2], Timing@pairCount3[data, p1, p2],
Timing@pairCount4[data, p1, p2], Timing@pairCount5[data, p1, p2]}]
times[10^7, 2, 3]
{{0.680051, 399704}, {0.683036, 399704}, {1.2015, 399704}, {1.19743,
399704}, {0.684635, 399704}}
times[10^7, 2, 1]
{{0.652513, 398875}, {0.65154, 398875}, {1.19801, 398875}, {1.20221,
398875}, {0.687839, 398875}}
My final version is almost as fast as Carl's original, and for me, that's
a VERY good day.
Bobby
On Thu, 10 Apr 2008 01:13:42 -0500, Carl Woll <carlw at wolfram.com> wrote:
> Nasser Abbasi wrote:
>
>> Hello;
>>
>> I think using Pattern is my weakest point in Mathematica.
>>
>> I have this list, say this: (it is all a list of integers, no real
>> numbers).
>>
>> x = {1, 3, 3, 3, 2, 3, 3, 1, 3, 3}
>>
>> And I want to count how many say a 3 followed immediately by 3. So in
>> the
>> above list, there will be 4 such occurrences. And if I want to count how
>> many 1 followed by a 3, there will be 2 such cases, etc...
>>
>> I tried Count[] but I do not know how to set the pattern for "3
>> followed by
>> a comma followed by 3" or just "3 followed immediately by 3".
>>
>> I tried few things, such as the following
>>
>> In[68]:= Count[x, {3, 3}_]
>> Out[68]= 0
>>
>> Also tried Cases, but again, I am not to good with Patterns, so not
>> sure how
>> to set this up at this moment.
>>
>> Any ideas will be appreciated.
>>
>> Nasser
>> I really need to sit down and study Patterns in Mathematica really well
>> one
>> day :)
>>
>>
>>
> If you have long lists and would like this to be very quick, I would do
> this by basically finding out the locations of the first and second
> elements, and seeing where the two line up. Here is a function that will
> do this:
>
> pairCount[data_, p1_, p2_] := Total @ BitAnd[
> Clip[Clip[Most[data], {p1, p1}, {p1 - 2, p1 - 2}], {p1 - 1, p1 - 1},
> {0, 1}],
> Clip[Clip[Rest[data], {p2, p2}, {p2 - 2, p2 - 2}], {p2 - 1, p2 - 1},
> {0, 1}]
> ]
>
> A couple examples:
>
> In[146]:= pairCount[{1, 3, 3, 3, 2, 3, 3, 1, 3, 3}, 3, 3]
>
> Out[146]= 4
>
> In[147]:= pairCount[{1, 3, 3, 3, 2, 3, 3, 1, 3, 3}, 1, 3]
>
> Out[147]= 2
>
> Carl Woll
> Wolfram Research
>
>
-- =
DrMajorBob at longhorns.com
Prev by Date:
**Re: Dynamic**
Next by Date:
**Re: Product**
Previous by thread:
**Re: Pattern problem: How to count from a long list of numbers**
Next by thread:
**Re: Pattern problem: How to count from a long list of numbers all occurrences of 2 numbers next to each others?**
| |