Using Nearest with periodic boundary conditions of a list

Take the list

e = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}


I want to get the nearest points but with a wraparound condition. So lets say I want to find the 5 nearest points to 2, typically writing Nearest[e,2,4] would result in

{1,2,3,4,5}


I want it to wrap around to the end of the list, such that I get

{10,1,2,3,4}


I would also like to use it with the format of Nearest[e,2,{Infinity,5}]. I've read up on the Nearest in the documentation, and I think I have to define a NearestFunction however I'm still not sure how I would go about doing this. Of course I'd like it to wrap both sides of the list.

I think the following NearestFunction does what you want:

nf = Nearest[
Range[10],
DistanceFunction -> (Min[Mod[{-1,1} (#1-#2), 10]]&)
];


A couple examples:

nf[2, 5]
nf[1, {Infinity, 2.1}]


{2, 1, 3, 4, 10}

{1, 2, 10, 3, 9}

Note that the order is from closest to farthest, with ties going to the entries that appear first in the dataset.

• This is the setup I was going for, it doesn't however work on the kind of list I am looking at. Take for example the following list: e={0., 14.0362, 18.4349, 26.5651, 33.6901, 36.8699, 45., 53.1301, 56.3099, 63.4349, 71.5651, 75.9638, 90., 104.036, 108.435, 116.565, 123.69, 126.87, 135., 143.13, 146.31, 153.435, 161.565, 165.964, 180.} Using the above as nf = Nearest[ e, DistanceFunction -> (Min[Mod[{-1,1} (#1-#2),Length@e]]&) ]; With nf[45, 5] does not quite give what one would expect Commented Jun 6, 2017 at 19:05
• Why are you using Length[e] instead of 180? Commented Jun 6, 2017 at 19:07
• Oh yes, of course!! That was silly of me. Well then this works just great :) I am going to change this to the answer as it answers my question in the desired manner. However, both your and @george2079 solutions work. Commented Jun 6, 2017 at 19:08

maybe there are more elegant approaches but this is i think what you are after:

e = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
target = Position[e, 2][[1, 1]]
Flatten[ConstantArray[e, 3]]
[[target + Length@e - 2 ;;  target + Length@e + 2]]


{10, 1, 2, 3, 4}

or maybe this:

cyclicpart[list_, n_] := list[[Mod[ n - 1, Length@e] + 1]]
Table[cyclicpart[e, i], {i, target - 2, target + 2}]


{10, 1, 2, 3, 4}

Edit: using Nearest

angles = RandomReal[{0, 180}, {20}];
(*just to show they need not be ordered*)
nf = Nearest[angles,
DistanceFunction :> (Min[Abs[Mod[#2 - #1, 180] - {0, 180}]] & )];
nf[2, 7]


{177.429, 11.5476, 17.0088, 164.773, 159.163, 27.8531, 144.853}

demo:

Manipulate[Show[
Graphics@{ {Blue, Line[{{p, -2}, {p, 4}}]},
Point[{#, 0}] & /@ angles,
{Red, Point[{#, 2}] & /@ nf[p, 7]}}], {{p, 0}, 0, 180}]

• Interesting, with a bit of editing I can get it to work for my purposes. The idea is the list is ordered. It is a list of angles, ranging from 0 to 180, with periodicity given by Mod[a, 180]. I need to find all angles in that list that match a given angle with a specified tolerance. Nearest seemed like the best function for that job, and by giving it some kind or periodicity would allow me to get the job done. I am happy with your version however, it still allows me to do what I needed, Thanks Commented Jun 6, 2017 at 18:43
• oh i get it, see edit using Nearest (Though it looks like Carl beat me to it.. ) Commented Jun 6, 2017 at 19:27