Veit wrote:
|
|
|The Union function gives logically inconsistent results when used with
|certain SameTest rules. The problem is that the argument of Union is
|first sorted into Mathematica's canonical order, which may be
|inconsistent with the supplied SameTest. Here's an innocent example of
|the problem:
|
|
(* examples deleted *)
|
|
|To fix this problem we have to be allowed to modify the ordering
|function used by Union in order to be consistent with SameTest. An
even |better solution would be to be able to overide Mathematica's
Order |function (which returns -1,0,1). This would accomplish both: a
|consistent rule for sorting and a criterion to decide if two elements
|are the same.
|
|This problem affects other set theoretic functions as well (e.g.
|Complement).
|
|
I was able to write my own version of Union that does what you want (see
below).
I tried to change the definition of Union so it would do what MyUnion
does below.
I also wanted to make it so you could provide the SameTest as an option
instead
of having it buried in the function definition. I had a very hard time
getting it to work.
Oh well the code below should be helpful.
In[1]:=
approxSame[x_,y_]:=Round[x-y]=={0,0};
compare[x_,y_]:=Negative[Plus@@(x-y)];
UnionRule={w___,x_,y_,z___}/;approxSame[x,y]:>{w,x,z};
In[2]:=
MyUnion[h__]:=Module[{sorted},
sorted=Sort[h,compare];
sorted//.UnionRule]
In[3]:=
demo={{1,1},{1.1,1},{1,2},{1,3},{1.3,2.1},{1,2.1}};
In[4]:=
Union[demo, SameTest->approxSame]
Out[4]=
{{1,1},{1,2},{1,3},{1.1,1},{1.3,2.1}} (* wrong answer *)
In[5]:=
MyUnion[demo]
Out[5]=
{{1,1},{1,2},{1,3}} (* right answer *)
Ted Ersek