/** ******************************************************************************* * @file etk/Matix.h * @brief Ewol Tool Kit : generique Matrix type (header) * @author Edouard DUPIN * @date 29/08/2012 * @par Project * Ewol TK * * @par Copyright * Copyright 2011 Edouard DUPIN, all right reserved * * This software is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY. * * Licence summary : * You can modify and redistribute the sources code and binaries. * You can send me the bug-fix * * Term of the licence in in the file licence.txt. * ******************************************************************************* */ #ifndef __ETK_TYPES_MATRIX_H__ #define __ETK_TYPES_MATRIX_H__ #include #include #include namespace etk { template class Matrix { private: Vector2D m_size; Vector m_data; public: /***************************************************** * Constructor *****************************************************/ Matrix(Vector2D size, T* defaultVal=NULL) : m_size(size), etk::Vector2D(size.x* size.y) { if (NULL != defaultVal) { // copy all the elements for(int32_t iii=0; iii<=m_size.x*m_size.y; iii++) { // cast and set value : m_data[iii] = (T)defaultVal++; } } else { Clear(); } }; Matrix(int32_t width=0, int32_t heigh=0, T* defaultVal=NULL) : m_size(width, heigh), etk::Vector2D(width*heigh) { if (NULL != defaultVal) { // copy all the elements for(int32_t iii=0; iii<=m_size.x*m_size.y; iii++) { // cast and set value : m_data[iii] = (T)defaultVal++; } } else { Clear(); } }; Matrix(const Matrix& obj) : m_size(obj.m_size.x, obj.m_size.y), etk::Vector2D(obj.m_size.x* obj.m_size.y) { // copy all the elements for(int32_t iii=0; iii<=m_size.x*m_size.y; iii++) { // cast and set value : m_data[iii] = (T)obj.m_data[iii]; } }; Matrix(const Matrix& obj) : m_size(obj.m_size.x, obj.m_size.y), etk::Vector2D(obj.m_size.x* obj.m_size.y) { // copy all the elements for(int32_t iii=0; iii<=m_size.x*m_size.y; iii++) { // cast and set value : m_data[iii] = (T)obj.m_data[iii]; } }; Matrix(const Matrix& obj) : m_size(obj.m_size.x, obj.m_size.y), etk::Vector2D(obj.m_size.x* obj.m_size.y) { // copy all the elements for(int32_t iii=0; iii<=m_size.x*m_size.y; iii++) { // cast and set value : m_data[iii] = (T)obj.m_data[iii]; } }; /***************************************************** * Destructor *****************************************************/ virtual ~Matrix(void) {}; /***************************************************** * = assigment *****************************************************/ const Matrix& operator= (const Matrix& obj ) { // check if it was the same pointer if( this == &obj ) { return *this; } // copy data : m_size = obj.m_size; m_data = obj.m_data; return *this; }; /***************************************************** * == operator *****************************************************/ bool operator== (const Matrix& obj) const { return (m_data == obj.m_data); }; /***************************************************** * != operator *****************************************************/ bool operator!= (const Matrix& obj) const { return (m_data != obj.m_data); }; /***************************************************** * += operator *****************************************************/ const Matrix& operator+= (const Matrix& obj) { if (m_size != obj.m_size) { //TK_CRITICAL("add 2 Matrix with différent size ... ==> generate the max size of all the 2 matrix"); etk::Matrix tmpMatrix(etk_max(m_size.x,obj.m_size.x), etk_max(m_size.y,obj.m_size.y)); for (int32_t jjj=0; jjj< m_size.y; jjj++) { T* tmpPointer = tmpMatrix[jjj]; T* tmpPointerIn = (*this)[jjj]; for (int32_t iii=0; iii< m_size.x; iii++) { tmpPointer[iii] = tmpPointerIn[iii]; } } for (int32_t jjj=0; jjj< obj.m_size.y; jjj++) { T* tmpPointer = tmpMatrix[jjj]; T* tmpPointerIn = obj[jjj]; for (int32_t iii=0; iii< obj.m_size.x; iii++) { tmpPointer[iii] += tmpPointerIn[iii]; } } // copy in local : m_size = tmpMatrix.m_size; m_data = tmpMatrix.m_data; } else { // copy data for the same size : for (int32_t iii=0; iii< m_data.Size(); iii++) { m_data[iii] += obj.m_data[iii]; } } return *this; }; /***************************************************** * + operator *****************************************************/ Matrix operator+ (const Matrix& obj) { Matrix tmpp(*this); tmpp += obj; return tmpp; } /***************************************************** * -= operator *****************************************************/ const Matrix& operator-= (const Matrix& obj) { if (m_size != obj.m_size) { //TK_CRITICAL("less 2 Matrix with différent size ... ==> generate the max size of all the 2 matrix"); etk::Matrix tmpMatrix(etk_max(m_size.x,obj.m_size.x), etk_max(m_size.y,obj.m_size.y)); for (int32_t jjj=0; jjj< m_size.y; jjj++) { T* tmpPointer = tmpMatrix[jjj]; T* tmpPointerIn = (*this)[jjj]; for (int32_t iii=0; iii< m_size.x; iii++) { tmpPointer[iii] = tmpPointerIn[iii]; } } for (int32_t jjj=0; jjj< obj.m_size.y; jjj++) { T* tmpPointer = tmpMatrix[jjj]; T* tmpPointerIn = obj[jjj]; for (int32_t iii=0; iii< obj.m_size.x; iii++) { tmpPointer[iii] -= tmpPointerIn[iii]; } } // copy in local : m_size = tmpMatrix.m_size; m_data = tmpMatrix.m_data; } else { // copy data for the same size : for (int32_t iii=0; iii< m_data.Size(); iii++) { m_data[iii] -= obj.m_data[iii]; } } return *this; }; /***************************************************** * - operator *****************************************************/ Matrix operator- (const Matrix& obj) { Matrix tmpp(*this); tmpp += obj; return tmpp; } /***************************************************** * *= operator *****************************************************/ const Matrix& operator*= (const Matrix& obj) { if( m_size.x != obj.m_size.y || m_size.y != obj.m_size.x) { //TK_CRITICAL("Error while multipliying 2 matrix with different size ==> impossible case ..."); return *this; } etk::Matrix tmpMatrix(m_size); for (int32_t jjj=0; jjj< obj.m_size.y; jjj++) { for (int32_t iii=0; iii< obj.m_size.x; iii++) { T tmpVal = 0; for (int32_t kkk=0; kkk< obj.m_size.x; kkk++) { tmpVal += (*this)[jjj][iii+kkk] * obj[jjj+kkk][iii]; } tmpMatrix[jjj][iii] = tmpVal; } } // copy in local : m_data = tmpMatrix.m_data; return *this; }; /***************************************************** * * operator *****************************************************/ Matrix operator* (const Matrix& obj) { Matrix tmpp(*this); tmpp *= obj; return tmpp; } /***************************************************** * [] operator *****************************************************/ const T* operator[] (int32_t line) const { return &m_data[line*m_size.x]; } T* operator[] (int32_t line) { return &m_data[line*m_size.x]; } /** * @ brief Transpose Matrix * @ return the transpose matrix */ Matrix Transpose(void) { // create a matrix with the inverted size Matrix tmpMatrix(m_size.x, m_size.y); for (int32_t jjj=0; jjj< m_size.y; jjj++) { for (int32_t iii=0; iii< m_size.x; iii++) { tmpMatrix[jjj][iii] = (*this)[iii][jjj]; } } return tmpMatrix; }; /***************************************************** * other stupid action : *****************************************************/ Vector2D Size(void) { return m_size; }; void Clear(void) { // copy data for the same size : for (int32_t iii=0; iii< m_size.x*m_size.y; iii++) { m_data[iii] = (T)0; } }; void Identity(void) { // copy data for the same size : for (int32_t iii=0; iii< etk_min(m_size.x, m_size.y); iii++) { (*this)[iii][iii] = (T)1; } }; void Set(int32_t iii, int32_t jjj, T value) { m_data[iii*m_size.x+jjj] = value; } T Get(int32_t iii, int32_t jjj) { return m_data[iii*m_size.x+jjj]; } void Display(void) { /* TK_INFO("Matrix display : "); for (int32_t jjj=0; jjj< m_size.y; jjj++) { if (m_size.x == 0) { TK_INFO(" --- , "); } else if (m_size.x == 1) { TK_INFO(" " << (*this)[jjj][0] << " , "); } else if (m_size.x == 2) { TK_INFO(" " << (*this)[jjj][0] << " , " << (*this)[jjj][1] << " , "); } else if (m_size.x == 3) { TK_INFO(" " << (*this)[jjj][0] << " , " << (*this)[jjj][1] << " , " << (*this)[jjj][2] << " , "); } else if (m_size.x == 4) { TK_INFO(" " << (*this)[jjj][0] << " , " << (*this)[jjj][1] << " , " << (*this)[jjj][2] << " , " << (*this)[jjj][3] << " , "); } else if (m_size.x == 5) { TK_INFO(" " << (*this)[jjj][0] << " , " << (*this)[jjj][1] << " , " << (*this)[jjj][2] << " , " << (*this)[jjj][3] << " , " << (*this)[jjj][4] << " , "); } else if (m_size.x == 6) { TK_INFO(" " << (*this)[jjj][0] << " , " << (*this)[jjj][1] << " , " << (*this)[jjj][2] << " , " << (*this)[jjj][3] << " , " << (*this)[jjj][4] << " , " << (*this)[jjj][5] << " , "); } else { TK_INFO(" " << (*this)[jjj][0] << " , " << (*this)[jjj][1] << " , " << (*this)[jjj][2] << " , " << (*this)[jjj][3] << " , " << (*this)[jjj][4] << " , " << (*this)[jjj][5] << " , " << (*this)[jjj][6] << " , "); } } */ }; }; }; #endif