00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "stdafx.h"
00021
00022 #include "gul_types.h"
00023 #include "guma_rkdtree.h"
00024 #include "guma_random.h"
00025 #include "guma_sorting.h"
00026
00027 #include <iostream>
00028
00029 namespace guma {
00030
00031 using gul::uint32;
00032 using gul::uint64;
00033 using gul::rtr;
00034 using gul::Ptr;
00035 using gul::List;
00036 using gul::ListNode;
00037 using gul::Map;
00038 using gul::Swap;
00039 using std::cout;
00040
00041
00042
00043
00044
00045 template< class U, class V >
00046 void kdtnode<U,V>::height( int cur_height, int *max_height,
00047 int *avg_count, double *avg_sum )
00048 {
00049 (*avg_count)++;
00050 (*avg_sum) += (double)cur_height;
00051
00052 if( m_parent == 0 )
00053 cout << "warning: parent == 0 in node " << (void *)this
00054 << "\n";
00055
00056 if( !m_left && !m_right )
00057 {
00058 if( cur_height > *max_height )
00059 *max_height = cur_height;
00060 }
00061 else
00062 {
00063 if( m_left )
00064 m_left->height( cur_height+1, max_height, avg_count, avg_sum );
00065 if( m_right )
00066 m_right->height( cur_height+1, max_height, avg_count, avg_sum );
00067 }
00068 }
00069
00070 template< class U, class V >
00071 void kdtnode<U,V>::dump(int dim,int space)
00072 {
00073 int i;
00074 ListNode< kdrec<U,V> > *r;
00075
00076 for( i = 0; i < space; i++ ) cout << " ";
00077 cout << "discriminant = " << m_disc << ", number of elements = "
00078 << m_nelems << "\n";
00079
00080 for( i = 0; i < space; i++ ) cout << " ";
00081 cout << "records: {";
00082 for( r = m_recs.First(); r; r = r->next )
00083 {
00084 cout << "(" << r->el[0];
00085 for( i = 1; i < dim; i++ )
00086 cout << ", " << r->el[i];
00087 cout << ") ";
00088 }
00089 cout << "}\n";
00090
00091 for( i = 0; i < space; i++ ) cout << " ";
00092 cout << "left subtree: " << (void *)m_left << "\n";
00093 if( m_left )
00094 {
00095 m_left->dump(dim,space+4);
00096 }
00097 for( i = 0; i < space; i++ ) cout << " ";
00098 cout << "right subtree: " << (void *)m_right << "\n";
00099 if( m_right )
00100 {
00101 m_right->dump(dim,space+4);
00102 }
00103 }
00104
00105 template< class U, class V >
00106 GULAPI void kdnnrec<U,V>::dump( int dim )
00107 {
00108 ListNode< kdrec<U,V> > *r;
00109 int i;
00110
00111 cout << "dist = " << m_dist << ", { ";
00112 for( r = m_recs.First(); r; r = r->next )
00113 {
00114 cout << (void *)r->el.m_base << ":(" << r->el[0];
00115 for( i = 1; i < dim; i++ )
00116 cout << ", " << r->el[i];
00117 cout << ") ";
00118 }
00119 cout << "}\n";
00120 }
00121
00122 template< class U, class V >
00123 void rkdtree_base<U,V>::split_recs(
00124 List< ListNode< kdrec<U,V> > >& recs, const V& key, int i,
00125 List< ListNode< kdrec<U,V> > >& recs1, List< ListNode< kdrec<U,V> > >& recs2,
00126 List< ListNode< kdrec<U,V> > >& C )
00127 {
00128 ListNode< kdrec<U,V> > *r;
00129 int sign;
00130
00131 r = recs.First();
00132 while( r )
00133 {
00134 recs.Remove(r);
00135
00136 sign = rtr<V>::cmp( r->el[i], key );
00137 if( sign < 0 )
00138 {
00139 recs1.Append(r);
00140 }
00141 else if( sign > 0 )
00142 {
00143 recs2.Append(r);
00144 }
00145 else
00146 C.Append(r);
00147
00148 r = recs.First();
00149 }
00150 }
00151 template< class U, class V >
00152 int kdtsearch<U,V>::compare_key_to_node( V *k, kdnnrec<U,V> *r )
00153 {
00154 return rtr<V>::cmp( *k, r->m_dist );
00155 }
00156
00157 template< class U, class V >
00158 V kdtsearch<U,V>::length( const Ptr<V>& P )
00159 {
00160 V dist;
00161 int i;
00162
00163 dist = (V)0;
00164 for( i = 0; i < m_dim; i++ )
00165 dist += P[i] * P[i];
00166 dist = rtr<V>::sqrt(dist);
00167 return dist;
00168 }
00169
00170 template< class U, class V >
00171 void kdtsearch<U,V>::scan_records(
00172 const U& P, const List< ListNode< kdrec<U,V> > >& recs )
00173 {
00174 ListNode< kdrec<U,V> > *rec;
00175 V dist,d;
00176 int i,side;
00177 Map< kdnnrec<U,V> >::Node mnode,mnode1;
00178
00179 for( rec = recs.First(); rec; rec = rec->next )
00180 {
00181 dist = (V)0;
00182 for( i = 0; i < m_dim; i++ )
00183 {
00184 d = P[i] - rec->el[i];
00185 dist += d * d;
00186 }
00187 dist = rtr<V>::sqrt(dist);
00188
00189 if( m_nNeighbors == 0 )
00190 {
00191 m_maxDist = dist;
00192
00193
00194
00195
00196
00197
00198
00199
00200 mnode = m_neighbors.NewNode();
00201 mnode.key()->m_dist = dist;
00202 mnode.key()->m_recs.Append( new gul::ListNode< kdrec<U,V> >(rec->el) );
00203
00204 m_neighbors.InsertNode( mnode, m_neighbors.root, 1 );
00205
00206 m_nNeighbors++;
00207
00208 continue;
00209 }
00210
00211 if( (m_nNeighbors == m_maxNeighbors) && (dist > m_maxDist) )
00212 continue;
00213
00214 side = m_neighbors.SearchNode( &dist, compare_key_to_node, &mnode);
00215 if( side == 0 )
00216 {
00217 mnode.key()->m_recs.Append( new ListNode< kdrec<U,V> >(rec->el) );
00218 }
00219 else
00220 {
00221 if( dist > m_maxDist )
00222 m_maxDist = dist;
00223
00224 mnode1 = m_neighbors.NewNode();
00225 mnode1.key()->m_dist = dist;
00226 mnode1.key()->m_recs.Append( new gul::ListNode< kdrec<U,V> >(rec->el) );
00227
00228 m_neighbors.InsertNode( mnode1, mnode, side );
00229 m_nNeighbors++;
00230 }
00231
00232 if( m_nNeighbors > m_maxNeighbors )
00233 {
00234 mnode = m_neighbors.Last();
00235
00236 mnode1 = m_neighbors.Predecessor(mnode);
00237 m_maxDist = mnode1.key()->m_dist;
00238
00239 m_neighbors.RemoveNode(mnode);
00240 m_neighbors.FreeNode(mnode);
00241
00242 m_nNeighbors--;
00243 }
00244 }
00245 };
00246
00247 template< class U, class V >
00248 void kdtsearch<U,V>::process_node(
00249 const U& P, const kdtnode<U,V> *n, const Ptr<V>& D, V d,
00250 List< ListNode< kdtsnode<U,V> > >& stack )
00251 {
00252 int i,j;
00253 V dist,d1,d2;
00254 Ptr<V> D1,D2;
00255 const kdtnode<U,V> *T1, *T2;
00256 ListNode< kdtsnode<U,V> > *sn;
00257
00258 scan_records( P, n->m_recs );
00259
00260 i = n->m_disc;
00261 dist = P[i] - n->key();
00262
00263 if( dist < (V)0 )
00264 {
00265 T1 = n->m_left;
00266 if( T1 )
00267 {
00268 if( (D[i] > (V)0) || (D[i] < dist) )
00269 {
00270 D1.reserve_pool(m_dim);
00271 for( j = 0; j < m_dim; j++ )
00272 D1[j] = D[j];
00273 D1[i] = (V)0;
00274 d1 = length( D1 );
00275 }
00276 else
00277 {
00278 D1 = D;
00279 d1 = d;
00280 }
00281 }
00282 T2 = n->m_right;
00283 }
00284 else if( dist > 0 )
00285 {
00286 T1 = n->m_right;
00287 if( T1 )
00288 {
00289 if( (D[i] < (V)0) || (D[i] > dist) )
00290 {
00291 D1.reserve_pool(m_dim);
00292 for( j = 0; j < m_dim; j++ )
00293 D1[j] = D[j];
00294 D1[i] = (V)0;
00295 d1 = length( D1 );
00296 }
00297 else
00298 {
00299 D1 = D;
00300 d1 = d;
00301 }
00302 }
00303 T2 = n->m_left;
00304 }
00305 else
00306 {
00307 T1 = n->m_left;
00308 if( T1 )
00309 {
00310 if( D[i] )
00311 {
00312 D1.reserve_pool(m_dim);
00313 for( j = 0; j < m_dim; j++ )
00314 D1[j] = D[j];
00315 D1[i] = (V)0;
00316 d1 = length( D1 );
00317 }
00318 else
00319 {
00320 D1 = D;
00321 d1 = d;
00322 }
00323 }
00324 T2 = n->m_right;
00325 }
00326
00327 if( T2 )
00328 {
00329 if( dist != D[i] )
00330 {
00331 D2.reserve_pool(m_dim);
00332 for( j = 0; j < m_dim; j++ )
00333 D2[j] = D[j];
00334 D2[i] = dist;
00335 d2 = length( D2 );
00336 }
00337 else
00338 {
00339 D2 = D;
00340 d2 = d;
00341 }
00342 }
00343
00344 if( T1 && ((d1 <= m_maxDist) || (m_nNeighbors < m_maxNeighbors)) )
00345 {
00346 sn = new ListNode< kdtsnode<U,V> >( kdtsnode<U,V>(T1,D1,d1) );
00347 stack.Append(sn);
00348 }
00349 if( T2 && ((d2 <= m_maxDist) || (m_nNeighbors < m_maxNeighbors)) )
00350 {
00351 sn = new ListNode< kdtsnode<U,V> >( kdtsnode<U,V>(T2,D2,d2) );
00352 stack.Append(sn);
00353 }
00354 }
00355
00356 template< class U, class V >
00357 GULAPI int rkdtree_base<U,V>::nearest_neighbors(
00358 const U& P, int m, Ptr< kdnnrec<U,V> >& M )
00359 {
00360 Ptr<V> D;
00361 V d;
00362 ListNode< kdtsnode<U,V> > *sn;
00363 List< ListNode< kdtsnode<U,V> > > S1,S2;
00364 List< ListNode< kdtsnode<U,V> > >* stack1 = &S1, *stack2 = &S2;
00365 const kdtnode<U,V> *curnod;
00366 int i, nEl;
00367 Ptr<kdnnrec<U,V> *> pm;
00368
00369 if( (m <= 0) || (!m_root) ) return 0;
00370
00371 kdtsearch<U,V> nns(m_dim,m);
00372
00373 D.reserve_pool(m_dim);
00374 for( i = 0; i < m_dim; i++ )
00375 D[i] = (V)0;
00376 d = 0;
00377
00378 sn = new ListNode< kdtsnode<U,V> >( kdtsnode<U,V>(m_root,D,d) );
00379 stack1->Append(sn);
00380
00381 while( !stack1->IsEmpty() )
00382 {
00383 sn = stack1->First();
00384 while( sn )
00385 {
00386 curnod = sn->el.m_n;
00387 D = sn->el.m_D;
00388 d = sn->el.m_d;
00389 stack1->Remove( sn );
00390 delete sn;
00391
00392 nns.process_node( P, curnod, D, d, *stack2 );
00393
00394 sn = stack1->First();
00395 }
00396
00397 Swap( stack1, stack2 );
00398 }
00399
00400 nEl = nns.m_neighbors.ConvertToArray(&pm);
00401 for( i = 0; i < nEl; i++ )
00402 M[i] = *(pm[i]);
00403
00404 return nEl;
00405 }
00406
00407 template< class U, class V >
00408 GULAPI void rkdtree_base<U,V>::dump_statistics()
00409 {
00410 int max_height = 0;
00411 double avg_pathlen = 0;
00412 int avg_count = 0;
00413
00414 if( m_root )
00415 {
00416 cout << "nelems (without collision records) = " << m_root->m_nelems << "\n";
00417 m_root->height( 1, &max_height, &avg_count, &avg_pathlen );
00418 cout << "max height = " << max_height << "\n";
00419 cout << "average pathlen = " << avg_pathlen/((double)avg_count) << "\n";
00420 }
00421 else
00422 {
00423 cout << "empty tree\n";
00424 }
00425 }
00426
00427 template< class U, class V >
00428 GULAPI void rkdtree_base<U,V>::dump_tree()
00429 {
00430 if( m_root )
00431 {
00432 m_root->dump(m_dim,0);
00433 }
00434 else
00435 {
00436 cout << "empty tree\n";
00437 }
00438 }
00439
00440
00441
00442 template< class U, class V, class Rand >
00443 GULAPI kdtnode<U,V> *rkdtree<U,V,Rand>::insert(
00444 kdtnode<U,V> *T, const kdrec<U,V>& rec )
00445 {
00446 int n,sign,k;
00447 double p;
00448 kdtnode<U,V> *L, *R, *root, *S, *Sold;
00449
00450 if( !T )
00451 {
00452 k = (int)(Rand::Random()*(double)m_dim);
00453 return new kdtnode<U,V>(rec, k);
00454 }
00455
00456 n = T->m_nelems;
00457 p = Rand::Random();
00458
00459 if( p*((double)(n+1)) < (double)n )
00460 {
00461 sign = rtr<V>::cmp( rec[T->m_disc], T->key() );
00462
00463 if( sign < 0 )
00464 {
00465 if( !T->m_left )
00466 {
00467 k = (int)(Rand::Random()*(double)m_dim);
00468 T->set_left( new kdtnode<U,V>(rec, k) );
00469 }
00470 else
00471 {
00472 Sold = T->m_left;
00473 S = insert( T->m_left, rec );
00474 if( S != Sold )
00475 T->set_left(S);
00476 }
00477 }
00478 else if( sign > 0 )
00479 {
00480 if( !T->m_right )
00481 {
00482 k = (int)(Rand::Random()*(double)m_dim);
00483 T->set_right( new kdtnode<U,V>(rec, k) );
00484 }
00485 else
00486 {
00487 Sold = T->m_right;
00488 S = insert( T->m_right, rec );
00489 if( S != Sold )
00490 T->set_right(S);
00491 }
00492 }
00493 else
00494 {
00495 T->add_rec( rec );
00496 }
00497
00498 root = T;
00499 }
00500 else
00501 {
00502 k = (int)(Rand::Random()*(double)m_dim);
00503 root = new kdtnode<U,V>(rec, k);
00504
00505 split( T, rec, k, &L, &R, root->m_recs );
00506 root->set_childs(L, R);
00507 }
00508
00509 return root;
00510 }
00511
00512 template< class U, class V, class Rand >
00513 GULAPI kdtnode<U,V> *rkdtree<U,V,Rand>::remove(
00514 kdtnode<U,V> *T,
00515 const kdrec<U,V>& rec,
00516 gul::List< gul::ListNode< kdrec<U,V> > >& outrecs )
00517 {
00518 int sign,i;
00519 kdtnode<U,V> *L,*Lold,*R,*Rold,*Told;
00520 gul::ListNode< kdrec<U,V> > *r,*r_next;
00521 gul::List< gul::ListNode< kdrec<U,V> > > dummyrecs;
00522
00523 if( !T ) return 0;
00524
00525
00526 sign = rtr<V>::cmp( rec[T->m_disc], T->key() );
00527
00528 if( sign < 0 )
00529 {
00530 Lold = T->m_left;
00531 L = remove(T->m_left,rec,outrecs);
00532 if( L != Lold ) T->set_left(L);
00533 }
00534 else if( sign > 0 )
00535 {
00536 Rold = T->m_right;
00537 R = remove(T->m_right,rec,outrecs);
00538 if( R != Rold ) T->set_right(R);
00539 }
00540 else
00541 {
00542
00543 r = T->m_recs.First();
00544 while( r )
00545 {
00546 for( i = 0; i < m_dim; i++ )
00547 {
00548 sign = rtr<V>::cmp( r->el[i], rec[i] );
00549 if( sign != 0 ) break;
00550 }
00551 r_next = r->next;
00552 if( sign == 0 )
00553 {
00554 T->m_recs.Remove(r);
00555 outrecs.Append(r);
00556 }
00557 r = r_next;
00558 }
00559
00560
00561 if( T->m_recs.nElems == 0 )
00562 {
00563 i = T->m_disc;
00564 Told = T;
00565 T->unlink(&L,&R,dummyrecs);
00566 T = join( L, R, i );
00567 delete Told;
00568 }
00569 }
00570 return T;
00571 }
00572
00573 template< class U, class V, class Rand >
00574 void rkdtree<U,V,Rand>::split(
00575 kdtnode<U,V> *T, const V& key, int i,
00576 kdtnode<U,V> **retL, kdtnode<U,V> **retR,
00577 List< ListNode< kdrec<U,V> > >& C )
00578 {
00579 kdtnode<U,V> *L, *R, *TL, *TR, *L1, *L2, *R1, *R2, *LR, *RL;
00580 List< ListNode< kdrec<U,V> > > recs,recs1,recs2;
00581 int j, sign;
00582
00583
00584 if( !T )
00585 {
00586 *retL = 0;
00587 *retR = 0;
00588 return;
00589 }
00590
00591
00592
00593 T->m_parent = 0;
00594
00595 j = T->m_disc;
00596
00597
00598 if( j == i )
00599 {
00600 sign = rtr<V>::cmp( T->key(), key );
00601
00602
00603 if( sign < 0 )
00604 {
00605 L = T;
00606 split( L->m_right, key, i, &LR, &R, C );
00607 L->set_right(LR);
00608 }
00609
00610 else if( sign > 0 )
00611 {
00612 R = T;
00613 split( R->m_left, key, i, &L, &RL, C );
00614 R->set_left(RL);
00615 }
00616 else
00617 {
00618 T->unlink(&L,&R,C);
00619 delete T;
00620 }
00621 }
00622
00623 else
00624 {
00625 T->unlink( &TL, &TR, recs );
00626 split_recs( recs, key, i, recs1, recs2, C );
00627 split( TL, key, i, &L1, &L2, C );
00628 split( TR, key, i, &R1, &R2, C );
00629
00630 if( recs1.nElems )
00631 {
00632 L = new kdtnode<U,V>( recs1, j );
00633 L->set_childs( L1, R1 );
00634 }
00635 else
00636 {
00637 L = join( L1, R1, j );
00638 }
00639
00640 if( recs2.nElems )
00641 {
00642 R = new kdtnode<U,V>( recs2, j );
00643 R->set_childs( L2, R2 );
00644 }
00645 else
00646 {
00647 R = join( L2, R2, j );
00648 }
00649
00650 delete T;
00651 }
00652
00653 *retL = L;
00654 *retR = R;
00655 }
00656
00657 template< class U, class V, class Rand >
00658 kdtnode<U,V> *rkdtree<U,V,Rand>::join( kdtnode<U,V> *A, kdtnode<U,V> *B, int i )
00659 {
00660 kdtnode<U,V> *root, *A1, *A2, *B1, *B2;
00661 int n,m,j;
00662 double p;
00663
00664 if( (!A) && (!B) ) return 0;
00665
00666
00667
00668
00669 if( !A ) { B->m_parent = 0; return B; }
00670 if( !B ) { A->m_parent = 0; return A; }
00671
00672 A->m_parent = 0;
00673 B->m_parent = 0;
00674
00675 n = A->m_nelems;
00676 m = B->m_nelems;
00677 p = Rand::Random();
00678
00679 if( p*((double)(n+m)) < (double)n )
00680 {
00681 j = A->m_disc;
00682 root = A;
00683
00684 if( j == i )
00685 {
00686 A2 = join( A->m_right, B, i );
00687 root->set_right( A2 );
00688 }
00689 else
00690 {
00691 split( B, A->key(), j, &B1, &B2, A->m_recs );
00692 A1 = join( A->m_left, B1, i );
00693 A2 = join( A->m_right, B2, i );
00694 A->set_childs( A1, A2 );
00695 }
00696 }
00697 else
00698 {
00699 j = B->m_disc;
00700 root = B;
00701
00702 if( j == i )
00703 {
00704 B1 = join( A, B->m_left, i );
00705 root->set_left( B1 );
00706 }
00707 else
00708 {
00709 split( A, B->key(), j, &A1, &A2, B->m_recs );
00710 B1 = join( A1, B->m_left, i );
00711 B2 = join( A2, B->m_right, i );
00712 B->set_childs( B1, B2 );
00713 }
00714 }
00715
00716 return root;
00717 }
00718
00719
00720
00721
00722 template class kdnnrec< gul::point<float>, float >;
00723 template class rkdtree_base< gul::point<float>, float >;
00724 template class rkdtree< gul::point<float>, float, random_des >;
00725
00726 template class kdnnrec< gul::point2<float>, float >;
00727 template class rkdtree_base< gul::point2<float>, float >;
00728 template class rkdtree< gul::point2<float>, float, random_des >;
00729
00730
00731 template class kdnnrec< gul::kdarray<float>, float >;
00732 template class rkdtree_base< gul::kdarray<float>, float >;
00733 template class rkdtree< gul::kdarray<float>, float, random_des >;
00734
00735
00736 template class kdnnrec< gul::kdpoint< float,gul::point<float> >, float >;
00737 template class rkdtree_base< gul::kdpoint< float,gul::point<float> >, float >;
00738 template class rkdtree< gul::kdpoint< float,gul::point<float> >, float,
00739 random_des >;
00740
00741 template class kdnnrec< gul::kdpoint< float,gul::point2<float> >, float >;
00742 template class rkdtree_base< gul::kdpoint< float,gul::point2<float> >, float >;
00743 template class rkdtree< gul::kdpoint< float,gul::point2<float> >, float,
00744 random_des >;
00745
00746
00747 template class kdnnrec< gul::point<double>, double >;
00748 template class rkdtree_base< gul::point<double>, double >;
00749 template class rkdtree< gul::point<double>, double, random_des >;
00750
00751 template class kdnnrec< gul::point2<double>, double >;
00752 template class rkdtree_base< gul::point2<double>, double >;
00753 template class rkdtree< gul::point2<double>, double, random_des >;
00754
00755
00756 template class kdnnrec< gul::kdarray<double>, double >;
00757 template class rkdtree_base< gul::kdarray<double>, double >;
00758 template class rkdtree< gul::kdarray<double>, double, random_des >;
00759
00760
00761 template class kdnnrec< gul::kdpoint< double,gul::point<double> >,double >;
00762 template class rkdtree_base< gul::kdpoint< double,gul::point<double> >,double >;
00763 template class rkdtree< gul::kdpoint< double,gul::point<double> >, double,
00764 random_des >;
00765
00766 template class kdnnrec< gul::kdpoint< double,gul::point2<double> >,double >;
00767 template class rkdtree_base< gul::kdpoint< double,gul::point2<double> >,double >;
00768 template class rkdtree< gul::kdpoint< double,gul::point2<double> >, double,
00769 random_des >;
00770
00771 }
00772