N1DArray.h

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 8th of March, 2007, by A.N. Yzelman
00006  *
00007  *  N1DArray.h: Defines a multi-dimensional matrix.
00008  *
00009  */
00010 
00011 #ifndef _H_N1DARRAY
00012 #define _H_N1DARRAY
00013 
00018 //#define _SET_INITIAL_ZERO
00019 
00020 #include <vector>
00021 
00023 //#define _DEBUG
00024 //#define _VOID_CHECK
00025 //#define _SMALLER_RESIZE_WARNING_ON
00026 
00028 #define _HP
00029 
00045 template<typename stored_type>
00046 class N1DArray {
00047 private:
00048 
00049 #ifdef _VOID_CHECK
00050 
00053         void voidCheckDBG() {
00054                 int c=0;
00055                 for (int i=0; i<size; i++)
00056                         if ( _storage[i] == 0 )
00057                                 c++;
00058                 cout << "Number of stored void blocks: " << c << endl; fflush( stdout );
00059         }
00060 #endif
00061 
00062 protected:
00063 
00065         unsigned int size;
00066         
00068         unsigned int _dimension;
00069         
00071         vector< unsigned int > _sizes;
00072         
00074         vector< unsigned int > _cumulative_size;
00075         
00077         stored_type *_storage;
00078 
00088         bool checkIndex( vector< unsigned int > index ) {
00089                 if ( index.size() == _dimension ) {
00090                         for ( unsigned int i=0; i<_dimension; i++ ) {
00091                                 if ( index[i] >= _sizes[i] || index[i] < 0) {
00092                                         cerr << "Warning: wrong index vector in N1DArray::checkIndex index[" << i << "] = " << index[i] << " not in [0, " << _sizes[i] << "]!" << endl;
00093                                         return false;
00094                                 } else {
00095                                         return true;
00096                                 }
00097                         }
00098                 }
00099                 cerr << "Warning: wrong index vector size in N1DArray::checkIndex (" << index.size() << ")" << endl;
00100                 return false;
00101         }
00102 
00103 public:
00104 
00106         class Iterator : public std::iterator<std::forward_iterator_tag, stored_type> {
00107                 private:
00108                 
00110                 unsigned int at;
00111                 
00113                 N1DArray< stored_type > *arr;
00114 
00115                 public:
00116                 
00123                 Iterator( N1DArray< stored_type > *a ) {
00124                         at = 0;
00125                         arr = a;
00126                 }
00127 
00135                 Iterator( N1DArray< stored_type > *a, unsigned int b ) {
00136                         at = b;
00137                         arr = a;
00138                 }
00139 
00141                 Iterator& operator=( const Iterator& other ) {
00142                         at = other.at;
00143                         arr = other.arr;
00144                         return (*this);
00145                 }
00146 
00148                 bool operator==( const Iterator& other ) {
00149                         return ( at == other.at && arr == other.arr );
00150                 }
00151 
00153                 bool operator!=(const Iterator& other ) {
00154                         return ( at != other.at || arr != other.arr );
00155                 }
00156         
00158                 Iterator& operator++() {
00159                         at++;
00160                         return (*this);
00161                 }
00162 
00169                 stored_type operator*() {
00170 
00171                         return arr->_storage[ at ];
00172                 }
00173 
00174         };
00175 
00183         Iterator begin() {
00184                 return Iterator( this );
00185         }
00186 
00194         Iterator end() {
00195                 return Iterator( this, size );
00196         }
00197 
00206         int get1D( vector< unsigned int > index ) {
00207         
00208                 //first check the index vector
00209                 if ( !checkIndex( index ) ) {
00210                         cerr << "N1DArray received bad index vector!" << endl;
00211                         exit(1);
00212                 }
00213                 
00214                 unsigned int index_1d = 0;
00215 
00216 #ifdef _DEBUG
00217                 cout << "Index vector: < ";
00218 #endif
00219 
00220                 //the actual transformation
00221                 for ( unsigned int i=0; i<_dimension; i++ ) {
00222                         index_1d += index[i] * _cumulative_size[i];
00223 
00224 #ifdef _DEBUG
00225                         cout << index[i] << " ";
00226 #endif
00227                 }
00228 #ifdef _DEBUG
00229                 cout << "> maps to " << index_1d << "/" << size << endl;
00230 #endif
00231 
00232 #ifndef _HP
00233                 //additional sanity checking
00234                 if ( index_1d >= size ) {
00235                         cerr << "1D index exceeds allocated number!" << endl;
00236                         cerr << "Requested index vector: < ";
00237                         for ( unsigned int i=0; i<_dimension; i++ )
00238                                 cerr << index[i] << " ";
00239                         cerr << ">" << endl;
00240                         cerr << "Size vector: < ";
00241                         for ( unsigned int i=0; i<_dimension; i++ )
00242                                 cerr << _sizes[i] << " ";
00243                         cerr << ">" << endl;
00244                         cerr << "Cumulative size vector: < ";
00245                         for ( unsigned int i=0; i<_dimension; i++ )
00246                                 cerr << _cumulative_size[i] << " ";
00247                         cerr << ">" << endl;
00248                         exit(1);
00249                 }
00250 #endif
00251                 
00252                 return index_1d;
00253         }
00254 
00262         N1DArray( vector< unsigned int > sizes ) {
00263         
00264         #ifdef _DEBUG
00265                 cout << "Size vector: < ";
00266                 for ( unsigned int i=0; i<sizes.size(); i++)
00267                         cout << sizes[i] << " ";
00268                 cout << ">" << endl; fflush( stdout );
00269         #endif
00270         
00271                 _dimension = sizes.size();
00272                 _sizes = sizes;
00273                 _cumulative_size = sizes;
00274                 size = 1;
00275                 for (int j=_dimension-1; j >=0; j--) {
00276                         size *= _sizes[j];
00277                 }
00278 
00279                 _storage = new stored_type[size];
00280 
00281 #ifdef _DEBUG
00282                 cout << "Allocated size: " << size << endl;
00283 #endif
00284 
00285                 _cumulative_size[0] = 1;
00286                 for ( unsigned int i=1; i<_dimension; i++ ) {
00287                         _cumulative_size[i] = _sizes[i-1] * _cumulative_size[i-1];
00288 #ifdef _DEBUG
00289                         cout << "Sumsiz[" << i << "]=" << _cumulative_size[i] << endl;
00290 #endif
00291                 }
00292 
00293 #ifdef _SET_INITIAL_ZERO
00294                 for (int i=0; i<size; i++)
00295                         _storage[i] = 0;
00296 #endif
00297 
00298         }
00299 
00310         N1DArray( unsigned int x, unsigned int y, unsigned int z, unsigned int w) {
00311                 //straightforward implementation. Uses the base constructor.
00312                 vector< unsigned int > v(4);
00313                 v[0]=x; v[1]=y; v[2]=z; v[3]=w;
00314                 this(v);
00315         }
00316 
00322         ~N1DArray() {
00323                 delete [] _storage;
00324         }
00325 
00333         stored_type get(vector< unsigned int > index) {
00334 
00335 #ifdef _VOID_CHECK
00336                 voidCheckDBG();
00337 #endif
00338                 //straightforward implementation
00339                 unsigned int index_1d = get1D(index);
00340                 return _storage[index_1d];
00341         }
00342 
00350         void set(vector< unsigned int > index, stored_type obj) {
00351 
00352 #ifdef _VOID_CHECK
00353                 voidCheckDBG();
00354 #endif
00355 
00356                 //straightforward implementation
00357         
00358 #ifdef _DEBUG
00359                 cout << "N1DArray::set called with index: < ";
00360                 for ( unsigned int i=0; i<index.size(); i++ )
00361                         cout << index[i] << " ";
00362                 cout << " >" << endl;
00363 #endif
00364 
00365                 unsigned int index_1d = get1D( index );
00366 
00367 #ifdef _DEBUG
00368                 cout << "1D location: " << index_1d << endl;
00369 #endif
00370 
00371                 _storage[index_1d] = obj;
00372         }
00373 
00386         void resize( vector< unsigned int > sizes ) {
00387         
00388 #ifdef _VOID_CHECK
00389                 voidCheckDBG();
00390 #endif
00391 
00392 #ifdef _DEBUG           
00393                 cout << "New sizes: < ";
00394                 for (int i=0; i<_dimension; i++)
00395                         cout << sizes[i] << " ";
00396                 cout << ">" << endl;
00397 #endif
00398 
00399                 //check dimensions
00400                 if ( sizes.size() != _sizes.size() ) {
00401                         cerr << "Cannot resize the vector dimension itself!" << endl;
00402                         exit(1);
00403                 }
00404 
00405                 //check sizes
00406                 bool same = true;
00407                 for ( unsigned int dim=0; dim<_dimension; dim++) {
00408                         if ( sizes[dim] != _sizes[dim] )
00409                                 same = false;
00410                         if ( sizes[dim] < _sizes[dim] ) {
00411 #ifdef _SMALLER_RESIZE_WARNING_ON
00412                                 cerr << "Cannot resize to smaller sizes (would possibly lose data)!" << endl;
00413                                 cerr << "Ignoring resize command (!)" << endl;
00414 #endif
00415                                 //exit(1);
00416                                 return; //just ignore instead of crash
00417                         }
00418                 }
00419 
00420                 //if sizes are equal, do nothing
00421                 if ( same )
00422                         return;
00423 
00424                 //allocate larger array 
00425                 N1DArray< stored_type > *replacement = new N1DArray< stored_type >( sizes );
00426 
00427                 vector< unsigned int > copy_index;
00428                 copy_index.resize( _dimension );
00429                 for ( unsigned int i=0; i<_dimension; i++ )
00430                         copy_index[i] = 0;
00431 
00432                 //copy elements
00433                 while (true) {
00434                         stored_type element = get( copy_index );
00435                         replacement->set( copy_index, element );
00436                         copy_index[0]++;
00437                         for ( unsigned int i=0; i<(_dimension-1); i++ ) {
00438                                 if (copy_index[i] == _sizes[i]) {
00439                                         copy_index[i] = 0;
00440                                         copy_index[i+1]++;
00441                                 }
00442                         }
00443                         if ( copy_index[_dimension-1] == _sizes[_dimension-1] )
00444                                 break;
00445                 }
00446 
00447                 //delete local storage
00448                 delete [] _storage;
00449                 _sizes.clear();
00450                 _cumulative_size.clear();
00451 
00452                 //become the new array
00453                 //dimension =...
00454                 size = replacement->size;
00455                 _storage = replacement->_storage;
00456                 _sizes = replacement->_sizes;
00457                 _cumulative_size = replacement->_cumulative_size;
00458 
00459 #ifdef _VOID_CHECK
00460                 voidCheckDBG();
00461 #endif
00462 
00463         }
00464 
00465 };
00466 
00467 #endif

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