3
$\begingroup$

There is an useful function Nearest in Mathematica, which finds the element in the aggregate given as its 1st argument that is nearest to its 2nd argument. It is very useful when we want to find the point out from a set which is the nearest to an arbitrary reference point.

On the other side, if we want to find the farthest point in a set from the reference point, a Farthest function would be useful. But looking at the documentation in the Mathematica v10.0.1, I was unable to find such an function or anything like one. Am I missing something?

This is a question out of curiosity, because I can get the farthest value constructing my own function considering euclidean distance. However, I would expect Mathematica to have in-built function that is already optimized.

$\endgroup$
  • 4
    $\begingroup$ Wouldn't negating the distance help? Nearest[{{1.5, .6}, {2, 0}, {1.25, 1.25}}, {0, 0}, DistanceFunction -> (-EuclideanDistance[#1, #2] &)]. $\endgroup$ – J. M. will be back soon Jul 31 '17 at 5:44
  • 2
    $\begingroup$ -EuclideanDistance doesn't work because it is neither a function nor a expression that evaluates to a function; it is Times[-1, EuclideanDistance] $\endgroup$ – m_goldberg Jul 31 '17 at 6:40
  • 4
    $\begingroup$ @J.M. Not knowing how Nearest works, I feel a bit uncomfortable about the fact that this does not satisfy the properties of a mathematical distance function. What if the algorithm used by Nearest assumes some of these properties? Perhaps it's better to explicitly use Method -> "Scan"? Do you know if this method simply tests the distance to each point separately, as the name would suggest? Maybe the default is always "Scan" for a custom DistanceFunction? $\endgroup$ – Szabolcs Jul 31 '17 at 7:34
  • 1
    $\begingroup$ @Mike he was not proposing Times[-1, EuclideanDistance] but rather explaining that -EuclideanDistance evaluates to that expression, and that it does not work because it is not a function. That said it would be nice shorthand if -function worked the way you thought it did. $\endgroup$ – Mr.Wizard Jul 31 '17 at 9:23
  • 2
    $\begingroup$ farthest[lst_, ele_] := Nearest[lst, ele, Infinity] // Cases[#, Last@#] &; does the job pretty quickly on my turdbook... $\endgroup$ – ciao Aug 1 '17 at 8:21
1
$\begingroup$

Say you have the data:

data = RandomReal[{-100, 100}, {10000, 2}];

and want Furthest[data -> "Index", data, 4]. Select the vertices of the convex hull and add to those the vertices of the new convex hull (of data without already found vertices). Stop after the 4th convex hull. In this code I only include these vertices in Nearest

element = Nest[Join[MeshCoordinates[ConvexHullMesh[Complement[data, #]]], #] &, {}, 4];
index = Lookup[PositionIndex[data], element][[All, 1]];
res = Transpose[index[[#]] & /@ Transpose[Take[Nearest[
  element -> "Index", data, Length[element]], All, {-1, -4, -1}]]];

I hope the DistanceFunction you are using allow this. Otherwise maybe you can still do it after some transformation of data.

I also tried using Compile with Ordering[#, -4] to avoid Nearest[, ,Length[element]], but it was only slightly faster, and I am not sure if Parallelization might cause problems for Ordering

c2 = Compile[{{x, _Real, 1}}, Function[u, #2[[u]]] /@ Reverse[Ordering[Plus @@ ((x - #)^2), -4]],
      Parallelization -> True, RuntimeAttributes -> {Listable}] &[Transpose[element], index];
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.