00001
00012
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #else
00016 #ifdef _MSC_VER
00017 #include "msdevstudio/MSconfig.h"
00018 #define isnan _isnan
00019 #endif
00020 #endif
00021
00022
00023 #ifdef __APPLE__
00024 #include <cstdlib>
00025 #define _GLIBCPP_USE_C99 1
00026 #endif
00027
00028 #include "DataSource.h"
00029
00030 #include "axes/Range.h"
00031 #include "pattern/Observer.h"
00032 #include "pattern/string_convert.h"
00033
00034 #include <algorithm>
00035 #include <functional>
00036 #include <stdexcept>
00037
00038 #include <cmath>
00039
00040 #include <cassert>
00041
00042 #ifdef __APPLE__
00043 using std::isnan;
00044 #endif
00045
00046 #ifdef ITERATOR_MEMBER_DEFECT
00047 using namespace std;
00048 #else
00049 using std::distance;
00050 using std::runtime_error;
00051 using std::string;
00052 using std::vector;
00053 #endif
00054
00055 using namespace hippodraw;
00056
00057 DataSource::
00058 DataSource ( const std::string & name )
00059 : m_ds_name ( name ),
00060 m_title(),
00061 m_is_null ( false )
00062 {
00063 }
00064
00065 DataSource::
00066 DataSource ( const char * name )
00067 : m_ds_name ( name ),
00068 m_title(),
00069 m_is_null ( false )
00070 {
00071 }
00072
00073 DataSource::
00074 DataSource ( const DataSource & ds )
00075 : Observable (),
00076 m_ds_name ( ds.m_ds_name ),
00077 m_title( ds.m_title ),
00078 m_labels ( ds.m_labels ),
00079 m_is_null ( false ),
00080 m_shape ( ds.m_shape )
00081 {
00082 }
00083
00084 DataSource::
00085 DataSource ( const std::vector < std::string > & labels )
00086 : m_labels ( labels ),
00087 m_is_null ( false )
00088 {
00089 }
00090
00091 DataSource::
00092 DataSource ()
00093 : m_ds_name ( ),
00094 m_title(),
00095 m_is_null ( false )
00096 {
00097 }
00098
00099 DataSource::
00100 DataSource ( bool yes )
00101 : m_ds_name ( "null" ),
00102 m_title ( "Not valid DataSource" ),
00103 m_is_null ( yes )
00104 {
00105 }
00106
00107 DataSource::~DataSource()
00108 {
00109 Observable::notifyObservers ( &hippodraw::Observer::willDelete );
00110 }
00111
00112 void
00113 DataSource::
00114 copyPrivate ( const DataSource & other )
00115 {
00116 m_ds_name = other.m_ds_name;
00117 m_is_null = other.m_is_null;
00118 m_labels = other.m_labels;
00119 m_shape = other.m_shape;
00120 m_title = other.m_title;
00121 }
00122
00123 bool
00124 DataSource::
00125 isNull () const
00126 {
00127 return m_is_null;
00128 }
00129
00130 void DataSource::setName ( const std::string & name )
00131 {
00132 m_ds_name = name;
00133 notifyObservers ();
00134 }
00135
00136 const string & DataSource::getName () const
00137 {
00138 return m_ds_name;
00139 }
00140
00141 const string & DataSource::title () const
00142 {
00143 return m_title;
00144 }
00145
00146 void DataSource::setTitle ( const std::string & title )
00147 {
00148 m_title = title;
00149 notifyObservers ();
00150 }
00151
00152 void
00153 DataSource::
00154 addLabel ( const std::string & label )
00155 {
00156 m_labels.push_back ( label );
00157 }
00158
00159 bool
00160 DataSource::
00161 setLabelAt( const std::string & s, unsigned int i )
00162 {
00163 if ( i >= m_labels.size() ) return false;
00164 m_labels[i] = s;
00165 notifyObservers ();
00166
00167 return true;
00168 }
00169
00170 const vector <string> &
00171 DataSource::
00172 getLabels () const
00173 {
00174 return m_labels;
00175 }
00176
00177 const string &
00178 DataSource::
00179 getLabelAt ( unsigned int i ) const
00180 {
00181 if ( isNull() ) return title ();
00182
00183 if ( m_labels.size () < i ) {
00184 string what ( "DataSource: argument out of range" );
00185 throw runtime_error ( what );
00186 }
00187
00188 return m_labels[i];
00189 }
00190
00191 int
00192 DataSource::
00193 indexOf ( const std::string & label ) const
00194 {
00195 int index = -1;
00196 vector< string >::const_iterator first
00197 = find ( m_labels.begin(), m_labels.end(), label );
00198
00199 if ( first != m_labels.end() ) {
00200 #ifdef DISTANCE_DEFECT
00201 index = first - m_labels.begin();
00202 #else
00203 index = distance ( m_labels.begin(), first );
00204 #endif
00205 }
00206
00207 return index;
00208 }
00209
00210 bool
00211 DataSource::
00212 isValidColumn ( unsigned int index ) const
00213 {
00214 unsigned int size = columns();
00215 if ( index >= size ) {
00216 string what ( "DataSource: Index `" );
00217 what += String::convert ( index );
00218 what += "' out of range 0 to ";
00219 what += String::convert ( size - 1 );
00220 throw runtime_error ( what );
00221 }
00222
00223 return true;
00224 }
00225
00226 const vector < double > &
00227 DataSource::
00228 getColumn ( unsigned int index ) const
00229 {
00230 isValidColumn ( index );
00231 unsigned int size = rows ();
00232
00233 m_array.resize ( size, 0.0 );
00234 for ( unsigned int i = 0; i < size; i++ ) {
00235 m_array [ i ] = valueAt ( i, index );
00236 }
00237
00238 return m_array;
00239 }
00240
00241 const vector < double > &
00242 DataSource::
00243 getColumn ( const std::string & label ) const
00244 {
00245 int index = indexOf ( label );
00246 if ( index < 0 ) {
00247 const string what ( "DataSource: Attempt to get column whose label"
00248 " doesn't exist" );
00249 throw runtime_error ( what );
00250 }
00251
00252 return getColumn ( index );
00253 }
00254
00255 bool
00256 DataSource::
00257 isValidLabel ( const std::string & label ) const
00258 {
00259 vector< string >::const_iterator first
00260 = find ( m_labels.begin(), m_labels.end(), label );
00261 bool yes = first != m_labels.end();
00262
00263 return yes;
00264 }
00265
00266 void
00267 DataSource::
00268 throwIfInvalidLabel ( const std::string & label ) const
00269 {
00270 bool yes = isValidLabel ( label );
00271 if ( yes == false ) {
00272 string what ( "DataSource: `" );
00273 what += label;
00274 what += "' not found in this data source";
00275 throw runtime_error ( what );
00276 }
00277 }
00278
00279 void
00280 DataSource::
00281 throwIfInvalidRowSize ( const std:: vector < double > & row )
00282 {
00283 unsigned int size = columns ();
00284 unsigned int cols = row.size ();
00285 if ( size != cols ) {
00286 string what ( "DataSource: Attempt to add row of size `" );
00287 what += String::convert ( cols );
00288 what += "' to DataSource with `";
00289 what += String::convert ( size );
00290 what += "' columns";
00291 throw runtime_error ( what );
00292 }
00293 }
00294
00295 void
00296 DataSource::
00297 setLabels ( const std::vector < std::string > & v )
00298 {
00299 m_labels = v;
00300
00301 notifyObservers ();
00302 }
00303
00304 void
00305 DataSource::
00306 setShape ( std::vector < unsigned int > & shape )
00307 {
00308 m_shape = shape;
00309 }
00310
00311 const vector < unsigned int > &
00312 DataSource::
00313 getShape () const
00314 {
00315 return m_shape;
00316 }
00317
00318 void
00319 DataSource::
00320 fillShape ( std::vector < int > & shape, unsigned int column ) const
00321 {
00322 shape.clear ();
00323 shape.push_back ( rows () );
00324 }
00325
00326 void
00327 DataSource::
00328 fillShape ( std::vector < int > & v,
00329 const std::string & label ) const
00330 {
00331 int index = indexOf ( label );
00332 if ( index < 0 ) {
00333 string what ( "DataSource: No column with label `" );
00334 what += label;
00335 what += "' exists";
00336 throw runtime_error ( what );
00337 }
00338 fillShape ( v, index );
00339 }
00340
00341
00342 unsigned int
00343 DataSource::getRank () const
00344 {
00345 return m_shape.size();
00346 }
00347
00348 void
00349 DataSource::
00350 replaceColumn ( unsigned int,
00351 const std::vector < double > & array )
00352 {
00353 string what ( "DataSource: The type of data source does not support "
00354 "replacing a column." );
00355 throw runtime_error ( what );
00356 }
00357
00358 void
00359 DataSource::
00360 replaceColumn ( const std::string & label,
00361 const std::vector < double > & array )
00362 {
00363 int index = indexOf ( label );
00364
00365 if ( index < 0 ) {
00366 string what ( "DataSource: Attempt to replace column `" );
00367 what += label;
00368 what += "' which does not exist.";
00369 throw runtime_error ( what );
00370 }
00371 else {
00372 replaceColumn ( index, array );
00373 }
00374 }
00375
00376 void
00377 DataSource::
00378 replaceColumn ( const std::string &,
00379 const std::vector < double > &,
00380 const std::vector < intptr_t > & )
00381 {
00382 string what ( "DataSource: This type of data source does not support"
00383 " the notion of shape." );
00384 throw runtime_error ( what );
00385 }
00386
00387
00388 int
00389 DataSource::
00390 addColumn ( const std::string &,
00391 const std::vector < double > & )
00392 {
00393 string what ( "DataSource: This type of data source does not support "
00394 "adding a column." );
00395 throw runtime_error ( what );
00396 }
00397
00398 int
00399 DataSource::
00400 addColumn ( const std::string &,
00401 const std::vector < double > &,
00402 const std::vector < intptr_t > & )
00403 {
00404 string what ( "DataSource: This type of data source does not support"
00405 " the notion of shape." );
00406 throw runtime_error ( what );
00407 }
00408
00409
00413 bool
00414 DataSource::
00415 fillRange ( unsigned int column, Range & range ) const
00416 {
00417 assert ( column < columns () );
00418 bool isValid = true;
00419
00420 unsigned int size = rows ();
00421 if ( size > 0 ) {
00422 bool valid = false;
00423 double min = DBL_MAX;
00424 double max = DBL_MIN;
00425 double pos = DBL_MAX;
00426 for ( unsigned int i = 0; i < size; i++ ) {
00427 double x = valueAt ( i, column );
00428
00429 if ( x != HUGE_VAL &&
00430 x != -HUGE_VAL &&
00431 isnan ( x ) == false ) {
00432 min = std::min ( min, x );
00433 max = std::max ( max, x );
00434 if ( x > 0.0 ) pos = std::min ( pos, x );
00435 valid = true;
00436 }
00437 else {
00438 isValid = false;
00439 }
00440 }
00441 if ( valid == true ) {
00442 range.setRange ( min, max, pos );
00443 }
00444 }
00445
00446 return isValid;
00447 }
00448
00449 bool
00450 DataSource::
00451 isMultiDimensional( const std::string & ) const
00452 {
00453 return false;
00454 }
00455
00456 bool
00457 DataSource::
00458 isUseable( const std::string & ) const
00459 {
00460 return true;
00461 }
00462
00463 bool
00464 DataSource::
00465 setReleventIndex( const std::string &,
00466 const std::vector< unsigned int > & )
00467 {
00468
00469 assert( 0 );
00470
00471 return false;
00472 }
00473
00474 unsigned int
00475 DataSource::
00476 indexOfMaxElement ( unsigned int column ) const
00477 {
00478 assert ( column < columns () );
00479
00480 unsigned int size = rows ();
00481 unsigned int index = 0;
00482 double m = valueAt ( 0, column );
00483
00484 for ( unsigned int i = 1; i < size; i++ ) {
00485 double v = valueAt ( i, column );
00486 if ( v > m ) {
00487 index = i;
00488 m = v;
00489 }
00490 }
00491
00492 return index;
00493 }
00494
00495 unsigned int
00496 DataSource::
00497 indexOfMinElement ( unsigned int column ) const
00498 {
00499 assert ( column < columns () );
00500
00501 unsigned int size = rows ();
00502 unsigned int index = 0;
00503 double m = valueAt ( 0, column );
00504
00505 for ( unsigned int i = 1; i < size; i++ ) {
00506 double v = valueAt ( i, column );
00507 if ( v < m ) {
00508 index = i;
00509 m = v;
00510 }
00511 }
00512
00513 return index;
00514 }
00515
00516 double
00517 DataSource::
00518 sum ( unsigned int column ) const
00519 {
00520 assert ( column < columns () );
00521
00522 unsigned int size = rows ();
00523 double sum = 0.0;
00524
00525 for ( unsigned int i = 0; i < size; i++ ) {
00526 sum += valueAt ( i, column );
00527 }
00528
00529 return sum;
00530 }
00531
00532 const vector < string > &
00533 DataSource::
00534 getDuplicatedLabels () const
00535 {
00536 return m_dups;
00537 }
00538
00539 double
00540 DataSource::
00541 valueAtNoCache ( unsigned int row, unsigned int column ) const
00542 {
00543 return valueAt ( row, column );
00544 }
00545
00546 void
00547 DataSource::
00548 addRow ( const std::vector < double > & row )
00549 {
00550 string what ( "This data source is not capable of adding rows" );
00551 throw runtime_error ( what );
00552 }
00553
00554 void
00555 DataSource::
00556 eraseRow ( unsigned int index )
00557 {
00558 string what ("This data source is not capable of erasing rows" );
00559 throw runtime_error ( what );
00560 }
00561
00562
00563 void
00564 DataSource::
00565 checkWidth ( const DataSource * source )
00566 {
00567 unsigned int ncolumns = source -> columns ();
00568 if ( ncolumns != columns () ) {
00569 string what ( "DataSource: Number of columns of source (" );
00570 what += String::convert ( ncolumns );
00571 what += ") not equal to current (";
00572 what += String::convert ( columns() );
00573 what += ").";
00574 throw runtime_error ( what );
00575 }
00576 }
00577
00578 void
00579 DataSource::
00580 append ( const DataSource * source )
00581 {
00582 checkWidth ( source );
00583
00584 unsigned int size = source -> rows ();
00585 for ( unsigned int i = 0; i < size; i++ ) {
00586 const vector < double > & src_row = source -> getRow ( i );
00587 addRow ( src_row );
00588 }
00589 }
00590
00591 double *
00592 DataSource::
00593 doubleArrayAt ( unsigned int row, unsigned int column ) const
00594 {
00595 string what ( "DataSource: This data source is not capable of containing\n"
00596 "an array in a column." );
00597 throw runtime_error ( what );
00598 }
00599
00600 void
00601 DataSource::
00602 expandIfNeeded ( const std::vector < std::string > & labels ) const
00603 {
00604
00605 }