00001
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #else
00015 #ifdef _MSC_VER
00016 #include "msdevstudio/MSconfig.h"
00017 #define isnan _isnan
00018 #endif
00019 #endif
00020
00021
00022 #ifdef __APPLE__
00023 #include <cstdlib>
00024 #define _GLIBCPP_USE_C99 1
00025 #endif
00026
00027 #include "DataSource.h"
00028
00029 #include "DataSourceException.h"
00030
00031 #include "axes/Range.h"
00032 #include "pattern/Observer.h"
00033
00034 #include <algorithm>
00035 #include <functional>
00036
00037 #include <cmath>
00038 #include <cfloat>
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::string;
00051 using std::vector;
00052 #endif
00053
00054 DataSource::
00055 DataSource ( const std::string & name )
00056 : m_ds_name ( name ),
00057 m_title(),
00058 m_is_null ( false )
00059 {
00060 }
00061
00062 DataSource::
00063 DataSource ( const char * name )
00064 : m_ds_name ( name ),
00065 m_title(),
00066 m_is_null ( false )
00067 {
00068 }
00069
00070 DataSource::
00071 DataSource ( const DataSource & ds )
00072 : m_ds_name ( ds.m_ds_name ),
00073 m_title( ds.m_title ),
00074 m_labels ( ds.m_labels ),
00075 m_is_null ( false ),
00076 m_shape ( ds.m_shape )
00077 {
00078 }
00079
00080 DataSource::
00081 DataSource ( const std::vector < std::string > & labels )
00082 : m_labels ( labels ),
00083 m_is_null ( false )
00084 {
00085 }
00086
00087 DataSource::
00088 DataSource ()
00089 : m_ds_name ( ),
00090 m_title(),
00091 m_is_null ( false )
00092 {
00093 }
00094
00095 DataSource::
00096 DataSource ( bool yes )
00097 : m_ds_name ( "null" ),
00098 m_title ( "Not valid DataSource" ),
00099 m_is_null ( yes )
00100 {
00101 }
00102
00103 DataSource::~DataSource()
00104 {
00105 Observable::notifyObservers ( &hippodraw::Observer::willDelete );
00106 }
00107
00108 void
00109 DataSource::
00110 copyPrivate ( const DataSource & other )
00111 {
00112 m_ds_name = other.m_ds_name;
00113 m_is_null = other.m_is_null;
00114 m_labels = other.m_labels;
00115 m_shape = other.m_shape;
00116 m_title = other.m_title;
00117 }
00118
00119 bool
00120 DataSource::
00121 isNull () const
00122 {
00123 return m_is_null;
00124 }
00125
00126 void DataSource::setName ( const std::string & name )
00127 {
00128 m_ds_name = name;
00129 notifyObservers ();
00130 }
00131
00132 const string & DataSource::getName () const
00133 {
00134 return m_ds_name;
00135 }
00136
00137 const string & DataSource::title () const
00138 {
00139 return m_title;
00140 }
00141
00142 void DataSource::setTitle ( const std::string & title )
00143 {
00144 m_title = title;
00145 notifyObservers ();
00146 }
00147
00148 void
00149 DataSource::
00150 addLabel ( const std::string & label )
00151 {
00152 m_labels.push_back ( label );
00153 }
00154
00155 bool
00156 DataSource::
00157 setLabelAt( const std::string & s, unsigned int i )
00158 {
00159 if ( i >= m_labels.size() ) return false;
00160 m_labels[i] = s;
00161 notifyObservers ();
00162
00163 return true;
00164 }
00165
00166 const vector <string> &
00167 DataSource::
00168 getLabels () const
00169 {
00170 return m_labels;
00171 }
00172
00173 const string &
00174 DataSource::
00175 getLabelAt ( unsigned int i ) const
00176 {
00177 if ( isNull() ) return title ();
00178
00179 if ( m_labels.size () < i ) {
00180 string what ( "DataSource: argument out of range" );
00181 throw DataSourceException ( what );
00182 }
00183
00184 return m_labels[i];
00185 }
00186
00187 int
00188 DataSource::
00189 indexOf ( const std::string & label ) const
00190 {
00191 int index = -1;
00192 vector< string >::const_iterator first
00193 = find ( m_labels.begin(), m_labels.end(), label );
00194
00195 if ( first != m_labels.end() ) {
00196 #ifdef DISTANCE_DEFECT
00197 index = first - m_labels.begin();
00198 #else
00199 index = distance ( m_labels.begin(), first );
00200 #endif
00201 }
00202
00203 return index;
00204 }
00205
00206 bool
00207 DataSource::
00208 isValidColumn ( unsigned int index ) const
00209 {
00210 unsigned int size = columns();
00211 if ( index >= size ) {
00212 const string what ( "DataSource: Index out of range" );
00213 throw DataSourceException ( what );
00214 }
00215
00216 return true;
00217 }
00218
00219 const vector < double > &
00220 DataSource::
00221 getColumn ( unsigned int index ) const
00222 {
00223 isValidColumn ( index );
00224 unsigned int size = rows ();
00225
00226 m_array.resize ( size, 0.0 );
00227 for ( unsigned int i = 0; i < size; i++ ) {
00228 m_array [ i ] = valueAt ( i, index );
00229 }
00230
00231 return m_array;
00232 }
00233
00234 const vector < double > &
00235 DataSource::
00236 getColumn ( const std::string & label ) const
00237 {
00238 int index = indexOf ( label );
00239 if ( index < 0 ) {
00240 const string what ( "DataSource: Attempt to get column whose label"
00241 " doesn't exist" );
00242 throw DataSourceException ( what );
00243 }
00244
00245 return getColumn ( index );
00246 }
00247
00248 bool
00249 DataSource::
00250 isValidLabel ( const std::string & label ) const
00251 {
00252 vector< string >::const_iterator first
00253 = find ( m_labels.begin(), m_labels.end(), label );
00254 bool yes = first != m_labels.end();
00255
00256 return yes;
00257 }
00258
00262 void
00263 DataSource::
00264 throwIfInvalidLabel ( const std::string & label ) const
00265 {
00266 bool yes = isValidLabel ( label );
00267 if ( yes == false ) {
00268 string what ( "DataSource: `" );
00269 what += label;
00270 what += "' not found in this data source";
00271 throw DataSourceException ( what );
00272 }
00273 }
00274
00275 void
00276 DataSource::
00277 throwIfInvalidRowSize ( const std:: vector < double > & row )
00278 {
00279 unsigned int size = columns ();
00280 if ( size != row.size () ) {
00281 const string what ( "DataSource: Attempt to add row whose size"
00282 " is not equal to number of columns" );
00283 throw DataSourceException ( what );
00284 }
00285 }
00286
00287 void
00288 DataSource::
00289 setLabels ( const std::vector < std::string > & v )
00290 {
00291 m_labels = v;
00292
00293 notifyObservers ();
00294 }
00295
00296 void
00297 DataSource::
00298 setShape ( std::vector < unsigned int > & shape )
00299 {
00300 unsigned int size = 1;
00301 for ( unsigned int i = 0; i < shape.size(); i++ ) {
00302 size *= shape[i];
00303 }
00304
00305 m_shape = shape;
00306 }
00307
00308 const vector < unsigned int > &
00309 DataSource::
00310 getShape () const
00311 {
00312 return m_shape;
00313 }
00314
00315 unsigned int
00316 DataSource::getRank () const
00317 {
00318 return m_shape.size();
00319 }
00320
00321 bool
00322 DataSource::
00323 fillRange ( unsigned int column, Range & range ) const
00324 {
00325 assert ( column < columns () );
00326 bool isValid = true;
00327
00328 unsigned int size = rows ();
00329 if ( size > 0 ) {
00330 bool valid = false;
00331 double min = DBL_MAX;
00332 double max = DBL_MIN;
00333 double pos = DBL_MAX;
00334 for ( unsigned int i = 0; i < size; i++ ) {
00335 double x = valueAt ( i, column );
00336
00337 if ( x != HUGE_VAL &&
00338 x != -HUGE_VAL &&
00339 isnan ( x ) == false ) {
00340 min = std::min ( min, x );
00341 max = std::max ( max, x );
00342 if ( x > 0.0 ) pos = std::min ( pos, x );
00343 valid = true;
00344 }
00345 else {
00346 isValid = false;
00347 }
00348 }
00349 if ( valid == true ) {
00350 range.setRange ( min, max, pos );
00351 }
00352 }
00353
00354 return isValid;
00355 }
00356
00357 bool
00358 DataSource::
00359 isMultiDimensional( const std::string & column ) const
00360 {
00361 return false;
00362 }
00363
00364 bool
00365 DataSource::
00366 setReleventIndex( const std::string & column,
00367 const std::vector< unsigned int >& index )
00368 {
00369
00370 assert( 0 );
00371
00372 return false;
00373 }
00374
00375 unsigned int
00376 DataSource::
00377 indexOfMaxElement ( unsigned int column ) const
00378 {
00379 assert ( column < columns () );
00380
00381 unsigned int size = rows ();
00382 unsigned int index = 0;
00383 double m = valueAt ( 0, column );
00384
00385 for ( unsigned int i = 1; i < size; i++ ) {
00386 double v = valueAt ( i, column );
00387 if ( v > m ) {
00388 index = i;
00389 m = v;
00390 }
00391 }
00392
00393 return index;
00394 }
00395
00396 unsigned int
00397 DataSource::
00398 indexOfMinElement ( unsigned int column ) const
00399 {
00400 assert ( column < columns () );
00401
00402 unsigned int size = rows ();
00403 unsigned int index = 0;
00404 double m = valueAt ( 0, column );
00405
00406 for ( unsigned int i = 1; i < size; i++ ) {
00407 double v = valueAt ( i, column );
00408 if ( v < m ) {
00409 index = i;
00410 m = v;
00411 }
00412 }
00413
00414 return index;
00415 }
00416
00417 double
00418 DataSource::
00419 sum ( unsigned int column ) const
00420 {
00421 assert ( column < columns () );
00422
00423 unsigned int size = rows ();
00424 double sum = 0.0;
00425
00426 for ( unsigned int i = 0; i < size; i++ ) {
00427 sum += valueAt ( i, column );
00428 }
00429
00430 return sum;
00431 }