www.pudn.com > NNBP.rar > Matrix.cpp
///////////////////////////////////////////////////////////////////////////// // Matrix.cpp : Implementation of the class Matrix // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Matrix.h" #include#include #include #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CMatrix::CMatrix() { 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; } } } CMatrix::~CMatrix() { } CMatrix::CMatrix(unsigned int nRow,unsigned int nCol) { // 动态分配二维数组 TMatrix tMatrix; tMatrix.resize (nRow); for(unsigned int i=0; i < nRow; i++) { for(unsigned int j=0; j < nCol; j++) { tMatrix[i].resize(nCol); tMatrix[i][j] = (double) 0; } } // 对对象变量赋值 m_nRow = nRow; m_nCol = nCol; m_pTMatrix = tMatrix; } CMatrix::CMatrix(CMatrix& cMatrixB) { // Initialize the variable m_nRow = cMatrixB.m_nRow ; m_nCol = cMatrixB.m_nCol ; m_pTMatrix = cMatrixB.m_pTMatrix ; // Copy Data for(unsigned int i=0; i< cMatrixB.m_nRow; i++) { for(unsigned int j=0; j < cMatrixB.m_nCol; j++) { m_pTMatrix [i][j] = cMatrixB.m_pTMatrix [i][j]; } } } ///////////////////////////////////////////////////////////////////////////// // CMatrix member functions // CMatrix CMatrix::operator +(CMatrix& cMatrixB) { // 要满足矩阵相加的条件: 行列数目相等! if(m_nRow != cMatrixB.m_nRow || m_nCol != cMatrixB.m_nCol ) { ::AfxMessageBox (TEXT("执行相加的两个矩阵维数不相等!"),MB_OK | MB_ICONERROR); } 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] = m_pTMatrix [i][j] + cMatrixB.m_pTMatrix [i][j]; } } return cMatrix; } CMatrix CMatrix::operator -(CMatrix& cMatrixB) { // 要满足矩阵相加的条件: 行列数数目相等! if(m_nRow != cMatrixB.m_nRow || m_nCol != cMatrixB.m_nCol ) { ::AfxMessageBox (TEXT("执行相减的两个矩阵维数不相等!"),MB_OK | MB_ICONERROR); } 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] = m_pTMatrix [i][j] - cMatrixB.m_pTMatrix [i][j]; } } return cMatrix; } CMatrix CMatrix::operator *(CMatrix& cMatrixB) { if( m_nCol != cMatrixB.m_nRow ) { ::AfxMessageBox (TEXT("执行相乘的两个矩阵维数不满足相乘的条件!"),MB_OK | MB_ICONERROR); } CMatrix cResultMatrix(m_nRow,cMatrixB.m_nCol); for(unsigned int i=0; i < m_nRow; i++) { for(unsigned int j=0; j < cMatrixB.m_nCol; j++) { for(unsigned int m=0; m < m_nCol; m++) { cResultMatrix.m_pTMatrix [i][j] += m_pTMatrix [i][m] * cMatrixB.m_pTMatrix [m][j]; } } } return cResultMatrix; } CMatrix CMatrix::operator * (double nValue) { 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] =m_pTMatrix [i][j] * nValue; } } return cMatrix; } CMatrix& CMatrix::operator =(CMatrix& cMatrixB) { if( (m_nRow != cMatrixB.m_nRow) || (m_nCol != cMatrixB.m_nCol) ) { ::AfxMessageBox(TEXT("等号左右两边的矩阵的维数不相等!"),MB_OK | MB_ICONERROR); return *this; // return invalid value } // 给变量赋值 m_nRow = cMatrixB.m_nRow ; m_nCol = cMatrixB.m_nCol ; m_pTMatrix = cMatrixB.m_pTMatrix ; // 赋值操作 for(unsigned int i=0; i < cMatrixB.m_nRow; i++) { for(unsigned int j=0; j< cMatrixB.m_nCol; j++) { m_pTMatrix [i][j] = cMatrixB.m_pTMatrix [i][j]; } } return *this; } CMatrix& CMatrix::operator += (CMatrix& cMatrixB) { if(m_nRow != cMatrixB.m_nRow || m_nCol != cMatrixB.m_nCol ) { //printf("错误!执行相加的两个矩阵维数不相等!\n"); ::AfxMessageBox (TEXT("运算符的两边矩阵的维数不相等!"),MB_OK | MB_ICONERROR); return *this; // return invalid value } // 赋值操作 for(unsigned int i=0; i < cMatrixB.m_nRow; i++) { for(unsigned int j=0; j< cMatrixB.m_nCol; j++) { m_pTMatrix [i][j] += cMatrixB.m_pTMatrix [i][j]; } } return *this; } CMatrix CMatrix::Transpose() { CMatrix cMatrix(m_nCol,m_nRow); for(unsigned int i=0; i < m_nRow; i++) { for(unsigned int j=0; j < m_nCol; j++) { cMatrix.m_pTMatrix [j][i] = m_pTMatrix [i][j]; } } return cMatrix; } ///////////////////////////////////////////////////////////////////////////// // 将矩阵的所有的元素按列合成一列 // 例如: // matrix = [ // 1 2 3 // 4 5 6 // 7 8 9 // ] // CMatrix cMatrix = matrix.MergeColumnsToColumnVector(); // cMatrix = // [ 1 // 4 // 7 // 2 // 5 // 8 // 3 // 6 // 9 ] ///////////////////////////////////////////////////////////////////////////// CMatrix CMatrix::MergeColumnsToColumnVector() { CMatrix cMatrix(m_nRow * m_nCol,(unsigned int)1); // 对矩阵赋值 for(unsigned int j=0; j < m_nCol; j++) { for(unsigned int i=0; i < m_nRow; i++) { cMatrix.m_pTMatrix [i + j * m_nRow][(unsigned int)0] = m_pTMatrix [i][j]; } } return cMatrix; } ///////////////////////////////////////////////////////////////////////////// // Get the total value of the matrix ///////////////////////////////////////////////////////////////////////////// double CMatrix::GetTotalElementValue() { double nTotalValue = 0; for(unsigned int i=0; i < m_nRow; i++) { for( unsigned int j=0; j < m_nCol; j++) { nTotalValue += m_pTMatrix [i][j]; } } return nTotalValue; } ///////////////////////////////////////////////////////////////////////////// // Get System Error ///////////////////////////////////////////////////////////////////////////// double CMatrix::GetSystemError() const { double nSystemError = 0; for(unsigned int i=0; i < m_nRow; i++) { for( unsigned int j=0; j < m_nCol; j++) { nSystemError += m_pTMatrix [i][j] * m_pTMatrix [i][j]; } } return nSystemError; } ///////////////////////////////////////////////////////////////////////////// // Make all the matrix elements to be changed into absolute value ///////////////////////////////////////////////////////////////////////////// CMatrix CMatrix::AbsoluteValue () { 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] = fabs( m_pTMatrix [i][j]); } } return cMatrix; } CMatrix CMatrix::Inverse() { ///////////////////////////////////////////////////////////////////////// // Using Gauss - Jordan Method // 参考书目: 计算机数值方法 --->施吉林 陈桂枝 ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// // 判断是否是可逆阵: // 可逆阵一定是方阵!!! if ( m_nRow != m_nCol) { //printf("错误!矩阵的行列数不相等,是非可逆阵!\n"); ::AfxMessageBox (TEXT("矩阵的行列数不相等,是非可逆阵!"),MB_OK | MB_ICONERROR); } CMatrix cMatrix = *this; //*********************************************************************** // 思路:(非常规思维!) // 动态分配整型数组(2*m_nCol)来存储每次交换的行坐标的值 // 不论有没有行交换都记录在数组中, // 1.没进行行交换的两个数据相等,在SwapMatrixRow()函数中 // 检测到两个值相等立即返回,在SwapMatrixCol()函数中也一样, // 检测到两个值相等立即返回,不占用系统资源; // 2.不相等的就交换 //*********************************************************************** // 分配内存 int *pIntArray = new int [2*m_nCol]; // nSetp --- 约化步数,按列展开 for(unsigned int k=0; k < cMatrix.m_nCol; k++) { ///////////////////////////////////////////////////////////////////// // 进行行交换 ---> 游戏规则: // 为保证计算过程的数值稳定性,在第k步约化时,先在{a(ik)}|i=k->n中选按 // 模最大者作为约化主元素,并交换矩阵相应的行 // 标记主元素 double nMaxElement = cMatrix.m_pTMatrix [k][k]; // 标记主元素所在的行数 unsigned int nMainRow = k; for(unsigned int nCount = k+1; nCount < cMatrix.m_nCol; nCount++) { if( fabs(nMaxElement) < fabs(cMatrix.m_pTMatrix [nCount][k]) ) { nMaxElement = cMatrix.m_pTMatrix [nCount][k]; nMainRow = nCount; } } // 将欲交换的行数存在数组中 pIntArray [2*k] = k; pIntArray [2*k+1] = nMainRow; // 交换行 cMatrix.SwapMatrixRow(k,nMainRow); //Display(); // 判断是否是可逆阵 if(cMatrix.m_pTMatrix [k][k] == 0) { //printf("错误!此矩阵为非可逆阵!\n"); ::AfxMessageBox (TEXT("此矩阵为非可逆阵,没有逆矩阵!"),MB_OK | MB_ICONERROR); } cMatrix.m_pTMatrix [k][k] = 1/(cMatrix.m_pTMatrix [k][k]); // 算主列 for(unsigned int i=0; i < cMatrix.m_nRow; i++) { if( i != k) cMatrix.m_pTMatrix [i][k] = -(cMatrix.m_pTMatrix [k][k]) * (cMatrix.m_pTMatrix [i][k]); //int nTempValue = m_pTMatrix [i][k]; } //printf("\n"); // 约化非主行 for(unsigned int m=0; m < cMatrix.m_nRow; m++) { if ( m == k) continue; for(unsigned int n=0; n < cMatrix.m_nCol; n++) { if ( n == k) continue; cMatrix.m_pTMatrix [m][n] += cMatrix.m_pTMatrix [m][k] * cMatrix.m_pTMatrix [k][n]; //printf("%10f ",m_pTMatrix [m][n]); } //printf("\n"); } // 算主行 for(unsigned int j=0; j < cMatrix.m_nCol; j++) { if( j != k) cMatrix.m_pTMatrix [k][j] = (cMatrix.m_pTMatrix [k][k]) * (cMatrix.m_pTMatrix [k][j]); } } ///////////////////////////////////////////////////////////////////////// // 进行列交换 ---> 对交换行后的矩阵进行列交换 ---> 还原矩阵 // 游戏规则: // 将开始矩阵中进行的行交换 ---> 现用相对应的列交换进行还原,即可得到所求的 // 逆矩阵 for(int i=2*m_nCol-1; i > 0; i--) { cMatrix.SwapMatrixCol(pIntArray[i],pIntArray[i-1]); i--; } delete []pIntArray; return cMatrix; } void CMatrix::SwapMatrixRow(unsigned int nRow1,unsigned int nRow2) { if( nRow1 == nRow2) return; double *pArray = new double; for(unsigned int i=0; i < m_nCol; i++) { // Swap the datum of the two rows pArray[0] = m_pTMatrix [nRow1][i]; m_pTMatrix [nRow1][i] = m_pTMatrix [nRow2][i]; m_pTMatrix [nRow2][i] = pArray[0]; } delete pArray; } void CMatrix::SwapMatrixCol(unsigned int nCol1,unsigned int nCol2) { if( nCol1 == nCol2) return; double *pArray = new double; for(unsigned int i=0; i < m_nRow; i++) { // Swap the datum of the two columns pArray[0] = m_pTMatrix [i][nCol1]; m_pTMatrix [i][nCol1] = m_pTMatrix [i][nCol2]; m_pTMatrix [i][nCol2] = pArray[0]; } delete pArray; } bool CMatrix::LoadDataFromFile(CString& strFileName) { CStdioFile dataFile; LPCTSTR lpszFileName = ""; // CString convert to LPCTSTR strFileName.TrimLeft (); strFileName.TrimRight (); //strFileName.Format (lpszFileName); lpszFileName = (LPCTSTR)strFileName; if(!dataFile.Open (lpszFileName,CFile::modeRead | CFile::typeText)) { ::AfxMessageBox (TEXT("不能打开要读取数据的文件!"),MB_OK | MB_ICONERROR); dataFile.Close (); return FALSE; } // 用来存储提取文本文件中一行的数据 CString strData; // 用来记录文本文件中一共有多少行数据? unsigned int nRow = 0; ///////////////////////////////////////////////////////////////////////// // Step 1: 得到文件的行列数目并根据文本文件的行列数目来设置对象(矩阵)的行 // 列数目 // while(dataFile.ReadString (strData) != FALSE) { ++nRow; } // 根据文本文件的数据的行数设置对象(矩阵)的行数 m_nRow = nRow; SetMatrixRowNumber(m_nRow); // 重新定位当前文件指针到文件开头 dataFile.SeekToBegin (); dataFile.ReadString (strData); strData.TrimLeft (); strData.TrimRight (); TCHAR SPACE_CHARACTER = ' '; // 用来记录文本文件中一行有多少列? unsigned int nCol = 0; // 空格符在字符串中的位置索引 int nIndex = 0; do { nIndex = strData.Find (SPACE_CHARACTER); ++nCol; // 提取字符串的子字符串,即提取一个double型实数数据 //CString strDoubleNumber = strData.Left (nIndex); // 将字符串转换为double型实数 //double RealNumber = atof(strDoubleNumber); //int nTempNumber = strData.GetLength (); strData = strData.Right (strData.GetLength () - nIndex -1); // 去掉多余的空格 strData.TrimLeft (); // Use for debugging //int nTempNum = strData.GetLength (); }while(nIndex != -1); // 根据文本文件的数据的列数设置对象(矩阵)的列数 m_nCol = nCol; SetMatrixColNumber(m_nCol); // End of Getting the Rows and Cols of the Text File ///////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// // Step 2: 根据文本文件中的数据对矩阵赋值,并检测每行的列数是否和第一行的 // 列数相等,不相等提示出错信息 // // 重新定位当前文件指针到文件开头 dataFile.SeekToBegin (); // 对矩阵中的元素装入文本文件的数据 for(unsigned int i=0; i < m_nRow; i++) { dataFile.ReadString (strData); strData.TrimLeft (); strData.TrimRight (); // 验证每行的列数是否与第一行的列数相等 unsigned int nVerifyColNum = 0; do { nIndex = strData.Find (SPACE_CHARACTER); ++nVerifyColNum; if(nIndex != -1) { // 提取字符串的子字符串,即提取一个double型实数数据 CString strDoubleNumber = strData.Left (nIndex); // 将字符串转换为double型实数 double RealNumber = atof(strDoubleNumber); m_pTMatrix [i][nVerifyColNum - 1] = RealNumber; //int nTempNumber = strData.GetLength (); strData = strData.Right (strData.GetLength () - nIndex -1); // 去掉多余的空格 strData.TrimLeft (); // Using for debugging //double nReadNumber = m_pTMatrix [i][nVerifyColNum - 1]; // Using for debugging //int nTempNum = strData.GetLength (); } else { double RealNumber = atof(strData); m_pTMatrix [i][nVerifyColNum - 1] = RealNumber; } }while(nIndex != -1); if(nVerifyColNum != m_nCol) { CString strRowNumber; strRowNumber.Format("%d",i + 1); CString strColNumber; strColNumber.Format("%d",m_nCol); CString strVerifyColNumber; strVerifyColNumber.Format("%d",nVerifyColNum); CString strMessage = CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!")); LPCTSTR lpszText = ""; lpszText = (LPCTSTR)strMessage; //strMessage.FormatMessage (lpszText); //::AfxMessageBox (lpszText,MB_OK); ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR); dataFile.Close (); return false; } } dataFile.Close (); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // Load the data from the file and reset the rows and the colums of // the matrixes. // Parameter: // [in] strFileName // [out]cMatrixInputToHideWeightValue // [out]cMatrixHideLayerValveValue // [out]cMatrixHideToOutputWeightValue // [out]cMatrixOutputLayerValveValue // [out]nInputLayerNumber // [out]nHideLayerNumber // [out]nOutputLayerNumber // [out]nComboArithmetic // [out]nComboFunc ///////////////////////////////////////////////////////////////////////////// bool CMatrix::LoadDataFromFileSpecial (CString& strFileName, CMatrix& cMatrixInputToHideWeightValue, CMatrix& cMatrixHideLayerValveValue, CMatrix& cMatrixHideToOutputWeightValue, CMatrix& cMatrixOutputLayerValveValue, unsigned int &nInputLayerNumber, unsigned int &nHideLayerNumber, unsigned int &nOutputLayerNumber, int &nComboArithmetic, int &nComboFunc) { CStdioFile dataFile; LPCTSTR lpszFileName = ""; // CString convert to LPCTSTR strFileName.TrimLeft (); strFileName.TrimRight (); lpszFileName = (LPCTSTR)strFileName; if(!dataFile.Open (lpszFileName,CFile::modeRead | CFile::typeText)) { ::AfxMessageBox (TEXT("不能打开要读取的数据文件!!!"),MB_OK | MB_ICONERROR); dataFile.Close (); return FALSE; } // 提取网络参数 dataFile.SeekToBegin (); // 用来存储提取文本文件中一行的数据 CString strData; // 注释标志符号 TCHAR cFirstCharacter = '#'; // 空格符号 TCHAR SPACE_CHARACTER = ' '; // 空格符在字符串中的位置索引 int nIndex = 0; // 读取文件中的网络的输入层数目 while(dataFile.ReadString (strData)) { strData.TrimLeft (); strData.TrimRight (); if((strData.Find (cFirstCharacter)) == 0) { continue; } else { LPCSTR strInputLayerNumber = (LPCSTR)strData; nInputLayerNumber = (unsigned int)atoi(strInputLayerNumber); break; } } // 读取文件中的网络的隐含层数目 while(dataFile.ReadString (strData)) { strData.TrimLeft (); strData.TrimRight (); if((strData.Find (cFirstCharacter)) == 0) { continue; } else { LPCSTR strHideLayerNumber = (LPCSTR)strData; nHideLayerNumber = (unsigned int)atoi(strHideLayerNumber); break; } } // 读取文件中的网络的输出层数目 while(dataFile.ReadString (strData)) { strData.TrimLeft (); strData.TrimRight (); if((strData.Find (cFirstCharacter)) == 0) { continue; } else { LPCSTR strOutputLayerNumber = (LPCSTR)strData; nOutputLayerNumber = (unsigned int)atoi(strOutputLayerNumber); break; } } // 读取文件中的训练网络所使用的算法的索引值 while(dataFile.ReadString (strData)) { strData.TrimLeft (); strData.TrimRight (); if((strData.Find (cFirstCharacter)) == 0) { continue; } else { LPCSTR strComboArithmetic = (LPCSTR)strData; nComboArithmetic = atoi(strComboArithmetic); break; } } // 读取文件中的网络的使用的函数的索引值 while(dataFile.ReadString (strData)) { strData.TrimLeft (); strData.TrimRight (); if((strData.Find (cFirstCharacter)) == 0) { continue; } else { LPCSTR strComboFunc = (LPCSTR)strData; nComboFunc = atoi(strComboFunc); break; } } // 根据网络参数设置输入层到隐含层的权值矩阵的行列数 cMatrixInputToHideWeightValue.SetMatrixRowAndCol (nHideLayerNumber,nInputLayerNumber); // 验证矩阵的行数 unsigned int nVerifyRowNum = 0; // 读取文件中的输入层到隐含层的权值矩阵到相应的矩阵对象中 while(dataFile.ReadString (strData)) { strData.TrimLeft (); strData.TrimRight (); if((strData.Find (cFirstCharacter)) == 0) { continue; } else { // 装入文本文件的数据到相对应的矩阵中 strData.TrimLeft (); strData.TrimRight (); // 验证每行的列数是否与第一行的列数相等 unsigned int nVerifyColNum = 0; do { nIndex = strData.Find (SPACE_CHARACTER); ++nVerifyColNum; if(nIndex != -1) { // 提取字符串的子字符串,即提取一个double型实数数据 CString strDoubleNumber = strData.Left (nIndex); // 将字符串转换为double型实数 double RealNumber = atof(strDoubleNumber); cMatrixInputToHideWeightValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber; strData = strData.Right (strData.GetLength () - nIndex -1); // 去掉多余的空格 strData.TrimLeft (); } else { double RealNumber = atof(strData); cMatrixInputToHideWeightValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber; } }while(nIndex != -1); if(nVerifyColNum != cMatrixInputToHideWeightValue.m_nCol) { CString strRowNumber; strRowNumber.Format("%d",nVerifyRowNum + 1); CString strColNumber; strColNumber.Format("%d",m_nCol); CString strVerifyColNumber; strVerifyColNumber.Format("%d",nVerifyColNum); CString strMessage = CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!")); LPCTSTR lpszText = ""; lpszText = (LPCTSTR)strMessage; ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR); dataFile.Close (); return FALSE; } ++nVerifyRowNum; if( nVerifyRowNum == cMatrixInputToHideWeightValue.m_nRow ) { break; } } } // Using for debugging //CString strInputToHideWeightValue = TEXT("TempInputToHideWeightValue.txt"); //cMatrixInputToHideWeightValue.SaveDataToFile (strInputToHideWeightValue); // 根据网络参数设置隐含层的阀值矩阵的行列数 cMatrixHideLayerValveValue.SetMatrixRowAndCol (nHideLayerNumber,(unsigned int)1); nIndex = 0; nVerifyRowNum = 0; // 读取文件中的隐含层的阀值矩阵到相应的矩阵对象中 while(dataFile.ReadString (strData)) { strData.TrimLeft (); strData.TrimRight (); if((strData.Find (cFirstCharacter)) == 0) { continue; } else { // 装入文本文件的数据到相对应的矩阵中 strData.TrimLeft (); strData.TrimRight (); // 验证每行的列数是否与第一行的列数相等 unsigned int nVerifyColNum = 0; do { nIndex = strData.Find (SPACE_CHARACTER); ++nVerifyColNum; if(nIndex != -1) { // 提取字符串的子字符串,即提取一个double型实数数据 CString strDoubleNumber = strData.Left (nIndex); // 将字符串转换为double型实数 double RealNumber = atof(strDoubleNumber); cMatrixHideLayerValveValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber; strData = strData.Right (strData.GetLength () - nIndex -1); // 去掉多余的空格 strData.TrimLeft (); } else { double RealNumber = atof(strData); cMatrixHideLayerValveValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber; } }while(nIndex != -1); if(nVerifyColNum != cMatrixHideLayerValveValue.m_nCol) { CString strRowNumber; strRowNumber.Format("%d",nVerifyRowNum + 1); CString strColNumber; strColNumber.Format("%d",m_nCol); CString strVerifyColNumber; strVerifyColNumber.Format("%d",nVerifyColNum); CString strMessage = CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!")); LPCTSTR lpszText = ""; lpszText = (LPCTSTR)strMessage; ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR); dataFile.Close (); return FALSE; } ++nVerifyRowNum; if( nVerifyRowNum == cMatrixHideLayerValveValue.m_nRow ) { break; } } } // Using for debugging //CString strHideLayerValveValue = TEXT("TempHideLayerValveValue.txt"); //cMatrixHideLayerValveValue.SaveDataToFile (strHideLayerValveValue); // 根据网络参数设置隐含层到输出层的权值矩阵的行列数 cMatrixHideToOutputWeightValue.SetMatrixRowAndCol (nOutputLayerNumber,nHideLayerNumber); nIndex = 0; nVerifyRowNum = 0; // 读取文件中的隐含层到输出层的权值矩阵到相应的矩阵对象中 while(dataFile.ReadString (strData)) { strData.TrimLeft (); strData.TrimRight (); if((strData.Find (cFirstCharacter)) == 0) { continue; } else { // 装入文本文件的数据到相对应的矩阵中 strData.TrimLeft (); strData.TrimRight (); // 验证每行的列数是否与第一行的列数相等 unsigned int nVerifyColNum = 0; do { nIndex = strData.Find (SPACE_CHARACTER); ++nVerifyColNum; if(nIndex != -1) { // 提取字符串的子字符串,即提取一个double型实数数据 CString strDoubleNumber = strData.Left (nIndex); // 将字符串转换为double型实数 double RealNumber = atof(strDoubleNumber); cMatrixHideToOutputWeightValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber; strData = strData.Right (strData.GetLength () - nIndex -1); // 去掉多余的空格 strData.TrimLeft (); } else { double RealNumber = atof(strData); cMatrixHideToOutputWeightValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber; } }while(nIndex != -1); if(nVerifyColNum != cMatrixHideToOutputWeightValue.m_nCol) { CString strRowNumber; strRowNumber.Format("%d",nVerifyRowNum + 1); CString strColNumber; strColNumber.Format("%d",m_nCol); CString strVerifyColNumber; strVerifyColNumber.Format("%d",nVerifyColNum); CString strMessage = CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!")); LPCTSTR lpszText = ""; lpszText = (LPCTSTR)strMessage; ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR); dataFile.Close (); return FALSE; } ++nVerifyRowNum; if( nVerifyRowNum == cMatrixHideToOutputWeightValue.m_nRow ) { break; } } } // Using for debugging //CString strHideToOutputWeightValue = TEXT("TempHideToOutputWeightValue.txt"); //cMatrixHideToOutputWeightValue.SaveDataToFile (strHideToOutputWeightValue); // 根据网络参数设置输出层的阀值矩阵的行列数 cMatrixOutputLayerValveValue.SetMatrixRowAndCol (nOutputLayerNumber,(unsigned int)1); nIndex = 0; nVerifyRowNum = 0; // 读取文件中的输出层的阀值矩阵到相应的矩阵对象中 while(dataFile.ReadString (strData)) { strData.TrimLeft (); strData.TrimRight (); if((strData.Find (cFirstCharacter)) == 0) { continue; } else { // 装入文本文件的数据到相对应的矩阵中 strData.TrimLeft (); strData.TrimRight (); // 验证每行的列数是否与第一行的列数相等 unsigned int nVerifyColNum = 0; do { nIndex = strData.Find (SPACE_CHARACTER); ++nVerifyColNum; if(nIndex != -1) { // 提取字符串的子字符串,即提取一个double型实数数据 CString strDoubleNumber = strData.Left (nIndex); // 将字符串转换为double型实数 double RealNumber = atof(strDoubleNumber); cMatrixOutputLayerValveValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber; strData = strData.Right (strData.GetLength () - nIndex -1); // 去掉多余的空格 strData.TrimLeft (); } else { double RealNumber = atof(strData); cMatrixOutputLayerValveValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber; } }while(nIndex != -1); if(nVerifyColNum != cMatrixOutputLayerValveValue.m_nCol) { CString strRowNumber; strRowNumber.Format("%d",nVerifyRowNum + 1); CString strColNumber; strColNumber.Format("%d",m_nCol); CString strVerifyColNumber; strVerifyColNumber.Format("%d",nVerifyColNum); CString strMessage = CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!")); LPCTSTR lpszText = ""; lpszText = (LPCTSTR)strMessage; ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR); dataFile.Close (); return FALSE; } ++nVerifyRowNum; if( nVerifyRowNum == cMatrixOutputLayerValveValue.m_nRow ) { break; } } } // Using for debugging //CString strOutputLayerValveValue = TEXT("TempOutputLayerValveValue.txt"); //cMatrixOutputLayerValveValue.SaveDataToFile (strOutputLayerValveValue); dataFile.Close (); return TRUE; } bool CMatrix::SaveDataToFile (CString& strFileName) { CStdioFile dataFile; LPCTSTR lpszFileName = ""; // CString convert to LPCTSTR strFileName.TrimLeft (); strFileName.TrimRight (); lpszFileName = (LPCTSTR)strFileName; if(!dataFile.Open (lpszFileName,CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::typeText)) { ::AfxMessageBox(TEXT("不能创建文件!"),MB_OK | MB_ICONERROR); dataFile.Close (); return false; } dataFile.SeekToEnd (); // 将对象(矩阵)中的数据写进文件 for(unsigned int i=0; i < m_nRow; i++) { for(unsigned int j=0; j < m_nCol; j++) { CString strRealNumber; strRealNumber.Format ("%.16f ", m_pTMatrix [i][j]); // Using for debugging //double nReadNumber = m_pTMatrix [i][j]; char *pBuffer = new char[strRealNumber.GetLength()]; memcpy(pBuffer,strRealNumber,strRealNumber.GetLength()); dataFile.Write (pBuffer,strRealNumber.GetLength ()); } if( i != m_nRow - 1) { //char ReturnNewline[] = "\r\n"; char ReturnNewline[] = "\n"; dataFile.Write (ReturnNewline, (sizeof(ReturnNewline) - 1)/sizeof(char)); } } dataFile.Close (); return true; } ///////////////////////////////////////////////////////////////////////////// // 对矩阵中的元素进行一次操作: // 使矩阵变为单位阵 ///////////////////////////////////////////////////////////////////////////// void CMatrix::Eye() { // Verify whether the rows is equal to the columns or not if(m_nRow != m_nCol) { ::AfxMessageBox (TEXT("此矩阵的行列数不相等!不能转变为单位阵!"),MB_OK | MB_ICONERROR); return; } for(unsigned int i=0; i < m_nRow; i++) { for(unsigned int j=0; j < m_nCol; j++) { if(i == j) { m_pTMatrix [i][j] = 1; } else { m_pTMatrix [i][j] = 0; } } } } ///////////////////////////////////////////////////////////////////////////// // Parameter: // CMatrix& cMatrix: 被拷贝的数据源 // unsigned int nIndex: 被拷贝的数据在对象中的开始索引位置,从0开始 // Purpose: // This function will copy all the data of the cMatrix // Notes: // 此对象必须是列向量!!! ///////////////////////////////////////////////////////////////////////////// void CMatrix::GetMatrixData(CMatrix& cMatrix, unsigned int nIndex) { if(m_nCol != 1) { ::AfxMessageBox (TEXT("拷贝的矩阵不是列向量!"),MB_OK | MB_ICONERROR); return; } if((m_nRow - nIndex) < (cMatrix.m_nRow * cMatrix.m_nCol)) { ::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++) { m_pTMatrix [nIndex + i * cMatrix.m_nCol + j][0] = cMatrix.m_pTMatrix [i][j]; } } } ///////////////////////////////////////////////////////////////////////////// // Parameter: // CMatrix& cMatrix: 被填充的矩阵 // unsigned int nIndex: 被拷贝的数据在对象中的开始索引位置 // Purpose: // This function will copy part of the object data into cMatrix // Notes: // The object must be column vector!!! ///////////////////////////////////////////////////////////////////////////// void CMatrix::SetMatrixData(CMatrix& cMatrix, unsigned int nIndex) { // Verify whether the colunm number is 1 if(m_nCol != 1) { ::AfxMessageBox (TEXT("本矩阵对象不是列向量,不满足条件!"),MB_OK | MB_ICONERROR); return; } // Verify whether the number of the object element is enough to be copyed if((m_nRow - nIndex) < (cMatrix.m_nRow * cMatrix.m_nCol)) { ::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 [nIndex + i * cMatrix.m_nCol + j][0]; // Using for debugging //unsigned int nIndexNumber = nIndex + i * cMatrix.m_nRow + j; //double nData = cMatrix.m_pTMatrix [i][j]; } } } ///////////////////////////////////////////////////////////////////////////// // Parameter: // CMatrix& cMatrix: 被填充的矩阵 // unsigned int nIndex: 被拷贝的数据在对象中的开始索引位置 // unsigned int nRow: 被填充的数据在被填充对象中的行索引 // Purpose: // This function will copy part of the object data to fill the special // row of the cMatrix // Notes: // The object must be column vector!!! ///////////////////////////////////////////////////////////////////////////// void CMatrix::SetMatrixRowData(CMatrix& cMatrix, unsigned int nIndex, unsigned int nRow) { // Verify whether the column number is 1 if(m_nCol != 1) { ::AfxMessageBox (TEXT("本矩阵对象不是列向量,不满足条件!"),MB_OK | MB_ICONERROR); return; } // Verify whether the number of the object element is enough to be copyed if((m_nRow - nIndex) < cMatrix.m_nCol ) { ::AfxMessageBox (TEXT("对象的元素数量不足!"),MB_OK | MB_ICONERROR); return; } for(unsigned int i=0; i < cMatrix.m_nCol; i++) { cMatrix.m_pTMatrix [nRow][i] = m_pTMatrix [nIndex + i][(unsigned int)0]; } } ///////////////////////////////////////////////////////////////////////////// // Parameter: // CMatrix& cMatrix: 被拷贝的数据源 // unsigned int nIndex: 被拷贝的数据在对象中的开始索引位置 // unsigned int nRow: 被拷贝的数据在被拷贝对象中的行索引(从0开始) // Purpose: // This function will copy all the data of the cMatrix // Notes: // 此对象必须是列向量!!! ///////////////////////////////////////////////////////////////////////////// void CMatrix::GetMatrixRowData(CMatrix& cMatrix, unsigned int nIndex, unsigned int nRow) { if(m_nCol != 1) { ::AfxMessageBox (TEXT("拷贝的矩阵不是列向量!"),MB_OK | MB_ICONERROR); return; } if((m_nRow - nIndex) < cMatrix.m_nCol) { ::AfxMessageBox (TEXT("拷贝矩阵的空间容量不足!"),MB_OK | MB_ICONERROR); return; } for(unsigned int i=0; i < cMatrix.m_nCol; i++) { m_pTMatrix [nIndex + i][(unsigned int)0] = cMatrix.m_pTMatrix [nRow][i]; } } void CMatrix::SetMatrixRowNumber(unsigned int nRow) { m_nRow = 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; } } } void CMatrix::SetMatrixColNumber(unsigned int nCol) { m_nCol = nCol; 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; } } } ///////////////////////////////////////////////////////////////////////// // 设置矩阵的行列数 void CMatrix::SetMatrixRowAndCol(unsigned int nRow,unsigned int nCol) { m_nRow = nRow; m_nCol = nCol; // 分配内存 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; } } } ///////////////////////////////////////////////////////////////////////////// // Initialize() // 矩阵初始化函数,矩阵的行列数目被初始化为零,矩阵中的元素全部初始化为零 ///////////////////////////////////////////////////////////////////////////// void CMatrix::Initialize() { 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; } } } ///////////////////////////////////////////////////////////////////////////// // 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 //***************************************************************************