一个矩阵类,很好用,分享给大家

这是在做一个神经网络训练时候发现得一个矩阵类,做的很好,推荐给大家,原来的矩阵是从txt中加载数据,现在添加函数bool LoadDataFromBase(); 实现从数据库中添加数据

/
// Matrix.h : 
//		Interface of the class CMatrix
// Author : freeia
// Modified Date : 3/11/2003
// E-mail : freeia@163.com
// Company/School : hdcad
/

#ifndef _MATRIX_H
#define _MATRIX_H

#include <vector>

using namespace std;

typedef vector <double> VDOUBLE;
typedef vector <VDOUBLE> TMatrix;


class __declspec(dllexport) CMatrix  
{	

	/************************************************************************
	*				the interface function of the class CMatrix 			*
	************************************************************************/
public:

	/
	// Construction and Destruction	
	CMatrix();

	CMatrix(CMatrix& cMatrixB);

	virtual ~CMatrix();

	TMatrix	m_pTMatrix;				// 指向矩阵的头指针

	/
	// According to the parameters nRow & nCol to construct a matrix
	CMatrix(unsigned int nRow, unsigned int nCol);


	/
	// This function initialize the matrix :
	//		the matrix which has been initialized has 0 row & 0 column, and
	// all elements in it is zeros.
	// 
	void Initialize();

	/
	// This function initialize the matrix :
	//		the matrix which has been initialized has 0 row & 0 column, and
	// all elements in it is zeros.
	// 
	void InitializeZero();

	/
	// To make random in the elements of the matrix and the elements of the 
	// matrix has been randomized between -1 and 1.These elements must be
	// decimal fractions.
	// 
	void RandomInitialize();

	/
	// Overload Operations

	// 'CMatrix + CMatrix'
	CMatrix operator + (CMatrix& cMatrixB);	
	// 'CMatrix - CMatrix'
	CMatrix operator - (CMatrix& cMatrixB);	
	// 'CMatrix * CMatrix'
	CMatrix operator * (CMatrix& cMatrixB);	
	// 'CMatrix * double'
	CMatrix operator * (double nValue);	
	// 'CMatrix = CMatrix'
	CMatrix& operator = (CMatrix& cMatrixB);	
	// 'CMatrix += CMatrix'
	CMatrix& operator += (CMatrix& cMatrixB);	
	// 'CMatrix .* CMatrix'
	CMatrix operator / (CMatrix& cMatrixB);	


	/
	// Transpose the matrix
	//
	CMatrix Transpose();

	/
	// Inverse the matrix
	//
	CMatrix Inverse();

	/
	// Load the data from the file and reset the rows and the colums of the 
	// matrix
	//
	bool LoadDataFromFile(CString& strFileName);

	bool LoadDataFromBase(char* TableName,int Row,int Col); //load form database sqlserver 2000 add by hzh 2015.2.5
	/
	// Save the data from the CMatrix object to the specified file
	//
	bool SaveDataToFile(CString& strFileName);
	
	/
	// Get the matrix Row Number
	//
	unsigned int GetMatrixRowNumber() const
	{
		return m_nRow;
	}

	/
	// Get the matrix Colum Number
	//
	unsigned int GetMatrixColNumber() const
	{
		return m_nCol;
	}


	/
	// 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 LoadDataFromFileSpecial (	CString& strFileName,
									CMatrix& cMatrixInputToHideWeightValue,
									CMatrix& cMatrixHideLayerValveValue,
									CMatrix& cMatrixHideToOutputWeightValue,
									CMatrix& cMatrixOutputLayerValveValue,
									unsigned int &nInputLayerNumber,
									unsigned int &nHideLayerNumber,
									unsigned int &nOutputLayerNumber,
									int &nComboArithmetic,
									int	&nComboFunc);


	/
	//	Copy data from a vector to a matrix
	//	Parameter:
	//		[out]	cMatrix ----> the returned value
	//		[in]	nIndex	----> the index in vector
	//	Notes:
	//		the object copied must be vector!!!
	//
	void CopySubMatrixFromVector(CMatrix& cMatrix,unsigned int nIndex);

	/
	// Copy data from sub matrix to another matrix
	// Parameter:
	//		[out]	cMatrix ----> 矩阵的子矩阵返回的结果
	//		[in]	nStartX ----> 子矩阵在矩阵中的起始坐标,对应行,索引从1开始
	//		[in]	nStartY ----> 子矩阵在矩阵中的起始坐标,对应列,索引从1开始
	//
	void CopySubMatrix(CMatrix& cMatrix,unsigned int nStartX,unsigned int nStartY);

	/
	// Copy Matrix
	//	Parameter:
	//		[in]	cMatrix ----> be copied matrix
	//
	void CopyMatrix(CMatrix& 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 MergeColumnsToColumnVector();

	/
	// 对矩阵中所有的元素进行一次非线性变换:
	//		变换后的值y与变换前的值的关系是:
	//			y = f(x) = 1 / (1 + exp(-x))	( 0 < f(x) < 1)
	//
	CMatrix Sigmoid();

	/
	// 对矩阵中所有的元素进行一次非线性变换:
	//		变换后的值y与变换前的值的关系是:
	//			y = f'(x) = (1 / (1 + exp(-x)))'	( 0 < f(x) < 1)
	//			  = exp(-x)/((1 + exp(-x))*(1 + exp(-x)))
	//
	CMatrix SigmoidDerivative();


	/
	// 对矩阵中所有的元素进行一次非线性变换:
	//		变换后的值y与变换前的值的关系是:
	//			y = tanh(x) = (1 - exp(-x)) / (1 + exp(-x))
	//					 =  1 - 2 * exp(-x) / (1 + exp(-x))	( -1 < f(x) < 1)
	//
	CMatrix tanh(); 

	/
	// 对矩阵中所有的元素进行一次非线性变换:
	//		变换后的值y与变换前的值的关系是:
	//			y = tanh'(x) = ((1 - exp(-x)) / (1 + exp(-x)))'	( -1 < f(x) < 1)
	//					 = 	2*exp(-x)/((1 + exp(-x))*(1 + exp(-x)))
	//
	CMatrix tanhDerivative();

	/
	// 对矩阵中所有的元素进行一次非线性变换:
	//		变换后的值y与变换前的值的关系是:
	//			y = Tansig(x) = 2 / (1 + exp(-2 * x)) -1
	//
	CMatrix Tansig();

	/
	// 对矩阵中所有的元素进行一次非线性变换:
	//		变换后的值y与变换前的值的关系是:
	//			y = Tansig'(x) = (2 / (1 + exp(-2 * x)) -1)'
	//				= (2 / (1 + exp(-2 * x)) -1) * (2 / (1 + exp(-2 * x)) -1) -1
	//
	CMatrix TansigDerivative();

	/
	// 对矩阵中的元素进行一次操作:
	//		使所有行中的相对应的列元素相等
	//	Parameter:
	//		nRowIndex	---->	行索引值(the index starts from 0)
	//							以此行做为标准,使矩阵中其余的行相对应的列的值
	//							与此行相对应的列的值相等	
	//
	void MakeAllColumnElementsSameValue(unsigned int nRowIndex);

	/
	// 对矩阵中的元素进行一次操作:
	//		使矩阵变为单位阵
	//
	void Eye();

	/
	// Get System Error
	//
	double	GetSystemError() const;

	/
	// Make all the matrix elements to be changed into absolute value
	//
	CMatrix AbsoluteValue();

	/
	// Parameter:
	//		CMatrix& cMatrix:		被拷贝的数据源
	//		unsigned int nIndex:	被拷贝的数据在对象中的开始索引位置
	// Purpose:
	//		This function will copy all the data of the cMatrix
	// Notes:
	//		The object must be column vector!!!
	//
	void GetMatrixData(CMatrix& cMatrix, unsigned int nIndex);

	/
	// 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 SetMatrixData(CMatrix& cMatrix, unsigned int nIndex);

	/
	// Parameter:
	//		CMatrix& cMatrix:		被拷贝的数据源
	//		unsigned int nIndex:	被拷贝的数据在对象中的开始索引位置
	//		unsigned int nRow:		被拷贝的数据在被拷贝对象中的行索引(从0开始)
	// Purpose:
	//		This function will copy all the data of the cMatrix
	// Notes:
	//		The object must be column vector!!!
	//
	void GetMatrixRowData(CMatrix& cMatrix, unsigned int nIndex, unsigned int nRow);

	/
	// 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 SetMatrixRowData(CMatrix& cMatrix, unsigned int nIndex, unsigned int nRow);

	/
	// Get the total value of the matrix
	double GetTotalElementValue();

	/
	// 对矩阵进行拓展
	//	实现功能:
	//		对矩阵的列数进行拓展,nTimes是每列拓展的次数
	//
	void nncpyi(CMatrix &cMatrix, unsigned int nTimes);

	/
	// 对矩阵进行拓展
	//	实现功能:
	//		对矩阵的列数进行拓展
	//	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 nncpyd(CMatrix &cMatrix);

	/
	// 对矩阵进行拓展
	//	实现功能:
	//		对矩阵的列数进行拓展,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 nncpy (CMatrix& cMatrix, unsigned int nTimes);



private:

	unsigned int m_nRow;			// 矩阵所拥有的行数
	unsigned int m_nCol;			// 矩阵所拥有的列数


	/
	// 注意:
	//		在重新设置矩阵的行数和列数后,矩阵中的元素被重新初始化为0
	/

	/
	// 设置矩阵的行数
	//
	void SetMatrixRowNumber(unsigned int nRow);

	/
	// 设置矩阵的列数
	//
	void SetMatrixColNumber(unsigned int nCol);

	/
	// 设置矩阵的行列数
	//
	void SetMatrixRowAndCol(unsigned int nRow,unsigned int nCol);


	/
	// 交换矩阵的两行
	//
	void SwapMatrixRow(unsigned int nRow1,unsigned int nRow2);

	/
	// 交换矩阵的两列
	//
	void SwapMatrixCol(unsigned int nCol1,unsigned int nCol2);


};


/
// overload operator 'double - CMatrix'
__declspec(dllexport) CMatrix operator - (double nValue,CMatrix& cMatrixB);



/
// 矩阵合并运算符
//	合并规则:
//		1. 参与合并运算的两个矩阵的行数必须相等;
//		2. 参与合并的两个矩阵的列数可以不相等;
//		3. 合并后返回的矩阵的行数与参与合并的矩阵的行数相等,列数是参与合并的
//			两个矩阵的列数之和;
//
__declspec(dllexport) CMatrix MergeMatrix(CMatrix& cMatrixA,CMatrix& cMatrixB);




#endif // _MATRIX_H

/
// Matrix.cpp : Implementation of the class Matrix
//
/

#include "stdafx.h"
#include "Matrix.h"
#include <math.h>
#include <stdlib.h>
#include "NNBP.h" //实例头文件,根据需要修改
#include <conio.h>
#include <stdio.h>

#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::LoadDataFromBase(char* TableName,int Row,int Col)
{
	CNNBPApp* pApp = (CNNBPApp*)AfxGetApp(); //实例名,根据需要修改
	//设置矩阵的行列
	m_nRow =Row;
	SetMatrixRowNumber(m_nRow);
	m_nCol =Col;
	SetMatrixColNumber(m_nCol);

	double GetValue;
	SDWORD cbName;
	char ss[1024];
	HSTMT hStmt;
	RETCODE retcode;
	sprintf(ss,"select * from %s",TableName);
	if(SQLAllocStmt(pApp->m_pDataBase->m_hdbc,&hStmt)!=SQL_SUCCESS)  //m_pDataBase为CDataBase*
	{
		AfxMessageBox("SQLAllocStmt error !",MB_OK);
		return FALSE;
	}
	retcode = SQLExecDirect(hStmt, (unsigned char *)ss, SQL_NTS); 
	if((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO)) 
	{
		SQLFreeStmt(hStmt,SQL_DROP);
		AfxMessageBox("SQLExecDirect Error",MB_OK);
		return FALSE;
	}
	int i=0;
	while(retcode==SQL_SUCCESS)
	{ 
		retcode = SQLFetch(hStmt); 
		if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
		{
			for(int j=1;j<=Col;j++)
			{	
				SQLGetData(hStmt, j, SQL_C_DOUBLE, &GetValue, 256, &cbName); 	
				m_pTMatrix [i][j-1] = GetValue;
			}

		}
		i++;
		if(i>=Row)
			break;
		
	}
	SQLFreeStmt(hStmt,SQL_DROP);
	
}

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
//***************************************************************************


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值