?? 操作矩陣的類 cmatrix.txt
字號:
//////////////////////////////////////////////////////////////////////
// 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 || j != m_nNumColumns-1)
s += sDelim;
}
}
if (bLineBreak)
if (i != m_nNumRows-1)
s += "\r\n";
}
return s;
}
//////////////////////////////////////////////////////////////////////
// 將矩陣指定行中各元素的值轉化為字符串
//
// 參數:
// 1. int nRow - 指定的矩陣行,nRow = 0表示第一行
// 2. const CString& sDelim - 數字之間的分隔符,默認為空格
//
// 返回值:CString 型,轉換得到的字符串
//////////////////////////////////////////////////////////////////////
CString CMatrix::RowToString(int nRow, const CString& sDelim /*= " "*/) const
{
CString s = "";
if (nRow >= m_nNumRows)
return s;
for (int j=0; j<m_nNumColumns; ++j)
{
CString ss;
ss.Format("%f", GetElement(nRow, j));
s += ss;
if (j != m_nNumColumns-1)
s += sDelim;
}
return s;
}
//////////////////////////////////////////////////////////////////////
// 將矩陣指定列中各元素的值轉化為字符串
//
// 參數:
// 1. int nCol - 指定的矩陣行,nCol = 0表示第一列
// 2. const CString& sDelim - 數字之間的分隔符,默認為空格
//
// 返回值:CString 型,轉換得到的字符串
//////////////////////////////////////////////////////////////////////
CString CMatrix::ColToString(int nCol, const CString& sDelim /*= " "*/) const
{
CString s = "";
if (nCol >= m_nNumColumns)
return s;
for (int i=0; i<m_nNumRows; ++i)
{
CString ss;
ss.Format("%f", GetElement(i, nCol));
s += ss;
if (i != m_nNumRows-1)
s += sDelim;
}
return s;
}
//////////////////////////////////////////////////////////////////////
// 設置矩陣各元素的值
//
// 參數:
// 1. double value[] - 一維數組,長度為m_nNumColumns*m_nNumRows,存儲
// 矩陣各元素的值
//
// 返回值:無
//////////////////////////////////////////////////////////////////////
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);
}
//////////////////////////////////////////////////////////////////////
// 設置指定元素的值
//
// 參數:
// 1. int nRows - 指定的矩陣行數
// 2. int nCols - 指定的矩陣列數
// 3. double value - 指定元素的值
//
// 返回值:BOOL 型,說明設置是否成功
//////////////////////////////////////////////////////////////////////
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;
}
//////////////////////////////////////////////////////////////////////
// 設置指定元素的值
//
// 參數:
// 1. int nRows - 指定的矩陣行數
// 2. int nCols - 指定的矩陣列數
//
// 返回值:double 型,指定元素的值
//////////////////////////////////////////////////////////////////////
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 型,矩陣的列數
//////////////////////////////////////////////////////////////////////
int CMatrix::GetNumColumns() const
{
return m_nNumColumns;
}
//////////////////////////////////////////////////////////////////////
// 獲取矩陣的行數
//
// 參數:無
//
// 返回值:int 型,矩陣的行數
//////////////////////////////////////////////////////////////////////
int CMatrix::GetNumRows() const
{
return m_nNumRows;
}
//////////////////////////////////////////////////////////////////////
// 獲取矩陣的數據
//
// 參數:無
//
// 返回值:double型指針,指向矩陣各元素的數據緩沖區
//////////////////////////////////////////////////////////////////////
double* CMatrix::GetData() const
{
return m_pData;
}
//////////////////////////////////////////////////////////////////////
// 獲取指定行的向量
//
// 參數:
// 1. int nRows - 指定的矩陣行數
// 2. double* pVector - 指向向量中各元素的緩沖區
//
// 返回值:int 型,向量中元素的個數,即矩陣的列數
//////////////////////////////////////////////////////////////////////
int CMatrix::GetRowVector(int nRow, double* pVector) const
{
if (pVector == NULL)
delete pVector;
pVector = new double[m_nNumColumns];
ASSERT(pVector != NULL);
for (int j=0; j<m_nNumColumns; ++j)
pVector[j] = GetElement(nRow, j);
return m_nNumColumns;
}
//////////////////////////////////////////////////////////////////////
// 獲取指定列的向量
//
// 參數:
// 1. int nCols - 指定的矩陣列數
// 2. double* pVector - 指向向量中各元素的緩沖區
//
// 返回值:int 型,向量中元素的個數,即矩陣的行數
//////////////////////////////////////////////////////////////////////
int CMatrix::GetColVector(int nCol, double* pVector) const
{
if (pVector == NULL)
delete pVector;
pVector = new double[m_nNumRows];
ASSERT(pVector != NULL);
for (int i=0; i<m_nNumRows; ++i)
pVector[i] = GetElement(i, nCol);
return m_nNumRows;
}
//////////////////////////////////////////////////////////////////////
// 重載運算符=,給矩陣賦值
//
// 參數:
// 1. const CMatrix& other - 用于給矩陣賦值的源矩陣
//
// 返回值:CMatrix型的引用,所引用的矩陣與other相等
//////////////////////////////////////////////////////////////////////
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 ;
}
//////////////////////////////////////////////////////////////////////
// 重載運算符==,判斷矩陣是否相等
//
// 參數:
// 1. const CMatrix& other - 用于比較的矩陣
//
// 返回值:BOOL 型,兩個矩陣相等則為TRUE,否則為FALSE
//////////////////////////////////////////////////////////////////////
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;
}
//////////////////////////////////////////////////////////////////////
// 重載運算符!=,判斷矩陣是否不相等
//
// 參數:
// 1. const CMatrix& other - 用于比較的矩陣
//
// 返回值:BOOL 型,兩個不矩陣相等則為TRUE,否則為FALSE
//////////////////////////////////////////////////////////////////////
BOOL CMatrix::operator!=(const CMatrix& other) const
{
return !(*this == other);
}
//////////////////////////////////////////////////////////////////////
// 重載運算符+,實現矩陣的加法
//
// 參數:
// 1. const CMatrix& other - 與指定矩陣相加的矩陣
//
// 返回值:CMatrix型,指定矩陣與other相加之和
//////////////////////////////////////////////////////////////////////
CMatrix CMatrix::operator+(const CMatrix& other) const
{
// 首先檢查行列數是否相等
ASSERT (m_nNumColumns == other.GetNumColumns() && m_nNumRows ==
other.GetNumRows());
// 構造結果矩陣
CMatrix result(*this) ; // 拷貝構造
// 矩陣加法
for (int i = 0 ; i < m_nNumRows ; ++i)
{
for (int j = 0 ; j < m_nNumColumns; ++j)
result.SetElement(i, j, result.GetElement(i, j) +
other.GetElement(i, j)) ;
}
return result ;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -