aimsalgo 6.0.0
Neuroimaging image processing
knn.h
Go to the documentation of this file.
1/* This software and supporting documentation are distributed by
2 * Institut Federatif de Recherche 49
3 * CEA/NeuroSpin, Batiment 145,
4 * 91191 Gif-sur-Yvette cedex
5 * France
6 *
7 * This software is governed by the CeCILL-B license under
8 * French law and abiding by the rules of distribution of free software.
9 * You can use, modify and/or redistribute the software under the
10 * terms of the CeCILL-B license as circulated by CEA, CNRS
11 * and INRIA at the following URL "http://www.cecill.info".
12 *
13 * As a counterpart to the access to the source code and rights to copy,
14 * modify and redistribute granted by the license, users are provided only
15 * with a limited warranty and the software's author, the holder of the
16 * economic rights, and the successive licensors have only limited
17 * liability.
18 *
19 * In this respect, the user's attention is drawn to the risks associated
20 * with loading, using, modifying and/or developing or reproducing the
21 * software by the user in light of its specific status of free software,
22 * that may mean that it is complicated to manipulate, and that also
23 * therefore means that it is reserved for developers and experienced
24 * professionals having in-depth computer knowledge. Users are therefore
25 * encouraged to load and test the software's suitability as regards their
26 * requirements in conditions enabling the security of their systems and/or
27 * data to be ensured and, more generally, to use and operate it in the
28 * same conditions as regards security.
29 *
30 * The fact that you are presently reading this means that you have had
31 * knowledge of the CeCILL-B license and that you accept its terms.
32 */
33
34#ifndef AIMS_MATH_KNN_H
35#define AIMS_MATH_KNN_H
36
37#include <cstdlib>
38#include <stdlib.h>
39#include <math.h>
40#include <vector>
41#include <algorithm>
42#include <iostream>
43#include <string.h>
44
45namespace aims
46{
47
48namespace knn
49{
50
52{
53public:
55 virtual ~Distance() {};
56
57 virtual inline const std::string &name(void) const
58 {
59 return _name;
60 }
61
62 virtual double operator()(const double *v1,
63 const double *v2, unsigned int dim) const = 0;
64
65 virtual double operator()(const std::vector<double> &v1,
66 const std::vector<double> &v2) const
67 {
68 return (*this)(&v1[0], &v2[0], v1.size());
69 }
70protected:
71 std::string _name;
72};
73
75{
76public:
78 {
79 _name = "euclidian";
80 }
81 virtual ~EuclidianDistance() {};
82
83 virtual double operator()(const double *v1,
84 const double *v2, unsigned int dim) const
85 {
86 double d, s = 0.;
87
88 for (unsigned int i = 0; i < dim; ++i)
89 {
90 d = v1[i] - v2[i];
91 s += d * d;
92 }
93 return sqrt(s);
94 }
95};
96
98{
99public:
101 {
102 _name = "squared_euclidian";
103 }
105
106 virtual double operator()(const double *v1,
107 const double *v2, unsigned int dim) const
108 {
109 double d, s = 0.;
110
111 for (unsigned int i = 0; i < dim; ++i)
112 {
113 d = v1[i] - v2[i];
114 s += d * d;
115 }
116 return s;
117 }
118};
119
121{
122public:
124 {
125 _name = "manhattan";
126 }
127 virtual ~ManhattanDistance() {};
128
129 virtual double operator()(const double *v1,
130 const double *v2, unsigned int dim) const
131 {
132 double s = 0.;
133
134 for (unsigned int i = 0; i < dim; ++i)
135 s += fabs(v1[i] - v2[i]);
136 return s;
137 }
138};
139
140
142{
143public:
145 {
146 _name = "tchebychev";
147 }
149
150 virtual double operator()(const double *v1,
151 const double *v2, unsigned int dim) const
152 {
153 double d = 0., max = 0.;
154
155 for (unsigned int i = 0; i < dim; ++i)
156 {
157 d = fabs(v1[i] - v2[i]);
158 if (d > max) max = d;
159 }
160 return max;
161 }
162};
163
164
166{
167public:
168 typedef double * value_type;
169 typedef double ** pointer;
170 typedef double *& reference;
171
172
174 Database(double *data, unsigned int size, unsigned int dim);
175 virtual ~Database() {};
176
177 void init(double *data, unsigned int size, unsigned int dim);
178 int search(const std::vector<double> &v,
179 unsigned int dim) const;
180 int search_with_hole(const std::vector<double> &v,
181 unsigned int dim) const;
182
183
184 class Vector
185 {
186 public:
187 Vector(Database *db, unsigned int ind)
188 {
189 init(db, ind);
190 }
191 Vector(const Vector &v)
192 {
193 _dim = v._dim;
194 _data = (double *) malloc(sizeof(double) * _dim);
195 memcpy(_data, v._data, sizeof(double) * _dim);
196 _own_data = true;
197 }
198
199 double *operator*(void)
200 {
201 return _data;
202 };
203
204 const double *operator*(void) const
205 {
206 return _data;
207 };
208
209 virtual ~Vector()
210 {
211 this->free();
212 }
213
214 inline void init(Database *db, unsigned int ind)
215 {
216 if (db != NULL)
217 {
218 _data = (*db)[ind];
219 _dim = db->dim();
220 }
221 else
222 {
223 _data = NULL;
224 _dim = 0;
225 }
226 _own_data = false;
227 }
228
229 inline void free()
230 {
231 if (_own_data) ::free(_data);
232 }
233
234 inline double operator()(unsigned int dim) const
235 {
236 return _data[dim];
237 }
238
239 inline void update(const Vector &v)
240 {
241 _data = v._data;
242 _dim = v._dim;
243 _own_data = false;
244 }
245
246 inline void update(Database *db, unsigned int ind)
247 {
248 this->free();
249 init(db, ind);
250 }
251
252 inline Vector &operator =(const Vector &v)
253 {
254 _dim = v._dim;
255 if (_data == NULL)
256 {
257 _data = (double *)malloc(sizeof(double)* _dim);
258 _own_data = true;
259 }
260 memcpy(_data, v._data, sizeof(double) * _dim);
261 return *this;
262 }
263 private:
264 bool _own_data;
265 double *_data;
266 unsigned int _dim;
267 };
268
270 {
271 public:
272 DatabaseCompare(unsigned int dim) : _dim(dim) {};
273
274 bool operator()(const Vector &v1, const Vector &v2) const
275 {
276 return v1(_dim) < v2(_dim);
277 }
278
279 private:
280 unsigned int _dim;
281 };
282
284 {
285 public:
286 typedef std::ptrdiff_t difference_type;
287 typedef std::bidirectional_iterator_tag iterator_category;
289 typedef Vector* pointer;
291
292
293
294 iterator() : _db(NULL), _ind(0), _vector(Vector(NULL, 0)) {}
295 iterator(Database *db, unsigned int ind=0) :
296 _db(db), _ind(ind), _vector(Vector(db, _ind)){}
297 iterator(const iterator &it) : _db(it._db), _ind(it._ind),
298 _vector(it._vector) {};
300
301 inline iterator &operator =(const iterator &it)
302 {
303 _ind = it._ind;
304 _db = it._db;
305 return *this;
306 }
307
308 bool operator!=(const iterator & it)
309 {
310 return _ind != it._ind;
311 };
312
313 bool operator==(const iterator & it)
314 {
315 return _ind == it._ind;
316 };
317
319 {
320 if (_ind < _db->size()) ++_ind;
321 return *this;
322 };
323
325 {
326 const iterator tmp = *this;
327 if (_ind < _db->size()) _ind++;
328 return tmp;
329 };
330
332 {
333 --_ind;
334 return *this;
335 };
336
338 {
339 const iterator tmp = *this;
340 _ind--;
341 return tmp;
342 };
343
344 int operator-(const iterator &it)
345 {
346 return _ind - it._ind;
347 };
348
349 int operator+(const iterator &it)
350 {
351 return _ind + it._ind;
352 };
353
354 iterator operator-(unsigned int ind)
355 {
356 return iterator(_db, _ind - ind);
357 };
358
359 iterator operator+(unsigned int ind)
360 {
361 return iterator(_db, _ind + ind);
362 };
363
364 iterator & operator +=( unsigned int ind )
365 {
366 for( unsigned i=0; i<ind; ++i )
367 this->operator ++();
368 return *this;
369 };
370
372 {
373 _vector.update(_db, _ind);
374 return _vector;
375 };
376
377 bool operator<(const iterator &it)
378 {
379 return _ind < it._ind;
380 };
381
382 bool operator<=(const iterator &it)
383 {
384 return _ind <= it._ind;
385 };
386
387 bool operator>(const iterator &it)
388 {
389 return _ind > it._ind;
390 };
391
392 bool operator>=(const iterator &it)
393 {
394 return _ind >= it._ind;
395 };
396
397 private:
398 Database *_db;
399 unsigned int _ind;
400 Vector _vector;
401 };
402
404 {
405 return iterator(this, 0);
406 }
407
409 {
410 return iterator(this, _size);
411 }
412
413 inline unsigned int size(void) const
414 {
415 return _size;
416 }
417
418 inline unsigned int dim(void) const
419 {
420 return _dim;
421 }
422
423 inline double operator()(unsigned int x, unsigned int y) const
424 {
425 return _data[x * _dim + y];
426 }
427
428 inline double *operator[](unsigned int ind)
429 {
430 return &_data[ind * _dim];
431 }
432
433 inline const double *operator[](unsigned int ind) const
434 {
435 return &_data[ind * _dim];
436 }
437
438 double variance_along_dim(unsigned int dim) const;
439
440 void sort(unsigned int dim);
441
442 inline const std::vector<bool> &holes() const
443 {
444 return _holes;
445 }
446
447 inline void setHole(unsigned int ind, bool status)
448 {
449 _holes[ind] = status;
450 }
451
452 inline void removeHoles(void)
453 {
454 _holes = std::vector<bool>(_size, false);
455 }
456
457protected:
458 double *_data;
459 unsigned int _size;
460 unsigned int _dim;
461 std::vector<bool> _holes;
462};
463
464
466{
467public:
468 MultiDatabase(double *data, unsigned int n, unsigned int dim) :
469 Database(data, n, dim) {};
470};
471
472class Heap
473{
474public:
476 {
477 public:
478 MiniHeap(double key, const void *value) :
479 _key(key), _value(value) {};
480 virtual ~MiniHeap() {};
481
482 MiniHeap(const MiniHeap &h) : _key(h._key), _value(h._value) {}
483
484 inline MiniHeap &operator =(const MiniHeap &h)
485 {
486 _key = h._key;
487 _value = h._value;
488 return *this;
489 }
490
491 inline double key() const
492 {
493 return _key;
494 }
495
496 inline const void *value() const
497 {
498 return _value;
499 }
500
501 inline bool operator < (const MiniHeap &h) const
502 {
503 return _key < h._key;
504 }
505
506 inline bool operator > (const MiniHeap &h) const
507 {
508 return _key > h._key;
509 }
510
511 private:
512 double _key;
513 const void *_value;
514 };
515
516 Heap(unsigned int n) : _n(0), _limit(n),
517 _list(std::vector<MiniHeap>(n + 1,
518 MiniHeap(HUGE_VAL, NULL))) {};
519 virtual ~Heap() {};
520
521 void exchange(unsigned int a, unsigned int b);
522 void erase_worst(void);
523 void insert(double key, const void *value);
524 std::pair<std::vector<unsigned int>, std::vector<double> >
525 toVectors(const Database &_db);
526
527 const MiniHeap &operator[](unsigned int ind) const
528 {
529 return _list[ind];
530 }
531
532 inline double get_worst_value()
533 {
534 return _list[0].key();
535 }
536
537private:
538 unsigned int _n;
539 unsigned int _limit;
540 std::vector<MiniHeap> _list;
541};
542
543class Knn
544{
545public:
546 Knn(Database &db, unsigned int k,
547 Distance *distance = new SquaredEuclidianDistance()) :
548 _db(db), _k(k), _distance(distance), _distance_n(-1) {};
549 virtual ~Knn() {};
550
551 virtual std::pair<std::vector<unsigned int>, std::vector<double> >
552 find(const std::vector<double> &v) = 0;
553
554protected:
558 unsigned int _k;
563};
564
565class KnnBruteForce : public Knn
566{
567public:
568 KnnBruteForce(Database &db, unsigned int k,
569 Distance *distance = new SquaredEuclidianDistance()) :
570 Knn(db, k, distance) {};
571 virtual ~KnnBruteForce() {};
572
573 virtual std::pair<std::vector<unsigned int>, std::vector<double> >
574 find(const std::vector<double> &v);
575};
576
577class KnnFriedman : public Knn
578{
579public:
580 KnnFriedman(Database &db, unsigned int k,
581 Distance *distance = new SquaredEuclidianDistance()) :
582 Knn(db, k, distance) {};
583 virtual ~KnnFriedman() {};
584
585 virtual void precompute(void) = 0;
586 virtual std::pair<std::vector<unsigned int>, std::vector<double> >
587 find(const std::vector<double> &v) = 0;
588};
589
591{
592public:
593 KnnGlobalFriedman(Database &db, unsigned int k,
594 Distance *distance = new SquaredEuclidianDistance()) :
595 KnnFriedman(db, k, distance) {};
596 virtual ~KnnGlobalFriedman() {};
597
598 virtual void precompute(void);
599 std::pair<std::vector<unsigned int>, std::vector<double> >
600 find(const std::vector<double> &v);
601
602private:
603 unsigned int _best_dim;
604};
605
606}; /* end of namespace knn */
607}; /* end of namespace aims */
608
609#endif
DatabaseCompare(unsigned int dim)
Definition knn.h:272
bool operator()(const Vector &v1, const Vector &v2) const
Definition knn.h:274
Vector(const Vector &v)
Definition knn.h:191
Vector & operator=(const Vector &v)
Definition knn.h:252
void update(const Vector &v)
Definition knn.h:239
Vector(Database *db, unsigned int ind)
Definition knn.h:187
const double * operator*(void) const
Definition knn.h:204
void update(Database *db, unsigned int ind)
Definition knn.h:246
double * operator*(void)
Definition knn.h:199
double operator()(unsigned int dim) const
Definition knn.h:234
void init(Database *db, unsigned int ind)
Definition knn.h:214
int operator-(const iterator &it)
Definition knn.h:344
Vector & operator*(void)
Definition knn.h:371
iterator operator-(unsigned int ind)
Definition knn.h:354
iterator operator++(void)
Definition knn.h:318
bool operator==(const iterator &it)
Definition knn.h:313
iterator operator--(void)
Definition knn.h:331
iterator operator--(int)
Definition knn.h:337
iterator(const iterator &it)
Definition knn.h:297
bool operator<(const iterator &it)
Definition knn.h:377
iterator operator++(int)
Definition knn.h:324
bool operator<=(const iterator &it)
Definition knn.h:382
bool operator!=(const iterator &it)
Definition knn.h:308
int operator+(const iterator &it)
Definition knn.h:349
iterator & operator+=(unsigned int ind)
Definition knn.h:364
std::bidirectional_iterator_tag iterator_category
Definition knn.h:287
iterator operator+(unsigned int ind)
Definition knn.h:359
bool operator>=(const iterator &it)
Definition knn.h:392
iterator & operator=(const iterator &it)
Definition knn.h:301
bool operator>(const iterator &it)
Definition knn.h:387
iterator(Database *db, unsigned int ind=0)
Definition knn.h:295
std::ptrdiff_t difference_type
Definition knn.h:286
double operator()(unsigned int x, unsigned int y) const
Definition knn.h:423
Database(double *data, unsigned int size, unsigned int dim)
double *& reference
Definition knn.h:170
iterator end(void)
Definition knn.h:408
double * _data
Definition knn.h:458
unsigned int _dim
Definition knn.h:460
std::vector< bool > _holes
Definition knn.h:461
int search(const std::vector< double > &v, unsigned int dim) const
virtual ~Database()
Definition knn.h:175
const std::vector< bool > & holes() const
Definition knn.h:442
unsigned int size(void) const
Definition knn.h:413
double * value_type
Definition knn.h:168
double variance_along_dim(unsigned int dim) const
unsigned int _size
Definition knn.h:459
void init(double *data, unsigned int size, unsigned int dim)
void setHole(unsigned int ind, bool status)
Definition knn.h:447
unsigned int dim(void) const
Definition knn.h:418
iterator begin(void)
Definition knn.h:403
const double * operator[](unsigned int ind) const
Definition knn.h:433
double ** pointer
Definition knn.h:169
void sort(unsigned int dim)
double * operator[](unsigned int ind)
Definition knn.h:428
void removeHoles(void)
Definition knn.h:452
int search_with_hole(const std::vector< double > &v, unsigned int dim) const
virtual double operator()(const std::vector< double > &v1, const std::vector< double > &v2) const
Definition knn.h:65
virtual double operator()(const double *v1, const double *v2, unsigned int dim) const =0
std::string _name
Definition knn.h:71
virtual ~Distance()
Definition knn.h:55
virtual const std::string & name(void) const
Definition knn.h:57
virtual double operator()(const double *v1, const double *v2, unsigned int dim) const
Definition knn.h:83
virtual ~EuclidianDistance()
Definition knn.h:81
bool operator>(const MiniHeap &h) const
Definition knn.h:506
virtual ~MiniHeap()
Definition knn.h:480
MiniHeap(double key, const void *value)
Definition knn.h:478
double key() const
Definition knn.h:491
const void * value() const
Definition knn.h:496
MiniHeap & operator=(const MiniHeap &h)
Definition knn.h:484
bool operator<(const MiniHeap &h) const
Definition knn.h:501
MiniHeap(const MiniHeap &h)
Definition knn.h:482
Heap(unsigned int n)
Definition knn.h:516
virtual ~Heap()
Definition knn.h:519
void erase_worst(void)
const MiniHeap & operator[](unsigned int ind) const
Definition knn.h:527
std::pair< std::vector< unsigned int >, std::vector< double > > toVectors(const Database &_db)
void exchange(unsigned int a, unsigned int b)
void insert(double key, const void *value)
double get_worst_value()
Definition knn.h:532
KnnBruteForce(Database &db, unsigned int k, Distance *distance=new SquaredEuclidianDistance())
Definition knn.h:568
virtual ~KnnBruteForce()
Definition knn.h:571
virtual std::pair< std::vector< unsigned int >, std::vector< double > > find(const std::vector< double > &v)
KnnFriedman(Database &db, unsigned int k, Distance *distance=new SquaredEuclidianDistance())
Definition knn.h:580
virtual ~KnnFriedman()
Definition knn.h:583
virtual std::pair< std::vector< unsigned int >, std::vector< double > > find(const std::vector< double > &v)=0
virtual void precompute(void)=0
virtual ~KnnGlobalFriedman()
Definition knn.h:596
KnnGlobalFriedman(Database &db, unsigned int k, Distance *distance=new SquaredEuclidianDistance())
Definition knn.h:593
std::pair< std::vector< unsigned int >, std::vector< double > > find(const std::vector< double > &v)
virtual void precompute(void)
virtual std::pair< std::vector< unsigned int >, std::vector< double > > find(const std::vector< double > &v)=0
Distance * _distance
distance used in nearest neighbours computations
Definition knn.h:560
Database & _db
database wrapper of data
Definition knn.h:556
unsigned int _k
k : number of nearest neighbours
Definition knn.h:558
int _distance_n
number of computed distance
Definition knn.h:562
Knn(Database &db, unsigned int k, Distance *distance=new SquaredEuclidianDistance())
Definition knn.h:546
virtual ~Knn()
Definition knn.h:549
virtual double operator()(const double *v1, const double *v2, unsigned int dim) const
Definition knn.h:129
virtual ~ManhattanDistance()
Definition knn.h:127
MultiDatabase(double *data, unsigned int n, unsigned int dim)
Definition knn.h:468
virtual double operator()(const double *v1, const double *v2, unsigned int dim) const
Definition knn.h:106
virtual ~TchebychevDistance()
Definition knn.h:148
virtual double operator()(const double *v1, const double *v2, unsigned int dim) const
Definition knn.h:150
T max(const Volume< T > &vol)
STL namespace.