Here you will find an useful class.
Recently, I have been working in the developing because I'll need it. In fact, I still developing it so if you are interested take care of my updates.
You can use it as you like. The only thing I ask you is to be recognized myself.
/* * File: Matrix.h * Author: Aikon * * Created on 20 de febrero de 2012, 22:43 */ #ifndef MATRIX_H #define MATRIX_H #include <vector> #include <iostream> #include <stdexcept> template<typename T> class Matrix { private: std::vector<T> _elements; public: unsigned _rows; unsigned _cols; public: T& operator()( unsigned i, unsigned j ) { return _elements[i*_cols+j]; } const T& operator()( unsigned i, unsigned j ) const { return _elements[i*_cols+j]; } const T& operator()( unsigned i) const { return _elements[i]; } public: // constructors Matrix( unsigned rows, unsigned cols); Matrix( unsigned rows, unsigned cols, T element); template<typename Function> Matrix( unsigned rows, unsigned cols, Function f) : _rows(rows), _cols(cols), _elements(rows*cols,T(0.0)){ if( rows == 0 || cols == 0 ) throw std::range_error("attempt to create a degenerate matrix"); for (int i=0 ;i < rows*cols ;i++) _elements[i] = f(); } //Matrix( Matrix& ); // destructor ~Matrix(); // assignment Matrix<T>& operator=( const Matrix<T>& ); // comparison bool operator==( const Matrix<T>& ) const; bool operator!=( const Matrix<T>& cmp) const{ return ((*this)==(cmp))? false : true; } // scalar multiplication Matrix<T>& operator*=( const T& a ); Matrix<T> operator*( const T& a ) const { return Matrix<T>(*this).operator*=(a); } Matrix<T> operator-() const{ return Matrix<T>(*this)*(-1); } // addition/subtraction Matrix<T>& operator+=( const Matrix<T>& ); Matrix<T>& operator-=( const Matrix<T>& ); Matrix<T> operator+( const Matrix<T>& M ) const { return Matrix<T>(*this).operator+=(M); } Matrix<T> operator-( const Matrix<T>& M ) const { return Matrix<T>(*this).operator-=(M); } // Matrix multiplication Matrix<T> operator*( const Matrix<T>& ) const; Matrix<T>& operator*=( const Matrix<T>& M ) { return *this = *this * M; } /* Matrix<T> getcol( unsigned i ) const; Matrix<T> getrow( unsigned j ) const; Matrix<T>& setcol( unsigned j, const Matrix<T>& C ); Matrix<T>& setrow( unsigned i, const Matrix<T>& R ); Matrix<T> delrow( unsigned i ) const; Matrix<T> delcol( unsigned j ) const; Matrix<T> transpose() const; */ void set( unsigned i, unsigned j, T in){ _elements[i*_cols+j] = in; } }; #endif /* MATRIX_H */ //constructors template<class T> Matrix<T>::Matrix( unsigned rows, unsigned cols) : _rows(rows), _cols(cols), _elements(rows*cols,T(0.0)){ //_elements(rows*cols,T(0.0) init with 0 values if( rows == 0 || cols == 0 ) throw std::range_error("attempt to create a degenerate matrix"); }; template<class T> Matrix<T>::Matrix( unsigned rows, unsigned cols, T element) : _rows(rows), _cols(cols), _elements(rows*cols,T(element)){ if( rows == 0 || cols == 0 ) throw std::range_error("attempt to create a degenerate matrix"); }; // destructor //Erases all the elements. Note that this function only erases //the elements, and that if the elements themselves are pointers, //the pointed-to memory is not touched in any way. Managing //the pointer is the user's responsibility. template<class T> Matrix<T>::~Matrix(){ _elements.clear(); } template<class T> Matrix<T>& Matrix<T>::operator=( const Matrix<T>& cp ){ _elements.clear(); for(int i = 0;i < cp._cols * cp._rows ;i++) _elements.push_back(cp(i)); _cols = cp._cols; _rows = cp._rows; return *this; } template<class T> bool Matrix<T>::operator==( const Matrix<T>& cmp) const{ if(cmp._rows != _rows && cmp._cols != _cols ) return false; for(unsigned i=0 ; i < _rows*_cols ; i++) if(_elements[i] != cmp._elements[i]) return false; return true; } template<class T> Matrix<T>& Matrix<T>::operator*=( const T& a ){ for(int i=0; i < _rows * _cols ; i++) _elements[i] *= a; return *this; } // addition/subtraction template<class T> Matrix<T>& Matrix<T>::operator+=( const Matrix<T>& in){ if(in._rows != _rows && in._cols != _cols ) throw std::domain_error("diferent size"); for(unsigned i=0 ; i < _rows*_cols ; i++) _elements[i] += in._elements[i]; return *this; } template<class T> Matrix<T>& Matrix<T>::operator-=( const Matrix<T>& in){ if(in._rows != _rows && in._cols != _cols ) throw std::domain_error("diferent size"); for(unsigned i=0 ; i < _rows*_cols ; i++) _elements[i] -= in._elements[i]; return *this; } // Matrix multiplication //(this)*B = C sizeX(files de this), sizeY = columnes de B sizeY template<class T> Matrix<T> Matrix<T>::operator*( const Matrix<T>& in) const{ Matrix<T> aux(_rows,in._cols); if(_cols != in._rows) throw std::domain_error("diferent size"); for(int i=0;i<_rows;i++) for(int j=0 ; j<in._cols ; j++) for(int k=0 ; k<_cols ; k++) (aux)(i, j) += (*this)(i,k)*in(k,j); return aux; } template<typename T> std::ostream& operator<<(std::ostream& out,Matrix<T>& M){ out << std::endl; for(int i = 0 ; i< M._rows ; i++){ for(int j = 0 ; j < M._cols ; j++) out << " " << M(i,j) << " "; out << std::endl; } return out; } #include <cstdlib> #include <ctime> double myfunction () { return (rand()%10)+1; } int main(){ try{ srand (time(0)); Matrix<double> m(4,2,myfunction); Matrix<double> m2(2,4,double(1)); //If the third argument is not an double (as the type of Matrix) //it will try to apply a "Function" instead of asigning the value //we could apply double(2) //Can I improve this std::cout << "isEqual: " << (m == m) << std::endl; std::cout << m << m2; m = m * m2; std::cout << m; m*=m;//m^2 m= -m; std::cout << m; }catch(const std::exception& in){ std::cout << in.what() << std::endl; } }
No comments:
Post a Comment