//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Matrix.cpp
//
// 操作矩阵的类 CMatrix 的实现文件
//
// 周长发编制, 2002/8
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Matrix.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// 基本构造函数
//////////////////////////////////////////////////////////////////////
CMatrix::CMatrix()
{
m_nNumColumns = 1;
m_nNumRows = 1;
m_pData = NULL;
BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);
ASSERT(bSuccess);
}
//////////////////////////////////////////////////////////////////////
// 指定行列构造函数
//
// 参数:
// 1. int nRows - 指定的矩阵行数
// 2. int nCols - 指定的矩阵列数
//////////////////////////////////////////////////////////////////////
CMatrix::CMatrix(int nRows, int nCols)
{
m_nNumRows = nRows;
m_nNumColumns = nCols;
m_pData = NULL;
BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);
ASSERT(bSuccess);
}
//////////////////////////////////////////////////////////////////////
// 指定值构造函数
//
// 参数:
// 1. int nRows - 指定的矩阵行数
// 2. int nCols - 指定的矩阵列数
// 3. double value[] - 一维数组,长度为nRows*nCols,存储矩阵各元素的值
//////////////////////////////////////////////////////////////////////
CMatrix::CMatrix(int nRows, int nCols, double value[])
{
m_nNumRows = nRows;
m_nNumColumns = nCols;
m_pData = NULL;
BOOL bSuccess = Init(m_nNumRows, m_nNumColumns);
ASSERT(bSuccess);
SetData(value);
}
//////////////////////////////////////////////////////////////////////
// 方阵构造函数
//
// 参数:
// 1. int nSize - 方阵行列数
//////////////////////////////////////////////////////////////////////
CMatrix::CMatrix(int nSize)
{
m_nNumRows = nSize;
m_nNumColumns = nSize;
m_pData = NULL;
BOOL bSuccess = Init(nSize, nSize);
ASSERT (bSuccess);
}
//////////////////////////////////////////////////////////////////////
// 方阵构造函数
//
// 参数:
// 1. int nSize - 方阵行列数
// 2. double value[] - 一维数组,长度为nRows*nRows,存储方阵各元素的值
//////////////////////////////////////////////////////////////////////
CMatrix::CMatrix(int nSize, double value[])
{
m_nNumRows = nSize;
m_nNumColumns = nSize;
m_pData = NULL;
BOOL bSuccess = Init(nSize, nSize);
ASSERT (bSuccess);
SetData(value);
}
//////////////////////////////////////////////////////////////////////
// 拷贝构造函数
//
// 参数:
// 1. const CMatrix& other - 源矩阵
//////////////////////////////////////////////////////////////////////
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;
}
}
//////////////////////////////////////////////////////////////////////
// 初始化函数
//
// 参数:
// 1. int nRows - 指定的矩阵行数
// 2. int nCols - 指定的矩阵列数
//
// 返回值:BOOL 型,初始化是否成功
//////////////////////////////////////////////////////////////////////
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; // 内存分配失败
if (IsBadReadPtr(m_pData, sizeof(double) * nSize))
return FALSE;
// 将各元素值置0
memset(m_pData, 0, sizeof(double) * nSize);
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// 将方阵初始化为单位矩阵
//
// 参数:
// 1. int nSize - 方阵行列数
//
// 返回值:BOOL 型,初始化是否成功
//////////////////////////////////////////////////////////////////////
BOOL CMatrix::MakeUnitMatrix(int nSize)
{
if (! Init(nSize, nSize))
return FALSE;
for (int i=0; i<nSize; ++i)
for (int j=0; j<nSize; ++j)
if (i == j)
SetElement(i, j, 1);
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// 将字符串转化为矩阵的值
//
// 参数:
// 1. CString s - 数字和分隔符构成的字符串
// 2. const CString& sDelim - 数字之间的分隔符,默认为空格
// 3. BOOL bLineBreak - 行与行之间是否有回车换行符,默认为真(有换行符)
// 当该参数为FALSE时,所有元素值都在一行中输入,字符串的第一个
// 数值应为矩阵的行数,第二个数值应为矩阵的列数
//
// 返回值:BOOL 型,转换是否成功
//////////////////////////////////////////////////////////////////////
BOOL CMatrix::FromString(CString s, const CString& sDelim /*= " "*/, BOOL
bLineBreak /*= TRUE*/)
{
if (s.IsEmpty())
return FALSE;
// 分行处理
if (bLineBreak)
{
CTokenizer tk(s, "\r\n");
CStringList ListRow;
CString sRow;
while (tk.Next(sRow))
{
sRow.TrimLeft();
sRow.TrimRight();
if (sRow.IsEmpty())
break;
ListRow.AddTail(sRow);
}
// 行数
m_nNumRows = ListRow.GetCount();
sRow = ListRow.GetHead();
CTokenizer tkRow(sRow, sDelim);
CString sElement;
// 列数
m_nNumColumns = 0;
while (tkRow.Next(sElement))
{
m_nNumColumns++;
}
// 初始化矩阵
if (! Init(m_nNumRows, m_nNumColumns))
return FALSE;
// 设置值
POSITION pos = ListRow.GetHeadPosition();
for (int i=0; i<m_nNumRows; i++)
{
sRow = ListRow.GetNext(pos);
int j = 0;
CTokenizer tkRow(sRow, sDelim);
while (tkRow.Next(sElement))
{
sElement.TrimLeft();
sElement.TrimRight();
double v = atof(sElement);
SetElement(i, j++, v);
}
}
return TRUE;
}
// 不分行(单行)处理
CTokenizer tk(s, sDelim);
CString sElement;
// 行数
tk.Next(sElement);
sElement.TrimLeft();
sElement.TrimRight();
m_nNumRows = atoi(sElement);
// 列数
tk.Next(sElement);
sElement.TrimLeft();
sElement.TrimRight();
m_nNumColumns = atoi(sElement);
// 初始化矩阵
if (! Init(m_nNumRows, m_nNumColumns))
return FALSE;
// 设置值
int i = 0, j = 0;
while (tk.Next(sElement))
{
sElement.TrimLeft();
sElement.TrimRight();
double v = atof(sElement);
SetElement(i, j++, v);
if (j == m_nNumColumns)
{
j = 0;
i++;
if (i == m_nNumRows)
break;
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// 将矩阵各元素的值转化为字符串
//
// 参数:
// 1. const CString& sDelim - 数字之间的分隔符,默认为空格
// 2 BOOL bLineBreak - 行与行之间是否有回车换行符,默认为真(有换行符)
//
// 返回值:CString 型,转换得到的字符串
//////////////////////////////////////////////////////////////////////
CString CMatrix::ToString(const CString& sDelim /*= " "*/, BOOL bLineBreak
/*= TRUE*/) const
{
CString s="";
for (int i=0; i<m_nNumRows; ++i)
{
for (int j=0; j<m_nNumColumns; ++j)
{
CString ss;
ss.Format("%f", GetElement(i, j));
s += ss;
if (bLineBreak)
{
if (j != m_nNumColumns-1)
s += sDelim;
}
else
{
if (i != m_nNumRows-1