00001
00002 #include <ReClaM/CoverTree.h>
00003
00004
00005 #define POINTSCALE -1022
00006
00007
00008 union IntWiseDouble
00009 {
00010 double d;
00011 int i[2];
00012 };
00013
00014
00015 double i_pow2(int exponent)
00016 {
00017 IntWiseDouble ret;
00018 ret.d = 2.0;
00019 ret.i[1] += (exponent << 20);
00020 return ret.d;
00021
00022 }
00023
00024 int i_log2(double dist2)
00025 {
00026 IntWiseDouble value;
00027 value.d = dist2;
00028 return (((value.i[1] & 0x7ff00000) >> 20) - 1023) >> 1;
00029
00030 }
00031
00032
00034
00035
00036 CoverTree::CoverTree(const Array<double>& points)
00037 {
00038 this->points = &points;
00039
00040 unsigned int i, ic = points.dim(0);
00041 mem.resize(2*ic);
00042 usedmem = 0;
00043
00044
00045 root = freeNode();
00046 root->index = 0;
00047 root->firstchild = NULL;
00048 root->nextsibling = NULL;
00049 root->scale = POINTSCALE;
00050
00051
00052 for (i=1; i<ic; i++) Insert(i);
00053 }
00054
00055 CoverTree::~CoverTree()
00056 {
00057 }
00058
00059
00060 unsigned int CoverTree::OneNN(const Array<double>& query) const
00061 {
00062 tNode n;
00063 std::vector<tNode> list1;
00064 std::vector<tNode> list2;
00065 std::vector<tNode>* cand = &list1;
00066 std::vector<tNode>* refine = &list2;
00067 double best_d = distance((*points)[root->index], query);
00068 n.node = root;
00069 n.dist = best_d;
00070 cand->push_back(n);
00071 int s = root->scale;
00072
00073
00074 while (true)
00075 {
00076
00077 int i, ic = cand->size();
00078
00079
00080 bool children = false;
00081 for (i=0; i<ic; i++)
00082 {
00083 tNode& nr = (*cand)[i];
00084 if (nr.node->scale >= s - 1)
00085 {
00086
00087 Node* child = nr.node->firstchild;
00088 while (child != NULL)
00089 {
00090 double d = distance((*points)[child->index], query);
00091 if (d <= best_d + i_pow2(child->scale))
00092 {
00093 n.node = child;
00094 n.dist = d;
00095 refine->push_back(n);
00096 children = children || (child->firstchild != NULL);
00097
00098 if (d < best_d) best_d = d;
00099 }
00100 child = child->nextsibling;
00101 }
00102 }
00103 else
00104 {
00105 if (nr.dist <= best_d + i_pow2(nr.node->scale))
00106 {
00107 refine->push_back(nr);
00108 children = children || (nr.node->firstchild != NULL);
00109 }
00110 }
00111 }
00112
00113
00114 if (! children) break;
00115
00116 cand->clear();
00117 std::swap(refine, cand);
00118 s--;
00119 }
00120
00121 return (*refine)[0].node->index;
00122 }
00123
00124 unsigned int CoverTree::SecondNN(unsigned int query) const
00125 {
00126 const ArrayReference<double> pt = (*points)[query];
00127 tNode n;
00128 std::vector<tNode> list1;
00129 std::vector<tNode> list2;
00130 std::vector<tNode>* cand = &list1;
00131 std::vector<tNode>* refine = &list2;
00132 double best_d = 1e100;
00133 n.node = root;
00134 n.dist = best_d;
00135 cand->push_back(n);
00136 int s = root->scale;
00137
00138
00139 while (true)
00140 {
00141
00142 int i, ic = cand->size();
00143
00144
00145 bool children = false;
00146 for (i=0; i<ic; i++)
00147 {
00148 tNode& nr = (*cand)[i];
00149 if (nr.node->scale >= s - 1)
00150 {
00151
00152 Node* child = nr.node->firstchild;
00153 while (child != NULL)
00154 {
00155 double d = distance((*points)[child->index], pt);
00156 if (d <= best_d + i_pow2(child->scale))
00157 {
00158 n.node = child;
00159 n.dist = d;
00160 refine->push_back(n);
00161 children = children || (child->firstchild != NULL);
00162
00163 if (d < best_d && child->index != query)
00164 {
00165 best_d = d;
00166 }
00167 }
00168 child = child->nextsibling;
00169 }
00170 }
00171 else
00172 {
00173 if (nr.dist <= best_d + i_pow2(nr.node->scale))
00174 {
00175 refine->push_back(nr);
00176 children = children || (nr.node->firstchild != NULL);
00177 }
00178 }
00179 }
00180
00181
00182 if (! children) break;
00183
00184 cand->clear();
00185 std::swap(refine, cand);
00186 s--;
00187 }
00188
00189 if (refine->size() < 2)
00190 {
00191 throw SHARKEXCEPTION("[CoverTree::SecondNN] internal error");
00192 }
00193 else if (refine->size() == 2)
00194 {
00195 if ((*refine)[0].node->index == query) return (*refine)[1].node->index;
00196 else return (*refine)[0].node->index;
00197 }
00198 else
00199 {
00200 double best_d2 = 1e100;
00201 unsigned int ret = 0;
00202 int i, ic = refine->size();
00203 for (i=0; i<ic; i++)
00204 {
00205 unsigned int index = (*refine)[i].node->index;
00206 if (index == query) continue;
00207 double d2 = distance2((*points)[index], pt);
00208 if (d2 < best_d2)
00209 {
00210 best_d2 = d2;
00211 ret = index;
00212 }
00213 }
00214 return ret;
00215 }
00216 }
00217
00218 bool cmp(const CoverTree::tNode& n1, const CoverTree::tNode& n2)
00219 {
00220 return (n1.dist < n2.dist);
00221 }
00222
00223 void CoverTree::KNN(const Array<double>& query, unsigned int k, std::vector<unsigned int>& neighbors) const
00224 {
00225 tNode n;
00226 std::vector<tNode> list1;
00227 std::vector<tNode> list2;
00228 std::vector<tNode>* cand = &list1;
00229 std::vector<tNode>* refine = &list2;
00230 double kth_best_d = 1e100;
00231 n.node = root;
00232 n.dist = kth_best_d;
00233 cand->push_back(n);
00234 int s = root->scale;
00235
00236
00237 while (true)
00238 {
00239
00240 int i, ic = cand->size();
00241
00242
00243 bool children = false;
00244 for (i=0; i<ic; i++)
00245 {
00246 tNode& nr = (*cand)[i];
00247 if (nr.node->scale >= s - 1)
00248 {
00249
00250 Node* child = nr.node->firstchild;
00251 while (child != NULL)
00252 {
00253 double d = distance((*points)[child->index], query);
00254 if (d <= kth_best_d + i_pow2(child->scale))
00255 {
00256 n.node = child;
00257 n.dist = d;
00258 refine->push_back(n);
00259 children = children || (child->firstchild != NULL);
00260 }
00261 child = child->nextsibling;
00262 }
00263 }
00264 else
00265 {
00266 if (nr.dist <= kth_best_d + i_pow2(nr.node->scale))
00267 {
00268 refine->push_back(nr);
00269 children = children || (nr.node->firstchild != NULL);
00270 }
00271 }
00272 }
00273
00274
00275 std::sort(refine->begin(), refine->end(), cmp);
00276 if (refine->size() >= k) kth_best_d = (*refine)[k - 1].dist;
00277 else kth_best_d = 1e100;
00278
00279
00280 if (! children) break;
00281
00282 cand->clear();
00283 std::swap(refine, cand);
00284 s--;
00285 }
00286
00287 neighbors.resize(k);
00288 unsigned int i;
00289 for (i=0; i<k; i++) neighbors[i] = (*refine)[i].node->index;
00290 }
00291
00292 double CoverTree::distance2(const Array<double>& p1, const Array<double>& p2) const
00293 {
00294 unsigned int d, dim = p1.dim(0);
00295 double dist2 = 0.0;
00296 for (d=0; d<dim; d++) dist2 += Shark::sqr(p2(d) - p1(d));
00297 return dist2;
00298 }
00299
00300 void CoverTree::Insert(unsigned int index)
00301 {
00302 const Array<double> point = (*points)[index];
00303 Node* parent = root;
00304 double pd2 = distance2((*points)[parent->index], point);
00305 int ps = i_log2(pd2);
00306
00307
00308 if (ps > parent->scale)
00309 {
00310
00311 parent = freeNode();
00312 parent->index = root->index;
00313 parent->scale = ps;
00314 parent->firstchild = root;
00315 parent->nextsibling = NULL;
00316
00317 Node* node = freeNode();
00318 node->index = index;
00319 node->firstchild = NULL;
00320 node->nextsibling = NULL;
00321 node->scale = POINTSCALE;
00322
00323 root->nextsibling = node;
00324 root = parent;
00325
00326 return;
00327 }
00328
00329
00330 while (true)
00331 {
00332
00333 Node* closest = parent->firstchild;
00334 if (closest == NULL)
00335 {
00336 throw SHARKEXCEPTION("[CoverTree::Insert] internal error");
00337 }
00338
00339 double cd2 = distance2((*points)[closest->index], point);
00340 Node* child = closest->nextsibling;
00341 while (child != NULL)
00342 {
00343 double d2 = distance2((*points)[child->index], point);
00344 if (d2 < cd2)
00345 {
00346 closest = child;
00347 cd2 = d2;
00348 }
00349 child = child->nextsibling;
00350 }
00351 int cs = i_log2(cd2);
00352
00353
00354 if (cs == parent->scale)
00355 {
00356
00357 Node* node = freeNode();
00358 node->index = index;
00359 node->scale = POINTSCALE;
00360 node->firstchild = NULL;
00361 node->nextsibling = parent->firstchild;
00362 parent->firstchild = node;
00363
00364 return;
00365 }
00366
00367 if (cs > closest->scale)
00368 {
00369 if (closest->scale == POINTSCALE)
00370 {
00371
00372 Node* copy = freeNode();
00373 Node* node = freeNode();
00374
00375 copy->index = closest->index;
00376 copy->scale = POINTSCALE;
00377 copy->firstchild = NULL;
00378 copy->nextsibling = node;
00379
00380 node->index = index;
00381 node->scale = POINTSCALE;
00382 node->firstchild = NULL;
00383 node->nextsibling = NULL;
00384
00385 closest->firstchild = copy;
00386 closest->scale = cs;
00387
00388 return;
00389 }
00390 else
00391 {
00392
00393 Node* copy = freeNode();
00394 Node* node = freeNode();
00395
00396 copy->index = closest->index;
00397 copy->scale = closest->scale;
00398 copy->firstchild = closest->firstchild;
00399 copy->nextsibling = node;
00400
00401 closest->scale = cs;
00402 closest->firstchild = copy;
00403
00404 node->index = index;
00405 node->scale = POINTSCALE;
00406 node->firstchild = NULL;
00407 node->nextsibling = NULL;
00408
00409 return;
00410 }
00411 }
00412
00413
00414 parent = closest;
00415 pd2 = cd2;
00416 ps = cs;
00417 }
00418 }
00419
00420
00422
00423
00424 KernelCoverTree::KernelCoverTree(KernelFunction* kernel, const Array<double>& points)
00425 : CoverTree(points)
00426 {
00427 this->kernel = kernel;
00428 }
00429
00430 KernelCoverTree::~KernelCoverTree()
00431 {
00432 }
00433
00434
00435 double KernelCoverTree::distance2(const Array<double>& p1, const Array<double>& p2) const
00436 {
00437 return (*kernel)(p1, p1) + (*kernel)(p2, p2) - 2.0 * (*kernel)(p1, p2);
00438 }