Ice Sheet System Model  4.18
Code documentation
Data Structures | Public Member Functions | Data Fields | Private Types | Private Member Functions | Private Attributes
Covertree Class Reference

#include <Covertree.h>

Data Structures

class  CoverTreeNode
 

Public Member Functions

 Covertree (int maxDist, const std::vector< Observation > &points=std::vector< Observation >())
 
 ~Covertree ()
 
void insert (const Observation &newObservation)
 
bool isValidTree () const
 
void remove (const Observation &p)
 
std::vector< ObservationkNearestNeighbors (const Observation &p, const unsigned int &k) const
 
int get_numberofobs ()
 
CoverTreeNodegetRoot () const
 
void print () const
 

Data Fields

double base
 

Private Types

typedef std::pair< double, CoverTreeNode * > distNodePair
 

Private Member Functions

distNodePair distance (const Observation &p, const std::vector< CoverTreeNode * > &Q)
 
bool insert_rec (const Observation &p, const std::vector< distNodePair > &Qi, const int &level)
 
std::vector< CoverTreeNode * > kNearestNodes (const Observation &o, const unsigned int &k) const
 
void remove_rec (const Observation &p, std::map< int, std::vector< distNodePair > > &coverSets, int level, bool &multi)
 

Private Attributes

CoverTreeNode_root
 
unsigned int _numNodes
 
int _maxLevel
 
int _minLevel
 

Detailed Description

Definition at line 8 of file Covertree.h.

Member Typedef Documentation

◆ distNodePair

typedef std::pair<double, CoverTreeNode*> Covertree::distNodePair
private

Definition at line 45 of file Covertree.h.

Constructor & Destructor Documentation

◆ Covertree()

Covertree::Covertree ( int  maxDist,
const std::vector< Observation > &  points = std::vector<Observation>() 
)

Constructs a cover tree which begins with all points in points.

maxDist should be the maximum distance that any two points can have between each other. IE p.distance(q) < maxDist for all p,q that you will ever try to insert. The cover tree may be invalid if an inaccurate maxDist is given.

Definition at line 6 of file Covertree.cpp.

6  {/*{{{*/
7  this->base = 2.;
8  _root=NULL;
9  _numNodes=0;
10  _maxLevel=maxLevel;//ceilf(log(maxDist)/log(base));
12  std::vector<Observation>::const_iterator it;
13  for(it=points.begin(); it!=points.end(); ++it) {
14  this->insert(*it);//adds data to the covertree object
15  }
16 }/*}}}*/

◆ ~Covertree()

Covertree::~Covertree ( )

Definition at line 17 of file Covertree.cpp.

17  {/*{{{*/
18  if(_root==NULL) return;
19  //Get all of the root's children (from any level),
20  //delete the root, repeat for each of the children
21  std::vector<CoverTreeNode*> nodes;
22  nodes.push_back(_root);
23  while(!nodes.empty()) {
24  CoverTreeNode* byeNode = nodes[0];
25  nodes.erase(nodes.begin());
26  std::vector<CoverTreeNode*> children = byeNode->getAllChildren();
27  nodes.insert(nodes.begin(),children.begin(),children.end());
28  delete byeNode;
29  }
30 }/*}}}*/

Member Function Documentation

◆ distance()

std::pair< double, Covertree::CoverTreeNode * > Covertree::distance ( const Observation p,
const std::vector< CoverTreeNode * > &  Q 
)
private

Definition at line 33 of file Covertree.cpp.

33  {/*{{{*/
34  double minDist = 1.e+50;
35  CoverTreeNode* minNode;
36  std::vector<CoverTreeNode*>::const_iterator it;
37  for(it=Q.begin();it!=Q.end();++it) {
38  double dist = p.distance((*it)->getObservation());
39  if(dist < minDist) {
40  minDist = dist;
41  minNode = *it;
42  }
43  }
44  return std::make_pair(minDist,minNode);
45 }/*}}}*/

◆ insert_rec()

bool Covertree::insert_rec ( const Observation p,
const std::vector< distNodePair > &  Qi,
const int &  level 
)
private

Recursive implementation of the insert algorithm (see paper).

Definition at line 69 of file Covertree.cpp.

69  {/*{{{*/
70  std::vector<std::pair<double, CoverTreeNode*> > Qj;
71  double sep = pow(base,level);
72  double minDist = 1.e+50;
73  std::pair<double,CoverTreeNode*> minQiDist(1.e+50,NULL);
74  std::vector<std::pair<double, CoverTreeNode*> >::const_iterator it;
75  for(it=Qi.begin(); it!=Qi.end(); ++it) {
76  if(it->first<minQiDist.first) minQiDist = *it;
77  if(it->first<minDist) minDist=it->first;
78  if(it->first<=sep) Qj.push_back(*it);
79  std::vector<CoverTreeNode*> children = it->second->getChildren(level);
80  std::vector<CoverTreeNode*>::const_iterator it2;
81  for(it2=children.begin();it2!=children.end();++it2) {
82  double d = p.distance((*it2)->getObservation());
83  if(d<minDist) minDist = d;
84  if(d<=sep) {
85  Qj.push_back(std::make_pair(d,*it2));
86  }
87  }
88  }
89  //std::cout << "level: " << level << ", sep: " << sep << ", dist: " << minQDist.first << "\n";
90  if(minDist > sep) {
91  return true;
92  } else {
93  bool found = insert_rec(p,Qj,level-1);
94  //distNodePair minQiDist = distance(p,Qi);
95  if(found && minQiDist.first <= sep) {
96  if(level-1<_minLevel) _minLevel=level-1;
97  minQiDist.second->addChild(level,
98  new CoverTreeNode(p));
99  //std::cout << "parent is ";
100  //minQiDist.second->getObservation().print();
101  _numNodes++;
102  return false;
103  } else {
104  return found;
105  }
106  }
107 }/*}}}*/

◆ kNearestNodes()

std::vector< Covertree::CoverTreeNode * > Covertree::kNearestNodes ( const Observation o,
const unsigned int &  k 
) const
private

Definition at line 108 of file Covertree.cpp.

108  {/*{{{*/
109  if(_root==NULL) return std::vector<CoverTreeNode*>();
110  //maxDist is the kth nearest known point to p, and also the farthest
111  //point from p in the set minNodes defined below.
112  double maxDist = p.distance(_root->getObservation());
113  //minNodes stores the k nearest known points to p.
114  std::set<distNodePair> minNodes;
115 
116  minNodes.insert(std::make_pair(maxDist,_root));
117  std::vector<distNodePair> Qj(1,std::make_pair(maxDist,_root));
118  for(int level = _maxLevel; level>=_minLevel;level--) {
119  std::vector<distNodePair>::const_iterator it;
120  int size = Qj.size();
121  for(int i=0; i<size; i++) {
122  std::vector<CoverTreeNode*> children =
123  Qj[i].second->getChildren(level);
124  std::vector<CoverTreeNode*>::const_iterator it2;
125  for(it2=children.begin(); it2!=children.end(); ++it2) {
126  double d = p.distance((*it2)->getObservation());
127  if(d < maxDist || minNodes.size() < k) {
128  minNodes.insert(std::make_pair(d,*it2));
129  //--minNodes.end() gives us an iterator to the greatest
130  //element of minNodes.
131  if(minNodes.size() > k) minNodes.erase(--minNodes.end());
132  maxDist = (--minNodes.end())->first;
133  }
134  Qj.push_back(std::make_pair(d,*it2));
135  }
136  }
137  double sep = maxDist + pow(base, level);
138  size = Qj.size();
139  for(int i=0; i<size; i++) {
140  if(Qj[i].first > sep) {
141  //quickly removes an element from a vector w/o preserving order.
142  Qj[i]=Qj.back();
143  Qj.pop_back();
144  size--; i--;
145  }
146  }
147  }
148  std::vector<CoverTreeNode*> kNN;
149  std::set<distNodePair>::const_iterator it;
150  for(it=minNodes.begin();it!=minNodes.end();++it) {
151  kNN.push_back(it->second);
152  }
153  return kNN;
154 }/*}}}*/

◆ remove_rec()

void Covertree::remove_rec ( const Observation p,
std::map< int, std::vector< distNodePair > > &  coverSets,
int  level,
bool &  multi 
)
private

Definition at line 232 of file Covertree.cpp.

232  {/*{{{*/
233  std::vector<distNodePair>& Qi = coverSets[level];
234  std::vector<distNodePair>& Qj = coverSets[level-1];
235  double minDist = 1.e+50;
236  CoverTreeNode* minNode = _root;
237  CoverTreeNode* parent = 0;
238  double sep = pow(base, level);
239  std::vector<distNodePair>::const_iterator it;
240  //set Qj to be all children q of Qi such that p.distance(q)<=sep
241  //and also keep track of the minimum distance from p to a node in Qj
242  //note that every node has itself as a child, but the
243  //getChildren function only returns non-self-children.
244  for(it=Qi.begin();it!=Qi.end();++it) {
245  std::vector<CoverTreeNode*> children = it->second->getChildren(level);
246  double dist = it->first;
247  if(dist<minDist) {
248  minDist = dist;
249  minNode = it->second;
250  }
251  if(dist <= sep) {
252  Qj.push_back(*it);
253  }
254  std::vector<CoverTreeNode*>::const_iterator it2;
255  for(it2=children.begin();it2!=children.end();++it2) {
256  dist = p.distance((*it2)->getObservation());
257  if(dist<minDist) {
258  minDist = dist;
259  minNode = *it2;
260  if(dist == 0.0) parent = it->second;
261  }
262  if(dist <= sep) {
263  Qj.push_back(std::make_pair(dist,*it2));
264  }
265  }
266  }
267  if(level>_minLevel) remove_rec(p,coverSets,level-1,multi);
268  if(minNode->hasObservation(p)) {
269  //the multi flag indicates the point we removed is from a
270  //node containing multiple points, and we have removed it,
271  //so we don't need to do anything else.
272  if(multi) return;
273  if(!minNode->isSingle()) {
274  minNode->removeObservation(p);
275  multi=true;
276  return;
277  }
278  if(parent!=NULL) parent->removeChild(level, minNode);
279  std::vector<CoverTreeNode*> children = minNode->getChildren(level-1);
280  std::vector<distNodePair>& Q = coverSets[level-1];
281  if(Q.size()==1 && Q[0].second==minNode) {
282  Q.pop_back();
283  } else {
284  for(unsigned int i=0;i<Q.size();i++) {
285  if(Q[i].second==minNode) {
286  Q[i]=Q.back();
287  Q.pop_back();
288  break;
289  }
290  }
291  }
292  std::vector<CoverTreeNode*>::const_iterator it;
293  for(it=children.begin();it!=children.end();++it) {
294  int i = level-1;
295  Observation q = (*it)->getObservation();
296  double minDQ = 1.e+50;
297  CoverTreeNode* minDQNode = NULL;
298  double sep = pow(base,i);
299  bool br=false;
300  while(true) {
301  std::vector<distNodePair>&
302  Q = coverSets[i];
303  std::vector<distNodePair>::const_iterator it2;
304  minDQ = 1.e+50;
305  for(it2=Q.begin();it2!=Q.end();++it2) {
306  double d = q.distance(it2->second->getObservation());
307  if(d<minDQ) {
308  minDQ = d;
309  minDQNode = it2->second;
310  if(d <=sep) {
311  br=true;
312  break;
313  }
314  }
315  }
316  minDQ=1.e+50;
317  if(br) break;
318  Q.push_back(std::make_pair((*it)->distance(p),*it));
319  i++;
320  sep = pow(base,i);
321  }
322  //minDQNode->getObservation().print();
323  //std::cout << " is level " << i << " parent of ";
324  //(*it)->getObservation().print();
325  if (minDQNode != NULL)
326  minDQNode->addChild(i,*it);
327  }
328  if(parent!=NULL) {
329  delete minNode;
330  _numNodes--;
331  }
332  }
333 }/*}}}*/

◆ insert()

void Covertree::insert ( const Observation newObservation)

Insert newPoint into the cover tree. If newPoint is already present, (that is, newPoint==p for some p already in the tree), then the tree is unchanged. If p.distance(newPoint)==0.0 but newPoint!=p, then newPoint WILL be inserted and both points may be returned in k-nearest- neighbor searches.

Definition at line 49 of file Covertree.cpp.

49  {/*{{{*/
50  if(_root==NULL) {
51  _root = new CoverTreeNode(newObservation);
52  _numNodes=1;
53  return;
54  }
55  //TODO: this is pretty inefficient, there may be a better way
56  //to check if the node already exists...
57  CoverTreeNode* n = kNearestNodes(newObservation,1)[0];
58  if(newObservation.distance(n->getObservation())==0.0) {
59  n->addObservation(newObservation);
60  } else {
61  //insert_rec acts under the assumption that there are no nodes with
62  //distance 0 to newObservation in the cover tree (the previous lines check it)
63  insert_rec(newObservation,
64  std::vector<distNodePair>
65  (1,std::make_pair(_root->distance(newObservation),_root)),
66  _maxLevel);
67  }
68 }/*}}}*/

◆ isValidTree()

bool Covertree::isValidTree ( ) const

Just for testing/debugging. Returns true iff the cover tree satisfies the the covering tree invariants (every node in level i is greater than base^i distance from every other node, and every node in level i is less than or equal to base^i distance from its children). See the cover tree papers for details.

Definition at line 376 of file Covertree.cpp.

376  {/*{{{*/
377  if(_numNodes==0)
378  return _root==NULL;
379 
380  std::vector<CoverTreeNode*> nodes;
381  nodes.push_back(_root);
382  for(int i=_maxLevel;i>_minLevel;i--) {
383  double sep = pow(base,i);
384  std::vector<CoverTreeNode*>::const_iterator it, it2;
385  //verify separation invariant of cover tree: for each level,
386  //every point is farther than base^level away
387  for(it=nodes.begin(); it!=nodes.end(); ++it) {
388  for(it2=nodes.begin(); it2!=nodes.end(); ++it2) {
389  double dist=(*it)->distance((*it2)->getObservation());
390  if(dist<=sep && dist!=0.0) {
391  std::cout << "Level " << i << " Separation invariant failed.\n";
392  return false;
393  }
394  }
395  }
396  std::vector<CoverTreeNode*> allChildren;
397  for(it=nodes.begin(); it!=nodes.end(); ++it) {
398  std::vector<CoverTreeNode*> children = (*it)->getChildren(i);
399  //verify covering tree invariant: the children of node n at level
400  //i are no further than base^i away
401  for(it2=children.begin(); it2!=children.end(); ++it2) {
402  double dist = (*it2)->distance((*it)->getObservation());
403  if(dist>sep) {
404  std::cout << "Level" << i << " covering tree invariant failed.n";
405  return false;
406  }
407  }
408  allChildren.insert
409  (allChildren.end(),children.begin(),children.end());
410  }
411  nodes.insert(nodes.begin(),allChildren.begin(),allChildren.end());
412  }
413  return true;
414 }/*}}}*/

◆ remove()

void Covertree::remove ( const Observation p)

Remove point p from the cover tree. If p is not present in the tree, it will remain unchanged. Otherwise, this will remove exactly one point q from the tree satisfying p==q.

Definition at line 194 of file Covertree.cpp.

194  {/*{{{*/
195  //Most of this function's code is for the special case of removing the root
196  if(_root==NULL) return;
197  bool removingRoot=_root->hasObservation(p);
198  if(removingRoot && !_root->isSingle()) {
200  return;
201  }
202  CoverTreeNode* newRoot=NULL;
203  if(removingRoot) {
204  if(_numNodes==1) {
205  //removing the last node...
206  delete _root;
207  _numNodes--;
208  _root=NULL;
209  return;
210  } else {
211  for(int i=_maxLevel;i>_minLevel;i--) {
212  if(!(_root->getChildren(i).empty())) {
213  newRoot = _root->getChildren(i).back();
214  _root->removeChild(i,newRoot);
215  break;
216  }
217  }
218  }
219  }
220  std::map<int, std::vector<distNodePair> > coverSets;
221  coverSets[_maxLevel].push_back(std::make_pair(_root->distance(p),_root));
222  if(removingRoot)
223  coverSets[_maxLevel].push_back(std::make_pair(newRoot->distance(p),newRoot));
224  bool multi = false;
225  remove_rec(p,coverSets,_maxLevel,multi);
226  if(removingRoot) {
227  delete _root;
228  _numNodes--;
229  _root=newRoot;
230  }
231 }/*}}}*/

◆ kNearestNeighbors()

std::vector< Observation > Covertree::kNearestNeighbors ( const Observation p,
const unsigned int &  k 
) const

Returns the k nearest points to p in order (the 0th element of the vector is closest to p, 1th is next, etc). It may return greater than k points if there is a tie for the kth place.

Definition at line 155 of file Covertree.cpp.

155  {/*{{{*/
156  if(_root==NULL) return std::vector<Observation>();
157  std::vector<CoverTreeNode*> v = kNearestNodes(p, k);
158  std::vector<Observation> kNN;
159  std::vector<CoverTreeNode*>::const_iterator it;
160  for(it=v.begin();it!=v.end();++it) {
161  const std::vector<Observation>& p = (*it)->getObservations();
162  kNN.insert(kNN.end(),p.begin(),p.end());
163  if(kNN.size() >= k) break;
164  }
165  return kNN;
166 }/*}}}*/

◆ get_numberofobs()

int Covertree::get_numberofobs ( )

Definition at line 46 of file Covertree.cpp.

46  {/*{{{*/
47  return _numNodes;
48 }/*}}}*/

◆ getRoot()

Covertree::CoverTreeNode * Covertree::getRoot ( ) const

Definition at line 367 of file Covertree.cpp.

367  {/*{{{*/
368  return _root;
369 }/*}}}*/

◆ print()

void Covertree::print ( ) const

Print the cover tree.

Definition at line 167 of file Covertree.cpp.

167  {/*{{{*/
168  int d = _maxLevel-_minLevel+1;
169  std::vector<CoverTreeNode*> Q;
170  Q.push_back(_root);
171  for(int i=0;i<d;i++) {
172  std::cout << "LEVEL " << _maxLevel-i << "\n";
173  std::vector<CoverTreeNode*>::const_iterator it;
174  for(it=Q.begin();it!=Q.end();++it) {
175  (*it)->getObservation().print();
176  std::vector<CoverTreeNode*>
177  children = (*it)->getChildren(_maxLevel-i);
178  std::vector<CoverTreeNode*>::const_iterator it2;
179  for(it2=children.begin();it2!=children.end();++it2) {
180  std::cout << " ";
181  (*it2)->getObservation().print();
182  }
183  }
184  std::vector<CoverTreeNode*> newQ;
185  for(it=Q.begin();it!=Q.end();++it) {
186  std::vector<CoverTreeNode*>
187  children = (*it)->getChildren(_maxLevel-i);
188  newQ.insert(newQ.end(),children.begin(),children.end());
189  }
190  Q.insert(Q.end(),newQ.begin(),newQ.end());
191  std::cout << "\n\n";
192  }
193 }/*}}}*/

Field Documentation

◆ _root

CoverTreeNode* Covertree::_root
private

Definition at line 47 of file Covertree.h.

◆ _numNodes

unsigned int Covertree::_numNodes
private

Definition at line 48 of file Covertree.h.

◆ _maxLevel

int Covertree::_maxLevel
private

Definition at line 49 of file Covertree.h.

◆ _minLevel

int Covertree::_minLevel
private

Definition at line 51 of file Covertree.h.

◆ base

double Covertree::base

Definition at line 65 of file Covertree.h.


The documentation for this class was generated from the following files:
Observation::distance
double distance(const Observation &ob) const
Definition: Observation.cpp:78
Covertree::insert
void insert(const Observation &newObservation)
Definition: Covertree.cpp:49
Observation
Definition: Observation.h:10
Covertree::CoverTreeNode::distance
double distance(const CoverTreeNode &p) const
Definition: Covertree.cpp:345
Covertree::CoverTreeNode::getObservation
const Observation & getObservation() const
Definition: Covertree.cpp:364
Covertree::kNearestNodes
std::vector< CoverTreeNode * > kNearestNodes(const Observation &o, const unsigned int &k) const
Definition: Covertree.cpp:108
Covertree::_root
CoverTreeNode * _root
Definition: Covertree.h:47
Covertree::base
double base
Definition: Covertree.h:65
Covertree::CoverTreeNode::isSingle
bool isSingle() const
Definition: Covertree.cpp:373
Covertree::_maxLevel
int _maxLevel
Definition: Covertree.h:49
Covertree::CoverTreeNode::removeChild
void removeChild(int level, CoverTreeNode *p)
Definition: Covertree.cpp:415
Covertree::remove_rec
void remove_rec(const Observation &p, std::map< int, std::vector< distNodePair > > &coverSets, int level, bool &multi)
Definition: Covertree.cpp:232
Covertree::_minLevel
int _minLevel
Definition: Covertree.h:51
Covertree::_numNodes
unsigned int _numNodes
Definition: Covertree.h:48
Covertree::CoverTreeNode::hasObservation
bool hasObservation(const Observation &o) const
Definition: Covertree.cpp:370
Covertree::CoverTreeNode::getChildren
std::vector< CoverTreeNode * > getChildren(int level) const
Definition: Covertree.cpp:356
Covertree::CoverTreeNode::removeObservation
void removeObservation(const Observation &o)
Definition: Covertree.cpp:425
Covertree::insert_rec
bool insert_rec(const Observation &p, const std::vector< distNodePair > &Qi, const int &level)
Definition: Covertree.cpp:69