Matrix.cpp
上传用户:guanx8y8
上传日期:2007-07-30
资源大小:326k
文件大小:48k
开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Matrix.cpp : Implementation of the class Matrix
  3. //
  4. /////////////////////////////////////////////////////////////////////////////
  5. #include "stdafx.h"
  6. #include "Matrix.h"
  7. #include <math.h>
  8. #include <stdlib.h>
  9. #include <conio.h>
  10. #include <stdio.h>
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. //////////////////////////////////////////////////////////////////////
  17. // Construction/Destruction
  18. //////////////////////////////////////////////////////////////////////
  19. CMatrix::CMatrix()
  20. {
  21. m_nRow = 0;
  22. m_nCol = 0;
  23. m_pTMatrix.resize (m_nRow);
  24. for(unsigned int i=0; i < m_nRow; i++)
  25. {
  26. for(unsigned int j=0; j < m_nCol; j++)
  27. {
  28. m_pTMatrix[i].resize (m_nCol);
  29. m_pTMatrix[i][j] = (double) 0;
  30. }
  31. }
  32. }
  33. CMatrix::~CMatrix()
  34. {
  35. }
  36. CMatrix::CMatrix(unsigned int nRow,unsigned int nCol)
  37. {
  38. // 动态分配二维数组
  39. TMatrix tMatrix;
  40. tMatrix.resize (nRow);
  41. for(unsigned int i=0; i < nRow; i++)
  42. {
  43. for(unsigned int j=0; j < nCol; j++)
  44. {
  45.         tMatrix[i].resize(nCol);
  46. tMatrix[i][j] = (double) 0;
  47. }
  48. }
  49. // 对对象变量赋值
  50. m_nRow = nRow;
  51. m_nCol = nCol;
  52. m_pTMatrix = tMatrix;
  53. }
  54. CMatrix::CMatrix(CMatrix& cMatrixB)
  55. {
  56. // Initialize the variable
  57. m_nRow = cMatrixB.m_nRow ;
  58. m_nCol = cMatrixB.m_nCol ;
  59. m_pTMatrix = cMatrixB.m_pTMatrix ;
  60. // Copy Data
  61. for(unsigned int i=0; i< cMatrixB.m_nRow; i++)
  62. {
  63. for(unsigned int j=0; j < cMatrixB.m_nCol; j++)
  64. {
  65. m_pTMatrix [i][j] = cMatrixB.m_pTMatrix [i][j];
  66. }
  67. }
  68. }
  69. /////////////////////////////////////////////////////////////////////////////
  70. // CMatrix member functions
  71. //
  72. CMatrix CMatrix::operator +(CMatrix& cMatrixB)
  73. {
  74. // 要满足矩阵相加的条件: 行列数目相等!
  75. if(m_nRow != cMatrixB.m_nRow || m_nCol != cMatrixB.m_nCol )
  76. {
  77. ::AfxMessageBox (TEXT("执行相加的两个矩阵维数不相等!"),MB_OK | MB_ICONERROR);
  78. }
  79. CMatrix cMatrix = *this;
  80. for(unsigned int i=0; i < m_nRow; i++)
  81. {
  82. for(unsigned int j=0; j < m_nCol; j++)
  83. {
  84. cMatrix.m_pTMatrix [i][j] = m_pTMatrix [i][j] + cMatrixB.m_pTMatrix [i][j];
  85. }
  86. }
  87. return cMatrix;
  88. }
  89. CMatrix CMatrix::operator -(CMatrix& cMatrixB)
  90. {
  91. // 要满足矩阵相加的条件: 行列数数目相等!
  92. if(m_nRow != cMatrixB.m_nRow || m_nCol != cMatrixB.m_nCol )
  93. {
  94. ::AfxMessageBox (TEXT("执行相减的两个矩阵维数不相等!"),MB_OK | MB_ICONERROR);
  95. }
  96. CMatrix cMatrix = *this;
  97. for(unsigned int i=0; i < m_nRow; i++)
  98. {
  99. for(unsigned int j=0; j < m_nCol; j++)
  100. {
  101. cMatrix.m_pTMatrix [i][j] = m_pTMatrix [i][j] - cMatrixB.m_pTMatrix [i][j];
  102. }
  103. }
  104. return cMatrix;
  105. }
  106. CMatrix CMatrix::operator *(CMatrix& cMatrixB)
  107. {
  108. if( m_nCol != cMatrixB.m_nRow )
  109. {
  110. ::AfxMessageBox (TEXT("执行相乘的两个矩阵维数不满足相乘的条件!"),MB_OK | MB_ICONERROR);
  111. }
  112. CMatrix cResultMatrix(m_nRow,cMatrixB.m_nCol);
  113. for(unsigned int i=0; i < m_nRow; i++)
  114. {
  115. for(unsigned int j=0; j < cMatrixB.m_nCol; j++)
  116. {
  117. for(unsigned int m=0; m < m_nCol; m++)
  118. {
  119. cResultMatrix.m_pTMatrix [i][j] +=  m_pTMatrix [i][m] * cMatrixB.m_pTMatrix [m][j];
  120. }
  121. }
  122. }
  123. return cResultMatrix;
  124. }
  125. CMatrix CMatrix::operator * (double nValue)
  126. {
  127. CMatrix cMatrix = *this;
  128. for(unsigned int i=0; i < m_nRow; i++)
  129. {
  130. for(unsigned int j=0; j < m_nCol; j++)
  131. {
  132. cMatrix.m_pTMatrix [i][j] =m_pTMatrix [i][j] * nValue;
  133. }
  134. }
  135. return cMatrix;
  136. }
  137. CMatrix& CMatrix::operator =(CMatrix& cMatrixB)
  138. {
  139. if( (m_nRow != cMatrixB.m_nRow) || (m_nCol != cMatrixB.m_nCol) )
  140. {
  141. ::AfxMessageBox(TEXT("等号左右两边的矩阵的维数不相等!"),MB_OK | MB_ICONERROR);
  142. return *this; // return invalid value
  143. }
  144. // 给变量赋值
  145. m_nRow = cMatrixB.m_nRow ;
  146. m_nCol = cMatrixB.m_nCol ;
  147. m_pTMatrix = cMatrixB.m_pTMatrix ;
  148. // 赋值操作
  149. for(unsigned int i=0; i < cMatrixB.m_nRow; i++)
  150. {
  151. for(unsigned int j=0; j< cMatrixB.m_nCol; j++)
  152. {
  153. m_pTMatrix [i][j] = cMatrixB.m_pTMatrix [i][j];
  154. }
  155. }
  156. return *this;
  157. }
  158. CMatrix& CMatrix::operator += (CMatrix& cMatrixB)
  159. {
  160. if(m_nRow != cMatrixB.m_nRow || m_nCol != cMatrixB.m_nCol )
  161. {
  162. //printf("错误!执行相加的两个矩阵维数不相等!n");
  163. ::AfxMessageBox (TEXT("运算符的两边矩阵的维数不相等!"),MB_OK | MB_ICONERROR);
  164. return *this; // return invalid value
  165. }
  166. // 赋值操作
  167. for(unsigned int i=0; i < cMatrixB.m_nRow; i++)
  168. {
  169. for(unsigned int j=0; j< cMatrixB.m_nCol; j++)
  170. {
  171. m_pTMatrix [i][j] += cMatrixB.m_pTMatrix [i][j];
  172. }
  173. }
  174. return *this;
  175. }
  176. CMatrix CMatrix::Transpose()
  177. {
  178. CMatrix cMatrix(m_nCol,m_nRow);
  179. for(unsigned int i=0; i < m_nRow; i++)
  180. {
  181. for(unsigned int j=0; j < m_nCol; j++)
  182. {
  183. cMatrix.m_pTMatrix [j][i] = m_pTMatrix [i][j];
  184. }
  185. }
  186. return cMatrix;
  187. }
  188. /////////////////////////////////////////////////////////////////////////////
  189. // 将矩阵的所有的元素按列合成一列
  190. // 例如:
  191. // matrix = [
  192. // 1 2 3
  193. // 4 5 6
  194. // 7 8 9
  195. // ]
  196. // CMatrix cMatrix = matrix.MergeColumnsToColumnVector();
  197. // cMatrix = 
  198. // [ 1
  199. // 4
  200. // 7
  201. // 2
  202. // 5
  203. // 8
  204. // 3
  205. // 6
  206. // 9 ]
  207. /////////////////////////////////////////////////////////////////////////////
  208. CMatrix CMatrix::MergeColumnsToColumnVector()
  209. {
  210. CMatrix cMatrix(m_nRow * m_nCol,(unsigned int)1);
  211. // 对矩阵赋值
  212. for(unsigned int j=0; j < m_nCol; j++)
  213. {
  214. for(unsigned int i=0; i < m_nRow; i++)
  215. {
  216. cMatrix.m_pTMatrix [i + j * m_nRow][(unsigned int)0] = m_pTMatrix [i][j];
  217. }
  218. }
  219. return cMatrix;
  220. }
  221. /////////////////////////////////////////////////////////////////////////////
  222. // Get the total value of the matrix
  223. /////////////////////////////////////////////////////////////////////////////
  224. double CMatrix::GetTotalElementValue()
  225. {
  226. double nTotalValue = 0;
  227. for(unsigned int i=0; i < m_nRow; i++)
  228. {
  229. for( unsigned int j=0; j < m_nCol; j++)
  230. {
  231. nTotalValue += m_pTMatrix [i][j];
  232. }
  233. }
  234. return nTotalValue;
  235. }
  236. /////////////////////////////////////////////////////////////////////////////
  237. // Get System Error
  238. /////////////////////////////////////////////////////////////////////////////
  239. double CMatrix::GetSystemError() const
  240. {
  241. double nSystemError = 0;
  242. for(unsigned int i=0; i < m_nRow; i++)
  243. {
  244. for( unsigned int j=0; j < m_nCol; j++)
  245. {
  246. nSystemError += m_pTMatrix [i][j] * m_pTMatrix [i][j];
  247. }
  248. }
  249. return nSystemError;
  250. }
  251. /////////////////////////////////////////////////////////////////////////////
  252. // Make all the matrix elements to be changed into absolute value
  253. /////////////////////////////////////////////////////////////////////////////
  254. CMatrix CMatrix::AbsoluteValue ()
  255. {
  256. CMatrix cMatrix = *this;
  257. for(unsigned int i=0; i < m_nRow; i++)
  258. {
  259. for(unsigned int j=0; j < m_nCol; j++)
  260. {
  261. cMatrix.m_pTMatrix [i][j] = fabs( m_pTMatrix [i][j]);
  262. }
  263. }
  264. return cMatrix;
  265. }
  266. CMatrix CMatrix::Inverse()
  267. {
  268. /////////////////////////////////////////////////////////////////////////
  269. // Using Gauss - Jordan Method
  270. // 参考书目: 计算机数值方法 --->施吉林 陈桂枝
  271. /////////////////////////////////////////////////////////////////////////
  272. /////////////////////////////////////////////////////////////////////////
  273. // 判断是否是可逆阵:
  274. // 可逆阵一定是方阵!!!
  275. if ( m_nRow != m_nCol)
  276. {
  277. //printf("错误!矩阵的行列数不相等,是非可逆阵!n");
  278. ::AfxMessageBox (TEXT("矩阵的行列数不相等,是非可逆阵!"),MB_OK | MB_ICONERROR);
  279. }
  280. CMatrix cMatrix = *this;
  281. //***********************************************************************
  282. // 思路:(非常规思维!)
  283. // 动态分配整型数组(2*m_nCol)来存储每次交换的行坐标的值
  284. // 不论有没有行交换都记录在数组中,
  285. // 1.没进行行交换的两个数据相等,在SwapMatrixRow()函数中
  286. // 检测到两个值相等立即返回,在SwapMatrixCol()函数中也一样,
  287. // 检测到两个值相等立即返回,不占用系统资源;
  288. // 2.不相等的就交换
  289. //***********************************************************************
  290.     
  291. // 分配内存
  292. int *pIntArray = new int [2*m_nCol];
  293. // nSetp --- 约化步数,按列展开
  294. for(unsigned int k=0; k < cMatrix.m_nCol; k++)
  295. {
  296. /////////////////////////////////////////////////////////////////////
  297. // 进行行交换 ---> 游戏规则:
  298. // 为保证计算过程的数值稳定性,在第k步约化时,先在{a(ik)}|i=k->n中选按
  299. // 模最大者作为约化主元素,并交换矩阵相应的行
  300. // 标记主元素
  301. double nMaxElement = cMatrix.m_pTMatrix [k][k];
  302. // 标记主元素所在的行数
  303. unsigned int nMainRow = k;
  304. for(unsigned int nCount = k+1; nCount < cMatrix.m_nCol; nCount++)
  305. {
  306. if( fabs(nMaxElement) < fabs(cMatrix.m_pTMatrix [nCount][k]) )
  307. {
  308. nMaxElement = cMatrix.m_pTMatrix [nCount][k];
  309. nMainRow = nCount;
  310. }
  311. }
  312. // 将欲交换的行数存在数组中
  313. pIntArray [2*k] = k;
  314. pIntArray [2*k+1] = nMainRow;
  315. // 交换行
  316. cMatrix.SwapMatrixRow(k,nMainRow);
  317. //Display();
  318. // 判断是否是可逆阵
  319. if(cMatrix.m_pTMatrix [k][k] == 0)
  320. {
  321. //printf("错误!此矩阵为非可逆阵!n");
  322. ::AfxMessageBox (TEXT("此矩阵为非可逆阵,没有逆矩阵!"),MB_OK | MB_ICONERROR);
  323. }
  324. cMatrix.m_pTMatrix [k][k] = 1/(cMatrix.m_pTMatrix [k][k]);
  325. // 算主列
  326. for(unsigned int i=0; i < cMatrix.m_nRow; i++)
  327. {
  328. if( i != k)
  329. cMatrix.m_pTMatrix [i][k] = -(cMatrix.m_pTMatrix [k][k]) * (cMatrix.m_pTMatrix [i][k]); 
  330. //int nTempValue = m_pTMatrix [i][k];
  331. }
  332. //printf("n");
  333. // 约化非主行
  334. for(unsigned int m=0; m < cMatrix.m_nRow; m++)
  335. {
  336. if ( m == k)
  337. continue;
  338. for(unsigned int n=0; n < cMatrix.m_nCol; n++)
  339. {
  340. if ( n == k)
  341. continue;
  342. cMatrix.m_pTMatrix [m][n] += cMatrix.m_pTMatrix [m][k] * cMatrix.m_pTMatrix [k][n];
  343. //printf("%10f ",m_pTMatrix [m][n]);
  344. }
  345. //printf("n");
  346. }
  347. // 算主行
  348. for(unsigned int j=0; j < cMatrix.m_nCol; j++)
  349. {
  350. if( j != k)
  351. cMatrix.m_pTMatrix [k][j] = (cMatrix.m_pTMatrix [k][k]) * (cMatrix.m_pTMatrix [k][j]);
  352. }
  353. }
  354. /////////////////////////////////////////////////////////////////////////
  355. // 进行列交换 ---> 对交换行后的矩阵进行列交换 ---> 还原矩阵
  356. // 游戏规则:
  357. // 将开始矩阵中进行的行交换 ---> 现用相对应的列交换进行还原,即可得到所求的
  358. // 逆矩阵
  359. for(int i=2*m_nCol-1; i > 0; i--)
  360. {
  361. cMatrix.SwapMatrixCol(pIntArray[i],pIntArray[i-1]);
  362. i--;
  363. }
  364. delete []pIntArray;
  365. return cMatrix;
  366. }
  367. void CMatrix::SwapMatrixRow(unsigned int nRow1,unsigned int nRow2)
  368. {
  369. if( nRow1 == nRow2)
  370. return;
  371. double *pArray = new double;
  372. for(unsigned int i=0; i < m_nCol; i++)
  373. {
  374. // Swap the datum of the two rows
  375. pArray[0] = m_pTMatrix [nRow1][i];
  376. m_pTMatrix [nRow1][i] = m_pTMatrix [nRow2][i];
  377. m_pTMatrix [nRow2][i] = pArray[0];
  378. }
  379. delete pArray;
  380. }
  381. void CMatrix::SwapMatrixCol(unsigned int nCol1,unsigned int nCol2)
  382. {
  383. if( nCol1 == nCol2)
  384. return;
  385. double *pArray = new double;
  386. for(unsigned int i=0; i < m_nRow; i++)
  387. {
  388. // Swap the datum of the two columns
  389. pArray[0] = m_pTMatrix [i][nCol1];
  390. m_pTMatrix [i][nCol1] = m_pTMatrix [i][nCol2];
  391. m_pTMatrix [i][nCol2] = pArray[0];
  392. }
  393. delete pArray;
  394. }
  395. bool CMatrix::LoadDataFromFile(CString& strFileName)
  396. {
  397. CStdioFile dataFile;
  398. LPCTSTR lpszFileName = "";
  399. // CString convert to LPCTSTR
  400. strFileName.TrimLeft ();
  401. strFileName.TrimRight ();
  402. //strFileName.Format (lpszFileName);
  403. lpszFileName = (LPCTSTR)strFileName;
  404. if(!dataFile.Open (lpszFileName,CFile::modeRead | CFile::typeText))
  405. {
  406. ::AfxMessageBox (TEXT("不能打开要读取数据的文件!"),MB_OK | MB_ICONERROR);
  407. dataFile.Close ();
  408. return FALSE;
  409. }
  410. // 用来存储提取文本文件中一行的数据
  411. CString strData;  
  412. // 用来记录文本文件中一共有多少行数据?
  413. unsigned int nRow = 0;
  414. /////////////////////////////////////////////////////////////////////////
  415. // Step 1: 得到文件的行列数目并根据文本文件的行列数目来设置对象(矩阵)的行
  416. // 列数目
  417. //
  418. while(dataFile.ReadString (strData) != FALSE)
  419. {
  420. ++nRow;
  421. }
  422. // 根据文本文件的数据的行数设置对象(矩阵)的行数
  423. m_nRow = nRow;
  424. SetMatrixRowNumber(m_nRow);
  425. // 重新定位当前文件指针到文件开头
  426. dataFile.SeekToBegin ();
  427. dataFile.ReadString (strData);
  428. strData.TrimLeft ();
  429. strData.TrimRight ();
  430. TCHAR SPACE_CHARACTER = ' ';
  431. // 用来记录文本文件中一行有多少列?
  432. unsigned int nCol = 0;
  433. // 空格符在字符串中的位置索引
  434. int nIndex = 0;
  435. do
  436. {
  437. nIndex = strData.Find (SPACE_CHARACTER);
  438. ++nCol;
  439. // 提取字符串的子字符串,即提取一个double型实数数据
  440. //CString strDoubleNumber = strData.Left (nIndex);
  441. // 将字符串转换为double型实数
  442. //double RealNumber = atof(strDoubleNumber);
  443. //int nTempNumber = strData.GetLength ();
  444. strData = strData.Right (strData.GetLength () - nIndex -1);
  445. // 去掉多余的空格
  446. strData.TrimLeft ();
  447. // Use for debugging
  448. //int nTempNum = strData.GetLength ();
  449. }while(nIndex != -1);
  450. // 根据文本文件的数据的列数设置对象(矩阵)的列数
  451. m_nCol = nCol;
  452. SetMatrixColNumber(m_nCol);
  453. // End of Getting the Rows and Cols of the Text File
  454. /////////////////////////////////////////////////////////////////////////
  455. /////////////////////////////////////////////////////////////////////////
  456. // Step 2: 根据文本文件中的数据对矩阵赋值,并检测每行的列数是否和第一行的
  457. // 列数相等,不相等提示出错信息
  458. //
  459. // 重新定位当前文件指针到文件开头
  460. dataFile.SeekToBegin ();
  461. // 对矩阵中的元素装入文本文件的数据
  462. for(unsigned int i=0; i < m_nRow; i++)
  463. {
  464. dataFile.ReadString (strData);
  465. strData.TrimLeft ();
  466. strData.TrimRight ();
  467. // 验证每行的列数是否与第一行的列数相等
  468. unsigned int nVerifyColNum = 0;
  469. do
  470. {
  471. nIndex = strData.Find (SPACE_CHARACTER);
  472. ++nVerifyColNum;
  473. if(nIndex != -1)
  474. {
  475. // 提取字符串的子字符串,即提取一个double型实数数据
  476. CString strDoubleNumber = strData.Left (nIndex);
  477. // 将字符串转换为double型实数
  478. double RealNumber = atof(strDoubleNumber);
  479. m_pTMatrix [i][nVerifyColNum - 1] = RealNumber;
  480. //int nTempNumber = strData.GetLength ();
  481. strData = strData.Right (strData.GetLength () - nIndex -1);
  482. // 去掉多余的空格
  483. strData.TrimLeft ();
  484. // Using for debugging
  485. //double nReadNumber = m_pTMatrix [i][nVerifyColNum - 1];
  486. // Using for debugging
  487. //int nTempNum = strData.GetLength ();
  488. }
  489. else
  490. {
  491. double RealNumber = atof(strData);
  492. m_pTMatrix [i][nVerifyColNum - 1] = RealNumber;
  493. }
  494. }while(nIndex != -1);
  495. if(nVerifyColNum != m_nCol)
  496. {
  497. CString strRowNumber;
  498. strRowNumber.Format("%d",i + 1);
  499. CString strColNumber;
  500. strColNumber.Format("%d",m_nCol);
  501. CString strVerifyColNumber;
  502. strVerifyColNumber.Format("%d",nVerifyColNum);
  503. CString strMessage =  CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!"));
  504. LPCTSTR lpszText = "";
  505. lpszText = (LPCTSTR)strMessage;
  506. //strMessage.FormatMessage (lpszText);
  507. //::AfxMessageBox (lpszText,MB_OK);
  508. ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR);
  509. dataFile.Close ();
  510. return false;
  511. }
  512. }
  513. dataFile.Close ();
  514. return TRUE;
  515. }
  516. /////////////////////////////////////////////////////////////////////////////
  517. // Load the data from the file and reset the rows and the colums of 
  518. // the matrixes.
  519. // Parameter:
  520. // [in] strFileName
  521. // [out]cMatrixInputToHideWeightValue
  522. // [out]cMatrixHideLayerValveValue
  523. // [out]cMatrixHideToOutputWeightValue
  524. // [out]cMatrixOutputLayerValveValue
  525. // [out]nInputLayerNumber
  526. // [out]nHideLayerNumber
  527. // [out]nOutputLayerNumber
  528. // [out]nComboArithmetic
  529. // [out]nComboFunc
  530. /////////////////////////////////////////////////////////////////////////////
  531. bool CMatrix::LoadDataFromFileSpecial (CString& strFileName,
  532. CMatrix& cMatrixInputToHideWeightValue,
  533. CMatrix& cMatrixHideLayerValveValue,
  534. CMatrix& cMatrixHideToOutputWeightValue,
  535. CMatrix& cMatrixOutputLayerValveValue,
  536. unsigned int &nInputLayerNumber,
  537. unsigned int &nHideLayerNumber,
  538. unsigned int &nOutputLayerNumber,
  539. int &nComboArithmetic,
  540. int &nComboFunc)
  541. {
  542. CStdioFile dataFile;
  543. LPCTSTR lpszFileName = "";
  544. // CString convert to LPCTSTR
  545. strFileName.TrimLeft ();
  546. strFileName.TrimRight ();
  547. lpszFileName = (LPCTSTR)strFileName;
  548. if(!dataFile.Open (lpszFileName,CFile::modeRead | CFile::typeText))
  549. {
  550. ::AfxMessageBox (TEXT("不能打开要读取的数据文件!!!"),MB_OK | MB_ICONERROR);
  551. dataFile.Close ();
  552. return FALSE;
  553. }
  554. // 提取网络参数
  555. dataFile.SeekToBegin ();
  556. // 用来存储提取文本文件中一行的数据
  557. CString strData;
  558. // 注释标志符号
  559. TCHAR cFirstCharacter = '#';
  560. // 空格符号
  561. TCHAR SPACE_CHARACTER = ' ';
  562. // 空格符在字符串中的位置索引
  563. int nIndex = 0;
  564. // 读取文件中的网络的输入层数目
  565. while(dataFile.ReadString (strData))
  566. {
  567. strData.TrimLeft ();
  568. strData.TrimRight ();
  569. if((strData.Find (cFirstCharacter)) == 0)
  570. {
  571. continue;
  572. }
  573. else
  574. {
  575. LPCSTR strInputLayerNumber = (LPCSTR)strData;
  576. nInputLayerNumber = (unsigned int)atoi(strInputLayerNumber);
  577. break;
  578.  
  579. }
  580. }
  581. // 读取文件中的网络的隐含层数目
  582. while(dataFile.ReadString (strData))
  583. {
  584. strData.TrimLeft ();
  585. strData.TrimRight ();
  586. if((strData.Find (cFirstCharacter)) == 0)
  587. {
  588. continue;
  589. }
  590. else
  591. {
  592. LPCSTR strHideLayerNumber = (LPCSTR)strData;
  593. nHideLayerNumber = (unsigned int)atoi(strHideLayerNumber);
  594. break;
  595. }
  596. }
  597. // 读取文件中的网络的输出层数目
  598. while(dataFile.ReadString (strData))
  599. {
  600. strData.TrimLeft ();
  601. strData.TrimRight ();
  602. if((strData.Find (cFirstCharacter)) == 0)
  603. {
  604. continue;
  605. }
  606. else
  607. {
  608. LPCSTR strOutputLayerNumber = (LPCSTR)strData;
  609. nOutputLayerNumber = (unsigned int)atoi(strOutputLayerNumber);
  610. break;
  611. }
  612. }
  613. // 读取文件中的训练网络所使用的算法的索引值
  614. while(dataFile.ReadString (strData))
  615. {
  616. strData.TrimLeft ();
  617. strData.TrimRight ();
  618. if((strData.Find (cFirstCharacter)) == 0)
  619. {
  620. continue;
  621. }
  622. else
  623. {
  624. LPCSTR strComboArithmetic = (LPCSTR)strData;
  625. nComboArithmetic = atoi(strComboArithmetic);
  626. break;
  627. }
  628. }
  629. // 读取文件中的网络的使用的函数的索引值
  630. while(dataFile.ReadString (strData))
  631. {
  632. strData.TrimLeft ();
  633. strData.TrimRight ();
  634. if((strData.Find (cFirstCharacter)) == 0)
  635. {
  636. continue;
  637. }
  638. else
  639. {
  640. LPCSTR strComboFunc = (LPCSTR)strData;
  641. nComboFunc = atoi(strComboFunc);
  642. break;
  643. }
  644. }
  645. // 根据网络参数设置输入层到隐含层的权值矩阵的行列数
  646. cMatrixInputToHideWeightValue.SetMatrixRowAndCol (nHideLayerNumber,nInputLayerNumber);
  647. // 验证矩阵的行数
  648. unsigned int nVerifyRowNum = 0;
  649. // 读取文件中的输入层到隐含层的权值矩阵到相应的矩阵对象中
  650. while(dataFile.ReadString (strData))
  651. {
  652. strData.TrimLeft ();
  653. strData.TrimRight ();
  654. if((strData.Find (cFirstCharacter)) == 0)
  655. {
  656. continue;
  657. }
  658. else
  659. {
  660. // 装入文本文件的数据到相对应的矩阵中
  661. strData.TrimLeft ();
  662. strData.TrimRight ();
  663. // 验证每行的列数是否与第一行的列数相等
  664. unsigned int nVerifyColNum = 0;
  665. do
  666. {
  667. nIndex = strData.Find (SPACE_CHARACTER);
  668. ++nVerifyColNum;
  669. if(nIndex != -1)
  670. {
  671. // 提取字符串的子字符串,即提取一个double型实数数据
  672. CString strDoubleNumber = strData.Left (nIndex);
  673. // 将字符串转换为double型实数
  674. double RealNumber = atof(strDoubleNumber);
  675. cMatrixInputToHideWeightValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber;
  676. strData = strData.Right (strData.GetLength () - nIndex -1);
  677. // 去掉多余的空格
  678. strData.TrimLeft ();
  679. }
  680. else
  681. {
  682. double RealNumber = atof(strData);
  683. cMatrixInputToHideWeightValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber;
  684. }
  685. }while(nIndex != -1);
  686. if(nVerifyColNum != cMatrixInputToHideWeightValue.m_nCol)
  687. {
  688. CString strRowNumber;
  689. strRowNumber.Format("%d",nVerifyRowNum + 1);
  690. CString strColNumber;
  691. strColNumber.Format("%d",m_nCol);
  692. CString strVerifyColNumber;
  693. strVerifyColNumber.Format("%d",nVerifyColNum);
  694. CString strMessage =  CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!"));
  695. LPCTSTR lpszText = "";
  696. lpszText = (LPCTSTR)strMessage;
  697. ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR);
  698. dataFile.Close ();
  699. return FALSE;
  700. }
  701. ++nVerifyRowNum;
  702. if( nVerifyRowNum == cMatrixInputToHideWeightValue.m_nRow )
  703. {
  704. break;
  705. }
  706. }
  707. }
  708. // Using for debugging
  709. //CString strInputToHideWeightValue = TEXT("TempInputToHideWeightValue.txt");
  710. //cMatrixInputToHideWeightValue.SaveDataToFile (strInputToHideWeightValue);
  711. // 根据网络参数设置隐含层的阀值矩阵的行列数
  712. cMatrixHideLayerValveValue.SetMatrixRowAndCol (nHideLayerNumber,(unsigned int)1);
  713. nIndex = 0;
  714. nVerifyRowNum = 0;
  715. // 读取文件中的隐含层的阀值矩阵到相应的矩阵对象中
  716. while(dataFile.ReadString (strData))
  717. {
  718. strData.TrimLeft ();
  719. strData.TrimRight ();
  720. if((strData.Find (cFirstCharacter)) == 0)
  721. {
  722. continue;
  723. }
  724. else
  725. {
  726. // 装入文本文件的数据到相对应的矩阵中
  727. strData.TrimLeft ();
  728. strData.TrimRight ();
  729. // 验证每行的列数是否与第一行的列数相等
  730. unsigned int nVerifyColNum = 0;
  731. do
  732. {
  733. nIndex = strData.Find (SPACE_CHARACTER);
  734. ++nVerifyColNum;
  735. if(nIndex != -1)
  736. {
  737. // 提取字符串的子字符串,即提取一个double型实数数据
  738. CString strDoubleNumber = strData.Left (nIndex);
  739. // 将字符串转换为double型实数
  740. double RealNumber = atof(strDoubleNumber);
  741. cMatrixHideLayerValveValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber;
  742. strData = strData.Right (strData.GetLength () - nIndex -1);
  743. // 去掉多余的空格
  744. strData.TrimLeft ();
  745. }
  746. else
  747. {
  748. double RealNumber = atof(strData);
  749. cMatrixHideLayerValveValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber;
  750. }
  751. }while(nIndex != -1);
  752. if(nVerifyColNum != cMatrixHideLayerValveValue.m_nCol)
  753. {
  754. CString strRowNumber;
  755. strRowNumber.Format("%d",nVerifyRowNum + 1);
  756. CString strColNumber;
  757. strColNumber.Format("%d",m_nCol);
  758. CString strVerifyColNumber;
  759. strVerifyColNumber.Format("%d",nVerifyColNum);
  760. CString strMessage =  CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!"));
  761. LPCTSTR lpszText = "";
  762. lpszText = (LPCTSTR)strMessage;
  763. ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR);
  764. dataFile.Close ();
  765. return FALSE;
  766. }
  767. ++nVerifyRowNum;
  768. if( nVerifyRowNum == cMatrixHideLayerValveValue.m_nRow )
  769. {
  770. break;
  771. }
  772. }
  773. }
  774. // Using for debugging
  775. //CString strHideLayerValveValue = TEXT("TempHideLayerValveValue.txt");
  776. //cMatrixHideLayerValveValue.SaveDataToFile (strHideLayerValveValue);
  777. // 根据网络参数设置隐含层到输出层的权值矩阵的行列数
  778. cMatrixHideToOutputWeightValue.SetMatrixRowAndCol (nOutputLayerNumber,nHideLayerNumber);
  779. nIndex = 0;
  780. nVerifyRowNum = 0;
  781. // 读取文件中的隐含层到输出层的权值矩阵到相应的矩阵对象中
  782. while(dataFile.ReadString (strData))
  783. {
  784. strData.TrimLeft ();
  785. strData.TrimRight ();
  786. if((strData.Find (cFirstCharacter)) == 0)
  787. {
  788. continue;
  789. }
  790. else
  791. {
  792. // 装入文本文件的数据到相对应的矩阵中
  793. strData.TrimLeft ();
  794. strData.TrimRight ();
  795. // 验证每行的列数是否与第一行的列数相等
  796. unsigned int nVerifyColNum = 0;
  797. do
  798. {
  799. nIndex = strData.Find (SPACE_CHARACTER);
  800. ++nVerifyColNum;
  801. if(nIndex != -1)
  802. {
  803. // 提取字符串的子字符串,即提取一个double型实数数据
  804. CString strDoubleNumber = strData.Left (nIndex);
  805. // 将字符串转换为double型实数
  806. double RealNumber = atof(strDoubleNumber);
  807. cMatrixHideToOutputWeightValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber;
  808. strData = strData.Right (strData.GetLength () - nIndex -1);
  809. // 去掉多余的空格
  810. strData.TrimLeft ();
  811. }
  812. else
  813. {
  814. double RealNumber = atof(strData);
  815. cMatrixHideToOutputWeightValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber;
  816. }
  817. }while(nIndex != -1);
  818. if(nVerifyColNum != cMatrixHideToOutputWeightValue.m_nCol)
  819. {
  820. CString strRowNumber;
  821. strRowNumber.Format("%d",nVerifyRowNum + 1);
  822. CString strColNumber;
  823. strColNumber.Format("%d",m_nCol);
  824. CString strVerifyColNumber;
  825. strVerifyColNumber.Format("%d",nVerifyColNum);
  826. CString strMessage =  CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!"));
  827. LPCTSTR lpszText = "";
  828. lpszText = (LPCTSTR)strMessage;
  829. ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR);
  830. dataFile.Close ();
  831. return FALSE;
  832. }
  833. ++nVerifyRowNum;
  834. if( nVerifyRowNum == cMatrixHideToOutputWeightValue.m_nRow )
  835. {
  836. break;
  837. }
  838. }
  839. }
  840. // Using for debugging
  841. //CString strHideToOutputWeightValue = TEXT("TempHideToOutputWeightValue.txt");
  842. //cMatrixHideToOutputWeightValue.SaveDataToFile (strHideToOutputWeightValue);
  843. // 根据网络参数设置输出层的阀值矩阵的行列数
  844. cMatrixOutputLayerValveValue.SetMatrixRowAndCol (nOutputLayerNumber,(unsigned int)1);
  845. nIndex = 0;
  846. nVerifyRowNum = 0;
  847. // 读取文件中的输出层的阀值矩阵到相应的矩阵对象中
  848. while(dataFile.ReadString (strData))
  849. {
  850. strData.TrimLeft ();
  851. strData.TrimRight ();
  852. if((strData.Find (cFirstCharacter)) == 0)
  853. {
  854. continue;
  855. }
  856. else
  857. {
  858. // 装入文本文件的数据到相对应的矩阵中
  859. strData.TrimLeft ();
  860. strData.TrimRight ();
  861. // 验证每行的列数是否与第一行的列数相等
  862. unsigned int nVerifyColNum = 0;
  863. do
  864. {
  865. nIndex = strData.Find (SPACE_CHARACTER);
  866. ++nVerifyColNum;
  867. if(nIndex != -1)
  868. {
  869. // 提取字符串的子字符串,即提取一个double型实数数据
  870. CString strDoubleNumber = strData.Left (nIndex);
  871. // 将字符串转换为double型实数
  872. double RealNumber = atof(strDoubleNumber);
  873. cMatrixOutputLayerValveValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber;
  874. strData = strData.Right (strData.GetLength () - nIndex -1);
  875. // 去掉多余的空格
  876. strData.TrimLeft ();
  877. }
  878. else
  879. {
  880. double RealNumber = atof(strData);
  881. cMatrixOutputLayerValveValue.m_pTMatrix [nVerifyRowNum][nVerifyColNum - 1] = RealNumber;
  882. }
  883. }while(nIndex != -1);
  884. if(nVerifyColNum != cMatrixOutputLayerValveValue.m_nCol)
  885. {
  886. CString strRowNumber;
  887. strRowNumber.Format("%d",nVerifyRowNum + 1);
  888. CString strColNumber;
  889. strColNumber.Format("%d",m_nCol);
  890. CString strVerifyColNumber;
  891. strVerifyColNumber.Format("%d",nVerifyColNum);
  892. CString strMessage =  CString(TEXT("文本文件第")) + strRowNumber + CString(TEXT("行一共有")) + strVerifyColNumber + CString(TEXT("列,与第一行中的列数")) + strColNumber + CString(TEXT("不相等!"));
  893. LPCTSTR lpszText = "";
  894. lpszText = (LPCTSTR)strMessage;
  895. ::AfxMessageBox (lpszText,MB_OK | MB_ICONERROR);
  896. dataFile.Close ();
  897. return FALSE;
  898. }
  899. ++nVerifyRowNum;
  900. if( nVerifyRowNum == cMatrixOutputLayerValveValue.m_nRow )
  901. {
  902. break;
  903. }
  904. }
  905. }
  906. // Using for debugging
  907. //CString strOutputLayerValveValue = TEXT("TempOutputLayerValveValue.txt");
  908. //cMatrixOutputLayerValveValue.SaveDataToFile (strOutputLayerValveValue);
  909. dataFile.Close ();
  910. return TRUE;
  911. }
  912. bool CMatrix::SaveDataToFile (CString& strFileName)
  913. {
  914. CStdioFile dataFile;
  915. LPCTSTR lpszFileName = "";
  916. // CString convert to LPCTSTR
  917. strFileName.TrimLeft ();
  918. strFileName.TrimRight ();
  919. lpszFileName = (LPCTSTR)strFileName;
  920. if(!dataFile.Open (lpszFileName,CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::typeText))
  921. {
  922. ::AfxMessageBox(TEXT("不能创建文件!"),MB_OK | MB_ICONERROR);
  923. dataFile.Close ();
  924. return false;
  925. }
  926. dataFile.SeekToEnd ();
  927. // 将对象(矩阵)中的数据写进文件
  928. for(unsigned int i=0; i < m_nRow; i++)
  929. {
  930. for(unsigned int j=0; j < m_nCol; j++)
  931. {
  932.  CString strRealNumber;
  933.  strRealNumber.Format ("%.16f  ", m_pTMatrix [i][j]);
  934.  // Using for debugging
  935.  //double nReadNumber = m_pTMatrix [i][j];
  936.  char *pBuffer = new char[strRealNumber.GetLength()];
  937.  memcpy(pBuffer,strRealNumber,strRealNumber.GetLength());
  938.  dataFile.Write (pBuffer,strRealNumber.GetLength ());
  939. }
  940. if( i != m_nRow - 1)
  941. {
  942. //char ReturnNewline[] = "rn";
  943. char ReturnNewline[] = "n";
  944. dataFile.Write (ReturnNewline, (sizeof(ReturnNewline) - 1)/sizeof(char));
  945. }
  946. }
  947. dataFile.Close ();
  948. return true;
  949. }
  950. /////////////////////////////////////////////////////////////////////////////
  951. // 对矩阵中的元素进行一次操作:
  952. // 使矩阵变为单位阵
  953. /////////////////////////////////////////////////////////////////////////////
  954. void CMatrix::Eye()
  955. {
  956. // Verify whether the rows is equal to the columns or not
  957. if(m_nRow != m_nCol)
  958. {
  959. ::AfxMessageBox (TEXT("此矩阵的行列数不相等!不能转变为单位阵!"),MB_OK | MB_ICONERROR);
  960. return;
  961. }
  962. for(unsigned int i=0; i < m_nRow; i++)
  963. {
  964. for(unsigned int j=0; j < m_nCol; j++)
  965. {
  966. if(i == j)
  967. {
  968. m_pTMatrix [i][j] = 1;
  969. }
  970. else
  971. {
  972. m_pTMatrix [i][j] = 0;
  973. }
  974. }
  975. }
  976. }
  977. /////////////////////////////////////////////////////////////////////////////
  978. // Parameter:
  979. // CMatrix& cMatrix: 被拷贝的数据源
  980. // unsigned int nIndex: 被拷贝的数据在对象中的开始索引位置,从0开始
  981. // Purpose:
  982. // This function will copy all the data of the cMatrix
  983. // Notes:
  984. // 此对象必须是列向量!!!
  985. /////////////////////////////////////////////////////////////////////////////
  986. void CMatrix::GetMatrixData(CMatrix& cMatrix, unsigned int nIndex)
  987. {
  988. if(m_nCol != 1)
  989. {
  990. ::AfxMessageBox (TEXT("拷贝的矩阵不是列向量!"),MB_OK | MB_ICONERROR);
  991. return;
  992. }
  993. if((m_nRow - nIndex) < (cMatrix.m_nRow * cMatrix.m_nCol))
  994. {
  995. ::AfxMessageBox (TEXT("拷贝矩阵的空间容量不足!"),MB_OK | MB_ICONERROR);
  996. return;
  997. }
  998. for(unsigned int i=0; i < cMatrix.m_nRow; i++)
  999. {
  1000. for(unsigned int j=0; j < cMatrix.m_nCol; j++)
  1001. {
  1002. m_pTMatrix [nIndex + i * cMatrix.m_nCol + j][0] = cMatrix.m_pTMatrix [i][j];
  1003. }
  1004. }
  1005. }
  1006. /////////////////////////////////////////////////////////////////////////////
  1007. // Parameter:
  1008. // CMatrix& cMatrix: 被填充的矩阵
  1009. // unsigned int nIndex: 被拷贝的数据在对象中的开始索引位置
  1010. // Purpose:
  1011. // This function will copy part of the object data into cMatrix
  1012. // Notes:
  1013. // The object must be column vector!!!
  1014. /////////////////////////////////////////////////////////////////////////////
  1015. void CMatrix::SetMatrixData(CMatrix& cMatrix, unsigned int nIndex)
  1016. {
  1017. // Verify whether the colunm number is 1
  1018. if(m_nCol != 1)
  1019. {
  1020. ::AfxMessageBox (TEXT("本矩阵对象不是列向量,不满足条件!"),MB_OK | MB_ICONERROR);
  1021. return;
  1022. }
  1023. // Verify whether the number of the object element is enough to be copyed
  1024. if((m_nRow - nIndex) < (cMatrix.m_nRow * cMatrix.m_nCol))
  1025. {
  1026. ::AfxMessageBox (TEXT("对象中的元素数量不足!"),MB_OK | MB_ICONERROR);
  1027. return;
  1028. }
  1029. for(unsigned int i=0; i < cMatrix.m_nRow; i++)
  1030. {
  1031. for(unsigned int j=0; j < cMatrix.m_nCol; j++)
  1032. {
  1033. cMatrix.m_pTMatrix [i][j] = m_pTMatrix [nIndex + i * cMatrix.m_nCol + j][0];
  1034. // Using for debugging
  1035. //unsigned int nIndexNumber = nIndex + i * cMatrix.m_nRow + j;
  1036. //double nData = cMatrix.m_pTMatrix [i][j];
  1037. }
  1038. }
  1039. }
  1040. /////////////////////////////////////////////////////////////////////////////
  1041. // Parameter:
  1042. // CMatrix& cMatrix: 被填充的矩阵
  1043. // unsigned int nIndex: 被拷贝的数据在对象中的开始索引位置
  1044. // unsigned int nRow: 被填充的数据在被填充对象中的行索引
  1045. // Purpose:
  1046. // This function will copy part of the object data to fill the special 
  1047. // row of the cMatrix
  1048. // Notes:
  1049. // The object must be column vector!!!
  1050. /////////////////////////////////////////////////////////////////////////////
  1051. void CMatrix::SetMatrixRowData(CMatrix& cMatrix, unsigned int nIndex, unsigned int nRow)
  1052. {
  1053. // Verify whether the column number is 1
  1054. if(m_nCol != 1)
  1055. {
  1056. ::AfxMessageBox (TEXT("本矩阵对象不是列向量,不满足条件!"),MB_OK | MB_ICONERROR);
  1057. return;
  1058. }
  1059. // Verify whether the number of the object element is enough to be copyed
  1060. if((m_nRow - nIndex) < cMatrix.m_nCol )
  1061. {
  1062. ::AfxMessageBox (TEXT("对象的元素数量不足!"),MB_OK | MB_ICONERROR);
  1063. return;
  1064. }
  1065. for(unsigned int i=0; i < cMatrix.m_nCol; i++)
  1066. {
  1067. cMatrix.m_pTMatrix [nRow][i] = m_pTMatrix [nIndex + i][(unsigned int)0];
  1068. }
  1069. }
  1070. /////////////////////////////////////////////////////////////////////////////
  1071. // Parameter:
  1072. // CMatrix& cMatrix: 被拷贝的数据源
  1073. // unsigned int nIndex: 被拷贝的数据在对象中的开始索引位置
  1074. // unsigned int nRow: 被拷贝的数据在被拷贝对象中的行索引(从0开始)
  1075. // Purpose:
  1076. // This function will copy all the data of the cMatrix
  1077. // Notes:
  1078. // 此对象必须是列向量!!!
  1079. /////////////////////////////////////////////////////////////////////////////
  1080. void CMatrix::GetMatrixRowData(CMatrix& cMatrix, unsigned int nIndex, unsigned int nRow)
  1081. {
  1082. if(m_nCol != 1)
  1083. {
  1084. ::AfxMessageBox (TEXT("拷贝的矩阵不是列向量!"),MB_OK | MB_ICONERROR);
  1085. return;
  1086. }
  1087. if((m_nRow - nIndex) < cMatrix.m_nCol)
  1088. {
  1089. ::AfxMessageBox (TEXT("拷贝矩阵的空间容量不足!"),MB_OK | MB_ICONERROR);
  1090. return;
  1091. }
  1092. for(unsigned int i=0; i < cMatrix.m_nCol; i++)
  1093. {
  1094. m_pTMatrix [nIndex + i][(unsigned int)0] = cMatrix.m_pTMatrix [nRow][i];
  1095. }
  1096. }
  1097. void CMatrix::SetMatrixRowNumber(unsigned int nRow)
  1098. {
  1099. m_nRow = nRow;
  1100. m_pTMatrix.resize (m_nRow);
  1101. for(unsigned int i=0; i < m_nRow; i++)
  1102. {
  1103. for(unsigned int j=0; j < m_nCol; j++)
  1104. {
  1105. m_pTMatrix[i].resize (m_nCol);
  1106. m_pTMatrix[i][j] = (double) 0;
  1107. }
  1108. }
  1109. }
  1110. void CMatrix::SetMatrixColNumber(unsigned int nCol)
  1111. {
  1112. m_nCol = nCol;
  1113. m_pTMatrix.resize (m_nRow);
  1114. for(unsigned int i=0; i < m_nRow; i++)
  1115. {
  1116. for(unsigned int j=0; j < m_nCol; j++)
  1117. {
  1118. m_pTMatrix[i].resize (m_nCol);
  1119. m_pTMatrix[i][j] = (double) 0;
  1120. }
  1121. }
  1122. }
  1123. /////////////////////////////////////////////////////////////////////////
  1124. // 设置矩阵的行列数
  1125. void CMatrix::SetMatrixRowAndCol(unsigned int nRow,unsigned int nCol)
  1126. {
  1127. m_nRow = nRow;
  1128. m_nCol = nCol;
  1129. // 分配内存
  1130. m_pTMatrix.resize (m_nRow);
  1131. for(unsigned int i=0; i < m_nRow; i++)
  1132. {
  1133. for(unsigned int j=0; j < m_nCol; j++)
  1134. {
  1135. m_pTMatrix[i].resize (m_nCol);
  1136. m_pTMatrix[i][j] = (double) 0;
  1137. }
  1138. }
  1139. }
  1140. /////////////////////////////////////////////////////////////////////////////
  1141. // Initialize()
  1142. // 矩阵初始化函数,矩阵的行列数目被初始化为零,矩阵中的元素全部初始化为零
  1143. /////////////////////////////////////////////////////////////////////////////
  1144. void CMatrix::Initialize()
  1145. {
  1146. m_nRow = 0;
  1147. m_nCol = 0;
  1148. m_pTMatrix.resize (m_nRow);
  1149. for(unsigned int i=0; i < m_nRow; i++)
  1150. {
  1151. for(unsigned int j=0; j < m_nCol; j++)
  1152. {
  1153. m_pTMatrix[i].resize (m_nCol);
  1154. m_pTMatrix[i][j] = (double) 0;
  1155. }
  1156. }
  1157. }
  1158. /////////////////////////////////////////////////////////////////////////////
  1159. // InitializeZero()
  1160. // 矩阵初始化函数,矩阵的行列数目被初始化为零,矩阵中的元素全部初始化为零
  1161. /////////////////////////////////////////////////////////////////////////////
  1162. void CMatrix::InitializeZero()
  1163. {
  1164. m_nRow = 0;
  1165. m_nCol = 0;
  1166. m_pTMatrix.resize (m_nRow);
  1167. for(unsigned int i=0; i < m_nRow; i++)
  1168. {
  1169. for(unsigned int j=0; j < m_nCol; j++)
  1170. {
  1171. m_pTMatrix[i].resize (m_nCol);
  1172. m_pTMatrix[i][j] = (double) 0;
  1173. }
  1174. }
  1175. }
  1176. /////////////////////////////////////////////////////////////////////////////
  1177. // RandomInitialize()
  1178. // 将矩阵中的元素随机初始化函数,元素的值在(-1,1)之间的小数
  1179. /////////////////////////////////////////////////////////////////////////////
  1180. void CMatrix::RandomInitialize ()
  1181. {
  1182. for(unsigned int i=0; i < m_nRow; i++)
  1183. {
  1184. for(unsigned int j=0; j < m_nCol; j++)
  1185. {
  1186. m_pTMatrix [i][j] = (double)(rand() - (0.5*RAND_MAX)) / (0.5*RAND_MAX);
  1187. }
  1188. }
  1189. }
  1190. /////////////////////////////////////////////////////////////////////////////
  1191. // 拷贝矩阵的子矩阵元素到另外一个矩阵中
  1192. // Parameter:
  1193. // [out] cMatrix ----> 矩阵的子矩阵返回的结果
  1194. // [in] nStartX ----> 子矩阵在矩阵中的起始坐标,对应行,索引从1开始
  1195. // [in] nStartY ----> 子矩阵在矩阵中的起始坐标,对应列,索引从1开始
  1196. /////////////////////////////////////////////////////////////////////////////
  1197. void CMatrix::CopySubMatrix(CMatrix& cMatrix,unsigned int nStartX,unsigned int nStartY)
  1198. {
  1199. if((m_nRow  < cMatrix.m_nRow + nStartY ) | (m_nCol  < cMatrix.m_nCol + nStartX))
  1200. {
  1201. ::AfxMessageBox (TEXT("被拷贝的矩阵维数小于要拷贝的矩阵所需要的维数!"),MB_OK | MB_ICONERROR);
  1202. return;
  1203. }
  1204. for(unsigned int i=0;  i < cMatrix.m_nRow; i++)
  1205. {
  1206. for(unsigned int j=0; j < cMatrix.m_nCol; j++)
  1207. {
  1208. cMatrix.m_pTMatrix [i][j] = m_pTMatrix [nStartY + i][nStartX + j];
  1209. }
  1210. }
  1211. }
  1212. /////////////////////////////////////////////////////////////////////////////
  1213. // Copy Matrix
  1214. // Parameter:
  1215. // [in] cMatrix ----> 被拷贝的矩阵
  1216. /////////////////////////////////////////////////////////////////////////////
  1217. void CMatrix::CopyMatrix(CMatrix& cMatrix)
  1218. {
  1219. m_nRow = cMatrix.m_nRow ;
  1220. m_nCol = cMatrix.m_nCol ;
  1221. m_pTMatrix = cMatrix.m_pTMatrix ;
  1222. for(unsigned int i=0; i < m_nRow; i++)
  1223. {
  1224. for(unsigned int j=0; j < m_nCol; j++)
  1225. {
  1226. m_pTMatrix [i][j] = cMatrix.m_pTMatrix [i][j];
  1227. }
  1228. }
  1229. }
  1230. /////////////////////////////////////////////////////////////////////////////
  1231. // 从一个列向量中拷贝数据到一个矩阵中
  1232. // Parameter:
  1233. // [out] cMatrix ----> 函数的返回结果
  1234. // [in] nIndex ----> 在列向量中的索引值
  1235. // Notes:
  1236. // 被拷贝的对象必须是列向量!!!
  1237. /////////////////////////////////////////////////////////////////////////////
  1238. void CMatrix::CopySubMatrixFromVector(CMatrix& cMatrix,unsigned int nIndex)
  1239. {
  1240. if(m_nCol != 1)
  1241. {
  1242. ::AfxMessageBox (TEXT("被拷贝的矩阵不是列向量!!!"),MB_OK | MB_ICONERROR);
  1243. return;
  1244. }
  1245. for(unsigned int j=0; j < cMatrix.m_nCol; j++)
  1246. {
  1247. for(unsigned int i=0; i < cMatrix.m_nRow; i++)
  1248. {
  1249. cMatrix.m_pTMatrix [i][j] = m_pTMatrix [nIndex + j * cMatrix.m_nRow + i ][(unsigned int)0];
  1250. }
  1251. }
  1252. }
  1253. /////////////////////////////////////////////////////////////////////////////
  1254. // 对矩阵进列拓展
  1255. // 实现功能:
  1256. // 对矩阵的列数进行拓展,nTimes是每列拓展的次数
  1257. /////////////////////////////////////////////////////////////////////////////
  1258. void CMatrix::nncpyi(CMatrix &cMatrix, unsigned int nTimes)
  1259. {
  1260. m_nRow = cMatrix.m_nRow ;
  1261. m_nCol = cMatrix.m_nCol * nTimes;
  1262. // 根据空间分配内存
  1263. m_pTMatrix.resize (m_nRow);
  1264. for(unsigned int i=0; i < m_nRow; i++)
  1265. {
  1266. for(unsigned int j=0; j < m_nCol; j++)
  1267. {
  1268. m_pTMatrix[i].resize (m_nCol);
  1269. m_pTMatrix[i][j] = (double) 0;
  1270. }
  1271. }
  1272. // 赋值
  1273. for(i=0; i < m_nRow; i++)
  1274. {
  1275. for(unsigned int j=0; j < cMatrix.m_nCol; j++)
  1276. {
  1277. for(unsigned int k=0; k < nTimes; k++)
  1278. {
  1279. m_pTMatrix [i][j * nTimes + k] = cMatrix.m_pTMatrix [i][j];
  1280. }
  1281. }
  1282. }
  1283. }
  1284. /////////////////////////////////////////////////////////////////////////////
  1285. // 对矩阵进行拓展
  1286. // 实现功能:
  1287. // 对矩阵的列数进行拓展
  1288. // matrix = [ 
  1289. // 1 2 3
  1290. // 4 5 6
  1291. // 7 8 9
  1292. // ]
  1293. //
  1294. // nncpyd(matrix) = [
  1295. // 1 0 0 2 0 0 3 0 0
  1296. // 0 4 0 0 5 0 0 6 0
  1297. // 0 0 7 0 0 8 0 0 9
  1298. // ]
  1299. /////////////////////////////////////////////////////////////////////////////
  1300. void CMatrix::nncpyd(CMatrix &cMatrix)
  1301. {
  1302. m_nRow = cMatrix.m_nRow ;
  1303. m_nCol = cMatrix.m_nCol * cMatrix.m_nRow ;
  1304. // 根据空间分配内存
  1305. m_pTMatrix.resize (m_nRow);
  1306. for(unsigned int i=0; i < m_nRow; i++)
  1307. {
  1308. for(unsigned int j=0; j < m_nCol; j++)
  1309. {
  1310. m_pTMatrix[i].resize (m_nCol);
  1311. m_pTMatrix[i][j] = (double) 0;
  1312. }
  1313. }
  1314. // 给矩阵赋值
  1315. for(i=0; i < m_nRow; i++)
  1316. {
  1317. for(unsigned int j=0; j < cMatrix.m_nCol; j++)
  1318. {
  1319. for(unsigned int k=0; k < cMatrix.m_nRow; k++)
  1320. {
  1321. if(i == (j * cMatrix.m_nRow + k) % cMatrix.m_nRow )
  1322. m_pTMatrix [i][j * cMatrix.m_nRow + k] = cMatrix.m_pTMatrix [i][j];
  1323. }
  1324. }
  1325. }
  1326. }
  1327. /////////////////////////////////////////////////////////////////////////////
  1328. // 对矩阵进行拓展
  1329. // 实现功能:
  1330. // 对矩阵的列数进行拓展,nTimes是每列拓展的次数
  1331. // matrix = [ 
  1332. // 1 2 3
  1333. // 4 5 6
  1334. // 7 8 9
  1335. // ]
  1336. // nTimes = 2
  1337. //
  1338. // nncpyd(matrix) = [
  1339. // 1 2 3 1 2 3
  1340. // 4 5 6 4 5 6
  1341. // 7 8 9 7 8 9
  1342. // ]
  1343. /////////////////////////////////////////////////////////////////////////////
  1344. void CMatrix::nncpy(CMatrix& cMatrix,unsigned int nTimes)
  1345. {
  1346. m_nRow = cMatrix.m_nRow ;
  1347. m_nCol = cMatrix.m_nCol * nTimes;
  1348. // 根据空间分配内存
  1349. m_pTMatrix.resize (m_nRow);
  1350. for(unsigned int i=0; i < m_nRow; i++)
  1351. {
  1352. for(unsigned int j=0; j < m_nCol; j++)
  1353. {
  1354. m_pTMatrix[i].resize (m_nCol);
  1355. m_pTMatrix[i][j] = (double) 0;
  1356. }
  1357. }
  1358. // 对矩阵赋值
  1359. for(i=0; i < m_nRow; i++)
  1360. {
  1361. for(unsigned int j=0; j < nTimes; j++)
  1362. {
  1363. for(unsigned int k=0; k < cMatrix.m_nCol; k++)
  1364. {
  1365. m_pTMatrix [i][j * cMatrix.m_nCol + k] = cMatrix.m_pTMatrix [i][k];
  1366. }
  1367. }
  1368. }
  1369. }
  1370. /////////////////////////////////////////////////////////////////////////////
  1371. // 对矩阵中所有的元素进行一次非线性变换:
  1372. // 变换后的值y与变换前的值的关系是:
  1373. // y = f(x) = 1 / (1 + exp(-x)) ( 0 < f(x) < 1)
  1374. //
  1375. /////////////////////////////////////////////////////////////////////////////
  1376. CMatrix CMatrix::Sigmoid()
  1377. {
  1378. CMatrix cMatrix = *this;
  1379. for(unsigned int i=0; i < m_nRow; i++)
  1380. {
  1381. for(unsigned int j=0; j < m_nCol; j++)
  1382. {
  1383. cMatrix.m_pTMatrix [i][j] = 1 / (1 + exp(-m_pTMatrix [i][j]));
  1384. }
  1385. }
  1386. return cMatrix;
  1387. }
  1388. /////////////////////////////////////////////////////////////////////////////
  1389. // 对矩阵中所有的元素进行一次非线性变换:
  1390. // 变换后的值y与变换前的值的关系是:
  1391. // y = tanh(x) = (1 - exp(-x)) / (1 + exp(-x))
  1392. //  =  1 - 2 * exp(-x) / (1 + exp(-x)) ( -1 < f(x) < 1)
  1393. //
  1394. /////////////////////////////////////////////////////////////////////////////
  1395. CMatrix CMatrix::tanh ()
  1396. {
  1397. CMatrix cMatrix = *this;
  1398. for(unsigned int i=0; i < m_nRow; i++)
  1399. {
  1400. for(unsigned int j=0; j < m_nCol; j++)
  1401. {
  1402. cMatrix.m_pTMatrix [i][j] = 1 - (2 * exp(-m_pTMatrix [i][j])) / (1 + exp(-m_pTMatrix [i][j]));
  1403. }
  1404. }
  1405. return cMatrix;
  1406. }
  1407. /////////////////////////////////////////////////////////////////////////////
  1408. // 对矩阵中所有的元素进行一次非线性变换:
  1409. // 变换后的值y与变换前的值的关系是:
  1410. // y = Tansig(x) = 2 / (1 + exp(-2 * x)) -1
  1411. /////////////////////////////////////////////////////////////////////////////
  1412. CMatrix CMatrix::Tansig()
  1413. {
  1414. CMatrix cMatrix = *this;
  1415. for(unsigned int i=0; i < m_nRow; i++)
  1416. {
  1417. for(unsigned int j=0; j < m_nCol; j++)
  1418. {
  1419. cMatrix.m_pTMatrix [i][j] = 2 / (1 + exp(- 2 * m_pTMatrix [i][j])) - 1;
  1420. }
  1421. }
  1422. return cMatrix;
  1423. }
  1424. /////////////////////////////////////////////////////////////////////////////
  1425. // 对矩阵中所有的元素进行一次非线性变换:
  1426. // 变换后的值y与变换前的值的关系是:
  1427. // y = Tansig'(x) = (2 / (1 + exp(-2 * x)) -1)'
  1428. // = (2 / (1 + exp(-2 * x)) -1) * (2 / (1 + exp(-2 * x)) -1) -1
  1429. /////////////////////////////////////////////////////////////////////////////
  1430. CMatrix CMatrix::TansigDerivative()
  1431. {
  1432. CMatrix cMatrix = *this;
  1433. for(unsigned int i=0; i < m_nRow; i++)
  1434. {
  1435. for(unsigned int j=0; j < m_nCol; j++)
  1436. {
  1437. cMatrix.m_pTMatrix [i][j] = (2 / (1 + exp(- 2 * m_pTMatrix [i][j])) - 1) * (2 / (1 + exp(- 2 * m_pTMatrix [i][j])) - 1) - 1;
  1438. }
  1439. }
  1440. return cMatrix;
  1441. }
  1442. /////////////////////////////////////////////////////////////////////////////
  1443. // 对矩阵中的元素进行一次操作:
  1444. // 使所有行中的相对应的列元素相等
  1445. // Parameter:
  1446. // nRowIndex ----> 行索引值(从零开始)
  1447. // 以此行做为标准,使矩阵中其余的行相对应的列的值
  1448. // 与此行相对应的列的值相等
  1449. /////////////////////////////////////////////////////////////////////////////
  1450. void CMatrix::MakeAllColumnElementsSameValue(unsigned int nRowIndex)
  1451. {
  1452. for(unsigned int i=0; i < m_nRow; i++)
  1453. {
  1454. if(i == nRowIndex)
  1455. continue;
  1456. for(unsigned int j=0; j < m_nCol; j++)
  1457. {
  1458. m_pTMatrix [i][j] = m_pTMatrix [nRowIndex][j];
  1459. }
  1460. }
  1461. }
  1462. /////////////////////////////////////////////////////////////////////////////
  1463. // 对矩阵中所有的元素进行一次非线性变换:
  1464. // 变换后的值y与变换前的值的关系是:
  1465. // y = f'(x) = (1 / (1 + exp(-x)))' ( 0 < f(x) < 1)
  1466. //   = exp(-x)/((1 + exp(-x))*(1 + exp(-x)))
  1467. /////////////////////////////////////////////////////////////////////////////
  1468. CMatrix CMatrix::SigmoidDerivative()
  1469. {
  1470. CMatrix cMatrix = *this;
  1471. for(unsigned int i=0; i < m_nRow; i++)
  1472. {
  1473. for(unsigned int j=0; j < m_nCol; j++)
  1474. {
  1475. cMatrix.m_pTMatrix [i][j] = exp(-m_pTMatrix [i][j]) / ((1 + exp(-m_pTMatrix [i][j])) * (1 + exp(-m_pTMatrix [i][j])));
  1476. }
  1477. }
  1478. return cMatrix;
  1479. }
  1480. /////////////////////////////////////////////////////////////////////////////
  1481. // 对矩阵中所有的元素进行一次非线性变换:
  1482. // 变换后的值y与变换前的值的关系是:
  1483. // y = tanh'(x) = ((1 - exp(-x)) / (1 + exp(-x)))' ( -1 < f(x) < 1)
  1484. //  =  2*exp(-x)/((1 + exp(-x))*(1 + exp(-x)))
  1485. /////////////////////////////////////////////////////////////////////////////
  1486. CMatrix CMatrix::tanhDerivative()
  1487. {
  1488. CMatrix cMatrix = *this;
  1489. for(unsigned int i=0; i < m_nRow; i++)
  1490. {
  1491. for(unsigned int j=0; j < m_nCol; j++)
  1492. {
  1493. cMatrix.m_pTMatrix [i][j] = 2 * exp(-m_pTMatrix [i][j]) / ((1 + exp(-m_pTMatrix [i][j])) * (1 + exp(-m_pTMatrix [i][j])));
  1494. }
  1495. }
  1496. return cMatrix;
  1497. }
  1498. /////////////////////////////////////////////////////////////////////////////
  1499. // 实现对点乘操作符的重载
  1500. /////////////////////////////////////////////////////////////////////////////
  1501. CMatrix CMatrix::operator / (CMatrix& cMatrixB)
  1502. {
  1503. CMatrix cMatrix = *this;
  1504. if( (m_nRow != cMatrixB.m_nRow) || (m_nCol != cMatrixB.m_nCol) )
  1505. {
  1506. ::AfxMessageBox (TEXT("两个矩阵的维数不相等,不满足矩阵点乘的条件!"),MB_OK | MB_ICONERROR);
  1507. return cMatrix; // return a invalid value
  1508. }
  1509. for(unsigned int i=0; i < m_nRow; i++)
  1510. {
  1511. for(unsigned int j=0; j < m_nCol; j++)
  1512. {
  1513. cMatrix.m_pTMatrix [i][j] = m_pTMatrix [i][j] * cMatrixB.m_pTMatrix [i][j];
  1514. }
  1515. }
  1516. return cMatrix;
  1517. }
  1518. //***************************************************************************
  1519. // ordinary function
  1520. //
  1521. /////////////////////////////////////////////////////////////////////////////
  1522. // 重载 'double - CMatrix' 运算符
  1523. /////////////////////////////////////////////////////////////////////////////
  1524. CMatrix operator - (double nValue,CMatrix& cMatrixB)
  1525. {
  1526. CMatrix cMatrix = cMatrixB;
  1527. for(unsigned int i=0; i < cMatrix.GetMatrixRowNumber (); i++)
  1528. {
  1529. for(unsigned int j=0; j < cMatrix.GetMatrixColNumber (); j++)
  1530. {
  1531. cMatrix.m_pTMatrix [i][j] = nValue - cMatrixB.m_pTMatrix [i][j];
  1532. }
  1533. }
  1534. return cMatrix;
  1535. }
  1536. /////////////////////////////////////////////////////////////////////////////
  1537. // 矩阵合并运算符
  1538. // 合并规则:
  1539. // 1. 参与合并运算的两个矩阵的行数必须相等;
  1540. // 2. 参与合并的两个矩阵的列数可以不相等;
  1541. // 3. 合并后返回的矩阵的行数与参与合并的矩阵的行数相等,列数是参与合并的
  1542. // 两个矩阵的列数之和;
  1543. /////////////////////////////////////////////////////////////////////////////
  1544. CMatrix MergeMatrix(CMatrix& cMatrixA,CMatrix& cMatrixB)
  1545. {
  1546. // 条件检测
  1547. if( cMatrixA.GetMatrixRowNumber () != cMatrixB.GetMatrixRowNumber () )
  1548. {
  1549. ::AfxMessageBox (TEXT("参与合并的两个矩阵的行数不相等!"),MB_OK | MB_ICONERROR);
  1550. return cMatrixA; // return invalid value
  1551. }
  1552. CMatrix cMatrix(cMatrixA.GetMatrixRowNumber (),cMatrixA.GetMatrixColNumber () + cMatrixB.GetMatrixColNumber ());
  1553. for(unsigned int i=0; i < cMatrixA.GetMatrixRowNumber (); i++)
  1554. {
  1555. for(unsigned int j=0; j < cMatrixA.GetMatrixColNumber (); j++)
  1556. {
  1557. cMatrix.m_pTMatrix [i][j] = cMatrixA.m_pTMatrix [i][j];
  1558. }
  1559. for(unsigned int k=0; k < cMatrixB.GetMatrixColNumber (); k++)
  1560. {
  1561. cMatrix.m_pTMatrix [i][cMatrixA.GetMatrixColNumber () + k] = cMatrixB.m_pTMatrix [i][k];
  1562. }
  1563. }
  1564. return cMatrix;
  1565. }
  1566. // End of ordinary function
  1567. //***************************************************************************