I am working on math / matrix library that will be open source (non-computer scientist) engineer friendly and capable of managing really big computations on shared memory machines.
I have created a few template classes describing matrices. The most basic matrix object looks like this:
template <class DATA_TYPE,class INT_TYPE=std::size_t>
class Matrix
{
//--------------------------------------------------------------------------
private:
INT_TYPE Rows, Cols;
DATA_TYPE *Data;
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
public:
Matrix(); //basic constructor
Matrix(const Matrix<DATA_TYPE,INT_TYPE> &M); //copy cnstructor
~Matrix(); //destructor
//--------------------------------------------------------------------------
inline void Alloc(INT_TYPE _Rows,INT_TYPE _Cols);
inline void Free();
inline void Resize(INT_TYPE _Rows,INT_TYPE _Cols);
inline void ResizeCopyNoFill(INT_TYPE _Rows,INT_TYPE _Cols);
inline void ResizeNoCopyNoFill(INT_TYPE _Rows,INT_TYPE _Cols);
inline void Fill(DATA_TYPE Value=DATA_TYPE());
inline void Copy(const Matrix<DATA_TYPE,INT_TYPE> &M);
//--------------------------------------------------------------------------
inline bool IsEmpty() const;
inline bool IsValid() const;
inline bool IsScalar() const;
inline bool IsVector() const;
inline bool IsRowVector() const;
inline bool IsColumnVector() const;
//--------------------------------------------------------------------------
inline Matrix<DATA_TYPE,INT_TYPE>& operator =(const Matrix<DATA_TYPE,INT_TYPE>& M); //A=B; Direct assignment operator
inline Matrix<DATA_TYPE,INT_TYPE>& operator +=(const Matrix<DATA_TYPE,INT_TYPE>& M); //A+=B; Addition operator
inline Matrix<DATA_TYPE,INT_TYPE>& operator -=(const Matrix<DATA_TYPE,INT_TYPE>& M); //A-=B; Substraction operator
inline Matrix<DATA_TYPE,INT_TYPE>& operator *=(const Matrix<DATA_TYPE,INT_TYPE>& M); //A*=B; Matrix multiplication operator
inline Matrix<DATA_TYPE,INT_TYPE>& operator /=(const Matrix<DATA_TYPE,INT_TYPE>& M); //A/=B; <=> A*=Inverse(B);
inline Matrix<DATA_TYPE,INT_TYPE>& operator ^=(const Matrix<DATA_TYPE,INT_TYPE>& M); //A^=B; Matrix elements to the power A[i]^B[i]
//--------------------------------------------------------------------------
inline Matrix<DATA_TYPE,INT_TYPE>& operator =(DATA_TYPE s); //M=s; Fills the matrix with s entries
inline Matrix<DATA_TYPE,INT_TYPE>& operator +=(DATA_TYPE s); //M+=s; Adds s to every element of M
inline Matrix<DATA_TYPE,INT_TYPE>& operator -=(DATA_TYPE s); //M-=s; Substracts s from every M element
inline Matrix<DATA_TYPE,INT_TYPE>& operator *=(DATA_TYPE s); //M*=s; Multiplies matrix elements by s
inline Matrix<DATA_TYPE,INT_TYPE>& operator /=(DATA_TYPE s); //M/=s; Divides matrix elements by s
inline Matrix<DATA_TYPE,INT_TYPE>& operator ^=(DATA_TYPE s); //A^=s; Matrix elements to the power A[i]^s
//--------------------------------------------------------------------------
inline DATA_TYPE operator ()(INT_TYPE _Row,INT_TYPE _Col) const; // a=M(i,j);
inline DATA_TYPE& operator ()(INT_TYPE _Row,INT_TYPE _Col); // M(i,j)=a;
inline DATA_TYPE operator ()(INT_TYPE ElementIndex) const; // a=M(i);
inline DATA_TYPE& operator ()(INT_TYPE ElementIndex); // M(i)=a;
//--------------------------------------------------------------------------
inline DATA_TYPE* GetDataPtr() const {return Data;}
inline void SetDataPtr(DATA_TYPE* DataPtr) { Data=DataPtr;} //use with extreme caution
//--------------------------------------------------------------------------
inline DATA_TYPE GetElement(INT_TYPE _Row,INT_TYPE _Col) const; //returns element, but index checking is done
inline void SetElement(INT_TYPE _Row,INT_TYPE _Col,DATA_TYPE Value); //sets element, but index checking is done
inline DATA_TYPE GetElement(INT_TYPE ElementIndex) const; //returns element, but index checking is done
inline void SetElement(INT_TYPE ElementIndex,DATA_TYPE Value); //sets element, but no index checking is done
//--------------------------------------------------------------------------
inline INT_TYPE NumOfElements()const {return Rows*Cols;}
inline INT_TYPE NumOfRows() const {return Rows;}
inline INT_TYPE NumOfCols() const {return Cols;}
inline INT_TYPE SetNumOfRows(INT_TYPE _Rows) const { Rows=_Rows;}
inline INT_TYPE SetNumOfCols(INT_TYPE _Cols) const { Cols=_Cols;}
//--------------------------------------------------------------------------
inline DATA_TYPE Sum() const;
inline DATA_TYPE Product() const;
inline DATA_TYPE Max() const;
inline DATA_TYPE Min() const;
inline std::tuple<DATA_TYPE,DATA_TYPE> MinMax() const;
//--------------------------------------------------------------------------
inline void Transpose();
inline void Inverse();
void Print();
//--------------------------------------------------------------------------
};
Of course it needs a lot of work, as I am at the very beginning. My problem is:
How to define and implement operators like multiplication, addition etc to avoid copying the matrix. For now the multiplication
operator looks like that:
template <class DATA_TYPE,class INT_TYPE>
inline Matrix<DATA_TYPE,INT_TYPE> operator *(const Matrix<DATA_TYPE,INT_TYPE>& A,const Matrix<DATA_TYPE,INT_TYPE>& B)
{
Matrix<DATA_TYPE,INT_TYPE> C;
Multiply<DATA_TYPE,INT_TYPE>(A,B,C);
return C;
}
How to avoid copyying the whole C matrix when such expression is used:
M=A*B;
If for example I would modify direct assignment operator, to copy only *Data, Rows and Cols, that would do, but then A=B would remind more the reference than copy, as it would refer to the same place in memory. What do You think about allowing to use pointers only, like
Matrix<float,int> *M=new Matrix();
Than it would work, as all operations would be done on pointers to matrices, but I somehow have feeling that I didn't notice some kind of disadvantage of such solution (except that using a variable again would require using delete M; first).
So, please help me with even absolutely general ideas about solving this problem, so it would look elegant and be fast (in the sense of avoiding of copying matrices).
Regards,
Misery
Edited by Misery, 28 June 2012 - 04:33 AM.







