MathGroup Archive 2002

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

Search the Archive

RE: Re: Intersection[...,SameTest->test] ?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg33155] RE: [mg33093] Re: Intersection[...,SameTest->test] ?
  • From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
  • Date: Wed, 6 Mar 2002 01:55:30 -0500 (EST)
  • Sender: owner-wri-mathgroup at wolfram.com

> -----Original Message-----
> From: Konstantin L Kouptsov [mailto:klk206 at is5.nyu.edu]
To: mathgroup at smc.vnet.net
> Sent: Friday, March 01, 2002 12:52 PM
> To: mathgroup at smc.vnet.net
> Subject: [mg33155] [mg33093] Re: Intersection[...,SameTest->test] ?
> 
> 
> 
> Thanks to all who answered. Indeed, in version 4 the 
> mentioned function works
> without problems; with the answer being as much meaningful as 
> the "test" being the
> "equivalence" predicate (well, sometimes it is just what one 
> needs). My examples
> were run using version 3.0, in which the implementation of 
> Intersection[..., SameTest->test] is buggy.
> 
> Konstantin.
> 

Aside from this technical problem with Version 3, the question was on the
operational semantics of Intersection (as implemented in Mathematica)

> 
> Konstantin L Kouptsov wrote:
> > 
...
> > 
> > It is not clear from the manual (book or help browser), what this
command
> > is supposed to return.
> > 
...
> > 
> > What idea stands behind this function? what is it supposed to do?
> > 


As to my observation

  Intersection[a, b, SameTest -> tst]

is just the same as

  Select[Sort[a], 
         Function[s1, Or @@ Function[s2, tst[s1, s2]] /@ b ]]

except for possible side effects when applying tst. 

(*
You also may account for that if you wish, using proper Catch-Throw
constructs:
compare 

 Select[Sort[a], Function[s1, 
   Catch[Scan[
     Function[s2, If[(Print[s1, "~", s2]; s1 == 2 s2), Throw[True]]], 
   b]]
 ]]

with

 Intersection[a, b, SameTest ->((Print[#1,"~",#2];#1==2 #2)&)]

*)

Given

a = {1, 6, 0, 0, 8};
b = {3, 8, 0, 0};

In[15]:= Intersection[a, b, SameTest -> (True &)]
Out[15]= {0, 0, 1, 6, 8}

In[23]:= Intersection[a, {}, SameTest -> (True &)]
Out[23]= {}

In[35]:= Intersection[a, b, SameTest -> (#1 == 2*#2 &)]
Out[35]= {0, 0, 6}

In[168]:= Intersection[a, b, SameTest -> (#1 == #2&)]
Out[168]= {0, 0, 8}

but:

In[170]:= Intersection[a, b]
Out[170]= {0, 8}

(This is to model set intersection, but with any test function unifying
would be too restrictive.)


In[148]:= Select[Sort[a], Or @@ Function[e, True] /@ b &]
Out[148]= {0, 0, 1, 6, 8}

In[149]:= Select[Sort[a], Or @@ Function[e, True] /@ {} &]
Out[149]= {}

In[105]:= Select[Sort[a], Or @@ Function[e, # == 2 e] /@ b &]
Out[105]= {0, 0, 6}

In[169]:= Select[Sort[a], Or @@ Function[e, # == e] /@ b &]
Out[169]= {0, 0, 8}

This is what the function does. For what you use it, is quite a different
matter. This also applies to the logical primitives (and we know how to deal
with that), viz.:

In[95]:= (True || Print["hello"])
Out[95]= True

In[97]:= (False || Print["hello"]) // InputForm
>From In[97]:= "hello"
Out[97]//InputForm= Null

Short cut evaluation and passing non-logical expressions makes this resemble
an If-expression.


The lists a and b need not be of the same type, see e.g.

In[157]:= 
isColor[hue_, "red"] := hue < 1/6 || hue > 5/6;
isColor[hue_, "green"] := 1/6 <= hue < 1/2;
isColor[hue_, "blue"] := 1/2 <= hue < 7/6

In[154]:= hh = Table[Random[Real], {10}]
Out[154]=
{0.599664, 0.131625, 0.377189, 0.410453, 0.502879,
 0.588352, 0.601769, 0.554794, 0.801087, 0.767142}

In[161]:= 
Intersection[hh, {"red", "blue"}, SameTest -> isColor]
Out[161]=
{0.131625, 0.502879, 0.554794, 0.588352, 
 0.599664, 0.601769, 0.767142, 0.801087}

In[162]:=
Intersection[hh, {"green"}, SameTest -> isColor]
Out[162]=
{0.377189, 0.410453}


On the other hand, to make the SameTest function be an equivalence function,
is just not enough for intuitive expectation. See

In[8]:= x_~r~y_ := MatchQ[y/x, _Rational | _Integer]
 
In[12]:=
Table[Sqrt[Random[Integer, {1, 5}]]Random[Integer, {1, 10}], {100}]
Out[12]=
\!\({3\ \@3, 4\ \@2, 5, 5, 3\ \@5, 8, 8\ \@5, 5\ \@3, 5, 14, 5\ \@5, 8, 
    7\ \@2, 8\ \@3, 4\ \@5, 10, 12, 1, 12, 5\ \@2, 9\ \@5, 5\ \@5, 2\ \@3,
4, 
    5\ \@5, 10, 9\ \@3, 14, 14, 9\ \@3, 9, 5\ \@2, 8, 4\ \@2, 18, \@5, 
    9\ \@5, \@3, 3\ \@2, 8, 5, 8\ \@2, 7\ \@5, 9\ \@2, 6, 10\ \@3, 10, 
    9\ \@3, 10\ \@3, 5\ \@3, 3, 3\ \@5, 4, 12, 18, 12, 8\ \@2, 8, 9\ \@2,
18, 
    10\ \@5, 4\ \@5, 16, 4\ \@2, 5\ \@5, 1, 5\ \@3, 2\ \@3, \@3, 5\ \@2, 
    7\ \@2, \@2, 2\ \@2, 3, 5\ \@3, \@2, 3\ \@2, 5\ \@5, 8\ \@3, 5\ \@3, 
    4\ \@2, 4, 9\ \@3, 10\ \@2, 5\ \@3, 3\ \@5, 6\ \@3, 10\ \@3, 9\ \@3, 7, 
    5\ \@5, 4\ \@3, 3, 7, 2, 2, 5, 14, 7\ \@2, 16}\)

(* I did not convert this to InputForm, read "\@3" as Sqrt[3], 4\ \@2 as
4*Sqrt[2] *)

In[13]:= Union[%, SameTest -> r]
Out[13]= \!\({1, \@2, \@3, \@5}\)

The equivalence classes.

In[14]:= a = 3*{Sqrt[3], Sqrt[5]}
Out[14]= \!\({3\ \@3, 3\ \@5}\)
In[15]:=
b = Table[Sqrt[Random[Integer, {1, 5}]]Random[Integer, {1, 10}], {10}]
Out[15]=
\!\({6, 5\ \@5, \@3, \@3, 5\ \@3, 9\ \@5, 4\ \@5, 7, 3, 2\ \@3}\)

In[16]:= Intersection[a, b]
Out[16]= {}

In[17]:= Intersection[a, b, SameTest -> r]
Out[17]= \!\({3\ \@3, 3\ \@5}\)

Although the elements of a do not occur in b, each meets another member of
its equivalence class, and such is part of the result. The representatives
are not "normalized" though. 

In[18]:= bb = Union[b, b, SameTest -> r]
Out[18]= \!\({3, \@3, 4\ \@5}\)

In[19]:= Intersection[a, bb, SameTest -> r]
Out[19]= \!\({3\ \@3, 3\ \@5}\)

Same result as above, since we still have  the same classes.

In[20]:= Intersection[b, b, SameTest -> r]
Out[20]=
\!\({3, 6, 7, \@3, \@3, 2\ \@3, 5\ \@3, 4\ \@5, 5\ \@5, 9\ \@5}\)

Obviously, the SameTest doesn't change anything here.

The Mathematica function "Intersection" clearly is not symmetric:

In[21]:= Intersection[bb, b, SameTest -> r]
Out[21]=
\!\({3, \@3, 4\ \@5}\)

In[22]:= Intersection[b, bb, SameTest -> r]
Out[22]=
\!\({3, 6, 7, \@3, \@3, 2\ \@3, 5\ \@3, 4\ \@5, 5\ \@5, 9\ \@5}\)


To conclude: the SameTest function for Intersection is of only limited help
implementing set operations on equivalence classes. One at least should
unify the first argument to Intersection, or better reduce each expression
to normal form and then use normal set operations (without SameTest).

The meaning of Intersection with SameTest is given by its operational
semantics. It is an asymmetrical operation, and there is no need for
SameTest to be symmetric, reflexive or transitive. Just consider it as an
idiom for a special - and useful - Select operation.

--
Hartmut Wolf



  • Prev by Date: MathML Conference: Demo and Poster Submission Deadline
  • Next by Date: Re: Re: mathlink beginner problem
  • Previous by thread: Re: Intersection[...,SameTest->test] ?
  • Next by thread: boundary problem with NDSolve