I was trying out a question in Wellin's Programming with Mathematica that says the following.
Question: Given a set of points in the plane (or 3-space), find the maximum distance between any pair of these points. This is often called the diameter of the pointset.
What I did:
Clear[x,y,pointset];
pointset={{1,5},{2,6},{4,2}} (* Set of coordinates*)
distance[{x_List,y_List}]:=Sqrt[Total[(x-y)^2]]; (*Euclidean distance function*)
Max[Map[distance,Flatten[Outer[List,pointset,pointset,1],1]]
(* Outer will give all possible pairings of the coordinates,
Flatten make the list into a collection of pairs of coordinates,
Map will apply the distance function to all the pairs,
and Max do the obvious thing
*)
For the example given above, I ran it and obtain $2\sqrt{5}$ which I expect. My problem come afterwards, I want to create a function that takes in pointset as argument and gives out the diameter. As I know the procedure above works, I defined the function as follows.
diameter[x_List]:=Max[Map[distance,Flatten[Outer[List,x,x,1],1]]
and then I ran, diameter[pointset]. The output gave me this.
Max[distance[{{{1,5},{1,5}},{{1,5},{2,6}},{{1,5},{4,2}}}]]....
While I understand that the output happened because distance is tried to be applied to the wrong type of object, I am unclear on where I went wrong. Thus, my questions are:
- How do I fix the function such that distance is applied at the correct level?
- Why does this happen? I expected it to work as I literally just copy pasted the working code and change the parameter pointset to x.
Thank you in advance for the read and replies.
Edit1: Based on suggestion from @evanb, I modified the codes into the following.
diameter[x_List]:=Max[Map[distance,Subsets[x,{2}],1]]
diameter[pointset]
which still doesn't work. However, Max[Map[distance,Subsets[pointset,{2}],1]]
gives the desired answer.
Edit2: @belisarius suggested another alternative approach and checked that the code works. Still trying to find a definitive explanation to why I couldn't get the answer on my version of Mathematica 10.
Outer[
and notOuter,
? When I make that fix,diameter[pointset]
gives2 Sqrt[5]
. $\endgroup$Subsets[x,{2}]
to accomplish what you're doing withFlatten
andOuter
. It should reduce redundant calculations. $\endgroup$