00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef _H_ORDERINGS
00013 #define _H_ORDERINGS
00014
00015
00016
00017 #include "randomUtils.h"
00018 #include "HilbertCoordinateMapper.h"
00019
00020 #include <vector>
00021 #include <iostream>
00022 using namespace std;
00023
00027 template < typename bb_type >
00028 class Ordering {
00029
00030 private:
00031
00032 void swap( bb_type** arr, unsigned int x, unsigned int y ) const {
00033 bb_type* temp = arr[x];
00034 arr[x] = arr[y];
00035 arr[y] = temp;
00036 }
00037
00038
00039 unsigned int pivotise( bb_type** arr, unsigned int left, unsigned int right, unsigned int pivot ) const {
00040 const double pivotMin = this->getVal( arr[ pivot ] );
00041
00042 swap( arr, pivot, right );
00043
00044 unsigned int l_hold = left;
00045
00046 for ( unsigned int i=left; i<right; i++ ) {
00047 if ( this->getVal( arr[ i ] ) <= pivotMin ) {
00048 swap( arr, l_hold, i );
00049 l_hold++;
00050 }
00051 }
00052
00053 swap( arr, right, l_hold );
00054
00055 return l_hold;
00056 }
00057
00058 void quicksort( bb_type** arr, unsigned int left, unsigned int right ) const {
00059 #ifdef _DEBUG
00060 cout << "QuickSort( " << arr << " , " << left << " , " << right << " )" << endl;
00061 fflush( stdout );
00062 #endif
00063 if ( right <= left )
00064 return;
00065 const unsigned int pivot = randomUtils::randomInt( left, right+1 );
00066 const unsigned int middle = pivotise( arr, left, right, pivot );
00067 if ( middle != 0 )
00068 quicksort( arr, left, middle-1 );
00069
00070 quicksort( arr, middle+1, right);
00071 #ifdef _DEBUG
00072 cout << "Exitting QuickSort( " << arr << " , " << left << " , " << right << " )" << endl;
00073 fflush( stdout );
00074 #endif
00075 }
00076
00077 static void cannotCall() { cerr << "Cannot call functions on abstract Orderings!" << endl; exit( 1 ); }
00078
00079 protected:
00080
00081
00082
00083 virtual double getVal( const bb_type * const in ) const = 0;
00084
00085 public:
00086
00087 typedef typename std::vector< bb_type* >::iterator curtypeIterator;
00088
00089 virtual void split( vector< bb_type* > *input, int loc, vector< bb_type* > *set_one, vector< bb_type* > *set_two ) {
00090 sort( input );
00091 set_one->assign( input->begin(), input->begin() + loc );
00092 set_two->assign( input->begin() + loc, input->end() );
00093 }
00094
00095 virtual bb_type* max( vector< bb_type* > *input ) const {
00096 #ifndef _HP
00097 if ( input->size() == 0 ) {
00098 cerr << "Tried to get the maximum of an empty set" << endl;
00099 exit( 1 );
00100 }
00101 #endif
00102
00103 bb_type* ret = (*input)[0];
00104 double curmax = this->getVal( ret );
00105
00106
00107
00108
00109
00110
00111 for( unsigned int i=1; i<input->size(); i++ ) {
00112 const double cur = this->getVal( (*input)[ i ] );
00113 if ( curmax < cur ) {
00114 curmax = cur;
00115
00116 ret = (*input)[ i ];
00117 }
00118 }
00119
00120 return ret;
00121 }
00122
00123 virtual bb_type* min( vector< bb_type* > *input ) const {
00124 #ifndef _HP
00125 if ( input->size() == 0 ) {
00126 cerr << "Tried to get the maximum of an empty set" << endl;
00127 exit( 1 );
00128 }
00129 #endif
00130
00131 bb_type* ret = (*input)[0];
00132 double curmin = this->getVal( ret );
00133
00134
00135
00136
00137 for ( unsigned int i=1; i<input->size(); i++ ) {
00138 const double cur = this->getVal( (*input)[ i ] );
00139 if ( curmin > cur ) {
00140 curmin = cur;
00141 ret = (*input)[ i ];
00142
00143 }
00144 }
00145
00146 return ret;
00147 }
00148
00149
00150 virtual void sort( vector< bb_type* > *input ) {
00151
00152 #ifdef _DEBUG
00153 cout << "Sorting..." << endl; fflush( stdout );
00154 #endif
00155 bb_type** curarr = &( ( *input )[0] );
00156 const unsigned int n = input->size();
00157 quicksort( curarr, 0, n - 1 );
00158 #ifdef _DEBUG
00159 cout << "Done Sorting!" << endl; fflush( stdout );
00160 #endif
00161
00162 }
00163
00164 virtual ~Ordering() {}
00165
00166 };
00167
00172 template< typename cur_type >
00173 class CURRENTORDERING: public Ordering< cur_type > {
00174
00175 protected:
00176 virtual double getVal( const cur_type * const in ) const {
00177 return 0.0;
00178 }
00179
00180
00181 public:
00182 virtual cur_type* min( vector< cur_type* > *input ) const {
00183 return input->front();
00184 }
00185
00186 virtual cur_type* max( vector< cur_type* > *input ) const {
00187 return input->back();
00188 }
00189
00190 virtual void sort( vector< cur_type* > *input ) {
00191 return;
00192 }
00193
00194 };
00195
00200 template< typename cur_type >
00201 class DistOrdering: public Ordering< cur_type > {
00202
00203 protected:
00204
00205 virtual double getVal( const cur_type * const in ) const {
00206
00207 const unsigned int dim = in->getDimension();
00208
00209 double ret = in->_mins[0] * in->_mins[0];
00210 for ( unsigned int i=1; i<dim; i++ )
00211 ret += in->_mins[1] * in->_mins[1];
00212 return ret;
00213 }
00214
00215 public:
00216
00217 };
00218
00224 template< int dim, typename cur_type >
00225 class CubicLowCoorOrdering : public Ordering< cur_type > {
00226
00227 protected:
00228
00229 virtual double getVal( const cur_type* const item ) const {
00230
00231 return item->_mins[ dim ];
00232 }
00233
00234 public:
00235
00236 };
00237
00243 template< typename cur_type >
00244 class HilbertOrdering2D: public Ordering< cur_type > {
00245
00246 protected:
00247
00248 virtual double getVal( const cur_type * const in ) const {
00249 return HilbertCoordinateMapper::toHilbert2D( in->getCenterCoordinate() );
00250 }
00251
00252 };
00253
00259 template< typename cur_type >
00260 class HilbertOrdering3D: public Ordering< cur_type > {
00261
00262 protected:
00263
00264 double* hilbertCache;
00265 unsigned int min;
00266
00267 virtual double getVal( const cur_type * const inp ) const {
00268
00269
00270
00271 return hilbertCache[ inp->getID() - min ];
00272 }
00273
00274 public:
00275 virtual void sort( vector< cur_type* > *input ) {
00276
00277 unsigned int max = (*input)[ 0 ]->getID();
00278 min = (*input)[ 0 ]->getID();
00279 for( unsigned int i=1; i<input->size(); i++ ) {
00280 if ( (*input)[ i ]->getID() > max )
00281 max = (*input)[ i ]->getID();
00282 if ( (*input)[ i ]->getID() < min )
00283 min = (*input)[ i ]->getID();
00284 }
00285
00286
00287 hilbertCache = new double[ max - min + 1 ];
00288 for( unsigned int i=0; i<input->size(); i++ ) {
00289 const unsigned int id = (*input)[ i ]->getID();
00290 vector< double > centre;
00291 (*input)[ i ]->getCenterCoordinate( ¢re );
00292 hilbertCache[ id - min ] = HilbertCoordinateMapper::toHilbert3D( ¢re );
00293 }
00294
00295 Ordering< cur_type >::sort( input );
00296
00297 delete [] hilbertCache;
00298 }
00299 };
00300
00301
00306 template< typename cur_type, typename cur_tree >
00307 class MinDistTreeOrdering : public Ordering< cur_tree > {
00308
00309 protected:
00310
00311 vector<double> p;
00312
00313
00314 virtual double getVal( const cur_tree * const intree ) const {
00315 const cur_type * in = intree->getMBR();
00316
00317 const unsigned int dim = in->getDimension();
00318 double ret = 0;
00319 for ( unsigned int i = 0; i < dim; i++ ) {
00320 if (p[i] < in->getMinCoordinateOnDimension(i)) {
00321 ret += (in->getMinCoordinateOnDimension(i) - p[i]) * (in->getMinCoordinateOnDimension(i) - p[i]);
00322 } else if (p[i] > in->getMaxCoordinateOnDimension(i)) {
00323 ret += (p[i] - in->getMaxCoordinateOnDimension(i)) * (p[i] - in->getMaxCoordinateOnDimension(i));
00324 } else {
00325 ret += 0;
00326 }
00327 }
00328 return ret;
00329 }
00330
00331 public:
00332 MinDistTreeOrdering(vector<double> point) : p(point) { }
00333 };
00334
00335
00336 #endif