openModeller
Version 1.4.0
|
00001 00002 #include <Sample.hh> 00003 00004 // check for malloc.h or stdlib.h 00005 #ifdef HAVE_MALLOC_H 00006 #include <malloc.h> 00007 #else 00008 #include <stdlib.h> 00009 #endif 00010 00011 // cmath is included for std::sqrt 00012 #include <cmath> 00013 00014 // String stream is included for the dump method 00015 #include <sstream> 00016 00017 // Algorithm is included for std::min and std::max. 00018 #include <algorithm> 00019 00020 // vector is used in a temporary variable in operator>> 00021 #include <vector> 00022 00023 // iterator is needed for istream_iterator 00024 #include <iterator> 00025 00026 // FIXME - SampleExpr.hh needs to be included after <vector> 00027 #include <SampleExpr.hh> 00028 00029 // Log is included for the dump method 00030 #include <openmodeller/Log.hh> 00031 00032 // To throw an out of memory exception 00033 #include <openmodeller/Exceptions.hh> 00034 00035 00036 using namespace std; 00037 00038 Sample::Sample() : 00039 size_( 0 ), 00040 value_( 0 ), 00041 start_( 0 ) 00042 { } 00043 00044 Sample::Sample( size_t size ) : 00045 size_( 0 ), 00046 value_( 0 ), 00047 start_( 0 ) 00048 { 00049 if ( size == 0 ) { 00050 return; 00051 } 00052 00053 alloc( size ); 00054 Scalar *v = value_; 00055 00056 for ( size_t i = 0; i < size; ++i, ++v ) { 00057 *v = Scalar(0); 00058 } 00059 } 00060 00061 Sample::Sample( std::size_t size, Scalar value ) : 00062 size_( 0 ), 00063 value_( 0 ), 00064 start_( 0 ) 00065 { 00066 if ( size == 0 ) { 00067 return; 00068 } 00069 alloc( size ); 00070 00071 Scalar *v = value_; 00072 for( size_t i = 0; i<size; ++i ) { 00073 *v++ = value; 00074 } 00075 } 00076 00077 Sample::Sample( size_t size, Scalar const * values ) : 00078 size_( 0 ), 00079 value_( 0 ), 00080 start_( 0 ) 00081 { 00082 if ( size == 0 ) { 00083 return; 00084 } 00085 alloc( size ); 00086 copy( size, values ); 00087 } 00088 00089 Sample::Sample( std::vector<Scalar> values ) : 00090 size_( 0 ), 00091 value_( 0 ), 00092 start_( 0 ) 00093 { 00094 size_ = values.size(); 00095 if ( size_ == 0 ) { 00096 return; 00097 } 00098 00099 alloc( size_ ); 00100 00101 std::vector<Scalar>::const_iterator it = values.begin(); 00102 std::vector<Scalar>::const_iterator end = values.end(); 00103 00104 Scalar *v = value_; 00105 while (it != end) { 00106 *v = (*it); 00107 ++v; 00108 ++it; 00109 } 00110 } 00111 00112 Sample::Sample( const Sample & rhs ) : 00113 size_( 0 ), 00114 value_( 0 ), 00115 start_( 0 ) 00116 { 00117 if ( rhs.size_ == 0 ) { 00118 return; 00119 } 00120 alloc( rhs.size_ ); 00121 copy( rhs.size_, rhs.value_ ); 00122 } 00123 00124 Sample::~Sample() 00125 { 00126 if ( value_ ) { 00127 free( value_ ); 00128 } 00129 } 00130 00131 Sample& 00132 Sample::operator=( const Sample & rhs ) 00133 { 00134 if ( this == &rhs ) { 00135 return *this; 00136 } 00137 00138 if ( this->size_ != rhs.size_ ) { 00139 if ( value_ ) { 00140 free( value_ ); 00141 } 00142 alloc( rhs.size_ ); 00143 } 00144 00145 copy( rhs.size_, rhs.value_ ); 00146 00147 start_ = rhs.start_; 00148 00149 return *this; 00150 } 00151 00152 void 00153 Sample::resize( size_t size ) 00154 { 00155 // Do the easy case first. 00156 // The size hasn't changed, then just return. 00157 if ( size == this->size_ ) { 00158 return; 00159 } 00160 00161 // Now check if the size is changing to 0. 00162 if ( size == 0 ) { 00163 // Since above, we tested for size == this->size, 00164 // we know that this->size != 0, and therefore 00165 // value_ != NULL; 00166 free( value_ ); 00167 value_ = 0; 00168 this->size_ = 0; 00169 this->start_ = 0; 00170 return; 00171 } 00172 00173 // Use realloc to make new space and copy. 00174 value_ = (Scalar*)realloc( value_, size*sizeof(Scalar) ); 00175 00176 // Now we need to loop through the new values, and initialize 00177 for ( Scalar *v = value_ + this->size_; 00178 v < value_ + size; 00179 ++v ) { 00180 *v = Scalar(0); 00181 } 00182 00183 // Finally, update this->size. 00184 this->size_ = size; 00185 00186 this->start_ = min( size, this->start_ ); 00187 } 00188 00189 00190 void 00191 Sample::setCategoricalThreshold( std::size_t index ) 00192 { 00193 index = max( (std::size_t)0, index ); // avoid negative values 00194 start_ = min( index, size_ ); // avoid values greater than the size 00195 } 00196 00197 00198 void 00199 Sample::alloc( size_t size ) 00200 { 00201 this->size_ = size; 00202 this->start_ = 0; 00203 value_ = (Scalar*)malloc( size * sizeof( Scalar ) ); 00204 00205 if ( ! value_ ) { 00206 00207 throw MemoryException( "Out of memory during Sample alloc" ); 00208 } 00209 } 00210 00211 void 00212 Sample::copy( size_t size, Scalar const * values ) 00213 { 00214 Scalar *v = value_; 00215 for( size_t i = 0; i<size; ++i ) { 00216 *v++ = *values++; 00217 } 00218 } 00219 00220 Scalar& 00221 Sample::operator[]( std::size_t index ) 00222 { 00223 if ( index >= size_ ) { 00224 00225 ostringstream ss; 00226 ss << "Sample index (" << index << ") out of bounds (" << size_ << ")"; 00227 00228 throw MemoryException( ss.str().c_str() ); 00229 } 00230 00231 return value_[index]; 00232 } 00233 00234 Scalar 00235 Sample::operator[]( std::size_t index ) const 00236 { 00237 if ( index >= size_ ) { 00238 00239 ostringstream ss; 00240 ss << "Sample index (" << index << ") out of bounds (" << size_ << ")"; 00241 00242 throw MemoryException( ss.str().c_str() ); 00243 } 00244 00245 return value_[index]; 00246 } 00247 00248 bool 00249 Sample::equals( const Sample& rhs ) const 00250 { 00251 // Zero vectors are equal. 00252 if ( size_ == 0 && rhs.size_ == 0 ) 00253 return true; 00254 00255 // If sizes are different, Samples must be different. 00256 if ( size_ != rhs.size_ ) 00257 return false; 00258 00259 // Check each value in Sample. 00260 Scalar *l = value_; 00261 Scalar *r = rhs.value_; 00262 for( size_t i = 0; i < size_; ++i ) { 00263 // If they are not equal, then Samples not equal 00264 if ( *l != *r ) 00265 return false; 00266 ++l; 00267 ++r; 00268 } 00269 00270 return true; 00271 } 00272 00273 void 00274 Sample::dump() const 00275 { 00276 ostringstream ss; 00277 ss << "["; 00278 Scalar *vl = value_; 00279 size_t count = size_; 00280 for( size_t i = 0; i < count; ++i ) { 00281 ss << *vl++; 00282 if ( i < count-1 ) 00283 ss << ", "; 00284 } 00285 ss << "]"; 00286 Log::instance()->info( "Sample %s\n", ss.str().c_str() ); 00287 } 00288 00289 Sample& 00290 Sample::operator+=( const Sample& rhs ) 00291 { 00292 Scalar *vl = value_; 00293 Scalar *vr = rhs.value_; 00294 size_t count = min( size_, rhs.size_); 00295 for( size_t i = 0; i < count; ++i,*vl++,*vr++ ) { 00296 if ( i >= start_ ) { 00297 *vl += *vr; 00298 } 00299 } 00300 (void) vr; // avoid unused var warning 00301 return *this; 00302 } 00303 00304 Sample& 00305 Sample::operator+=( const Scalar& rhs ) 00306 { 00307 iterator it = begin(); 00308 for( size_t i = 0; it != end() ; ++it,++i ) { 00309 if ( i >= start_ ) { 00310 *it += rhs; 00311 } 00312 } 00313 return *this; 00314 } 00315 00316 Sample& 00317 Sample::operator-=( const Sample& rhs ) 00318 { 00319 Scalar *vl = value_; 00320 Scalar *vr = rhs.value_; 00321 size_t count = min( size_, rhs.size_); 00322 for( size_t i = 0; i < count; ++i,*vl++,*vr++ ) { 00323 if ( i >= start_ ) { 00324 *vl -= *vr; 00325 } 00326 } 00327 return *this; 00328 } 00329 00330 Sample& 00331 Sample::operator-=( const Scalar& rhs ) 00332 { 00333 iterator it = begin(); 00334 for( size_t i = 0; it != end() ; ++it,++i ) { 00335 if ( i >= start_ ) { 00336 *it -= rhs; 00337 } 00338 } 00339 return *this; 00340 } 00341 00342 Sample& 00343 Sample::operator*=( const Sample& rhs ) 00344 { 00345 Scalar *vl = value_; 00346 Scalar *vr = rhs.value_; 00347 size_t count = min( size_, rhs.size_); 00348 for( size_t i = 0; i < count; ++i,*vl++,*vr++ ) { 00349 if ( i >= start_ ) { 00350 *vl *= *vr; 00351 } 00352 } 00353 return *this; 00354 } 00355 00356 Sample& 00357 Sample::operator*=( const Scalar& rhs ) 00358 { 00359 Scalar *vl = value_; 00360 size_t count = size_; 00361 for( size_t i = 0; i < count; ++i,*vl++ ) { 00362 if ( i >= start_ ) { 00363 *vl *= rhs; 00364 } 00365 } 00366 return *this; 00367 } 00368 00369 Sample& 00370 Sample::operator/=( const Sample& rhs ) 00371 { 00372 Scalar *vl = value_; 00373 Scalar *vr = rhs.value_; 00374 size_t count = min( size_, rhs.size_); 00375 for( size_t i = 0; i < count; ++i,*vl++,*vr++ ) { 00376 if ( i >= start_ ) { 00377 *vl /= *vr; 00378 } 00379 } 00380 return *this; 00381 } 00382 00383 Sample& 00384 Sample::operator/=( const Scalar& rhs ) 00385 { 00386 Scalar *vl = value_; 00387 size_t count = size_; 00388 for( size_t i = start_; i < count; ++i,*vl++ ) { 00389 if ( i >= start_ ) { 00390 *vl /= rhs; 00391 } 00392 } 00393 return *this; 00394 } 00395 00396 Sample& 00397 Sample::operator&=( const Sample& rhs ) 00398 { 00399 Scalar *vl = value_; 00400 Scalar *vr = rhs.value_; 00401 size_t count = min( size_, rhs.size_); 00402 for( size_t i = 0; i < count; ++i,vl++,vr++ ) { 00403 // The increments are not in the min() statement 00404 // because gcc has problems producing good code 00405 // when using -fno-inline. For safety sake 00406 // the increments are explicitly after the min. 00407 if ( i >= start_ ) { 00408 *vl = min(*vl,*vr); 00409 } 00410 } 00411 return *this; 00412 } 00413 00414 Sample& 00415 Sample::operator|=( const Sample& rhs ) 00416 { 00417 Scalar *vl = value_; 00418 Scalar *vr = rhs.value_; 00419 size_t count = min( size_, rhs.size_); 00420 for( size_t i = start_; i < count; ++i,vl++,vr++ ) { 00421 // The increments are not in the max() statement 00422 // because gcc has problems producing good code 00423 // when using -fno-inline. For safety sake 00424 // the increments are explicitly after the max. 00425 if ( i >= start_ ) { 00426 *vl = max(*vl,*vr); 00427 } 00428 } 00429 return *this; 00430 } 00431 00432 Sample& 00433 Sample::sqr() 00434 { 00435 iterator it = begin(); 00436 for( size_t i = 0; it != end() ; ++it,++i ) { 00437 if ( i >= start_ ) { 00438 *it = (*it) * (*it); 00439 } 00440 } 00441 return *this; 00442 } 00443 00444 Sample& 00445 Sample::sqrt() 00446 { 00447 iterator it = begin(); 00448 for( size_t i = 0; it != end() ; ++it,++i ) { 00449 if ( i >= start_ ) { 00450 *it = std::sqrt( *it ); 00451 } 00452 } 00453 return *this; 00454 } 00455 00456 Scalar 00457 Sample::norm() const 00458 { 00459 Scalar norm = 0.0; 00460 const_iterator it = begin(); 00461 for( size_t i = 0; it != end() ; ++it,++i ) { 00462 if ( i >= start_ ) { 00463 norm += *it* *it; 00464 } 00465 } 00466 return std::sqrt(norm); 00467 } 00468 00469 Scalar 00470 Sample::dotProduct( const Sample& rhs ) const 00471 { 00472 Scalar norm = 0.0; 00473 const_iterator lhs_it = begin(); 00474 const_iterator rhs_it = rhs.begin(); 00475 for( size_t i = 0; lhs_it != end() && rhs_it != rhs.end() ; ++lhs_it, ++rhs_it, ++i ) { 00476 if ( i >= start_ ) { 00477 norm += *lhs_it* *rhs_it; 00478 } 00479 } 00480 return std::sqrt(norm); 00481 } 00482 00483 ostream& 00484 operator<<( ostream& os, const Sample& value ) 00485 { 00486 if ( value.size() == 0 ) 00487 return os; 00488 00489 int oldprecision = os.precision(25); 00490 00491 copy( value.begin(), value.end(), 00492 ostream_iterator<Scalar>(os," ") ); 00493 00494 os.precision( oldprecision ); 00495 return os; 00496 } 00497 00498 istream& 00499 operator>>( istream& is, Sample& value ) 00500 { 00501 // Temporarily spool values into a vector<double> 00502 vector<double>v; 00503 00504 copy( istream_iterator<double>(is), 00505 istream_iterator<double>(), 00506 back_inserter( v ) ); 00507 00508 // Copy from temporary vector<double> into value 00509 value.resize( v.size() ); 00510 00511 copy( v.begin(), 00512 v.end(), 00513 value.begin() ); 00514 00515 return is; 00516 00517 }