📄 matrix.cpp
字号:
}
}
}
/////////////////////////////////////////////////////////////////////////////
// InitializeZero()
// 矩阵初始化函数,矩阵的行列数目被初始化为零,矩阵中的元素全部初始化为零
/////////////////////////////////////////////////////////////////////////////
void CMatrix::InitializeZero()
{
m_nRow = 0;
m_nCol = 0;
m_pTMatrix.resize (m_nRow);
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
m_pTMatrix[i].resize (m_nCol);
m_pTMatrix[i][j] = (double) 0;
}
}
}
/////////////////////////////////////////////////////////////////////////////
// RandomInitialize()
// 将矩阵中的元素随机初始化函数,元素的值在(-1,1)之间的小数
/////////////////////////////////////////////////////////////////////////////
void CMatrix::RandomInitialize ()
{
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
m_pTMatrix [i][j] = (double)(rand() - (0.5*RAND_MAX)) / (0.5*RAND_MAX);
}
}
}
/////////////////////////////////////////////////////////////////////////////
// 拷贝矩阵的子矩阵元素到另外一个矩阵中
// Parameter:
// [out] cMatrix ----> 矩阵的子矩阵返回的结果
// [in] nStartX ----> 子矩阵在矩阵中的起始坐标,对应行,索引从1开始
// [in] nStartY ----> 子矩阵在矩阵中的起始坐标,对应列,索引从1开始
/////////////////////////////////////////////////////////////////////////////
void CMatrix::CopySubMatrix(CMatrix& cMatrix,unsigned int nStartX,unsigned int nStartY)
{
if((m_nRow < cMatrix.m_nRow + nStartY ) | (m_nCol < cMatrix.m_nCol + nStartX))
{
::AfxMessageBox (TEXT("被拷贝的矩阵维数小于要拷贝的矩阵所需要的维数!"),MB_OK | MB_ICONERROR);
return;
}
for(unsigned int i=0; i < cMatrix.m_nRow; i++)
{
for(unsigned int j=0; j < cMatrix.m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = m_pTMatrix [nStartY + i][nStartX + j];
}
}
}
/////////////////////////////////////////////////////////////////////////////
// Copy Matrix
// Parameter:
// [in] cMatrix ----> 被拷贝的矩阵
/////////////////////////////////////////////////////////////////////////////
void CMatrix::CopyMatrix(CMatrix& cMatrix)
{
m_nRow = cMatrix.m_nRow ;
m_nCol = cMatrix.m_nCol ;
m_pTMatrix = cMatrix.m_pTMatrix ;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
m_pTMatrix [i][j] = cMatrix.m_pTMatrix [i][j];
}
}
}
/////////////////////////////////////////////////////////////////////////////
// 从一个列向量中拷贝数据到一个矩阵中
// Parameter:
// [out] cMatrix ----> 函数的返回结果
// [in] nIndex ----> 在列向量中的索引值
// Notes:
// 被拷贝的对象必须是列向量!!!
/////////////////////////////////////////////////////////////////////////////
void CMatrix::CopySubMatrixFromVector(CMatrix& cMatrix,unsigned int nIndex)
{
if(m_nCol != 1)
{
::AfxMessageBox (TEXT("被拷贝的矩阵不是列向量!!!"),MB_OK | MB_ICONERROR);
return;
}
for(unsigned int j=0; j < cMatrix.m_nCol; j++)
{
for(unsigned int i=0; i < cMatrix.m_nRow; i++)
{
cMatrix.m_pTMatrix [i][j] = m_pTMatrix [nIndex + j * cMatrix.m_nRow + i ][(unsigned int)0];
}
}
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵进列拓展
// 实现功能:
// 对矩阵的列数进行拓展,nTimes是每列拓展的次数
/////////////////////////////////////////////////////////////////////////////
void CMatrix::nncpyi(CMatrix &cMatrix, unsigned int nTimes)
{
m_nRow = cMatrix.m_nRow ;
m_nCol = cMatrix.m_nCol * nTimes;
// 根据空间分配内存
m_pTMatrix.resize (m_nRow);
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
m_pTMatrix[i].resize (m_nCol);
m_pTMatrix[i][j] = (double) 0;
}
}
// 赋值
for(i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < cMatrix.m_nCol; j++)
{
for(unsigned int k=0; k < nTimes; k++)
{
m_pTMatrix [i][j * nTimes + k] = cMatrix.m_pTMatrix [i][j];
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵进行拓展
// 实现功能:
// 对矩阵的列数进行拓展
// matrix = [
// 1 2 3
// 4 5 6
// 7 8 9
// ]
//
// nncpyd(matrix) = [
// 1 0 0 2 0 0 3 0 0
// 0 4 0 0 5 0 0 6 0
// 0 0 7 0 0 8 0 0 9
// ]
/////////////////////////////////////////////////////////////////////////////
void CMatrix::nncpyd(CMatrix &cMatrix)
{
m_nRow = cMatrix.m_nRow ;
m_nCol = cMatrix.m_nCol * cMatrix.m_nRow ;
// 根据空间分配内存
m_pTMatrix.resize (m_nRow);
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
m_pTMatrix[i].resize (m_nCol);
m_pTMatrix[i][j] = (double) 0;
}
}
// 给矩阵赋值
for(i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < cMatrix.m_nCol; j++)
{
for(unsigned int k=0; k < cMatrix.m_nRow; k++)
{
if(i == (j * cMatrix.m_nRow + k) % cMatrix.m_nRow )
m_pTMatrix [i][j * cMatrix.m_nRow + k] = cMatrix.m_pTMatrix [i][j];
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵进行拓展
// 实现功能:
// 对矩阵的列数进行拓展,nTimes是每列拓展的次数
// matrix = [
// 1 2 3
// 4 5 6
// 7 8 9
// ]
// nTimes = 2
//
// nncpyd(matrix) = [
// 1 2 3 1 2 3
// 4 5 6 4 5 6
// 7 8 9 7 8 9
// ]
/////////////////////////////////////////////////////////////////////////////
void CMatrix::nncpy(CMatrix& cMatrix,unsigned int nTimes)
{
m_nRow = cMatrix.m_nRow ;
m_nCol = cMatrix.m_nCol * nTimes;
// 根据空间分配内存
m_pTMatrix.resize (m_nRow);
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
m_pTMatrix[i].resize (m_nCol);
m_pTMatrix[i][j] = (double) 0;
}
}
// 对矩阵赋值
for(i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < nTimes; j++)
{
for(unsigned int k=0; k < cMatrix.m_nCol; k++)
{
m_pTMatrix [i][j * cMatrix.m_nCol + k] = cMatrix.m_pTMatrix [i][k];
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵中所有的元素进行一次非线性变换:
// 变换后的值y与变换前的值的关系是:
// y = f(x) = 1 / (1 + exp(-x)) ( 0 < f(x) < 1)
//
/////////////////////////////////////////////////////////////////////////////
CMatrix CMatrix::Sigmoid()
{
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = 1 / (1 + exp(-m_pTMatrix [i][j]));
}
}
return cMatrix;
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵中所有的元素进行一次非线性变换:
// 变换后的值y与变换前的值的关系是:
// y = tanh(x) = (1 - exp(-x)) / (1 + exp(-x))
// = 1 - 2 * exp(-x) / (1 + exp(-x)) ( -1 < f(x) < 1)
//
/////////////////////////////////////////////////////////////////////////////
CMatrix CMatrix::tanh ()
{
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = 1 - (2 * exp(-m_pTMatrix [i][j])) / (1 + exp(-m_pTMatrix [i][j]));
}
}
return cMatrix;
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵中所有的元素进行一次非线性变换:
// 变换后的值y与变换前的值的关系是:
// y = Tansig(x) = 2 / (1 + exp(-2 * x)) -1
/////////////////////////////////////////////////////////////////////////////
CMatrix CMatrix::Tansig()
{
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = 2 / (1 + exp(- 2 * m_pTMatrix [i][j])) - 1;
}
}
return cMatrix;
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵中所有的元素进行一次非线性变换:
// 变换后的值y与变换前的值的关系是:
// y = Tansig'(x) = (2 / (1 + exp(-2 * x)) -1)'
// = (2 / (1 + exp(-2 * x)) -1) * (2 / (1 + exp(-2 * x)) -1) -1
/////////////////////////////////////////////////////////////////////////////
CMatrix CMatrix::TansigDerivative()
{
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = (2 / (1 + exp(- 2 * m_pTMatrix [i][j])) - 1) * (2 / (1 + exp(- 2 * m_pTMatrix [i][j])) - 1) - 1;
}
}
return cMatrix;
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵中的元素进行一次操作:
// 使所有行中的相对应的列元素相等
// Parameter:
// nRowIndex ----> 行索引值(从零开始)
// 以此行做为标准,使矩阵中其余的行相对应的列的值
// 与此行相对应的列的值相等
/////////////////////////////////////////////////////////////////////////////
void CMatrix::MakeAllColumnElementsSameValue(unsigned int nRowIndex)
{
for(unsigned int i=0; i < m_nRow; i++)
{
if(i == nRowIndex)
continue;
for(unsigned int j=0; j < m_nCol; j++)
{
m_pTMatrix [i][j] = m_pTMatrix [nRowIndex][j];
}
}
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵中所有的元素进行一次非线性变换:
// 变换后的值y与变换前的值的关系是:
// y = f'(x) = (1 / (1 + exp(-x)))' ( 0 < f(x) < 1)
// = exp(-x)/((1 + exp(-x))*(1 + exp(-x)))
/////////////////////////////////////////////////////////////////////////////
CMatrix CMatrix::SigmoidDerivative()
{
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = exp(-m_pTMatrix [i][j]) / ((1 + exp(-m_pTMatrix [i][j])) * (1 + exp(-m_pTMatrix [i][j])));
}
}
return cMatrix;
}
/////////////////////////////////////////////////////////////////////////////
// 对矩阵中所有的元素进行一次非线性变换:
// 变换后的值y与变换前的值的关系是:
// y = tanh'(x) = ((1 - exp(-x)) / (1 + exp(-x)))' ( -1 < f(x) < 1)
// = 2*exp(-x)/((1 + exp(-x))*(1 + exp(-x)))
/////////////////////////////////////////////////////////////////////////////
CMatrix CMatrix::tanhDerivative()
{
CMatrix cMatrix = *this;
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = 2 * exp(-m_pTMatrix [i][j]) / ((1 + exp(-m_pTMatrix [i][j])) * (1 + exp(-m_pTMatrix [i][j])));
}
}
return cMatrix;
}
/////////////////////////////////////////////////////////////////////////////
// 实现对点乘操作符的重载
/////////////////////////////////////////////////////////////////////////////
CMatrix CMatrix::operator / (CMatrix& cMatrixB)
{
CMatrix cMatrix = *this;
if( (m_nRow != cMatrixB.m_nRow) || (m_nCol != cMatrixB.m_nCol) )
{
::AfxMessageBox (TEXT("两个矩阵的维数不相等,不满足矩阵点乘的条件!"),MB_OK | MB_ICONERROR);
return cMatrix; // return a invalid value
}
for(unsigned int i=0; i < m_nRow; i++)
{
for(unsigned int j=0; j < m_nCol; j++)
{
cMatrix.m_pTMatrix [i][j] = m_pTMatrix [i][j] * cMatrixB.m_pTMatrix [i][j];
}
}
return cMatrix;
}
//***************************************************************************
// ordinary function
//
/////////////////////////////////////////////////////////////////////////////
// 重载 'double - CMatrix' 运算符
/////////////////////////////////////////////////////////////////////////////
CMatrix operator - (double nValue,CMatrix& cMatrixB)
{
CMatrix cMatrix = cMatrixB;
for(unsigned int i=0; i < cMatrix.GetMatrixRowNumber (); i++)
{
for(unsigned int j=0; j < cMatrix.GetMatrixColNumber (); j++)
{
cMatrix.m_pTMatrix [i][j] = nValue - cMatrixB.m_pTMatrix [i][j];
}
}
return cMatrix;
}
/////////////////////////////////////////////////////////////////////////////
// 矩阵合并运算符
// 合并规则:
// 1. 参与合并运算的两个矩阵的行数必须相等;
// 2. 参与合并的两个矩阵的列数可以不相等;
// 3. 合并后返回的矩阵的行数与参与合并的矩阵的行数相等,列数是参与合并的
// 两个矩阵的列数之和;
/////////////////////////////////////////////////////////////////////////////
CMatrix MergeMatrix(CMatrix& cMatrixA,CMatrix& cMatrixB)
{
// 条件检测
if( cMatrixA.GetMatrixRowNumber () != cMatrixB.GetMatrixRowNumber () )
{
::AfxMessageBox (TEXT("参与合并的两个矩阵的行数不相等!"),MB_OK | MB_ICONERROR);
return cMatrixA; // return invalid value
}
CMatrix cMatrix(cMatrixA.GetMatrixRowNumber (),cMatrixA.GetMatrixColNumber () + cMatrixB.GetMatrixColNumber ());
for(unsigned int i=0; i < cMatrixA.GetMatrixRowNumber (); i++)
{
for(unsigned int j=0; j < cMatrixA.GetMatrixColNumber (); j++)
{
cMatrix.m_pTMatrix [i][j] = cMatrixA.m_pTMatrix [i][j];
}
for(unsigned int k=0; k < cMatrixB.GetMatrixColNumber (); k++)
{
cMatrix.m_pTMatrix [i][cMatrixA.GetMatrixColNumber () + k] = cMatrixB.m_pTMatrix [i][k];
}
}
return cMatrix;
}
// End of ordinary function
//***************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -