HilbertCoordinateMapper.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2007  A.N. Yzelman
00003  *  Released under LGPL, see license.txt
00004  *
00005  *  Last modified at 23th of May, 2007, by A.N. Yzelman
00006  *
00007  *  HilbertCoordinateMapper.cpp: implementation of HilbertCoordinateMapper.h
00008  *
00009  */
00010 
00011 #include "HilbertCoordinateMapper.h"
00012 #include <iostream>
00013 
00021 void HilbertCoordinateMapper::makeVec( const double x, const double y, vector< double >* where ) {
00022         (*where)[ 0 ] = x;
00023         (*where)[ 1 ] = y;
00024 }
00025 
00034 void HilbertCoordinateMapper::makeVec( const double x, const double y, const double z, vector< double >* where ) {
00035         (*where)[ 0 ] = x;
00036         (*where)[ 1 ] = y;
00037         (*where)[ 2 ] = z;
00038 }
00039 
00048 double HilbertCoordinateMapper::dist( const vector< double > *vx, const vector< double > *vy, const unsigned int dim ) {
00049 
00050         double ret = ( (*vx)[ 0 ] - (*vy)[ 0 ] ); ret *= ret;
00051         for ( unsigned int i=1; i<dim; i++ ) {
00052                 const double cur = ( (*vx)[ i ] - (*vy)[ i ] );
00053                 ret += cur*cur;
00054         }
00055         
00056         return sqrt( ret );
00057 }
00058 
00068 unsigned int HilbertCoordinateMapper::closestTo( const vector< double > *coor, const vector< vector< double > > *corners, const unsigned int dim ) {
00069 
00070         if (corners->size() == 0 )
00071                 cerr << "Empty corners vector passed to HilbertCoordinateMapper::closestTo()!" << endl;
00072         
00073         unsigned int ret = 0;
00074         double min = dist( coor, &( corners->at( 0 ) ), dim );
00075         
00076         
00077         for ( unsigned int i=1 ; i<corners->size(); i++ ) {
00078                 const double curcost = dist( coor, & ( corners->at( i ) ), dim );
00079                 if ( curcost < min ) {
00080                         min = curcost;
00081                         ret = i;
00082                 }
00083         }
00084         
00085         return ret;
00086 }
00087 
00096 void HilbertCoordinateMapper::mid( const vector< double > *x, const vector< double > *y, vector< double > *to ) {
00097         
00098         double* toArr = & ( (*to)[ 0 ] );
00099         for( unsigned int i=0; i<x->size(); i++ )
00100                 toArr[ i ] = ( (*x)[ i ] + (*y)[ i ] ) / 2;
00101 
00102 }
00103 
00112 inline
00113 void HilbertCoordinateMapper::mid3D( unsigned int pos, unsigned int i, unsigned int j ) {
00114         //multi_array<double, 1> ret(extents[3]);
00115         for( unsigned int d=0; d<3; d++ )
00116                 Box_3Dtemp[ pos ][ d ] = ( Box_3D[ i ][ d ] + Box_3D[ j ][ d ] ) / 2.0;
00117 //return ret;
00118 }
00119 
00126 void HilbertCoordinateMapper::refineCoors2D( vector< vector< double > > *corners, const unsigned int cell ) {
00127 
00128         vector< double > a( 2 );
00129         vector< double > b( 2 );
00130         vector< double > c( 2 );
00131         vector< double > d( 2 );
00132 
00133         vector< double > *in = &( ( *corners )[ 0 ] );
00134 
00135         //assume order of the vector to be alphabetical
00136         switch( cell ) {
00137                 case 1:
00138                         a = in[ 0 ];
00139                         mid( &in[ 0 ], &in[ 3 ], &b );
00140                         mid( &in[ 0 ], &in[ 2 ], &c );
00141                         mid( &in[ 0 ], &in[ 1 ], &d );
00142                         break;
00143                 case 2:
00144                         mid( &in[ 0 ], &in[ 1 ], &a );
00145                         b = in[ 1 ];
00146                         mid( &in[ 1 ], &in[ 2 ], &c );
00147                         mid( &in[ 1 ], &in[ 3 ], &d );
00148                         break;
00149                 case 3:
00150                         mid( &in[ 0 ], &in[ 2 ], &a );
00151                         mid( &in[ 1 ], &in[ 2 ], &b );
00152                         c = in[ 2 ];
00153                         mid( &in[ 2 ], &in[ 3 ], &d );
00154                         break;
00155                 case 4:
00156                         mid( &in[ 3 ], &in[ 2 ], &a );
00157                         mid( &in[ 1 ], &in[ 3 ], &b );
00158                         mid( &in[ 3 ], &in[ 0 ], &c );
00159                         d = in[ 3 ];
00160                         break;
00161                 default:
00162                         cerr << "Invalid cell no. given in refineHilbert2D!" << endl;
00163                         exit( 1 );
00164         }
00165         
00166         /*corners->clear();
00167         corners->push_back( a );
00168         corners->push_back( b );
00169         corners->push_back( c );
00170         corners->push_back( d );*/
00171         (*corners)[ 0 ] = a;
00172         (*corners)[ 1 ] = b;
00173         (*corners)[ 2 ] = c;
00174         (*corners)[ 3 ] = d;
00175 
00176 }
00177 
00184 void HilbertCoordinateMapper::refineCoors3D( const unsigned int cell ) {
00185 
00186         //assume order of the vector to be alphabetical
00187         switch( cell ) {
00188                 case 1:
00189                         Box_3Dtemp[ 0 ] = Box_3D[ 0 ];
00190                         mid3D( 1, 0, 3 );
00191                         mid3D( 2, 0, 4 );
00192                         mid3D( 3, 0, 7 );
00193                         mid3D( 4, 0, 6 );
00194                         mid3D( 5, 0, 5 );
00195                         mid3D( 6, 0, 2 );
00196                         mid3D( 7, 0, 1 );
00197                         break;
00198                 case 2:
00199                         mid3D( 0, 0, 1 );
00200                         mid3D( 1, 0, 6 );
00201                         mid3D( 2, 1, 6 );
00202                         Box_3Dtemp[ 3 ] = Box_3D[ 1 ];
00203                         mid3D( 4, 1, 2 );
00204                         mid3D( 5, 1, 5 );
00205                         mid3D( 6, 0, 5 );
00206                         mid3D( 7, 0, 2 );
00207                         break;
00208                 case 3:
00209                         mid3D( 0, 0, 2 );
00210                         mid3D( 1, 0, 5 );
00211                         mid3D( 2, 1, 5 );
00212                         mid3D( 3, 1, 2 );
00213                         Box_3Dtemp[ 4 ] = Box_3D[ 2 ];
00214                         mid3D( 5, 2, 5 );
00215                         mid3D( 6, 3, 5 );
00216                         mid3D( 7, 3, 2 );
00217                         break;
00218                 case 4:
00219                         mid3D( 0, 3, 2 );
00220                         Box_3Dtemp[ 1 ] = Box_3D[ 3 ];
00221                         mid3D( 2, 0, 3 );
00222                         mid3D( 3, 0, 2 );
00223                         mid3D( 4, 0, 5 );
00224                         mid3D( 5, 0, 4 );
00225                         mid3D( 6, 3, 4 );
00226                         mid3D( 7, 3, 5 );
00227                         break;
00228                 case 5:
00229                         mid3D( 0, 3, 5 );
00230                         mid3D( 1, 3, 4 );
00231                         mid3D( 2, 0, 4 );
00232                         mid3D( 3, 0, 5 );
00233                         mid3D( 4, 7, 5 );
00234                         mid3D( 5, 4, 7 );
00235                         Box_3Dtemp[ 6 ] = Box_3D[ 4 ];
00236                         mid3D( 7, 4, 5 );
00237                         break;
00238                 case 6:
00239                         mid3D( 0, 4, 5 );
00240                         mid3D( 1, 3, 5 );
00241                         mid3D( 2, 2, 5 );
00242                         Box_3Dtemp[ 3 ] = Box_3D[ 5 ];
00243                         mid3D( 4, 6, 5 );
00244                         mid3D( 5, 1, 5 );
00245                         mid3D( 6, 0, 5 );
00246                         mid3D( 7, 7, 5 );
00247                         break;
00248                 case 7:
00249                         mid3D( 0, 7, 5 );
00250                         mid3D( 1, 0, 5 );
00251                         mid3D( 2, 2, 5 );
00252                         mid3D( 3, 6, 5 );
00253                         Box_3Dtemp[ 4 ] = Box_3D[ 6 ];
00254                         mid3D( 5, 1, 6 );
00255                         mid3D( 6, 0, 6 );
00256                         mid3D( 7, 7, 6 );
00257                         break;
00258                 case 8:
00259                         mid3D( 0, 7, 6 );
00260                         mid3D( 1, 7, 5 );
00261                         mid3D( 2, 0, 5 );
00262                         mid3D( 3, 6, 0 );
00263                         mid3D( 4, 0, 7 );
00264                         mid3D( 5, 0, 5 );
00265                         mid3D( 6, 7, 5 );
00266                         Box_3Dtemp[ 7 ] = Box_3D[ 7 ];
00267                         break;
00268                 default:
00269                         cerr << "Invalid cell no. given in refineHilbert3D!" << endl;
00270                         exit( 1 );
00271         }
00272                 
00273         Box_3D = Box_3Dtemp;
00274 }
00275 
00289 double HilbertCoordinateMapper::toHilbert2D( const vector< double > *coordinates ) {
00290         vector< unsigned int > digits;
00291         vector< vector< double > > Box;
00292         
00293         //note: remember that the order matters!
00294         vector< double > a( 2 ); makeVec( 0, 0, &a); Box.push_back( a );
00295         vector< double > b( 2 ); makeVec( 0, 1, &b); Box.push_back( b );
00296         vector< double > c( 2 ); makeVec( 1, 1, &c); Box.push_back( c );
00297         vector< double > d( 2 ); makeVec( 1, 0, &d); Box.push_back( d );
00298         
00299         double curDist;
00300         unsigned int closest = closestTo( coordinates, &Box, 2 );
00301         digits.push_back( closest );
00302         
00303         for ( unsigned int i=0; i<RECURSE_LEVEL; i++ ) {
00304         
00305                 refineCoors2D( &Box, closest+1 );
00306         
00307                 closest = closestTo( coordinates, &Box, 2 );
00308                 
00309                 digits.push_back( closest );
00310                 
00311                 curDist = dist( coordinates, &Box.at( closest ), 2 );   
00312         
00313         }
00314 
00315         //const double divBy = pow( static_cast< double >( 4 ), static_cast< int >( RECURSE_LEVEL + 1 ) ) - 1;
00316         //return base4_to_base10( &digits ) / divBy;    
00317         return base4_to_base10( &digits );      
00318 }
00319 
00333 double HilbertCoordinateMapper::toHilbert3D( const vector< double > *coordinates ) {
00334         vector< unsigned int > digits;
00335         Box_3D = pattern;
00336         
00337         unsigned int closest = closestTo3D( coordinates );
00338         digits.push_back( closest );
00339         
00340         for ( unsigned int i=0; i<RECURSE_LEVEL; i++ ) {
00341         
00342                 refineCoors3D( closest + 1 );
00343         
00344                 closest = closestTo3D( coordinates );
00345                 
00346                 digits.push_back( closest );
00347 
00348         }
00349         
00350         //const double divBy = pow( static_cast< double >( 8 ), static_cast< int >( RECURSE_LEVEL + 1 ) ) - 1;
00351 #ifdef _DEBUG
00352         //cout << "bs: " ;
00353         //for( unsigned int i=0; i<digits.size() ; i++ )
00354         //      cout << digits[ i ];
00355         //cout << endl;
00356         //cout << "up: " << base8_to_base10( &digits ) << endl;
00357         //cout << "dw: " << divBy << endl;
00358 #endif
00359         //return base8_to_base10( &digits ) / divBy;
00360         return base8_to_base10( &digits );
00361 }
00362 
00372 unsigned int HilbertCoordinateMapper::closestTo3D( const vector< double > *coor ) {
00373         
00374         unsigned int ret = 0;
00375         double min = dist3D( coor, 0 );
00376         
00377         for ( unsigned int i=1; i<8; i++ ) {
00378                 const double curcost = dist3D( coor, i );
00379                 if ( curcost < min ) {
00380                         min = curcost;
00381                         ret = i;
00382                 }
00383         }
00384         
00385         return ret;
00386 }
00387 
00396 inline double HilbertCoordinateMapper::dist3D( const vector< double > *vx, const unsigned int num ) {
00397 
00398         double ret = ( (*vx)[ 0 ] - Box_3D[ num ][ 0 ] ); ret *= ret;
00399         for ( unsigned int i=1; i<3; i++ ) {
00400                 const double cur = ( (*vx)[ i ] - Box_3D[ num ][ i ] );
00401                 ret += cur*cur;
00402         }
00403         
00404         //return sqrt( ret );
00405         return ret;
00406 }
00407 
00408 typedef boost::multi_array<double, 2 > array_type;   
00409 
00410 array_type HilbertCoordinateMapper::pattern = HilbertCoordinateMapper::makePattern();
00411 
00412 array_type HilbertCoordinateMapper::Box_3D = HilbertCoordinateMapper::pattern;
00413 
00414 array_type HilbertCoordinateMapper::Box_3Dtemp = HilbertCoordinateMapper::pattern;

Generated on Sat Oct 13 17:34:42 2007 for R-Tree by  doxygen 1.5.2