# How to get a NearestNeighborGraph[] for a given radius with periodic boundaries?

I'm wondering if there's a way to use NearestNeighborGraph with periodic boundaries, using all nearest neighbors within some radius.

I am aware of similar custom functions, like this one, but I want to simply use the built-in NearestNeighborGraph.

radiusOfInteraction = 0.25;
myNeighborGraph =
NearestNeighborGraph[
RandomReal[{-1, 1}, {100, 2}], {All, radiusOfInteraction}]


How could this be generalized to 3D?

Again, I don't want a customized function (which exist already), I'm just wondering if one could do it with a slight modification/application of the built-in NearestNeighborGraph.

Thanks!

• Just use the same DistanceFunction from that answer in the NearestNeighborGraph Commented Jul 9, 2020 at 17:27

With 3D points, and using the same DistanceFunction from here. Since it's a 3D graph, you can move around it. I also added a Manipulate just like in that answer to visually inspect that the periodic NearestFunction was working properly:

SeedRandom[1];
box = {{2, 3}, {2, 3}, {2, 3}};
pts = RandomVariate[UniformDistribution[box], 200];
boxfn[x_, b_] := Mod[x, Subtract @@ b, -0.5 Subtract @@ b]
dist[a_, b_, box_] := Norm@MapThread[boxfn[#1, #2] &, {b - a, box}];
nf = Nearest[pts, DistanceFunction -> (dist[##, box] &)];

(* verify the periodic nf is working *)
Manipulate[With[{near = nf[{x, y, z}, {n, radius}]},
Graphics3D[{
Point[pts],
PointSize[Large], Blue, Point[{x, y, z}],
Red, PointSize[Large], Point[near]
},
PlotRange -> box,
ImageSize -> 250]],
{x, 2, 3}, {y, 2, 3}, {z, 2, 3},
{{n, 8}, 1, 20, 1}]

(* generate the graph of nearest 3 elements within radius *)
g = NearestNeighborGraph[pts, {3,radius}, DistanceFunction -> (dist[##, box] &),
DirectedEdges -> False, GraphStyle -> "LargeGraph"]


The 2D case requires very little modification:

SeedRandom[1];
box = {{0, 1}, {0, 1}};
pts = RandomVariate[UniformDistribution[box], 100];
boxfn[x_, b_] := Mod[x, Subtract @@ b, -0.5 Subtract @@ b]
dist[a_, b_, box_] := Norm@MapThread[boxfn[#1, #2] &, {b - a, box}];
nf = Nearest[pts, DistanceFunction -> (dist[##, box] &)];

(*verify the periodic nf is working*)
Manipulate[
With[{near = nf[{x, y}, {All, radius}]},
Graphics[{Point[pts], PointSize[Large], Blue, Point[{x, y}], Red,
PointSize[Large], Point[near]}, PlotRange -> box,
ImageSize -> 250]], {x, 0, 1}, {y, 0, 1}]

(*generate the graph of all nearest elements within radius*)
DistanceFunction -> (dist[##, box] &), DirectedEdges -> False,
GraphStyle -> "LargeGraph"]

• .@flinty Very nice! I was wondering if one can choose all nearest neighbors within a radius. I didn't clarify enough in my original question, but I just edited it. Also, I am still not sure how do you apply the DistanceFunction for the 2D case. Could you give an example? Thanks! Commented Jul 9, 2020 at 20:23
• @TumbiSapichu updated with radius. Use {All, radius} instead if you want all of them within distance. Commented Jul 9, 2020 at 20:27
• I see. Also, I did find how to make the 2D case, so Nvm on that. Thanks! Commented Jul 9, 2020 at 20:35