#include <math.h>
#include <iostream>
#include "CMatrix.h"
CMatrix::CMatrix()
{
m_nNumColumns = 1;
m_nNumRows = 1;
m_pData = NULL;
bool bSuccess = Init(m_nNumRows, m_nNumColumns);
_ASSERT(bSuccess);
}
CMatrix::CMatrix(int nRows, int nCols)
{
m_nNumRows = nRows;
m_nNumColumns = nCols;
m_pData = NULL;
bool bSuccess = Init(m_nNumRows, m_nNumColumns);
_ASSERT(bSuccess);
}
CMatrix::CMatrix(int nSize, double value[])
{
m_nNumRows = nSize;
m_nNumColumns = nSize;
m_pData = NULL;
bool bSuccess = Init(nSize, nSize);
_ASSERT(bSuccess);
SetData(value);
}
CMatrix::CMatrix(const CMatrix& other)
{
m_nNumColumns = other.GetNumColumns();
m_nNumRows = other.GetNumRows();
m_pData = NULL;
bool bSuccess = Init(m_nNumRows, m_nNumColumns);
_ASSERT(bSuccess);
// copy the pointer
memcpy(m_pData, other.m_pData, sizeof(double)*m_nNumColumns*m_nNumRows);
}
CMatrix::~CMatrix()
{
if (m_pData)
{
delete[] m_pData;
m_pData = NULL;
}
}
bool CMatrix::Init(int nRows, int nCols)
{
if (m_pData)
{
delete[] m_pData;
m_pData = NULL;
}
m_nNumRows = nRows;
m_nNumColumns = nCols;
int nSize = nCols*nRows;
if (nSize < 0)
return false;
// 分配内存
m_pData = new double[nSize];
if (m_pData == NULL)
return false; // 内存分配失败
memset(m_pData, 0, sizeof(double)* nSize);
return true;
}
void CMatrix::SetData(double value[])
{
// empty the memory
memset(m_pData, 0, sizeof(double)* m_nNumColumns*m_nNumRows);
// copy data
memcpy(m_pData, value, sizeof(double)*m_nNumColumns*m_nNumRows);
}
bool CMatrix::SetElement(int nRow, int nCol, double value)
{
if (nCol < 0 || nCol >= m_nNumColumns || nRow < 0 || nRow >= m_nNumRows)
return false; // array bounds error
if (m_pData == NULL)
return false; // bad pointer error
m_pData[nCol + nRow * m_nNumColumns] = value;
return true;
}
double CMatrix::GetElement(int nRow, int nCol) const
{
_ASSERT(nCol >= 0 && nCol < m_nNumColumns && nRow >= 0 && nRow < m_nNumRows); // array bounds error
_ASSERT(m_pData); // bad pointer error
return m_pData[nCol + nRow * m_nNumColumns];
}
int CMatrix::GetNumColumns() const
{
return m_nNumColumns;
}
int CMatrix::GetNumRows() const
{
return m_nNumRows;
}
double* CMatrix::GetData() const
{
return m_pData;
}
CMatrix& CMatrix::operator=(const CMatrix& other)
{
if (&other != this)
{
bool bSuccess = Init(other.GetNumRows(), other.GetNumColumns());
_ASSERT (bSuccess);
// copy the pointer
memcpy(m_pData, other.m_pData, sizeof(double)*m_nNumColumns*m_nNumRows);
}
// finally return a reference to ourselves
return *this;
}
bool CMatrix::operator==(const CMatrix& other) const
{
// 首先检查行列数是否相等
if (m_nNumColumns != other.GetNumColumns() || m_nNumRows != other.GetNumRows())
return false;
for (int i = 0; i<m_nNumRows; ++i)
{
for (int j = 0; j<m_nNumColumns; ++j)
{
if (GetElement(i, j) != other.GetElement(i, j))
return false;
}
}
return true;
}
bool CMatrix::operator!=(const CMatrix& other) const
{
return !(*this == other);
}
bool CMatrix::InvertGaussJordan()
{
int *pnRow, *pnCol, i, j, k, l, u, v;
double d = 0, p = 0;
// 分配内存
pnRow = new int[m_nNumColumns];
pnCol = new int[m_nNumColumns];
if (pnRow == NULL || pnCol == NULL)
return false;
// 消元
for (k = 0; k <= m_nNumColumns - 1; k++)
{
d = 0.0;
for (i = k; i <= m_nNumColumns - 1; i++)
{
for (j = k; j <= m_nNumColumns - 1; j++)
{
l = i*m_nNumColumns + j; p = fabs(m_pData[l]);
if (p>d)
{
d = p;
pnRow[k] = i;
pnCol[k] = j;
}
}
}
// 失败
if (d == 0.0)
{
delete[] pnRow;
delete[] pnCol;
return false;
}
if (pnRow[k] != k)
{
for (j = 0; j <= m_nNumColumns - 1; j++)
{
u = k*m_nNumColumns + j;
v = pnRow[k] * m_nNumColumns + j;
p = m_pData[u];
m_pData[u] = m_pData[v];
m_pData[v] = p;
}
}
if (pnCol[k] != k)
{
for (i = 0; i <= m_nNumColumns - 1; i++)
{
u = i*m_nNumColumns + k;
v = i*m_nNumColumns + pnCol[k];
p = m_pData[u];
m_pData[u] = m_pData[v];
m_pData[v] = p;
}
}
l = k*m_nNumColumns + k;
m_pData[l] = 1.0 / m_pData[l];
for (j = 0; j <= m_nNumColumns - 1; j++)
{
if (j != k)
{
u = k*m_nNumColumns + j;
m_pData[u] = m_pData[u] * m_pData[l];
}
}
for (i = 0; i <= m_nNumColumns - 1; i++)
{
if (i != k)
{
for (j = 0; j <= m_nNumColumns - 1; j++)
{
if (j != k)
{
u = i*m_nNumColumns + j;
m_pData[u] = m_pData[u] - m_pData[i*m_nNumColumns + k] * m_pData[k*m_nNumColumns + j];
}
}
}
}
for (i = 0; i <= m_nNumColumns - 1; i++)
{
if (i != k)
{
u = i*m_nNumColumns + k;
m_pData[u] = -m_pData[u] * m_pData[l];
}
}
}
// 调整恢复行列次序
for (k = m_nNumColumns - 1; k >= 0; k--)
{
if (pnCol[k] != k)
{
for (j = 0; j <= m_nNumColumns - 1; j++)
{
u = k*m_nNumColumns + j;
v = pnCol[k] * m_nNumColumns + j;
p = m_pData[u];
m_pData[u] = m_pData[v];
m_pData[v] = p;
}
}
if (pnRow[k] != k)
{
for (i = 0; i <= m_nNumColumns - 1; i++)
{
u = i*m_nNumColumns + k;
v = i*m_nNumColumns + pnRow[k];
p = m_pData[u];
m_pData[u] = m_pData[v];
m_pData[v] = p;
}
}
}
// 清理内存
delete[] pnRow;
delete[] pnCol;
// 成功返回
return true;
}
bool CMatrix::CMul(const CMatrix& AR, const CMatrix& AI, const CMatrix& BR, const CMatrix& BI, CMatrix& CR, CMatrix& CI) const
{
// 首先检查行列数是否符合要求
if (AR.GetNumColumns() != AI.GetNumColumns() ||
AR.GetNumRows() != AI.GetNumRows() ||
BR.GetNumColumns() != BI.GetNumColumns() ||
BR.GetNumRows() != BI.GetNumRows() ||
AR.GetNumColumns() != BR.GetNumRows())
return false;
// 构造乘积矩阵实部矩阵和虚部矩阵
CMatrix mtxCR(AR.GetNumRows(), BR.GetNumColumns()), mtxCI(AR.GetNumRows(), BR.GetNumColumns());
// 复矩阵相乘
for (int i = 0; i<AR.GetNumRows(); ++i)
{
for (int j = 0; j<BR.GetNumColumns(); ++j)
{
double vr = 0;
double vi = 0;
for (int k = 0; k<AR.GetNumColumns(); ++k)
{
double p = AR.GetElement(i, k) * BR.GetElement(k, j);
double q = AI.GetElement(i, k) * BI.GetElement(k, j);
double s = (AR.GetElement(i, k) + AI.GetElement(i, k)) * (BR.GetElement(k, j) + BI.GetElement(k, j));
vr += p - q;
vi += s - p - q;
}
mtxCR.SetElement(i, j, vr);
mtxCI.SetElement(i, j, vi);
}
}
CR = mtxCR;
CI = mtxCI;
return true;
}
bool CMatrix::Cadd(const CMatrix& AR, const CMatrix& AI, const CMatrix& BR, const CMatrix& BI, CMatrix& CR, CMatrix& CI) const
{
// 首先检查行列数是否符合要求
if (AR.GetNumColumns() != AI.GetNumColumns() ||
AR.GetNumRows() != AI.GetNumRows() ||
BR.GetNumColumns() != BI.GetNumColumns() ||
BR.GetNumRows() != BI.GetNumRows())
return false;
// 构造和矩阵实部矩阵和虚部矩阵
CMatrix mtxCR(AR.GetNumRows(), BR.GetNumColumns()), mtxCI(AR.GetNumRows(), BR.GetNumColumns());
// 复矩阵加
for (int i = 0; i<AR.GetNumRows(); ++i)
{
for (int j = 0; j<BR.GetNumColumns(); ++j)
{
double p = AR.GetElement(i, j)+BR.GetElement(i, j);
double q = AI.GetElement(i, j)+ BI.GetElement(i,j);
mtxCR.SetElement(i, j, p);
mtxCI.SetElement(i, j, q);
}
}
CR = mtxCR;
CI = mtxCI;
return true;
}
bool CMatrix::Csub(const CMatrix& AR, const CMatrix& AI, const CMatrix& BR, const CMatrix& BI, CMatrix& CR, CMatrix& CI) const
{
// 首先检查行列数是否符合要求
if (AR.GetNumColumns() != AI.GetNumColumns() ||
AR.GetNumRows() != AI.GetNumRows() ||
BR.GetNumColumns() != BI.GetNumColumns() ||
BR.GetNumRows() != BI.GetNumRows() )
return false;
// 构造和矩阵实部矩阵和虚部矩阵
CMatrix mtxCR(AR.GetNumRows(), BR.GetNum
评论1