Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

NTuple.cxx

Go to the documentation of this file.
00001 
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #else
00015 #ifdef _MSC_VER
00016 #include "msdevstudio/MSconfig.h"
00017 #endif
00018 #endif
00019 
00020 #include "NTuple.h"
00021 
00022 #include "DataSourceException.h"
00023 
00024 #include "axes/Range.h"
00025 #include "pattern/Observer.h"
00026 
00027 #include <algorithm>
00028 #include <functional>
00029 #include <numeric>
00030 
00031 #include <cassert>
00032 
00033 #ifdef ITERATOR_MEMBER_DEFECT
00034 using namespace std;
00035 #else
00036 using std::distance;
00037 using std::string;
00038 using std::vector;
00039 using std::find;
00040 using std::min_element;
00041 using std::max_element;
00042 #endif
00043 
00044 NTuple::NTuple ( const std::string & name )
00045   : DataSource ( name ),
00046     m_i_count ( 1 ),
00047     m_i_current ( 0 ),
00048     m_i_enabled ( false )
00049 {
00050 }
00051 NTuple::NTuple ( const char * name )
00052   : DataSource ( name ),
00053     m_i_count ( 1 ),
00054     m_i_current ( 0 ),
00055     m_i_enabled ( false )
00056 {
00057 }
00058 
00059 NTuple::NTuple ( const std::vector< std::string >  & labels )
00060   : DataSource ( labels ),
00061     m_i_count ( 1 ),
00062     m_i_current ( 0 ),
00063     m_i_enabled ( false )
00064 {
00065   std::size_t size = labels.size ();
00066   for ( std::size_t i = 0; i < size; i++ ) {
00067     vector< double > * vp = new vector< double > ();
00068     m_data.push_back ( vp );
00069   }
00070 }
00071 
00072 NTuple::NTuple ( const NTuple & nt )
00073   : DataSource ( nt ),
00074     m_i_count ( nt.m_i_count ),
00075     m_i_current ( nt.m_i_current ),
00076     m_i_enabled ( nt.m_i_enabled )
00077 {
00078   copy( nt );
00079 }
00080 
00081 NTuple::
00082 NTuple ( const DataSource * ds )
00083   : DataSource ( *ds ),
00084     m_i_count ( 1 ),
00085     m_i_current ( 0 ),
00086     m_i_enabled ( false )
00087 {
00088   copy ( *ds );
00089 }
00090 
00091 NTuple::NTuple ( unsigned int n )
00092   : DataSource ( ),
00093     m_i_count ( 1 ),
00094     m_i_current ( 0 ),
00095     m_i_enabled ( false )
00096 {
00097   vector < string > labels;
00098   for ( unsigned int i = 0; i < n; i++ ) {
00099     vector<double> * v = new vector<double> ();
00100     m_data.push_back( v );
00101     labels.push_back ( string ( "nil" ) );
00102   }
00103 
00104   setLabels ( labels );
00105 }
00106 
00107 NTuple::NTuple ()
00108   : DataSource ( ),
00109     m_i_count ( 1 ),
00110     m_i_current ( 0 ),
00111     m_i_enabled ( false ){
00112 }
00113 
00114 NTuple::
00115 NTuple ( bool yes )
00116   : DataSource ( yes ),
00117     m_i_count ( 1 ),
00118     m_i_current ( 0 ),
00119     m_i_enabled ( false )
00120 {
00121 }
00122 
00123 NTuple::~NTuple()
00124 {
00125   Observable::notifyObservers ( &hippodraw::Observer::willDelete );
00126 
00127   vector< vector<double> *>::iterator it = m_data.begin();
00128   for ( ; it != m_data.end(); ++it ) {
00129     delete *it;
00130   }
00131 }
00132 
00133 void NTuple::resizeColumns ( size_t new_size )
00134 {
00135   size_t old_size = m_data.size ();
00136 
00137   if ( new_size > old_size ) {
00138     for ( ; old_size < new_size; old_size++ ) {
00139       vector< double > * v = new vector<double> ();
00140       m_data.push_back ( v );
00141     }
00142   }
00143   else {
00144     m_data.erase ( m_data.begin() + new_size, m_data.end() );
00145   }
00146 
00147 }
00148 
00149 void
00150 NTuple::
00151 copy ( const DataSource  & rhs )
00152 {
00153   DataSource::copyPrivate ( rhs );
00154   m_data.clear ();
00155   try {
00156     const NTuple & ntuple = dynamic_cast < const NTuple & > ( rhs );
00157 
00158     vector< vector<double> *>::const_iterator it = ntuple.m_data.begin();
00159     for ( ; it != ntuple.m_data.end(); ++it ) {
00160       vector<double> * v = new vector<double> ( **it );
00161       m_data.push_back( v );
00162     }
00163     m_i_count = ntuple.m_i_count;
00164     m_i_current = ntuple.m_i_current;
00165     m_i_enabled = ntuple.m_i_enabled;
00166   }
00167   catch ( ... ) {
00168     unsigned int columns = rhs.columns ();
00169 
00170     for ( unsigned int i = 0; i < columns; i++ ) {
00171       vector < double > * vec = new vector < double >;
00172       m_data.push_back ( vec );
00173     }
00174 
00175     unsigned int size = rhs.rows ();
00176     for ( unsigned int i = 0; i < size; i++ ) {
00177       const vector < double > & src = rhs.getRow ( i );
00178       for ( unsigned int j = 0; j < columns; j++ ) {
00179         vector < double > & d = *m_data[j];
00180         d.push_back ( src[j] );
00181       }
00182     }
00183   }
00184 
00185 }
00186 
00187 void NTuple::clear()
00188 {
00189   vector< vector<double> *>::iterator it = m_data.begin();
00190   for ( ; it < m_data.end(); ++it ) {
00191     (*it)->clear();
00192   }
00193 
00194   notifyObservers ();
00195 }
00196 
00197 bool
00198 NTuple::
00199 empty () const
00200 {
00201   return m_data.empty () ? true : m_data[0] -> empty ();
00202 }
00203 
00204 unsigned int
00205 NTuple::
00206 rows () const
00207 {
00208   unsigned int count = 0;
00209 
00210   if ( m_data.empty() == false &&
00211        m_data[0] -> empty () == false ) {
00212     count = m_data[0] -> size ();
00213   }
00214 
00215   return count;
00216 }
00217 
00218 void
00219 NTuple::
00220 replaceRow ( unsigned int i, const std::vector < double > & v )
00221 {
00222   if ( ! ( i < rows () ) ) {
00223     const string what ( "NTuple::replaceRow: index invalid" );
00224     throw DataSourceException ( what );
00225   }
00226 
00227   throwIfInvalidRowSize ( v );
00228 
00229   vector < vector < double > * >:: iterator first = m_data.begin ();
00230   vector < double > :: const_iterator d = v.begin();
00231   while ( first != m_data.end () ) {
00232     vector < double > * column = *first++;
00233     column->operator[] ( i ) = *d++;
00234   }
00235 
00236   notifyObservers ();
00237 }
00238 
00239 // note: Using index is twice as fast as using iterators
00240 void
00241 NTuple::
00242 addRow ( const std::vector < double > & v )
00243 {
00244   throwIfInvalidRowSize ( v );
00245 
00246   unsigned int size = m_data.size ();
00247   for ( unsigned int i = 0; i < size; i++ ) {
00248     vector < double > & column = *m_data[i];
00249     column.push_back ( v[i] );
00250   }
00251   notifyObservers ();
00252 }
00253 
00254 void
00255 NTuple::
00256 insertRow ( unsigned int index, const std::vector < double > & v )
00257 {
00258   if ( m_data.size() != v.size() ) {
00259     const string what ( "NTuple: Attempt to insert a row whose size"
00260                         " is not equal to other rows." );
00261     throw DataSourceException ( what );
00262   }
00263 
00264   if ( index > rows () ) {
00265     const string what ( "NTuple::insertRow: index out of range" );
00266     throw DataSourceException ( what );
00267   }
00268 
00269   vector<double>::const_iterator vit = v.begin();
00270   vector< vector<double> *>::iterator it = m_data.begin();
00271   for ( ; it != m_data.end(); ++it ) {
00272     vector < double > * p = *it;
00273     vector < double > :: iterator where = p->begin() + index;
00274     p->insert ( where, *vit++ );
00275   }
00276 
00277   notifyObservers ();
00278 }
00279 
00280 void
00281 NTuple::
00282 eraseRow ( unsigned int index )
00283 {
00284   if ( index >= rows () ) {
00285     const string what ( "NTuple::insertRow: index out of range" );
00286     throw DataSourceException ( what );
00287   }
00288 
00289   vector< vector<double> *>::iterator it = m_data.begin();
00290   for ( ; it != m_data.end(); ++it ) {
00291     vector < double > * p = *it;
00292     vector < double > :: iterator where = p->begin() + index;
00293     p->erase ( where);
00294   }
00295 
00296   notifyObservers ();
00297 }
00298 
00299 // note: clearing and using push_back was twice as fast as
00300 // resizing and using operator[]
00301 const std::vector < double > & NTuple::getRow ( unsigned int row ) const
00302 {
00303   if ( row >= rows () ) {
00304     string what ( "NTuple::getRow: argument out of range" );
00305     throw DataSourceException ( what );
00306   }
00307   unsigned int cols = columns ();
00308   m_row.clear ();
00309 
00310   for ( unsigned int i = 0; i < cols; i++ ) {
00311     const vector < double > & column = *m_data[i];
00312     m_row.push_back ( column[row] );
00313   }
00314 
00315   return m_row;
00316 }
00317 
00318 double
00319 NTuple::
00320 operator [] ( std::vector < unsigned int > & indices ) const
00321 {
00322   unsigned int rank = getRank ();
00323   assert ( indices.size() == rank );
00324 
00325 
00326 if ( rank == 1 ) {
00327     unsigned int size = m_data.size();
00328     unsigned int row = indices[0] / size;
00329     unsigned int col = indices[0] % size;
00330     const vector < double > & column = *m_data[col];
00331     return column[row];
00332   }
00333 
00334   if ( rank == 2 ) {
00335     unsigned int col = indices[1];
00336     unsigned int row = indices[0];
00337     const vector < double > & column = *m_data[col];
00338     return column[row];
00339   }
00340 
00341   if ( rank == 3 ) {
00342     unsigned int size = m_data.size();
00343     unsigned int col = indices[2];
00344     unsigned int j = indices[1];
00345     unsigned int i = indices[0];
00346 
00347     assert ( col < size );
00348     assert ( j < m_shape[1] );
00349     assert ( i < m_shape[0] );
00350 
00351     unsigned int row = j + i * m_shape[1];
00352     const vector < double > & column = *m_data[col];
00353     return column[row];
00354   }
00355   return 0.0;
00356 }
00357 
00358 double
00359 NTuple::
00360 valueAt ( unsigned int row, unsigned int column ) const
00361 {
00362   //return (*m_data[column])[row];
00363   vector < double > * v = m_data [ column ];
00364   return v -> operator [] ( row );
00365 }
00366 
00367 void NTuple::reserve ( unsigned int count )
00368 {
00369   vector < vector < double > * >::iterator it = m_data.begin();
00370   for ( ; it != m_data.end(); ++it ) {
00371     (*it)->reserve ( count );
00372   }
00373 }
00374 
00375 int
00376 NTuple::
00377 addColumn ( const std::string & label,
00378             const std::vector< double > & col )
00379 {
00380   // Check if label already exists.
00381   int index = indexOf ( label );
00382   if ( index >= 0 ) {
00383     string what ( "NTuple: Attempt to add a column whose label"
00384                   " is same as other column." );
00385     throw DataSourceException ( what );
00386   }
00387 
00388   // Check if column has right size.
00389   if ( m_data.empty () == false ) {
00390     unsigned int size = rows ();
00391     if ( size != 0 && size != col.size() ) {
00392       string what ( "NTuple: Attempt to add a column whose size"
00393                     " is not equal to other columns." );
00394       throw DataSourceException ( what );
00395     }
00396   }
00397 
00398   vector < double > * vec = new vector < double > ( col );
00399   m_data.push_back ( vec );
00400   addLabel ( label );
00401 
00402   return m_data.size() - 1;
00403 }
00404 
00405 void
00406 NTuple::
00407 replaceColumn ( unsigned int col, const std::vector< double > & data )
00408 {
00409   unsigned int size = columns ();
00410   if ( col >= size ) {
00411     const string what ( "NTuple::replaceColumn: column index out of range" );
00412     throw DataSourceException ( what );
00413   }
00414 
00415   size = rows();
00416   unsigned int new_size = data.size ();
00417   if ( size != 0 && size != new_size ) {
00418     const string what ( "NTuple: Attempt to replace column with one whose"
00419                         " size is not equal to other columns." );
00420     throw DataSourceException ( what );
00421   }
00422   m_data[col]->resize ( data.size() );
00423   // need std:: below, else conflicts with NTuple::copy()
00424   std:: copy ( data.begin (), data.end(), m_data[col]->begin() );
00425 
00426   notifyObservers ();
00427 }
00428 
00429 void
00430 NTuple::
00431 replaceColumn ( const std::string & label,
00432                 const std::vector< double > & data )
00433 {
00434   unsigned int index = indexOf ( label );
00435 
00436   replaceColumn ( index, data );
00437 }
00438 
00439 void
00440 NTuple::
00441 setLabels ( const std::vector< std::string > & v )
00442 {
00443   if ( rows () == 0 ) {
00444     resizeColumns ( v.size () );
00445   }
00446   else {
00447     if ( v.size () != columns () ) {
00448       const string what ( "NTuple::setLabels "
00449                           "Number of labels not same as number of columns" );
00450       throw DataSourceException ( what );
00451     }
00452   }
00453 
00454   DataSource::setLabels ( v );
00455 }
00456 
00457 const vector<double> & NTuple::getColumn ( unsigned int i ) const
00458 {
00459   isValidColumn ( i ); // will throw exception if bad
00460 
00461   return *m_data[i];
00462 }
00463 
00464 vector<double> & NTuple::getColumn ( unsigned int i )
00465 {
00466   unsigned int size = columns();
00467   if ( i >= size ) {
00468     const string what ( "NTuple::getColumn argument out of range" );
00469     throw DataSourceException ( what );
00470   }
00471 
00472   return *m_data[i];
00473 }
00474 
00475 const vector< double > & NTuple::getColumn ( const std::string & name ) const
00476 {
00477   throwIfInvalidLabel ( name );
00478   int index = indexOf ( name );
00479 
00480   return *m_data[index];
00481 }
00482 
00483 unsigned int
00484 NTuple::
00485 indexOfMinElement( unsigned int index ) const
00486 {
00487   const vector< double > & c = getColumn( index );
00488 
00489   vector < double > :: const_iterator first
00490     = min_element ( c.begin(), c.end() );
00491 
00492   return distance ( c.begin(), first );
00493 }
00494 
00495 double
00496 NTuple::
00497 minElement ( unsigned int column ) const
00498 {
00499   vector < double > & v = *m_data[column];
00500 
00501   return *min_element ( v.begin(), v.end() );
00502 }
00503 
00504 unsigned int
00505 NTuple::
00506 indexOfMaxElement ( unsigned int index ) const
00507 {
00508   const vector< double > & c = getColumn( index );
00509 
00510   vector < double > :: const_iterator first
00511     = max_element ( c.begin(), c.end() );
00512 
00513   return distance ( c.begin(), first );
00514 }
00515 
00516 double
00517 NTuple::
00518 maxElement ( unsigned int column ) const
00519 {
00520   vector < double > & v = *m_data[column];
00521 
00522   return *max_element ( v.begin(), v.end() );
00523 }
00524 
00525 double NTuple::columnMin( const std::string & name ) const
00526 {
00527   const vector< double > & c = getColumn( name );
00528   return *min_element( c.begin(), c.end() );
00529 }
00530 
00531 double NTuple::columnMax( const std::string & name ) const
00532 {
00533   const vector< double > & c = getColumn( name );
00534   return *max_element( c.begin(), c.end() );
00535 }
00536 
00537 /* virtual */
00538 void NTuple::notifyObservers ( ) const
00539 {
00540   if ( m_i_enabled == false ) {
00541     Observable::notifyObservers ( );
00542     return;
00543   }
00544 
00545   m_i_current++;
00546 
00547   if ( m_i_current == m_i_count ) {
00548     Observable::notifyObservers ( );
00549     m_i_current = 0;
00550   }
00551 }
00552 
00553 void NTuple::setIntervalEnabled ( bool yes )
00554 {
00555   m_i_enabled = yes;
00556   m_i_current = 0;
00557 
00558   if ( yes == false ) notifyObservers ();
00559 }
00560 
00561 bool NTuple::isIntervalEnabled () const
00562 {
00563   return m_i_enabled;
00564 }
00565 
00566 void NTuple::setIntervalCount ( int number )
00567 {
00568   m_i_count = number;
00569   m_i_current = 0;
00570 }
00571 
00572 unsigned int NTuple::getIntervalCount ( ) const
00573 {
00574   return m_i_count;
00575 }
00576 
00577 bool
00578 NTuple::
00579 fillRange ( unsigned int column, Range & range ) const
00580 {
00581   vector < double > & v = *m_data[column];
00582 
00583   range.setRange ( v.begin(), v.end() );
00584 
00585   return true;
00586 }
00587 
00588 double
00589 NTuple::
00590 sum ( unsigned int column ) const
00591 {
00592   double sum = 0.0;
00593   const vector < double > & data = *m_data[ column ];
00594 
00595   return accumulate ( data.begin(), data.end(), sum );
00596 }

Generated for HippoDraw-1.14.8.5 by doxygen 1.4.3