/** * @author Edouard DUPIN * * @copyright 2011, Edouard DUPIN, all right reserved * * @license APACHE v2.0 (see license file) */ #ifndef __ETK_TYPES_MATRIX_H__ #define __ETK_TYPES_MATRIX_H__ #include #include #include namespace etk { template class Matrix { private: etk::Vector2D m_size; std::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() {}; /***************************************************** * = 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; }; const Matrix& operator= (T& value) { // set data : for (int32_t iii=0; iii& 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(std::max(m_size.x,obj.m_size.x), std::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(std::max(m_size.x,obj.m_size.x), std::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]; } /***************************************************** * () operator *****************************************************/ T& operator () (int32_t line, int32_t colomn) { return m_data[line*m_size.x + colomn]; } /***************************************************** * - operator *****************************************************/ Matrix operator - () { Matrix tmp(m_size); for (int32_t iii=0; iii transpose() { // 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; }; /** * @ brief Create a convolution on the matrix : set convolution on the lines * @ param[in] obj The convolution operator * @ return the value of the convolution */ Matrix& convolution(Matrix& obj) { Matrix tmppp(1,1); // TODO : ... return tmppp; }; /** * @ brief generate a devide of the curent Matrix with the specify power of 2 * @ param[in] decalage The power of 2 of the division * @ return the result */ Matrix& fix(int32_t decalage) { Matrix tmppp(m_size); T tmpVal = 0; for(int32_t iii=0; iii> decalage; tmpVal++; } else { tmpVal = tmpVal >> decalage; } tmppp.m_data[iii] = tmpVal; } return tmppp; }; /** * @ brief generate a devide of the curent Matrix with the specify power of 2 * @ param[in] decalage The power of 2 of the division * @ return the result */ Matrix& round(int32_t decalage) { Matrix tmppp(m_size); for(int32_t iii=0; iii> decalage; } return tmppp; }; /** * @ brief Generate a resised matrix * @ param[in] size new output size * @ return Te resied matrix */ Matrix& resize(etk::Vector2D size) { Matrix tmppp(size); for(int32_t iii=0; iii& select(int32_t np, int32_t *p, int32_t nq, int32_t *q) { if (np < 1 || nq < 1) { TK_WARNING("bad index array sizes"); } Matrix tmppp(np,nq); for (int32_t iii=0; iii= m_size.x || q[i] < 0 || q[i] >= m_size.y) { TK_WARNING("bad index arrays"); } tmppp(iii,jjj) = (*this)(p[i],q[j]); } } return tmppp; } /***************************************************** * utilities : *****************************************************/ /** * @brief Clear the Upper triangle of the current Matrix *
			 *   x 0 0 0 0
			 *   x x 0 0 0
			 *   x x x 0 0
			 *   x x x x 0
			 *   x x x x x
			 * 
*/ void clearUpperTriangle() { if (m_size.x != m_size.y) { TK_WARNING("better to do with square Matrix"); } for (int32_t iii=0; iii * x x x x x * 0 x x x x * 0 0 x x x * 0 0 0 x x * 0 0 0 0 x * */ void clearLowerTriangle() { if (m_size.x != m_size.y) { TK_WARNING("better to do with square Matrix"); } for (int32_t iii=0; iii& input) { if (m_size != input.m_size) TK_WARNING("better to do with same size Matrix"); } T max = 0; for(int32_t iii = 0; iii < m_data.size() && iii < input.m_data.size(); ++iii) { T diff = m_data[iii] - input.m_data[iii]; if (diff<0) { diff = -diff; } if (diff > max) max = diff; } } return max; }; /** * @brief Clear all the matrix. */ void clear() { // copy data for the same size : for (int32_t iii=0; iii< m_size.x*m_size.y; iii++) { m_data[iii] = (T)0; } }; /** * @brief Set the diagonal at 1 */ void identity() { // copy data for the same size : for (int32_t iii=0; iii< std::mim(m_size.x, m_size.y); iii++) { (*this)(iii,iii) = (T)1; } }; /** * @brief Clear and set the diagonal at 1 */ void eye() { clear(); identity(); }; /** * @brief Get the size of the current Matrix. * @return Dimention of the matrix */ Vector2D size() { return m_size; }; }; }; // To siplify the writing of the code ==> this is not compatible with GLSL ... typedef etk::Matrix mat; typedef etk::Matrix imat; typedef etk::Matrix uimat; #endif