MathGroup Archive 1997

[Date Index] [Thread Index] [Author Index]

Search the Archive

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.                    |
> /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
> 
> 
> 
> 




  • Prev by Date: Re: Digitizing a graph/plot
  • Next by Date: Dynamics of billiards
  • Previous by thread: Union & precision <<take 2>>
  • Next by thread: Re: Union & precision <<take 2>>