KGraph
 All Classes Namespaces Functions Pages
kgraph.h
1 // Copyright (C) 2013-2015 Wei Dong <wdong@wdong.org>. All Rights Reserved.
2 //
3 // \mainpage KGraph: A Library for Efficient K-NN Search
4 // \author Wei Dong \f$ wdong@wdong.org \f$
5 // \author 2013-2015
6 //
7 
8 #ifndef WDONG_KGRAPH
9 #define WDONG_KGRAPH
10 
11 #include <stdexcept>
12 
13 namespace kgraph {
14  static unsigned const default_iterations = 30;
15  static unsigned const default_L = 100;
16  static unsigned const default_K = 25;
17  static unsigned const default_P = 100;
18  static unsigned const default_M = 0;
19  static unsigned const default_T = 1;
20  static unsigned const default_S = 10;
21  static unsigned const default_R = 100;
22  static unsigned const default_controls = 100;
23  static unsigned const default_seed = 1998;
24  static float const default_delta = 0.002;
25  static float const default_recall = 0.99;
26  static float const default_epsilon = 1e30;
27  static unsigned const default_verbosity = 1;
28  enum {
29  PRUNE_LEVEL_1 = 1,
30  PRUNE_LEVEL_2 = 2
31  };
32  enum {
33  REVERSE_AUTO = -1,
34  REVERSE_NONE = 0,
35  };
36  static unsigned const default_prune = 0;
37  static int const default_reverse = REVERSE_NONE;
38 
40 
42  extern unsigned verbosity;
43 
45 
49  class IndexOracle {
50  public:
52  virtual unsigned size () const = 0;
54 
58  virtual float operator () (unsigned i, unsigned j) const = 0;
59  };
60 
62 
66  class SearchOracle {
67  public:
69  virtual unsigned size () const = 0;
71 
75  virtual float operator () (unsigned i) const = 0;
77 
85  unsigned search (unsigned K, float epsilon, unsigned *ids, float *dists = nullptr) const;
86  };
87 
89 
91  class KGraph {
92  public:
94  struct IndexParams {
95  unsigned iterations;
96  unsigned L;
97  unsigned K;
98  unsigned S;
99  unsigned R;
100  unsigned controls;
101  unsigned seed;
102  float delta;
103  float recall;
104  unsigned prune;
105  int reverse;
106 
108  IndexParams (): iterations(default_iterations), L(default_L), K(default_K), S(default_S), R(default_R), controls(default_controls), seed(default_seed), delta(default_delta), recall(default_recall), prune(default_prune), reverse(default_reverse) {
109  }
110  };
111 
113  struct SearchParams {
114  unsigned K;
115  unsigned M;
116  unsigned P;
117  unsigned S;
118  unsigned T;
119  float epsilon;
120  unsigned seed;
121  unsigned init;
122 
124  SearchParams (): K(default_K), M(default_M), P(default_P), S(default_S), T(default_T), epsilon(default_epsilon), seed(1998), init(0) {
125  }
126  };
127 
128  enum {
129  FORMAT_DEFAULT = 0,
130  FORMAT_NO_DIST = 1
131  };
132 
134  struct IndexInfo {
135  enum StopCondition {
136  ITERATION = 0,
137  DELTA,
138  RECALL
139  } stop_condition;
140  unsigned iterations;
141  float cost;
142  float recall;
143  float accuracy;
144  float delta;
145  float M;
146  };
147 
149  struct SearchInfo {
150  float cost;
151  unsigned updates;
152  };
153 
154  virtual ~KGraph () {
155  }
157 
160  virtual void load (char const *path) = 0;
162 
165  virtual void save (char const *path, int format = FORMAT_DEFAULT) const = 0; // save to file
167  virtual void build (IndexOracle const &oracle, IndexParams const &params, IndexInfo *info = 0) = 0;
169 
179  virtual void prune (IndexOracle const &oracle, unsigned level) = 0;
181 
186  unsigned search (SearchOracle const &oracle, SearchParams const &params, unsigned *ids, SearchInfo *info = 0) const {
187  return search(oracle, params, ids, nullptr, info);
188  }
190 
196  virtual unsigned search (SearchOracle const &oracle, SearchParams const &params, unsigned *ids, float *dists, SearchInfo *info) const = 0;
198  static KGraph *create ();
200  static char const* version ();
201 
203 
206  virtual void get_nn (unsigned id, unsigned *nns, unsigned *M, unsigned *L) const {
207  get_nn(id, nns, nullptr, M, L);
208  }
210 
224  virtual void get_nn (unsigned id, unsigned *nns, float *dists, unsigned *M, unsigned *L) const = 0;
225 
226  virtual void reverse (int) = 0;
227  };
228 }
229 
230 #if __cplusplus > 199711L
231 #include <functional>
232 namespace kgraph {
234 
244  template <typename CONTAINER_TYPE, typename OBJECT_TYPE>
245  class VectorOracle: public IndexOracle {
246  public:
247  typedef std::function<float(OBJECT_TYPE const &, OBJECT_TYPE const &)> METRIC_TYPE;
248  private:
249  CONTAINER_TYPE const &data;
250  METRIC_TYPE dist;
251  public:
252  class VectorSearchOracle: public SearchOracle {
253  CONTAINER_TYPE const &data;
254  OBJECT_TYPE const query;
255  METRIC_TYPE dist;
256  public:
257  VectorSearchOracle (CONTAINER_TYPE const &p, OBJECT_TYPE const &q, METRIC_TYPE m): data(p), query(q), dist(m) {
258  }
259  virtual unsigned size () const {
260  return data.size();
261  }
262  virtual float operator () (unsigned i) const {
263  return dist(data[i], query);
264  }
265  };
267 
272  VectorOracle (CONTAINER_TYPE const &d, METRIC_TYPE m): data(d), dist(m) {
273  }
274  virtual unsigned size () const {
275  return data.size();
276  }
277  virtual float operator () (unsigned i, unsigned j) const {
278  return dist(data[i], data[j]);
279  }
281  VectorSearchOracle query (OBJECT_TYPE const &q) const {
282  return VectorSearchOracle(data, q, dist);
283  }
284  };
285 
286  class invalid_argument: public std::invalid_argument {
287  public:
288  using std::invalid_argument::invalid_argument;
289  };
290 
291  class runtime_error: public std::runtime_error {
292  public:
293  using std::runtime_error::runtime_error;
294  };
295 
296  class io_error: public runtime_error {
297  public:
298  using runtime_error::runtime_error;
299  };
300 
301 }
302 #endif
303 
304 #endif
305 
virtual float operator()(unsigned i, unsigned j) const =0
Computes similarity.
unsigned search(unsigned K, float epsilon, unsigned *ids, float *dists=nullptr) const
Search with brutal force.
static KGraph * create()
Constructor.
Information and statistics of the search algorithm.
Definition: kgraph.h:149
Search oracle.
Definition: kgraph.h:66
virtual void prune(IndexOracle const &oracle, unsigned level)=0
Prune the index.
virtual void get_nn(unsigned id, unsigned *nns, unsigned *M, unsigned *L) const
Get offline computed k-NNs of a given object.
Definition: kgraph.h:206
Index oracle.
Definition: kgraph.h:49
virtual unsigned size() const =0
Returns the size of the dataset.
SearchParams()
Construct with default values.
Definition: kgraph.h:124
IndexParams()
Construct with default values.
Definition: kgraph.h:108
virtual void load(char const *path)=0
Load index from file.
static char const * version()
Returns version string.
Search parameters.
Definition: kgraph.h:113
virtual unsigned size() const =0
Returns the size of the dataset.
Information and statistics of the indexing algorithm.
Definition: kgraph.h:134
virtual void build(IndexOracle const &oracle, IndexParams const &params, IndexInfo *info=0)=0
Build the index.
The KGraph index.
Definition: kgraph.h:91
Indexing parameters.
Definition: kgraph.h:94
unsigned search(SearchOracle const &oracle, SearchParams const &params, unsigned *ids, SearchInfo *info=0) const
Online k-NN search.
Definition: kgraph.h:186
virtual void save(char const *path, int format=FORMAT_DEFAULT) const =0
Save index to file.
virtual float operator()(unsigned i) const =0
Computes similarity.