libMems/Matrix.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * $Id: Matrix.h,v 1.6 2004/02/27 23:08:55 darling Exp $
00003  * This file is copyright 2002-2007 Aaron Darling and authors listed in the AUTHORS file.
00004  * This file is licensed under the GPL.
00005  * Please see the file called COPYING for licensing details.
00006  * **************
00007  ******************************************************************************/
00008 
00009 #ifndef __Matrix_h__
00010 #define __Matrix_h__
00011 
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #endif
00015 
00016 #include "libGenome/gnSetup.h"
00017 #include <iostream>
00018 #include <sstream>
00019 #include <vector>
00020 #include <stdexcept>
00021 
00022 template<class T>
00023 class Matrix
00024 {
00025 public:
00026         Matrix();
00027         Matrix(unsigned nrows, unsigned ncols);
00028         // Throws a BadSize object if either size is zero
00029         class BadSize : public std::range_error{
00030         public:
00031                 BadSize() : std::range_error( "Bad matrix size" ){}
00032         };
00033 
00034         // Based on the Law Of The Big Three:
00035         ~Matrix();      
00036         Matrix(const Matrix<T>& m);
00037         Matrix<T>& operator= (const Matrix<T>& m);
00038         // Access methods to get the (i,j) element:     
00039         T& operator() (unsigned i, unsigned j);
00040         const T& operator() (unsigned i, unsigned j) const;
00041         // These throw a BoundsViolation object if i or j is too big
00042         class BoundsViolation : public std::range_error{
00043         public:
00044                 BoundsViolation() : std::range_error( "Index out of bounds" ){}
00045          };
00046         // Support for initializing each matrix element to a value
00047         void init( const T& init_val );
00048         
00049         void print( std::ostream& os ) const;
00050         void read( std::istream& is );
00051 
00052         unsigned rows() const;
00053         unsigned cols() const;
00054 protected:
00055         T* data_;
00056         unsigned nrows_, ncols_;
00057 };
00058    
00059 template<class T>
00060 inline Matrix<T>::Matrix()
00061 {
00062         data_ = NULL;
00063         nrows_ = 0;
00064         ncols_ = 0;
00065 }
00066 
00067 template<class T>
00068 inline unsigned Matrix<T>::rows() const
00069 {
00070         return nrows_;
00071 }
00072 
00073 template<class T>
00074 inline unsigned Matrix<T>::cols() const
00075 {
00076         return ncols_;
00077 }
00078 
00079 template<class T>
00080 inline T& Matrix<T>::operator() (unsigned row, unsigned col)
00081 {
00082         if (row >= nrows_ || col >= ncols_) 
00083                 throw BoundsViolation();
00084         return data_[row*ncols_ + col];
00085 }
00086    
00087 template<class T>
00088 inline const T& Matrix<T>::operator() (unsigned row, unsigned col) const
00089 {
00090         if (row >= nrows_ || col >= ncols_) {
00091                 std::cout << "debug me ";
00092                 throw BoundsViolation();
00093         }
00094         return data_[row*ncols_ + col];
00095 }
00096    
00097 template<class T>
00098 inline Matrix<T>::Matrix(unsigned nrows, unsigned ncols)
00099         : data_  (new T[nrows * ncols]),
00100           nrows_ (nrows),
00101           ncols_ (ncols)
00102 {
00103 }
00104 template<class T>
00105 inline Matrix<T>::Matrix(const Matrix<T>& m){
00106         *this = m;
00107 }
00108 
00109 template<class T>
00110 inline Matrix<T>& Matrix<T>::operator=( const Matrix<T>& m )
00111 {
00112         if( data_ != NULL )
00113                 delete[] data_;
00114         data_ = new T[m.nrows_ * m.ncols_];
00115         nrows_ = m.nrows_;
00116         ncols_ = m.ncols_;
00117         memcpy( data_, m.data_, nrows_ * ncols_ * sizeof( T ) );
00118         return *this;
00119 }
00120 
00121 template<class T>
00122 inline Matrix<T>::~Matrix()
00123 {
00124         if( data_ != NULL )
00125                 delete[] data_;
00126 }
00127 
00128 template<class T>
00129 inline void Matrix<T>::init( const T& init_val )
00130 {
00131         for( unsigned rowI = 0; rowI < nrows_; rowI++ )
00132                 for( unsigned colI = 0; colI < ncols_; colI++ )
00133                         data_[ rowI * ncols_ + colI ] = init_val;
00134 }
00135 
00136 template<class T>
00137 inline void Matrix<T>::print( std::ostream& os ) const{
00138         for( unsigned rowI = 0; rowI < nrows_; rowI++ ){
00139                 for( unsigned colI = 0; colI < ncols_; colI++ ){
00140                         if( colI > 0 )
00141                                 os << '\t';
00142                         os << data_[ rowI * ncols_ + colI ];
00143                 }
00144                 os << std::endl;
00145         }
00146 }
00147 
00148 template<class T>
00149 inline void Matrix<T>::read( std::istream& is ){
00150         std::vector< std::string > lines;
00151         std::string cur_line;
00152         while( std::getline( is, cur_line ) )
00153                 lines.push_back( cur_line );
00154                 
00155         nrows_ = lines.size();
00156         // count ncols
00157         std::stringstream ss( lines[0] );
00158         ncols_ = 0;
00159         while( std::getline( ss, cur_line, '\t' ) )
00160                 ncols_++;
00161 
00162         data_ = new T[nrows_ * ncols_];
00163         
00164         int valueI = 0;
00165         for( int lineI = 0; lineI < lines.size(); lineI++ ){
00166                 ss = std::stringstream( lines[ lineI ] );
00167                 std::getline( ss, cur_line, '\t' );
00168                 std::stringstream type_stream( cur_line );
00169                 type_stream >> data_[ valueI ];
00170                 valueI++;
00171         }
00172 }
00173 
00174 #endif // __Matrix_h__

Generated on Fri Mar 14 06:01:03 2008 for libMems by doxygen 1.3.6