#pragma once


template <int N, class Real>
class CMatrix
{
public:
	CMatrix(){

	}
	~CMatrix(){

	}

	void MakeZero (){
		memset(m_data, 0, N*N*sizeof(Real));
	}
	void MakeIdentity (){
		memset(m_data,0,N*N*sizeof(Real));
		for (int i = 0; i < N; i++)
			m_data[Index(i,i)] = (Real)1.0;
	}

	Real operator() (int iRow, int iCol) const{
		return m_data[Index(iRow,iCol)];
	}
	Real& operator() (int iRow, int iCol){
		return m_data[Index(iRow,iCol)];
	}
	
	CMatrix<N,Real> Transpose () const  // M^T
	{
		CMatrix<N,Real> kTranspose;
		for (int iRow = 0; iRow < N; iRow++)
		{
			for (int iCol = 0; iCol < N; iCol++)
				kTranspose.m_data[Index(iRow,iCol)] = m_data[Index(iCol,iRow)];
		}
		return kTranspose;
	}

protected:
	static int Index (int iRow, int iCol){
		return iCol + N*iRow;
	}

	Real m_data[N*N];
};


typedef CMatrix<3,float> CMatrix3f;
typedef CMatrix<3,double> CMatrix3d;
