Re: Element Extraction

• To: mathgroup at smc.vnet.net
• Subject: [mg19316] Re: [mg19240] Element Extraction
• From: "Carl K.Woll" <carlw at fermi.phys.washington.edu>
• Date: Sat, 14 Aug 1999 23:42:48 -0400
• Organization: Department of Physics
• References: <199908110606.CAA01017@smc.vnet.net.> <37B47049.33AB607@fermi.phys.washington.edu> <37B54909.973D6F5E@hixnet.co.za>
• Sender: owner-wri-mathgroup at wolfram.com

```Below Kew complains about the lack of generality of the fastest solution
to his problem. I should have given some words of
explanation about how the fastest solution worked.

Basically, for my hamming[5] function, I took Allan Hayes solution, and tried
to speed it up. There were two things that I did.

1. He used MapThread to thread SameQ over his two vectors. I temporarily
gave SameQ the attribute Listable to achieve the
same thing. This gave a 20-30% improvement in speed. I modified my previous
hamming[5] function to do just this single
change.

2. Rather than counting the number of false entries and seeing if it was
less than some prescribed number, given the
shortness of the vector I instead hardcoded the close enough possibilities
(alternatively, I could have hardcoded the far
enough away possibilities). This provided another 100% improvement in speed at
the sacrifice of generality.

For the hamming[6] function, I tried to attack the problem from a different angle.
Since Position and Part are such
extremely quick functions, I massaged the whole testlist function instead
of each element individually. I also used the two
things I noted above.

If we want a general hamming function, then approach 2 above is obviously
not the way to go. However, for the approach taken
in hamming[6], I was able to come up with a similar method, which was still
general enough. In this approach I used the ever
useful Sequence[] function. At any rate, here is a revised version of my
previous notebook with the above changes using your
new syntax hamming[list,target,distance] (I also had to change David Park's solution a little bit more than the others to
make it work, and in the process speeded it up a bit).

In[1]:=
(* Hayes *)
hamming[1][lis_,tar_,dist_]:=
Cases[lis,x_/;Count[MapThread[SameQ,{target,x}],False]<=dist]

(* Park revised *)
hamming[2][lis_,tar_,dist_]:=Select[lis,Count[#-tar,0]>Length[tar]-dist -1&]

(* Kozlowski *)
distance[a_, b_] := If[a === b, 0, 1]
SetAttributes[distance, Listable]

hamming[3][lis_,tar_,dist_]:=
Select[lis, Apply[Plus, distance[tar, #]] <= dist &]

(* Hanlon *)
hammingDistance[x_?VectorQ, y_?VectorQ] /; Length[x] == Length[y] :=
Plus @@ MapThread[If[#1 == #2, 0, 1] &, {x, y}];

hamming[4][lis_,tar_,dist_]:=Select[lis, hammingDistance[tar, #] < dist +1&]

(* Woll #1 *)hamming[5][lis_,tar_,dist_]:=Module[{ans},
SetAttributes[SameQ,{Listable}];
ans=Cases[lis,x_/;Count[SameQ[x,tar],False]<=dist];
ClearAttributes[SameQ,{Listable}];
ans]

(* Woll #2 *)
hamming[6][lis_,tar_,dist_]:=Module[{ans,t,len=Length[lis]},
SetAttributes[SameQ,{Listable}];
t=SameQ[testlist,Table[tar,{len}]];
ans=lis[[
Flatten[Position[Length/@(t/.True->Sequence[]),
Alternatives@@Range[0,dist]]]]];
ClearAttributes[SameQ,{Listable}];
ans]
In[27]:=
target = Table[Random[Integer,{0,2}],{10}];
In[28]:=
testlist =
Table[Random[Integer, {0, 2}], {10000},{10}];
In[29]:=
Do[Print[Timing[r[i]=hamming[i][testlist,target,2];]],{i,1,6}]

r[1]==r[2]==r[3]==r[4]==r[5]==r[6]
{3.734 Second,Null}
{4.547 Second,Null}
{9.281 Second,Null}
{9.109 Second,Null}
{3.063 Second,Null}
{2.187 Second,Null}
Out[30]=
True

Carl Woll
Dept of Physics
U of Washington

Kew Joinery wrote:

> Hello,
> I'd like to thank to all replies again.
> Only to add few words:
> To define universal Humming function it should be of the form :
> Hamming[someList , target , distance]
> Obviously all solutions from the different authors (excluding the farstest solution
> of Mr.K.Woll )could be easy adapted to this form (they are at the moment of the form
> hamming[someList ,target] .
> What about the fastest solution? At the moment it detects only lists with elements of
> length=3 and distance <=1. Consider example when testing
> someList={{0,1,2,3,4,5,6,7,8,9},{0,0,1,2,3,4,5,6,7,8},{0,0,0,1,2,3,4,5,6,7},{0,0,0,0,1,2,3,4,5,6},{0,0,0,0,0,0,0,0,0,0}}
>
> According to Mr.Woll I should define all 10! success[]=0 inn advance to detect
> someList in Hamming Distance <= for example.I thing this solution is
inpractical .
> Regards,
> Eugene
>
> Carl K.Woll wrote:
>
> > Hi all,
> >
> > I thought I would give a comparison of the various solutions provided
, along with
> > a couple of new ones by yours truly.
> >
> > (* Hayes *)
> > hamming[1][lis_,tar_]:=
> >   Cases[lis,x_/;Count[MapThread[SameQ,{target,x}],False]<=1]
> >
> > (* Park *)
> > hammtest[p : {_, _, _}, t : {_, _, _}] := Count[Abs[t - p], 0] > 1;
> >
> > hamming[2][lis_,tar_]:=Select[lis,hammtest[#,tar]&]
> >
> > (* Kozlowski *)
> > dist[a_, b_] := If[a === b, 0, 1]
> > SetAttributes[dist, Listable]
> >
> > hamming[3][lis_,tar_]:=Select[lis, Apply[Plus, dist[tar, #]] <= 1
&]
> >
> > (* Hanlon *)
> > hammingDistance[x_?VectorQ, y_?VectorQ] /; Length[x] == Length[y]
:=
> >     Plus @@ MapThread[If[#1 == #2, 0, 1] &, {x, y}];
> >
> > hamming[4][lis_,tar_]:=Select[lis, hammingDistance[tar, #] < 2 &]
> >
> > (* Woll #1 *)
> > Clear[closeEnough];
> > closeEnough[{True,True,True}]=True;
> > closeEnough[{True,True,False}]=True;
> > closeEnough[{True,False,True}]=True;
> > closeEnough[{False,True,True}]=True;
> >
> > hamming[5][lis_,tar_]:=Module[{ans},
> >   SetAttributes[SameQ,{Listable}];
> >   ans=Select[lis,closeEnough[SameQ[#,tar]]&];
> >   ClearAttributes[SameQ,{Listable}];
> >   ans]
> >
> > (* Woll #2 *)
> > Clear[success]
> > success[True,True,True]=0;
> > success[True,True,False]=0;
> > success[True,False,True]=0;
> > success[False,True,True]=0;
> >
> > hamming[6][lis_,tar_]:=Module[{ans,t,len=Length[lis]},
> >   SetAttributes[SameQ,{Listable}];
> >   t=SameQ[testlist,Table[tar,{len}]];
> >   ans=lis[[Flatten[Position[Apply[success,t,1],0]]]];
> >   ClearAttributes[SameQ,{Listable}];
> >   ans]
> > In[22]:=
> > target = {0, 0, 1};
> > In[263]:=
> > testlist =
> >     Table[{Random[Integer, {0, 2}], Random[Integer, {0, 2}],
> >         Random[Integer, {0, 2}]}, {10000}];
> > In[381]:=
> > Do[Print[Timing[r[i]=hamming[i][testlist,target];]],{i,1,6}]
> >
> > r[1]==r[2]==r[3]==r[4]==r[5]==r[6]
> > {2.703 Second,Null}
> > {3.937 Second,Null}
> > {3.969 Second,Null}
> > {5.234 Second,Null}
> > {1.125 Second,Null}
> > {0.969 Second,Null}
> > Out[382]=
> > True
> >
> > Carl Woll
> > Dept of Physics
> > U of Washington
> >
> > Kew Joinery wrote:
> >
> > > Hello everyone,
> > > I have a problem extracting list of list.
> > > Given some list, consisting of elements (not all of them distinct)
with
> > > the same length and some target list of the same length, for example:
> > > In[26]:=
> > > someList={{0,0,0},{0,0,1},{0,0,2},{0,1,0},{0,1,1},{0,1,2},{0,2,0}
,{0,2,1},{0,
> > >
> > > 2,2},{1,0,0},{1,0,1},{1,0,2},{1,1,0},{1,1,1},{1,1,2},{1,2,0},{1,2,1
},{1,
> > >
> > > 2,2},{2,0,0},{2,0,1},{2,0,2},{2,1,0},{2,1,1},{2,1,2},{2,2,0},{2,2,1
},{2,
> > >
> > >       2,2}};
> > >
> > > In[27]:=
> > > target={0,0,1};
> > >
> > > Hamming distance between two bit strings means the number of bit
> > > positions in which they differ. For example consecutive elements of
the
> > > Gray code list have Hamming distance = 1.
> > > I need to extract these cases(elements of someList) which differ from
> > > target in one coordinate (Hamming distance = 1) or less (the
> > > element===target itself//Hamming distance=0), so the answer
should be:
> > >
> > > In[33]:=
> > > answer={{0,0,0},{0,0,1},{0,0,2},{0,1,1},{0,2,1},{1,0,1},{2,0,1}};
> > >
> > > How could I achieve the extraction efficiently?
> > > Thank you in advance for any suggestions.
> > > Eugene

```

• Prev by Date: Re: Win32 MathLink .exe from Matheamtica 3 on a Mac
• Next by Date: Re: Re: Re: Subscripts, Doh!!!
• Previous by thread: Re: Element Extraction
• Next by thread: Re: Element Extraction