Graphviz 12.0.1~dev.20240716.0800
Loading...
Searching...
No Matches
nearest_neighbor_graph_ann.cpp
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include "config.h"
12
13#ifdef HAVE_ANN
14
15#include <ANN/ANN.h> // ANN declarations
17#include <utility>
18#include <vector>
19
20static const int dim = 4; // dimension
21
22static void sortPtsX(int n, ANNpointArray pts){
23 /* sort so that edges always go from left to right in x-doordinate */
24 for (int i = 0; i < n; i++){
25 ANNpoint p = pts[i];
26 if (p[0] < p[2] || (p[0] == p[2] && p[1] < p[3])) continue;
27 std::swap(p[0], p[2]);
28 std::swap(p[1], p[3]);
29 }
30}
31
32static void sortPtsY(int n, ANNpointArray pts){
33 /* sort so that edges always go from left to right in x-doordinate */
34 for (int i = 0; i < n; i++){
35 ANNpoint p = pts[i];
36 if (p[1] < p[3] || (p[1] == p[3] && p[0] < p[2])) continue;
37 std::swap(p[0], p[2]);
38 std::swap(p[1], p[3]);
39 }
40}
41
42void nearest_neighbor_graph_ann(int nPts, int k, const std::vector<double> &x,
43 int &nz0, std::vector<int> &irn,
44 std::vector<int> &jcn,
45 std::vector<double> &val) {
46
47 /* Gives a nearest neighbor graph is a list of dim-dimendional points. The connectivity is in irn/jcn, and the distance in val.
48
49 nPts: number of points
50 dim: dimension
51 k: number of neighbors needed
52 x: nPts*dim vector. The i-th point is x[i*dim : i*dim + dim - 1]
53 nz: number of entries in the connectivity matrix irn/jcn/val
54 irn, jcn: the connectivity
55 val: the distance
56
57 note that there could be repeates
58 */
59
60 // error tolerance
61 const double eps = 0;
62
63 ANNpointArray dataPts = annAllocPts(nPts, dim); // allocate data points
64 std::vector<ANNidx> nnIdx(k); // allocate near neighbor indices
65 std::vector<ANNdist> dists(k); // allocate near neighbor dists
66
67 for (int i = 0; i < nPts; i++){
68 double *xx = dataPts[i];
69 for (int j = 0; j < dim; j++) xx[j] = x[i*dim + j];
70 }
71
72 //========= graph when sort based on x ========
73 int nz = 0;
74 sortPtsX(nPts, dataPts);
75 ANNkd_tree kdTree( // build search structure
76 dataPts, // the data points
77 nPts, // number of points
78 dim); // dimension of space
79 for (int ip = 0; ip < nPts; ip++){
80 kdTree.annkSearch( // search
81 dataPts[ip], // query point
82 k, // number of near neighbors
83 nnIdx.data(), // nearest neighbors (returned)
84 dists.data(), // distance (returned)
85 eps); // error bound
86
87 for (int i = 0; i < k; i++) { // print summary
88 if (nnIdx[i] == ip) continue;
89 val[nz] = dists[i];
90 irn[nz] = ip;
91 jcn[nz++] = nnIdx[i];
92 }
93 }
94
95
96 //========= graph when sort based on y ========
97 sortPtsY(nPts, dataPts);
98 kdTree = ANNkd_tree( // build search structure
99 dataPts, // the data points
100 nPts, // number of points
101 dim); // dimension of space
102 for (int ip = 0; ip < nPts; ip++){
103 kdTree.annkSearch( // search
104 dataPts[ip], // query point
105 k, // number of near neighbors
106 nnIdx.data(), // nearest neighbors (returned)
107 dists.data(), // distance (returned)
108 eps); // error bound
109
110 for (int i = 0; i < k; i++) { // print summary
111 if (nnIdx[i] == ip) continue;
112 val[nz] = dists[i];
113 irn[nz] = ip;
114 jcn[nz++] = nnIdx[i];
115 }
116 }
117
118 nz0 = nz;
119
120 annDeallocPts(dataPts);
121 annClose(); // done with ANN
122
123
124
125}
126
127#endif /* HAVE_ANN */
void nearest_neighbor_graph_ann(int nPts, int k, const std::vector< double > &x, int &nz0, std::vector< int > &irn, std::vector< int > &jcn, std::vector< double > &val)