openModeller  Version 1.4.0
Sample.hh
Go to the documentation of this file.
00001 
00011 #ifndef _SAMPLE_HH_
00012 #define _SAMPLE_HH_
00013 
00014 #include <openmodeller/om_defs.hh>
00015 #include <openmodeller/os_specific.hh>
00016 #include <cstddef>
00017 #include <iostream>
00018 #include <vector>
00019 //Needed for using free in template function with gcc4.3.2
00020 #include <stdlib.h>
00021 
00022 // Decl of SExp which is defined in SampleExpr.hh
00023 template< typename T > class SExpr;
00024 
00025 class dllexp Sample
00026 {
00027 
00028 public:
00029   // Construct an empty one.
00030   Sample();
00031 
00032   // Construct one of this size initialized with zeros
00033   explicit Sample( std::size_t size );
00034 
00035   // Construct one with the same value in all elements
00036   Sample ( std::size_t size, Scalar value );
00037 
00038   // Construct one with these values.
00039   // Copies the contents of the values array.
00040   Sample( std::size_t size, Scalar const * values );
00041 
00042   // Construct one with these values from a std::vector<Scalar>
00043   Sample( std::vector<Scalar> );
00044 
00045 
00046   // Copy one.
00047   // Currently implemented slowly by doing an
00048   // allocation and deep copy.
00049   Sample( const Sample & rhs );
00050 
00051   ~Sample();
00052 
00053   // Assignment operator.
00054   Sample& operator=( const Sample & rhs );
00055 
00056   // Assignment from an Expression Template.
00057   // Evalute the SExpr and assign to this.
00058   template< typename T > inline
00059   Sample( const SExpr<T>& rhs );
00060   
00061   template< typename T > inline
00062   Sample& operator=( const SExpr<T>& rhs );
00063  
00064   // Redimensions this.
00065   // Slow operation since it does a memcpy.
00066   // Any new elements are initialized to 0.
00067   void resize( std::size_t size );
00068 
00069   // First iteration mechanism works with indexing.
00070   inline std::size_t size() const { return size_; }
00071 
00072   // Set the index of the first attribute related to a continuous variable.
00073   // When a Sample contains attributes from both categorical and continuous
00074   // variables, categorical attributes always come first and their values 
00075   // should not be changed in most operations.
00076   void setCategoricalThreshold( std::size_t index );
00077 
00078   // Return an lvalue.
00079   Scalar& operator[]( std::size_t index );
00080 
00081   // Return an rvalue from a const reference.
00082   Scalar operator[]( std::size_t index ) const;
00083 
00084   // Second iteration mechanism works with pointers.
00085   // Looks like a real iterator;
00086   typedef Scalar* iterator;
00087   inline iterator begin() { return value_; }
00088   inline iterator end() { return value_ + size_; }
00089 
00090   typedef Scalar const * const_iterator;
00091   inline const_iterator begin() const { return value_; }
00092   inline const_iterator end() const  { return value_ + size_; }
00093 
00094   // define an equality check
00095   bool equals( const Sample& ) const;
00096 
00097   // dump values
00098   void dump() const;
00099 
00100   // define some mutating operators for convience
00101   
00102   // pointwise addition
00103   Sample& operator+= ( const Sample& );
00104   Sample& operator+= ( const Scalar& );
00105  
00106   // pointwise subtraction
00107   Sample& operator-= ( const Sample& );
00108   Sample& operator-= ( const Scalar& );
00109  
00110   // pointwise multiplication
00111   Sample& operator*= ( const Sample& );
00112   Sample& operator*= ( const Scalar& );
00113 
00114   // pointwise division
00115   Sample& operator/= ( const Sample& );
00116   Sample& operator/= ( const Scalar& );
00117 
00118   // pointwise minimum - this may not seem like a natural
00119   // overload but "and" in lattices means minimum.
00120   Sample& operator&= ( const Sample& );
00121 
00122   // pointwise maximum
00123   Sample& operator|= ( const Sample& );
00124 
00125   // Take the square of this and return this
00126   Sample& sqr();
00127 
00128   // Take the root of this and return this
00129   Sample& sqrt();
00130 
00131   // Compute the vector "norm" = sqrt ( sum squares )
00132   Scalar norm() const;
00133 
00134   // Compute the vector dot product with another vector
00135   Scalar dotProduct( const Sample& rhs ) const;
00136 
00137 private:
00138 
00139   std::size_t size_;
00140   Scalar *value_;
00141 
00142   std::size_t start_; // index of the first attribute of a continuous variable
00143 
00144   void alloc( std::size_t size );
00145 
00146   void copy( std::size_t size, Scalar const * values );
00147 
00148 };
00149 
00150 //
00151 // IO operator decls
00152 //
00153 dllexp std::ostream&
00154 operator<<(std::ostream&,const Sample&);
00155 
00156 dllexp std::istream&
00157 operator>>(std::istream&, Sample&);
00158 
00159 
00160 // Definitions of inlined functions
00161 dllexp bool inline
00162 operator==( const Sample& lhs, const Sample& rhs )
00163 {
00164   return lhs.equals( rhs );
00165 }
00166 
00167 dllexp bool inline
00168 operator!=( const Sample& lhs, const Sample& rhs )
00169 {
00170   return !lhs.equals( rhs );
00171 }
00172 
00173 template< typename T >
00174 inline
00175 Sample::Sample( const SExpr<T>& rhs ) :
00176   size_(0),
00177   value_(0)
00178 {
00179   operator=(rhs);
00180 }
00181 
00182 template< typename T >
00183 inline Sample&
00184 Sample::operator=( const SExpr<T>& rhs )
00185 {
00186   if ( this->size_ != rhs.size() ) {
00187     if ( value_ ) {
00188       free( value_ );
00189     }
00190     alloc( rhs.size() );
00191   }
00192   rhs.reset();
00193   iterator meIter = begin();
00194   while ( meIter != end() ) {
00195     *meIter = *rhs;
00196     ++meIter;
00197     ++rhs;
00198   }
00199   
00200   return *this;
00201   
00202 }
00203 
00204 #endif