3

I have a code that generates coordinate points for a 2 dimensional lattice. So the coordinates are of the form {x,y}. Now, I generate a graph out of these coordinates by connecting the nearest neighbors with an edge and translating it to a graph problem.
Let us say the data points are stored in object data. Then calculating the distances between the two coordinates, I determine if they are neighbors if the distance is d1, else they are not. This information is stored inside file mat.
This is my MWE:

distance[z1_,z2_]=1/2 ArcCosh[1 + (2 Abs[z1 - z2]^2)/((1 - Abs[z1]^2) (1 - Abs[z2]^2))];

(Generating a graph from data points ) mat = 0 IdentityMatrix[1*Length[data]];

DistributeDefinitions[d1, math, data]; (Constructing the graph ) mat = ParallelTable[ Table[If[0 < dist[data[[i]], data[[j]]] < 1.01 d1, mat[[i, j]] = 1, mat[[i, j]] = 0], {i, Length[data]}], {j, Length[data]}];

NearestNeighborGraph[data, {All, 1.01 d0}, DistanceFunction -> dist, VertexLabels -> None]

However, if the file size of data i.e., is stored in data is huge like 155k or so. The above code fails miserably, and it even crashes sometimes. Is there a way to write more efficiently and faster?
If I use NearestNeighborGraph, the problem is, instead of having an edge between the points, I am having two directed lines in opposite directions between the vertices. This only happens for large values of data.
The part of the graph that has the issue. It means there is only one directed arrow to some points!!! However if I write a Adjacency matrix by finding the distance between the points, and to connect them if it equals to some value, then it works! Where am I going wrong?

enter image description here

CORRECTIONS:
Finally, the code is working with this new change NearestNeighborGraph[data, {All, 1.01 d0}, DistanceFunction -> dist, VertexLabels -> None]. However, it is pathetically slow than my table code.

Shamina
  • 633
  • 4
  • 16
  • 6
    Mathematica has functions to work with graphs directly https://reference.wolfram.com/language/ref/NearestNeighborGraph.html -- creating a table with 24 billion elements is not the way to go – Barry Carter Aug 05 '22 at 13:51
  • 1
    You are probably looking for something like NearestNeighborGraph. – Henrik Schumacher Aug 05 '22 at 14:02
  • 1
    Besides the point BarryCarter pointed out, here are some notes on your code: you're building the matrix with ParallelTable, there is no need to set mat[[ ... ]] inside, If you want to do that, remove mat = and use ParallelDo. For creating a zero matrix, you can use ConstantArray. – Ben Izd Aug 05 '22 at 14:03
  • @BarryCarter I completely agree with you. But the distance can have a metric inside. So, the distance have to be calculated in a non-trivial way. For instance, in hyperbolic case, we can have Poincare metric – Shamina Aug 05 '22 at 14:04
  • @HenrikSchumacher There is a subtlety which I forgot to mention. Please feel fre to have a look in my previous comment. The distance between the points is not Euclidean. For e.g., it distance[z1_,z2_]=1/2 ArcCosh[1 + (2 Abs[z1 - z2]^2)/((1 - Abs[z1]^2) (1 - Abs[z2]^2))];, where z stores coordinates point in 2D. – Shamina Aug 05 '22 at 14:08
  • @BenIzd, Thanks, I again emphasize the subtlety. – Shamina Aug 05 '22 at 14:09
  • You could use DistanceFunction to set any distance function you want, but a complicated enough distance function may end up looking at all pairs of distances. – Barry Carter Aug 05 '22 at 14:11
  • @BarryCarter Does the DistanceFunction will still work even if the data point set is one dimensional i.e., without any partitioning? – Shamina Aug 05 '22 at 17:13
  • I haven't checked, but, in theory, it should work for any DistanceFunction. Oh wait, it might assume things like the triangle inequality or something – Barry Carter Aug 06 '22 at 01:06
  • @BarryCarter I can share a small data set in my question also. I would be very interested in implementing the approach mentioned by and others! – Shamina Aug 06 '22 at 06:59
  • Please do share data, I'm sort of curious myself now – Barry Carter Aug 06 '22 at 12:17
  • @BarryCarter I have aded the data file link in the main text. Any more inputs from your side is infinitely valuable. :) – Shamina Aug 06 '22 at 14:16
  • 1
  • @J.M. This is a wonderful link! Many thanks! :) I am gonna have a look. At least, I will see where I failed in the distance function. – Shamina Aug 08 '22 at 11:51
  • @J.M.'spersistentexhaustion I tried your very nicely written code. But I think I am having some problems, maybe because of my ignorance. – Shamina Aug 09 '22 at 13:31
  • @J.M.'spersistentexhaustion The problem is, instead of having an edge between the points, I am having two directed lines in opposite directions between the vertices. This only happens for large values of data. I edited my question accordingly to implement your code in it. – Shamina Aug 09 '22 at 13:33
  • 1
    If you pass NearestNeighborGraph the option DirectedEdges -> False, does it work? I'd imagine it's happening due to numerical errors causing the distance function to be asymmetrical, though, and if so those errors might warrant correction somehow instead of just being "papered over" by setting DirectedEdges -> False. I'm not sure, though. – thorimur Aug 11 '22 at 02:23
  • @thorimur thanks for this suggestion. I tried this already, however, this doesn't;t solve the problem completely. But, you will see the change in the main question now where it seems to work now. Only problem is, it is pathetically slow. You are right it is connected with the distance function that is not always numerically equal but some errors. – Shamina Aug 11 '22 at 20:00

0 Answers0