Re: Union & precision <<take 2>>

*To*: mathgroup at smc.vnet.net*Subject*: [mg8669] Re: [mg8627] Union & precision <<take 2>>*From*: "C. Woll" <carlw at u.washington.edu>*Date*: Mon, 15 Sep 1997 02:48:57 -0400*Sender*: owner-wri-mathgroup at wolfram.com

Hi Gadi, The problem you are having is that Union first sorts its arguments, and then applies your test between adjacent arguments. Since your test case had the first and third elements the same after sorting, those elements couldn't be combined by the Union function. Here is a suggestion which might do what you want. Distinct[a_List]:=Flatten[Map[First,CombineSecond/@CombineFirst[a],{2}]] CombineFirst[a_List]:=Split[Sort[a],SameFirstQ] CombineSecond[a_List]:=Split[Sort[a,LastOrder],SameLastQ] SameFirstQ:=Take[#1,1]===Take[#2,1]& SameLastQ:=Last[#1]===Last[#2]& LastOrder:=Last[#1]<Last[#2]& CombineFirst collects those elements with the same head and first element into a set. CombineSecond takes each of these collections and splits them up into elements with the same second element. Then Distinct grabs the first element of these sets, and then flattens everything. You can replace the === in the above tests with your norm and pre test if you like. Good luck! Carl Woll Dept of Physics U of Washington On Fri, 12 Sep 1997, Gadi Oron wrote: > Hello again, > > This is the second chapter im my adventure of trying to use Union taking > into account the precision. > > As suggested by the replies to my last message (thanx) the use of > SameTest-> testfunc should do the thing. > > Since my sets contain only one of the two structures > "eline[{x1,y1},{x2,y2}]" and "Circle[{x,y},r]" I wrote the following: > > pre=10^(-4); > norm[v_List]:=Sqrt[v.v]; > > Clear[test]; > > test[lhs_Circle,rhs_Circle]:= > (norm[lhs[[1]]-rhs[[1]]]<pre && Abs[lhs[[2]]-rhs[[2]]]<pre ); > > test[lhs_eline , rhs_eline]:= > (norm[lhs[[1]]-rhs[[1]]]<pre && norm[lhs[[2]]-rhs[[2]]]<pre); > > test[lhs_,rhs_]:=TrueQ[(lhs==rhs)]; > > Now, it seems to work all right: Check : > > test[Circle[{0.192450089729875202`,0.277777777777777767`}, > 0.0555555555555555535`], > Circle[{0.192450089729875308`,0.277777777777777901`}, > 0.0555555555555555802`]] > > Gives : True. > > Also : > > Union[{Circle[{0.192450089729875202`,0.277777777777777767`}, > 0.0555555555555555535`], > Circle[{0.192450089729875308`,0.277777777777777901`}, > 0.0555555555555555802`]},SameTest->test] > > Gives (right): > > {Circle[{0.19245,0.277778},0.0555556]} > > But (surprise): > > Union[{Circle[{0.192450089729875202`,0.277777777777777767`}, > 0.0555555555555555535`], > Circle[{0.192450089729875202`,0.722222222222222232`}, > 0.0555555555555555535`], > Circle[{0.192450089729875308`,0.277777777777777901`}, > 0.0555555555555555802`]},SameTest->test] > > Gives (!!) : > > {Circle[{0.19245,0.277778},0.0555556],Circle[{0.19245,0.722222},0.0555556], > Circle[{0.19245,0.277778},0.0555556]} > > Notice that the set is not well ordered and that we have 2 of the > element equal by the SameTest. > > What is going wrong?? > > Thank you. > > P.S. Sorry for the illisibility, I have put in the full form of the > numbers in order to show the precision. > > /\/\/\/\/\/\/\/\/\/\/\/>> Gadi ORON <<\/\/\/\/\/\/\/\/\/\/\/\/\ > | EMAIL : oron at pmmh.espci.fr :::: oron at clipper.ens.fr | > | Homepage : http://pmmh.espci.fr/~oron/personal.html | > | fido : 2:325/302.8 | > | Soyez braves - be brave. | > /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ > > > >