openModeller  Version 1.5.0
Sample.cpp
Go to the documentation of this file.
1 
2 #include <Sample.hh>
3 
4 // check for malloc.h or stdlib.h
5 #ifdef HAVE_MALLOC_H
6 #include <malloc.h>
7 #else
8 #include <stdlib.h>
9 #endif
10 
11 // cmath is included for std::sqrt
12 #include <cmath>
13 
14 // String stream is included for the dump method
15 #include <sstream>
16 
17 // Algorithm is included for std::min and std::max.
18 #include <algorithm>
19 
20 // vector is used in a temporary variable in operator>>
21 #include <vector>
22 
23 // iterator is needed for istream_iterator
24 #include <iterator>
25 
26 // FIXME - SampleExpr.hh needs to be included after <vector>
27 #include <SampleExpr.hh>
28 
29 // Log is included for the dump method
30 #include <openmodeller/Log.hh>
31 
32 // To throw an out of memory exception
34 
35 
36 using namespace std;
37 
39  size_( 0 ),
40  value_( 0 ),
41  start_( 0 )
42 { }
43 
44 Sample::Sample( size_t size ) :
45  size_( 0 ),
46  value_( 0 ),
47  start_( 0 )
48 {
49  if ( size == 0 ) {
50  return;
51  }
52 
53  alloc( size );
54  Scalar *v = value_;
55 
56  for ( size_t i = 0; i < size; ++i, ++v ) {
57  *v = Scalar(0);
58  }
59 }
60 
61 Sample::Sample( std::size_t size, Scalar value ) :
62  size_( 0 ),
63  value_( 0 ),
64  start_( 0 )
65 {
66  if ( size == 0 ) {
67  return;
68  }
69  alloc( size );
70 
71  Scalar *v = value_;
72  for( size_t i = 0; i<size; ++i ) {
73  *v++ = value;
74  }
75 }
76 
77 Sample::Sample( size_t size, Scalar const * values ) :
78  size_( 0 ),
79  value_( 0 ),
80  start_( 0 )
81 {
82  if ( size == 0 ) {
83  return;
84  }
85  alloc( size );
86  copy( size, values );
87 }
88 
89 Sample::Sample( std::vector<Scalar> values ) :
90  size_( 0 ),
91  value_( 0 ),
92  start_( 0 )
93 {
94  size_ = values.size();
95  if ( size_ == 0 ) {
96  return;
97  }
98 
99  alloc( size_ );
100 
101  std::vector<Scalar>::const_iterator it = values.begin();
102  std::vector<Scalar>::const_iterator end = values.end();
103 
104  Scalar *v = value_;
105  while (it != end) {
106  *v = (*it);
107  ++v;
108  ++it;
109  }
110 }
111 
112 Sample::Sample( const Sample & rhs ) :
113  size_( 0 ),
114  value_( 0 ),
115  start_( 0 )
116 {
117  if ( rhs.size_ == 0 ) {
118  return;
119  }
120  alloc( rhs.size_ );
121  copy( rhs.size_, rhs.value_ );
122 }
123 
125 {
126  if ( value_ ) {
127  free( value_ );
128  }
129 }
130 
131 Sample&
132 Sample::operator=( const Sample & rhs )
133 {
134  if ( this == &rhs ) {
135  return *this;
136  }
137 
138  if ( this->size_ != rhs.size_ ) {
139  if ( value_ ) {
140  free( value_ );
141  }
142  alloc( rhs.size_ );
143  }
144 
145  copy( rhs.size_, rhs.value_ );
146 
147  start_ = rhs.start_;
148 
149  return *this;
150 }
151 
152 void
153 Sample::resize( size_t size )
154 {
155  // Do the easy case first.
156  // The size hasn't changed, then just return.
157  if ( size == this->size_ ) {
158  return;
159  }
160 
161  // Now check if the size is changing to 0.
162  if ( size == 0 ) {
163  // Since above, we tested for size == this->size,
164  // we know that this->size != 0, and therefore
165  // value_ != NULL;
166  free( value_ );
167  value_ = 0;
168  this->size_ = 0;
169  this->start_ = 0;
170  return;
171  }
172 
173  // Use realloc to make new space and copy.
174  value_ = (Scalar*)realloc( value_, size*sizeof(Scalar) );
175 
176  // Now we need to loop through the new values, and initialize
177  for ( Scalar *v = value_ + this->size_;
178  v < value_ + size;
179  ++v ) {
180  *v = Scalar(0);
181  }
182 
183  // Finally, update this->size.
184  this->size_ = size;
185 
186  this->start_ = min( size, this->start_ );
187 }
188 
189 
190 void
192 {
193  index = max( (std::size_t)0, index ); // avoid negative values
194  start_ = min( index, size_ ); // avoid values greater than the size
195 }
196 
197 
198 void
199 Sample::alloc( size_t size )
200 {
201  this->size_ = size;
202  this->start_ = 0;
203  value_ = (Scalar*)malloc( size * sizeof( Scalar ) );
204 
205  if ( ! value_ ) {
206 
207  throw MemoryException( "Out of memory during Sample alloc" );
208  }
209 }
210 
211 void
212 Sample::copy( size_t size, Scalar const * values )
213 {
214  Scalar *v = value_;
215  for( size_t i = 0; i<size; ++i ) {
216  *v++ = *values++;
217  }
218 }
219 
220 Scalar&
221 Sample::operator[]( std::size_t index )
222 {
223  if ( index >= size_ ) {
224 
225  ostringstream ss;
226  ss << "Sample index (" << index << ") out of bounds (" << size_ << ")";
227 
228  throw MemoryException( ss.str().c_str() );
229  }
230 
231  return value_[index];
232 }
233 
234 Scalar
235 Sample::operator[]( std::size_t index ) const
236 {
237  if ( index >= size_ ) {
238 
239  ostringstream ss;
240  ss << "Sample index (" << index << ") out of bounds (" << size_ << ")";
241 
242  throw MemoryException( ss.str().c_str() );
243  }
244 
245  return value_[index];
246 }
247 
248 bool
249 Sample::equals( const Sample& rhs ) const
250 {
251  // Zero vectors are equal.
252  if ( size_ == 0 && rhs.size_ == 0 )
253  return true;
254 
255  // If sizes are different, Samples must be different.
256  if ( size_ != rhs.size_ )
257  return false;
258 
259  // Check each value in Sample.
260  Scalar *l = value_;
261  Scalar *r = rhs.value_;
262  for( size_t i = 0; i < size_; ++i ) {
263  // If they are not equal, then Samples not equal
264  if ( *l != *r )
265  return false;
266  ++l;
267  ++r;
268  }
269 
270  return true;
271 }
272 
273 void
275 {
276  ostringstream ss;
277  ss << "[";
278  Scalar *vl = value_;
279  size_t count = size_;
280  for( size_t i = 0; i < count; ++i ) {
281  ss << *vl++;
282  if ( i < count-1 )
283  ss << ", ";
284  }
285  ss << "]";
286  Log::instance()->info( "Sample %s\n", ss.str().c_str() );
287 }
288 
289 Sample&
291 {
292  Scalar *vl = value_;
293  Scalar *vr = rhs.value_;
294  size_t count = min( size_, rhs.size_);
295  for( size_t i = 0; i < count; ++i,*vl++,*vr++ ) {
296  if ( i >= start_ ) {
297  *vl += *vr;
298  }
299  }
300  (void) vr; // avoid unused var warning
301  return *this;
302 }
303 
304 Sample&
306 {
307  iterator it = begin();
308  for( size_t i = 0; it != end() ; ++it,++i ) {
309  if ( i >= start_ ) {
310  *it += rhs;
311  }
312  }
313  return *this;
314 }
315 
316 Sample&
318 {
319  Scalar *vl = value_;
320  Scalar *vr = rhs.value_;
321  size_t count = min( size_, rhs.size_);
322  for( size_t i = 0; i < count; ++i,*vl++,*vr++ ) {
323  if ( i >= start_ ) {
324  *vl -= *vr;
325  }
326  }
327  return *this;
328 }
329 
330 Sample&
332 {
333  iterator it = begin();
334  for( size_t i = 0; it != end() ; ++it,++i ) {
335  if ( i >= start_ ) {
336  *it -= rhs;
337  }
338  }
339  return *this;
340 }
341 
342 Sample&
344 {
345  Scalar *vl = value_;
346  Scalar *vr = rhs.value_;
347  size_t count = min( size_, rhs.size_);
348  for( size_t i = 0; i < count; ++i,*vl++,*vr++ ) {
349  if ( i >= start_ ) {
350  *vl *= *vr;
351  }
352  }
353  return *this;
354 }
355 
356 Sample&
358 {
359  Scalar *vl = value_;
360  size_t count = size_;
361  for( size_t i = 0; i < count; ++i,*vl++ ) {
362  if ( i >= start_ ) {
363  *vl *= rhs;
364  }
365  }
366  return *this;
367 }
368 
369 Sample&
371 {
372  Scalar *vl = value_;
373  Scalar *vr = rhs.value_;
374  size_t count = min( size_, rhs.size_);
375  for( size_t i = 0; i < count; ++i,*vl++,*vr++ ) {
376  if ( i >= start_ ) {
377  *vl /= *vr;
378  }
379  }
380  return *this;
381 }
382 
383 Sample&
385 {
386  Scalar *vl = value_;
387  size_t count = size_;
388  for( size_t i = start_; i < count; ++i,*vl++ ) {
389  if ( i >= start_ ) {
390  *vl /= rhs;
391  }
392  }
393  return *this;
394 }
395 
396 Sample&
398 {
399  Scalar *vl = value_;
400  Scalar *vr = rhs.value_;
401  size_t count = min( size_, rhs.size_);
402  for( size_t i = 0; i < count; ++i,vl++,vr++ ) {
403  // The increments are not in the min() statement
404  // because gcc has problems producing good code
405  // when using -fno-inline. For safety sake
406  // the increments are explicitly after the min.
407  if ( i >= start_ ) {
408  *vl = min(*vl,*vr);
409  }
410  }
411  return *this;
412 }
413 
414 Sample&
416 {
417  Scalar *vl = value_;
418  Scalar *vr = rhs.value_;
419  size_t count = min( size_, rhs.size_);
420  for( size_t i = start_; i < count; ++i,vl++,vr++ ) {
421  // The increments are not in the max() statement
422  // because gcc has problems producing good code
423  // when using -fno-inline. For safety sake
424  // the increments are explicitly after the max.
425  if ( i >= start_ ) {
426  *vl = max(*vl,*vr);
427  }
428  }
429  return *this;
430 }
431 
432 Sample&
434 {
435  iterator it = begin();
436  for( size_t i = 0; it != end() ; ++it,++i ) {
437  if ( i >= start_ ) {
438  *it = (*it) * (*it);
439  }
440  }
441  return *this;
442 }
443 
444 Sample&
446 {
447  iterator it = begin();
448  for( size_t i = 0; it != end() ; ++it,++i ) {
449  if ( i >= start_ ) {
450  *it = std::sqrt( *it );
451  }
452  }
453  return *this;
454 }
455 
456 Scalar
458 {
459  Scalar norm = 0.0;
460  const_iterator it = begin();
461  for( size_t i = 0; it != end() ; ++it,++i ) {
462  if ( i >= start_ ) {
463  norm += *it* *it;
464  }
465  }
466  return std::sqrt(norm);
467 }
468 
469 Scalar
470 Sample::dotProduct( const Sample& rhs ) const
471 {
472  Scalar norm = 0.0;
473  const_iterator lhs_it = begin();
474  const_iterator rhs_it = rhs.begin();
475  for( size_t i = 0; lhs_it != end() && rhs_it != rhs.end() ; ++lhs_it, ++rhs_it, ++i ) {
476  if ( i >= start_ ) {
477  norm += *lhs_it* *rhs_it;
478  }
479  }
480  return std::sqrt(norm);
481 }
482 
483 ostream&
484 operator<<( ostream& os, const Sample& value )
485 {
486  if ( value.size() == 0 )
487  return os;
488 
489  int oldprecision = os.precision(25);
490 
491  copy( value.begin(), value.end(),
492  ostream_iterator<Scalar>(os," ") );
493 
494  os.precision( oldprecision );
495  return os;
496 }
497 
498 istream&
499 operator>>( istream& is, Sample& value )
500 {
501  // Temporarily spool values into a vector<double>
502  vector<double>v;
503 
504  copy( istream_iterator<double>(is),
505  istream_iterator<double>(),
506  back_inserter( v ) );
507 
508  // Copy from temporary vector<double> into value
509  value.resize( v.size() );
510 
511  copy( v.begin(),
512  v.end(),
513  value.begin() );
514 
515  return is;
516 
517 }
void setCategoricalThreshold(std::size_t index)
Definition: Sample.cpp:191
Sample & operator|=(const Sample &)
Definition: Sample.cpp:415
iterator end()
Definition: Sample.hh:88
void copy(std::size_t size, Scalar const *values)
Definition: Sample.cpp:212
double Scalar
Type of map values.
Definition: om_defs.hh:39
Scalar & operator[](std::size_t index)
Definition: Sample.cpp:221
Scalar dotProduct(const Sample &rhs) const
Definition: Sample.cpp:470
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Definition: Log.cpp:45
bool equals(const Sample &) const
Definition: Sample.cpp:249
ostream & operator<<(ostream &os, const Sample &value)
Definition: Sample.cpp:484
void dump() const
Definition: Sample.cpp:274
iterator begin()
Definition: Sample.hh:87
Sample & operator&=(const Sample &)
Definition: Sample.cpp:397
std::size_t size_
Definition: Sample.hh:139
void alloc(std::size_t size)
Definition: Sample.cpp:199
Sample & operator/=(const Sample &)
Definition: Sample.cpp:370
Scalar * value_
Definition: Sample.hh:140
Sample & operator+=(const Sample &)
Definition: Sample.cpp:290
void resize(std::size_t size)
Definition: Sample.cpp:153
Sample & sqr()
Definition: Sample.cpp:433
Scalar const * const_iterator
Definition: Sample.hh:90
Scalar norm() const
Definition: Sample.cpp:457
Scalar * iterator
Definition: Sample.hh:86
std::size_t size() const
Definition: Sample.hh:70
std::size_t start_
Definition: Sample.hh:142
Sample & sqrt()
Definition: Sample.cpp:445
Sample & operator*=(const Sample &)
Definition: Sample.cpp:343
Sample & operator-=(const Sample &)
Definition: Sample.cpp:317
~Sample()
Definition: Sample.cpp:124
void info(const char *format,...)
'Info' level.
Definition: Log.cpp:256
Sample & operator=(const Sample &rhs)
Definition: Sample.cpp:132
Sample()
Definition: Sample.cpp:38
istream & operator>>(istream &is, Sample &value)
Definition: Sample.cpp:499
int min(int v1, int v2)
Definition: rules_base.cpp:56
Definition: Sample.hh:25