327 lines
10 KiB
C++
327 lines
10 KiB
C++
/**
|
|
*******************************************************************************
|
|
* @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 <etk/DebugInternal.h>
|
|
#include <etk/math/Vector2D.h>
|
|
#include <etk/Vector.h>
|
|
|
|
namespace etk {
|
|
template <typename T> class Matrix
|
|
{
|
|
private:
|
|
Vector2D<int32_t> m_size;
|
|
Vector<T> m_data;
|
|
public:
|
|
/*****************************************************
|
|
* Constructor
|
|
*****************************************************/
|
|
Matrix(Vector2D<int32_t> size, T* defaultVal=NULL) :
|
|
m_size(size),
|
|
etk::Vector2D<T>(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<T>(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<double>& obj) :
|
|
m_size(obj.m_size.x, obj.m_size.y),
|
|
etk::Vector2D<T>(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<float>& obj) :
|
|
m_size(obj.m_size.x, obj.m_size.y),
|
|
etk::Vector2D<T>(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<int32_t>& obj) :
|
|
m_size(obj.m_size.x, obj.m_size.y),
|
|
etk::Vector2D<T>(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<T>& operator= (const Matrix<T>& 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<T>& obj) const
|
|
{
|
|
return (m_data == obj.m_data);
|
|
};
|
|
/*****************************************************
|
|
* != operator
|
|
*****************************************************/
|
|
bool operator!= (const Matrix<T>& obj) const
|
|
{
|
|
return (m_data != obj.m_data);
|
|
};
|
|
/*****************************************************
|
|
* += operator
|
|
*****************************************************/
|
|
const Matrix<T>& operator+= (const Matrix<T>& 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<T> 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<T> operator+ (const Matrix<T>& obj) {
|
|
Matrix<T> tmpp(*this);
|
|
tmpp += obj;
|
|
return tmpp;
|
|
}
|
|
/*****************************************************
|
|
* -= operator
|
|
*****************************************************/
|
|
const Matrix<T>& operator-= (const Matrix<T>& 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<T> 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<T> operator- (const Matrix<T>& obj) {
|
|
Matrix<T> tmpp(*this);
|
|
tmpp += obj;
|
|
return tmpp;
|
|
}
|
|
/*****************************************************
|
|
* *= operator
|
|
*****************************************************/
|
|
const Matrix<T>& operator*= (const Matrix<T>& 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<T> 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<T> operator* (const Matrix<T>& 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<T> Transpose(void)
|
|
{
|
|
// create a matrix with the inverted size
|
|
Matrix<T> 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<int32_t> 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
|