www.pudn.com > NNBP.rar > Procedure.cpp


///////////////////////////////////////////////////////////////////////////// 
// Procedure.cpp 
//		the implementation of the specified arithmetic 
// Author : freeia 
// E-mail : freeia@163.com 
// Date : 3/20/2003 
///////////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "Matrix.h" 
#include "AllDef.h" 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
//	Levenberg-Marquart		---->	第一次前向计算初始化				   // 
///////////////////////////////////////////////////////////////////////////// 
__declspec (dllexport) void LMForwardCalculateInit( int nInputLayerNumber, 
													int nHideLayerNumber, 
													int nOutputLayerNumber, 
													CMatrix &matrixDemoDataInput, 
													CMatrix &matrixInputLayerValue, 
													CMatrix &matrixInputToHideWeightValue, 
													CMatrix &matrixHideLayerValveValue, 
													CMatrix &matrixHideToOutputWeightValue, 
													CMatrix &matrixOutputLayerValveValue 
												   ) 
{ 
 
	/************************************************************************ 
	*					--------->Use Matlab Method <---------              * 
	************************************************************************/ 
 
		 
	///////////////////////////////////////////////////////////////////////// 
	// 构造输入层元素的矩阵 
	// 构造规则: 
	//		1. 样本数目做为矩阵的行数; 
	//		2. 单个样本的输入层的数目做为矩阵的列数; 
	//		3. 矩阵中的元素即为对应的输入层的值 
	// 
 
	CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber); 
 
	// 得到样本的输入值 
	matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue,(unsigned int)0,(unsigned int)0); 
 
	CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose (); 
 
	matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue); 
 
 
	///////////////////////////////////////////////////////////////////////// 
	// 构造权值矩阵 -----> 由单个样本输入层与隐含层之间的权值做为元素组成 
	// 构造规则: 
	//		1. 单个样本的输入层的数目做为矩阵行数; 
	//		2. 单个样本的隐含层的数目做为矩阵的列数; 
	//		3. 对矩阵中的元素进行随机初始化,值在(-1,1)之间; 
	//		4. 所有样本的输入层和隐含层的数目是相等的; 
	//		5. 所有样本使用的是同一个权值矩阵. 
	// 
 
	CMatrix	cMatrixInputToHideWeightValue(nHideLayerNumber, nInputLayerNumber); 
 
	// 随机初始化矩阵内元素的值 
	cMatrixInputToHideWeightValue.RandomInitialize (); 
 
	matrixInputToHideWeightValue.CopyMatrix (cMatrixInputToHideWeightValue); 
 
 
	///////////////////////////////////////////////////////////////////// 
	//	构造样本隐含层的阀值矩阵 
	//	构造规则: 
	//		1. 样本的数目做为矩阵行数; 
	//		2. 单个样本的隐含层的数目做为矩阵的列数; 
	//		3. 随机初始化矩阵中的元素,使值在(-1,1)之间; 
	//		4. 矩阵中每行的数据都和第一行数据相对应的位置相等. 
	// 
 
	CMatrix cMatrixHideLayerValveValue(nHideLayerNumber,(unsigned int)1); 
 
	// 随机初始化矩阵内元素的值 
	cMatrixHideLayerValveValue.RandomInitialize (); 
 
	matrixHideLayerValveValue.CopyMatrix(cMatrixHideLayerValveValue); 
 
 
	///////////////////////////////////////////////////////////////////// 
	//	构造权值矩阵	----->	由单个样本的隐含层与输出层之间权值做为元素 
	//							组成 
	//	构造规则: 
	//		1. 单个样本的隐含层的数目做为矩阵的行数; 
	//		2. 单个样本的输出层的数目做为矩阵的列数; 
	//		3. 对矩阵中的元素进行随机初始化,值在(-1,1)之间; 
	//		4. 所有样本的隐含层和输出层的数目是相等的; 
	//		5. 所有样本使用的是同一个权值矩阵. 
	// 
 
	CMatrix cMatrixHideToOutputWeightValue(nOutputLayerNumber, nHideLayerNumber); 
 
	// 对矩阵的元素随机初始化 
	cMatrixHideToOutputWeightValue.RandomInitialize (); 
 
	matrixHideToOutputWeightValue.CopyMatrix (cMatrixHideToOutputWeightValue); 
 
 
	///////////////////////////////////////////////////////////////////// 
	//	构造样本的输出层的阀值矩阵 
	//	构造规则: 
	//		1. 样本的数目做为矩阵的行数; 
	//		2. 单个样本的输出层的数目做为矩阵的列数; 
	//		3. 随机初始化矩阵中的元素,使值在(-1,1)之间; 
	//		4. 矩阵中每行的数据都和第一行数据相对应的位置相等. 
	// 
 
	CMatrix cMatrixOutputLayerValveValue(nOutputLayerNumber,(unsigned int)1); 
 
	// 随机初始化矩阵内元素的值 
	cMatrixOutputLayerValveValue.RandomInitialize (); 
 
	matrixOutputLayerValveValue.CopyMatrix(cMatrixOutputLayerValveValue); 
 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
//	Levenberg-Marquart		---->		前向计算						   // 
///////////////////////////////////////////////////////////////////////////// 
__declspec(dllexport) void LMForwardCalculate ( int nInputLayerNumber, 
												int nHideLayerNumber, 
												int nOutputLayerNumber, 
												bool bSimulateDataFlag, 
												int nComboFunc, 
												CMatrix &matrixDemoDataInput, 
												CMatrix &matrixInputLayerValue, 
												CMatrix &matrixInputToHideWeightValue, 
												CMatrix &matrixHideLayerValveValue, 
												CMatrix &matrixHideLayerOutput, 
												CMatrix &matrixHideToOutputWeightValue, 
												CMatrix &matrixOutputLayerOutput, 
												CMatrix &matrixOutputLayerValveValue 
											   ) 
{ 
 
	if(bSimulateDataFlag) 
	{ 
 
		CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber); 
 
		// 得到样本的输入值 
		matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue, (unsigned int)0, (unsigned int)0); 
 
		CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose (); 
 
		matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue); 
 
 
	} 
 
	///////////////////////////////////////////////////////////////////////// 
	// 得到所有样本的隐含层的净输入 
	// 构造规则: 
	//		1. 样本的数目做为矩阵行数; 
	//		2. 单个样本的隐含层的数目做为矩阵的列数; 
	//		3. 矩阵元素中的值即为对应的样本的隐含层的净输入: 
	//		   由  
	//				cMatrixInputLayerValue * cMatrixInputToHideWeightValue  
	//				+ cMatrixHideLayerValveValue 
	//			得到. 
	// 
		 
	CMatrix cMatrixExHideLayerValveValue; 
	cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	CMatrix cMatrixHideLayerPureInput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	cMatrixHideLayerPureInput = matrixInputToHideWeightValue * matrixInputLayerValue; 
 
	cMatrixHideLayerPureInput += cMatrixExHideLayerValveValue; 
 
 
	///////////////////////////////////////////////////////////////////// 
	//	算出所有样本的隐含层的输出 
	//	构造规则: 
	//		1. 隐含层的输出y与隐含层的输入x的关系可用函数表示 
	//			y = f(x) 
	//		2. 矩阵的维数和隐含层的净输入矩阵的维数相等 
	// 
 
	CMatrix cMatrixHideLayerOutput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	switch(nComboFunc) 
	{ 
	case 0: 
		cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Sigmoid (); 
		break; 
 
	case 1: 
		cMatrixHideLayerOutput = cMatrixHideLayerPureInput.tanh (); 
		break; 
 
	case 2: 
		cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Tansig(); 
		break; 
 
	default: 
		return; 
	} 
	 
	matrixHideLayerOutput.CopyMatrix(cMatrixHideLayerOutput); 
 
	///////////////////////////////////////////////////////////////////// 
	//	得到所有样本输出层的净输入 
	//	构造规则; 
	//		1. 样本的数目做为矩阵的行数; 
	//		2. 单个样本的输出层的数目做为矩阵的列数; 
	//		3. 矩阵中元素的值即为对应样本的输出层的净输入: 
	//			由 
	//				cMatrixHideLayerOutput * cMatrixHideToOutputWeightValue 
	//				+ cMatrixOutputLayerValveValue 
	//			得到 
	// 
 
	CMatrix cMatrixExOutputLayerValveValue; 
	cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	CMatrix cMatrixOutputLayerPureInput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	cMatrixOutputLayerPureInput = matrixHideToOutputWeightValue * cMatrixHideLayerOutput; 
	cMatrixOutputLayerPureInput  += cMatrixExOutputLayerValveValue; 
 
 
	///////////////////////////////////////////////////////////////////// 
	//	算出所有样本的输出层的输出 
	//	构造规则: 
	//		1. 矩阵的维数与得到的所有样本的输出层的净输入组成的矩阵一样; 
	//		2. 输出层的输出y和输出层的输入可用关系式 
	//			y = f(x) 
	//		表示 
	// 
 
	CMatrix cMatrixOutputLayerOutput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	switch(nComboFunc) 
	{ 
	case 0: 
		cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Sigmoid (); 
		break; 
 
	case 1: 
		cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.tanh (); 
		break; 
 
	case 2: 
		cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Tansig (); 
		break; 
 
	default: 
		return ; 
	} 
 
	matrixOutputLayerOutput.CopyMatrix(cMatrixOutputLayerOutput); 
 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
//	Levenberg-Marquart		---->		反馈计算						   // 
///////////////////////////////////////////////////////////////////////////// 
__declspec(dllexport) bool LMDemoDataTrainRepeat (	int nInputLayerNumber, 
													int nHideLayerNumber, 
													int nOutputLayerNumber, 
													bool bSimulateDataFlag, 
													int nComboFunc, 
													double nSystemErrorOld, 
													double nSystemErrorNew, 
													double nSystemErrorLevel, 
													double nSystemError, 
													double nStep, 
													UINT nMaxTrainTimes, 
													UINT nTrainTimes, 
													DWORD ID_SYSTEM_ERROR, 
													DWORD ID_TRAIN_TIMES, 
													HWND  hWnd, 
													CMatrix &matrixDemoDataInput, 
													CMatrix &matrixInputLayerValue, 
													CMatrix &matrixInputToHideWeightValue, 
													CMatrix &matrixHideLayerValveValue, 
													CMatrix &matrixHideLayerOutput, 
													CMatrix &matrixHideToOutputWeightValue, 
													CMatrix &matrixOutputLayerOutput, 
													CMatrix &matrixOutputLayerValveValue 
												 ) 
{ 
 
	LMForwardCalculate (nInputLayerNumber, 
						nHideLayerNumber, 
						nOutputLayerNumber, 
						bSimulateDataFlag, 
						nComboFunc, 
						matrixDemoDataInput, 
						matrixInputLayerValue, 
						matrixInputToHideWeightValue, 
						matrixHideLayerValveValue, 
						matrixHideLayerOutput, 
						matrixHideToOutputWeightValue, 
						matrixOutputLayerOutput, 
						matrixOutputLayerValveValue 
						); 
		 
 
	///////////////////////////////////////////////////////////////////// 
	//	算出所有样本的输出层的delta矩阵 
	//	构造规则: 
	//		1. 样本的数目为矩阵的行数; 
	//		2. 样本输出层的数目为矩阵的列数; 
	//		3. 矩阵中的元素的值y为: 
	//				y = -(前向计算出的输出层的值 - 样本的输出层的值) * f'(net) 
	// 
 
 
	CMatrix cMatrixTDemoOutput(matrixDemoDataInput.GetMatrixRowNumber (), nOutputLayerNumber); 
		 
	// 得到样本中输出层的数据 
	matrixDemoDataInput.CopySubMatrix (cMatrixTDemoOutput, (unsigned int)nInputLayerNumber, (unsigned int)0); 
 
	CMatrix cMatrixDemoOutput = cMatrixTDemoOutput.Transpose (); 
 
	// 得到样本中输出层的误差 
	CMatrix cMatrixOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	cMatrixOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput; 
 
		 
	nSystemErrorOld = cMatrixOutputLayerError.GetSystemError (); 
 
	for(int nLoopTimes=1; nLoopTimes < nMaxTrainTimes; nLoopTimes++)	 
	{ 
		if(nSystemErrorOld < nSystemErrorLevel) 
		{ 
			nLoopTimes--; 
			break; 
		} 
 
		CMatrix	cMatrixExHideLayerOutput; 
		cMatrixExHideLayerOutput.nncpyi (matrixHideLayerOutput, nOutputLayerNumber); 
 
 
		CMatrix	cMatrixOutputLayerDelta (nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber()); 
		 
		// 注意: 此处'/' 是 '点乘'!!! 
		cMatrixOutputLayerDelta = 1 - matrixOutputLayerOutput / matrixOutputLayerOutput; 
 
		CMatrix cMatrixExOutputLayerDelta; 
		cMatrixExOutputLayerDelta.nncpyd (cMatrixOutputLayerDelta); 
		 
		cMatrixExOutputLayerDelta = cMatrixExOutputLayerDelta * (-1.0); 
 
	 
		CMatrix cMatrixTHideToOutputWeightValue (matrixHideToOutputWeightValue.GetMatrixColNumber(), matrixHideToOutputWeightValue.GetMatrixRowNumber()); 
		cMatrixTHideToOutputWeightValue = matrixHideToOutputWeightValue.Transpose(); 
 
		CMatrix cMatrixExHideLayerDelta; 
		// 注意: 此处'/' 是 '点乘'!!! 
		cMatrixExHideLayerDelta.CopyMatrix ( (1 - (cMatrixExHideLayerOutput / cMatrixExHideLayerOutput)) / ( cMatrixTHideToOutputWeightValue * cMatrixExOutputLayerDelta) ); 
				 
 
		CMatrix	cMatrixExInputLayerValue; 
		cMatrixExInputLayerValue.nncpyi (matrixInputLayerValue, nOutputLayerNumber); 
 
		 
		CMatrix	cMatrixJ11; 
		cMatrixJ11.nncpy (cMatrixExHideLayerDelta.Transpose(), cMatrixExInputLayerValue.GetMatrixRowNumber ()); 
 
		CMatrix cMatrixJ12; 
		cMatrixJ12.nncpyi(cMatrixExInputLayerValue.Transpose (), cMatrixExHideLayerDelta.GetMatrixRowNumber()); 
 
 
		CMatrix	cMatrixJ1; 
		// 注意: 此处'/' 是 '点乘'!!! 
		cMatrixJ1.CopyMatrix (cMatrixJ11 / cMatrixJ12); 
 
 
		CMatrix cMatrixJ21; 
		cMatrixJ21.nncpy (cMatrixExOutputLayerDelta.Transpose (), cMatrixExHideLayerOutput.GetMatrixRowNumber ()); 
 
		CMatrix cMatrixJ22; 
		cMatrixJ22.nncpyi (cMatrixExHideLayerOutput.Transpose (), cMatrixExOutputLayerDelta.GetMatrixRowNumber ()); 
 
		CMatrix cMatrixJ2; 
		// 注意: 此处'/' 是 '点乘'!!! 
		cMatrixJ2.CopyMatrix (cMatrixJ21 / cMatrixJ22); 
 
		 
		CMatrix cMatrixZ; 
		cMatrixZ.CopyMatrix (MergeMatrix(MergeMatrix(MergeMatrix(cMatrixJ1, cMatrixExHideLayerDelta.Transpose ()), cMatrixJ2), cMatrixExOutputLayerDelta.Transpose ())); 
 
 
		CMatrix cMatrixMOutputLayerError; 
		cMatrixMOutputLayerError.CopyMatrix ( cMatrixOutputLayerError.MergeColumnsToColumnVector () ); 
 
 
		CMatrix	cMatrixJE; 
		cMatrixJE.CopyMatrix ( (cMatrixZ.Transpose ()) * cMatrixMOutputLayerError ); 
 
 
		CMatrix cMatrixJJ; 
		cMatrixJJ.CopyMatrix ( (cMatrixZ.Transpose ()) * cMatrixZ ); 
		 
 
		// 定义新的输入层到隐含层的权值 
		CMatrix cMatrixNewInputToHideWeight; 
		// 定义的新的隐含层的阀值 
		CMatrix cMatrixNewHideLayerValve; 
		// 定义新的隐含层到输出层的权值 
		CMatrix cMatrixNewHideToOutputWeight; 
		// 定义新的输出层的阀值 
		CMatrix cMatrixNewOutputLayerValve; 
 
		// 定义新的误差矩阵 
		CMatrix cMatrixNewOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
		///////////////////////////////////////////////////////////////// 
		// the weight value is adjusted 
 
		while(nStep <= MAX_ADJUST_VALUE) 
		{ 
			CMatrix	cMatrixI (cMatrixZ.GetMatrixColNumber (), cMatrixZ.GetMatrixColNumber ()); 
 
			cMatrixI.Eye (); 
 
 
			CMatrix cMatrixDX; 
			cMatrixDX.CopyMatrix ( (((cMatrixJJ + cMatrixI * nStep).Inverse ()) * cMatrixJE) * (-1.0) ); 
				 
 
			///////////////////////////////////////////////////////////////////////// 
			// 拆分cMatrixDX矩阵 
 
			unsigned int nIndex = 0; 
				 
			// 得到输入层到隐含层的权值的修正量 
			CMatrix cMatrixInputToHideWeightChange(nHideLayerNumber, nInputLayerNumber); 
 
			cMatrixDX.CopySubMatrixFromVector (cMatrixInputToHideWeightChange, nIndex); 
 
			nIndex += nHideLayerNumber * nInputLayerNumber; 
 
			// 得到隐含层阀值的修正量 
			CMatrix cMatrixHideLayerValveChange (nHideLayerNumber, (unsigned int)1); 
				 
			cMatrixDX.CopySubMatrixFromVector (cMatrixHideLayerValveChange, nIndex); 
 
 
			nIndex += nHideLayerNumber; 
 
			// 得到隐含层到输出层的权值的修正量 
			CMatrix cMatrixHideToOutputWeightChange (nOutputLayerNumber, nHideLayerNumber); 
				 
			cMatrixDX.CopySubMatrixFromVector (cMatrixHideToOutputWeightChange, nIndex); 
 
			nIndex += nOutputLayerNumber * nHideLayerNumber; 
 
			// 得到输出层阀值的修正值 
			CMatrix cMatrixOutputValveChange (nOutputLayerNumber, (unsigned int)1); 
 
			cMatrixDX.CopySubMatrixFromVector (cMatrixOutputValveChange, nIndex); 
	 
			cMatrixNewInputToHideWeight.CopyMatrix (matrixInputToHideWeightValue + cMatrixInputToHideWeightChange); 
 
			cMatrixNewHideLayerValve.CopyMatrix (matrixHideLayerValveValue + cMatrixHideLayerValveChange); 
 
			cMatrixNewHideToOutputWeight.CopyMatrix (matrixHideToOutputWeightValue + cMatrixHideToOutputWeightChange); 
 
			cMatrixNewOutputLayerValve.CopyMatrix (matrixOutputLayerValveValue + cMatrixOutputValveChange); 
		 
			// 前向计算 
			LMForwardCalculate (nInputLayerNumber, 
								nHideLayerNumber, 
								nOutputLayerNumber, 
								bSimulateDataFlag, 
								nComboFunc, 
								matrixDemoDataInput, 
								matrixInputLayerValue, 
								cMatrixNewInputToHideWeight, 
								cMatrixNewHideLayerValve, 
								matrixHideLayerOutput, 
								cMatrixNewHideToOutputWeight, 
								matrixOutputLayerOutput, 
								cMatrixNewOutputLayerValve 
								); 
 
				 
			cMatrixNewOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput; 
			nSystemErrorNew = 	cMatrixNewOutputLayerError.GetSystemError (); 
 
			if(nSystemErrorNew < nSystemErrorOld) 
			{ 
				break; 
			} 
			else 
			{ 
				nStep *= 10; 
			} 
				 
		}// End for while loop 
 
		if ( nStep > MAX_ADJUST_VALUE) 
		{ 
			nLoopTimes--; 
			return false; 
		} 
 
		nStep	*= 0.1; 
 
		// 赋值 
		matrixInputToHideWeightValue = cMatrixNewInputToHideWeight; 
		matrixHideLayerValveValue = cMatrixNewHideLayerValve; 
		matrixHideToOutputWeightValue = cMatrixNewHideToOutputWeight; 
		matrixOutputLayerValveValue = cMatrixNewOutputLayerValve; 
		cMatrixOutputLayerError = cMatrixNewOutputLayerError; 
		nSystemErrorOld = nSystemErrorNew; 
 
		// 显示数据和程序运行状态 
		nSystemError = nSystemErrorOld; 
		nTrainTimes = nLoopTimes; 
 
 
		// 显示系统误差 
		//char res_buffer[128] = {0}; 
		//sprintf(res_buffer,"%.16lf", nSystemError); 
		//HWND	hwnd = ::GetDlgItem (hWnd, ID_SYSTEM_ERROR); 
		//::SetWindowText (hwnd, res_buffer); 
 
		CString	strSystemError; 
		strSystemError.Format ("%.16lf", nSystemError); 
		LPCTSTR	lpstrSystemError = (LPCTSTR)strSystemError; 
		HWND	hwnd = ::GetDlgItem (hWnd, ID_SYSTEM_ERROR); 
		::SetWindowText (hwnd, lpstrSystemError); 
		 
	 
		// 显示训练次数 
		CString strTrainTimes; 
		strTrainTimes.Format ("%u", nTrainTimes + 1); 
		LPCTSTR lpstrTrainTimes = (LPCTSTR)strTrainTimes; 
		hwnd = ::GetDlgItem (hWnd, ID_TRAIN_TIMES); 
		::SetWindowText (hwnd, lpstrTrainTimes); 
 
	}// End the "for" loop 
	 
	return true; 
} 
 
///////////////////////////////////////////////////////////////////////////// 
//	Back propagation		---->		前向计算(Only for Training)		   // 
///////////////////////////////////////////////////////////////////////////// 
__declspec(dllexport) void BPForwardCalculate ( int nInputLayerNumber, 
												int nHideLayerNumber, 
												int nOutputLayerNumber, 
												bool bSimulateDataFlag, 
												int nComboFunc, 
												CMatrix &matrixDemoDataInput, 
												CMatrix &matrixInputLayerValue, 
												CMatrix &matrixInputToHideWeightValue, 
												CMatrix &matrixHideLayerValveValue, 
												CMatrix &matrixHideLayerOutput, 
												CMatrix &matrixHideToOutputWeightValue, 
												CMatrix &matrixOutputLayerOutput, 
												CMatrix &matrixOutputLayerValveValue, 
												CMatrix &cMatrixExHideLayerValveValue, 
												CMatrix &cMatrixExOutputLayerValveValue 
											   ) 
{ 
 
	if(bSimulateDataFlag) 
	{ 
 
		CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber); 
 
		// 得到样本的输入值 
		matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue, (unsigned int)0, (unsigned int)0); 
 
		CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose (); 
 
		matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue); 
 
 
	} 
 
	///////////////////////////////////////////////////////////////////////// 
	// 得到所有样本的隐含层的净输入 
	// 构造规则: 
	//		1. 样本的数目做为矩阵行数; 
	//		2. 单个样本的隐含层的数目做为矩阵的列数; 
	//		3. 矩阵元素中的值即为对应的样本的隐含层的净输入: 
	//		   由  
	//				cMatrixInputLayerValue * cMatrixInputToHideWeightValue  
	//				+ cMatrixHideLayerValveValue 
	//			得到. 
	// 
		 
	//CMatrix cMatrixExHideLayerValveValue; 
	//cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	CMatrix cMatrixHideLayerPureInput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	cMatrixHideLayerPureInput = matrixInputToHideWeightValue * matrixInputLayerValue; 
 
	cMatrixHideLayerPureInput += cMatrixExHideLayerValveValue; 
 
	///////////////////////////////////////////////////////////////////// 
	//	算出所有样本的隐含层的输出 
	//	构造规则: 
	//		1. 隐含层的输出y与隐含层的输入x的关系可用函数表示 
	//			y = f(x) 
	//		2. 矩阵的维数和隐含层的净输入矩阵的维数相等 
	// 
 
	CMatrix cMatrixHideLayerOutput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	switch(nComboFunc) 
	{ 
	case 0: 
		cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Sigmoid (); 
		break; 
 
	case 1: 
		cMatrixHideLayerOutput = cMatrixHideLayerPureInput.tanh (); 
		break; 
 
	case 2: 
		cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Tansig(); 
		break; 
 
	default: 
		return; 
	} 
	 
	matrixHideLayerOutput.CopyMatrix(cMatrixHideLayerOutput); 
 
	///////////////////////////////////////////////////////////////////// 
	//	得到所有样本输出层的净输入 
	//	构造规则; 
	//		1. 样本的数目做为矩阵的行数; 
	//		2. 单个样本的输出层的数目做为矩阵的列数; 
	//		3. 矩阵中元素的值即为对应样本的输出层的净输入: 
	//			由 
	//				cMatrixHideLayerOutput * cMatrixHideToOutputWeightValue 
	//				+ cMatrixOutputLayerValveValue 
	//			得到 
	// 
 
	//CMatrix cMatrixExOutputLayerValveValue; 
	//cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	CMatrix cMatrixOutputLayerPureInput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	cMatrixOutputLayerPureInput = matrixHideToOutputWeightValue * cMatrixHideLayerOutput; 
	cMatrixOutputLayerPureInput  += cMatrixExOutputLayerValveValue; 
 
 
	///////////////////////////////////////////////////////////////////// 
	//	算出所有样本的输出层的输出 
	//	构造规则: 
	//		1. 矩阵的维数与得到的所有样本的输出层的净输入组成的矩阵一样; 
	//		2. 输出层的输出y和输出层的输入可用关系式 
	//			y = f(x) 
	//		表示 
	// 
 
	CMatrix cMatrixOutputLayerOutput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	switch(nComboFunc) 
	{ 
	case 0: 
		cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Sigmoid (); 
		break; 
 
	case 1: 
		cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.tanh (); 
		break; 
 
	case 2: 
		cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Tansig (); 
		break; 
 
	default: 
		return ; 
	} 
 
	matrixOutputLayerOutput.CopyMatrix(cMatrixOutputLayerOutput); 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
//	Back propagation		---->		前向计算(Only for Simulating)	   // 
///////////////////////////////////////////////////////////////////////////// 
__declspec(dllexport) void BPForwardCalculate2( int nInputLayerNumber, 
												int nHideLayerNumber, 
												int nOutputLayerNumber, 
												bool bSimulateDataFlag, 
												int nComboFunc, 
												CMatrix &matrixDemoDataInput, 
												CMatrix &matrixInputLayerValue, 
												CMatrix &matrixInputToHideWeightValue, 
												CMatrix &matrixHideLayerValveValue, 
												CMatrix &matrixHideLayerOutput, 
												CMatrix &matrixHideToOutputWeightValue, 
												CMatrix &matrixOutputLayerOutput, 
												CMatrix &matrixOutputLayerValveValue 
											   ) 
{ 
 
	if(bSimulateDataFlag) 
	{ 
 
		CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber); 
 
		// 得到样本的输入值 
		matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue, (unsigned int)0, (unsigned int)0); 
 
		CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose (); 
 
		matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue); 
 
 
	} 
 
	///////////////////////////////////////////////////////////////////////// 
	// 得到所有样本的隐含层的净输入 
	// 构造规则: 
	//		1. 样本的数目做为矩阵行数; 
	//		2. 单个样本的隐含层的数目做为矩阵的列数; 
	//		3. 矩阵元素中的值即为对应的样本的隐含层的净输入: 
	//		   由  
	//				cMatrixInputLayerValue * cMatrixInputToHideWeightValue  
	//				+ cMatrixHideLayerValveValue 
	//			得到. 
	// 
		 
	CMatrix cMatrixExHideLayerValveValue; 
	cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	CMatrix cMatrixHideLayerPureInput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	cMatrixHideLayerPureInput = matrixInputToHideWeightValue * matrixInputLayerValue; 
 
	cMatrixHideLayerPureInput += cMatrixExHideLayerValveValue; 
 
 
	///////////////////////////////////////////////////////////////////// 
	//	算出所有样本的隐含层的输出 
	//	构造规则: 
	//		1. 隐含层的输出y与隐含层的输入x的关系可用函数表示 
	//			y = f(x) 
	//		2. 矩阵的维数和隐含层的净输入矩阵的维数相等 
	// 
 
	CMatrix cMatrixHideLayerOutput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	switch(nComboFunc) 
	{ 
	case 0: 
		cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Sigmoid (); 
		break; 
 
	case 1: 
		cMatrixHideLayerOutput = cMatrixHideLayerPureInput.tanh (); 
		break; 
 
	case 2: 
		cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Tansig(); 
		break; 
 
	default: 
		return; 
	} 
	 
	matrixHideLayerOutput.CopyMatrix(cMatrixHideLayerOutput); 
 
	///////////////////////////////////////////////////////////////////// 
	//	得到所有样本输出层的净输入 
	//	构造规则; 
	//		1. 样本的数目做为矩阵的行数; 
	//		2. 单个样本的输出层的数目做为矩阵的列数; 
	//		3. 矩阵中元素的值即为对应样本的输出层的净输入: 
	//			由 
	//				cMatrixHideLayerOutput * cMatrixHideToOutputWeightValue 
	//				+ cMatrixOutputLayerValveValue 
	//			得到 
	// 
 
	CMatrix cMatrixExOutputLayerValveValue; 
	cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	CMatrix cMatrixOutputLayerPureInput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	cMatrixOutputLayerPureInput = matrixHideToOutputWeightValue * cMatrixHideLayerOutput; 
	cMatrixOutputLayerPureInput  += cMatrixExOutputLayerValveValue; 
 
 
	///////////////////////////////////////////////////////////////////// 
	//	算出所有样本的输出层的输出 
	//	构造规则: 
	//		1. 矩阵的维数与得到的所有样本的输出层的净输入组成的矩阵一样; 
	//		2. 输出层的输出y和输出层的输入可用关系式 
	//			y = f(x) 
	//		表示 
	// 
 
	CMatrix cMatrixOutputLayerOutput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
	switch(nComboFunc) 
	{ 
	case 0: 
		cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Sigmoid (); 
		break; 
 
	case 1: 
		cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.tanh (); 
		break; 
 
	case 2: 
		cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Tansig (); 
		break; 
 
	default: 
		return ; 
	} 
 
	matrixOutputLayerOutput.CopyMatrix(cMatrixOutputLayerOutput); 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
//	Back propagation		---->		反馈计算						   // 
///////////////////////////////////////////////////////////////////////////// 
__declspec(dllexport) bool BPDemoDataTrainRepeat (	int nInputLayerNumber, 
													int nHideLayerNumber, 
													int nOutputLayerNumber, 
													bool bSimulateDataFlag, 
													int nComboFunc, 
													double nSystemErrorOld, 
													double nSystemErrorNew, 
													double nSystemErrorLevel, 
													double nSystemError, 
													double nStep, 
													UINT nMaxTrainTimes, 
													UINT nTrainTimes, 
													DWORD ID_SYSTEM_ERROR, 
													DWORD ID_TRAIN_TIMES, 
													HWND  hWnd, 
													CMatrix &matrixDemoDataInput, 
													CMatrix &matrixInputLayerValue, 
													CMatrix &matrixInputToHideWeightValue, 
													CMatrix &matrixHideLayerValveValue, 
													CMatrix &matrixHideLayerOutput, 
													CMatrix &matrixHideToOutputWeightValue, 
													CMatrix &matrixOutputLayerOutput, 
													CMatrix &matrixOutputLayerValveValue 
												 ) 
{ 
	// 根据BP算法修正nStep的初始值 
	nStep = 0.1; 
 
	// 前向计算 
	LMForwardCalculate (nInputLayerNumber, 
						nHideLayerNumber, 
						nOutputLayerNumber, 
						bSimulateDataFlag, 
						nComboFunc, 
						matrixDemoDataInput, 
						matrixInputLayerValue, 
						matrixInputToHideWeightValue, 
						matrixHideLayerValveValue, 
						matrixHideLayerOutput, 
						matrixHideToOutputWeightValue, 
						matrixOutputLayerOutput, 
						matrixOutputLayerValveValue 
						); 
		 
 
	///////////////////////////////////////////////////////////////////// 
	//	算出所有样本的输出层的delta矩阵 
	//	构造规则: 
	//		1. 样本的数目为矩阵的行数; 
	//		2. 样本输出层的数目为矩阵的列数; 
	//		3. 矩阵中的元素的值y为: 
	//				y = (前向计算出的输出层的值 - 样本的输出层的值) .* f'(net) 
	// 
	CMatrix cMatrixTDemoOutput(matrixDemoDataInput.GetMatrixRowNumber (), nOutputLayerNumber); 
		 
	// 得到样本中输出层的数据 
	matrixDemoDataInput.CopySubMatrix (cMatrixTDemoOutput, (unsigned int)nInputLayerNumber, (unsigned int)0); 
 
	CMatrix cMatrixDemoOutput = cMatrixTDemoOutput.Transpose (); 
 
	// 得到样本中输出层的误差 
	CMatrix cMatrixOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
	cMatrixOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput; 
 
	nSystemErrorOld = cMatrixOutputLayerError.GetSystemError (); 
 
	for(int nLoopTimes=1; nLoopTimes < nMaxTrainTimes; nLoopTimes++)	 
	{ 
		if(nSystemErrorOld < nSystemErrorLevel) 
		{ 
			nLoopTimes--; 
			break; 
		} 
 
		// 求输出层的delta值 
		// 注意: 此处'/' 是 '点乘'!!! 
		CMatrix	cMatrixOutputLayerDelta (nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber()); 
		cMatrixOutputLayerDelta = (matrixOutputLayerOutput - matrixOutputLayerOutput / matrixOutputLayerOutput) / cMatrixOutputLayerError; 
	 
		CMatrix cMatrixTHideToOutputWeightValue (matrixHideToOutputWeightValue.GetMatrixColNumber(), matrixHideToOutputWeightValue.GetMatrixRowNumber()); 
		cMatrixTHideToOutputWeightValue = matrixHideToOutputWeightValue.Transpose(); 
 
		// 求隐含层的delta值 
		// 注意: 此处'/' 是 '点乘'!!! 
		CMatrix cMatrixHideLayerDelta; 
		cMatrixHideLayerDelta.CopyMatrix ( (matrixHideLayerOutput - (matrixHideLayerOutput / matrixHideLayerOutput)) / ( cMatrixTHideToOutputWeightValue * cMatrixOutputLayerDelta) ); 
				 
		// 定义新的输入层到隐含层的权值 
		CMatrix cMatrixNewInputToHideWeight (matrixInputToHideWeightValue.GetMatrixRowNumber (), matrixInputToHideWeightValue.GetMatrixColNumber ()); 
		// 定义的新的隐含层的阀值 
		CMatrix cMatrixNewHideLayerValve (nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
		// 定义新的隐含层到输出层的权值 
		CMatrix cMatrixNewHideToOutputWeight (matrixHideToOutputWeightValue.GetMatrixRowNumber (), matrixHideToOutputWeightValue.GetMatrixColNumber ()); 
		// 定义新的输出层的阀值 
		CMatrix cMatrixNewOutputLayerValve (nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
		// 定义新的误差矩阵 
		CMatrix cMatrixNewOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ()); 
 
 
		// 权值和阀值调整 
		cMatrixNewHideToOutputWeight = cMatrixOutputLayerDelta * (matrixHideLayerOutput.Transpose ()) * (nStep); 
		cMatrixNewOutputLayerValve = cMatrixOutputLayerDelta; 
 
		cMatrixNewInputToHideWeight = cMatrixHideLayerDelta * (matrixInputLayerValue.Transpose ()) * (nStep); 
		cMatrixNewHideLayerValve = cMatrixHideLayerDelta; 
 
		// 赋值 
		matrixInputToHideWeightValue += cMatrixNewInputToHideWeight; 
 
		CMatrix cMatrixExHideLayerValveValue; 
		cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ()); 
		cMatrixExHideLayerValveValue += cMatrixNewHideLayerValve; 
 
		matrixHideToOutputWeightValue += cMatrixNewHideToOutputWeight; 
 
		CMatrix cMatrixExOutputLayerValveValue; 
		cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ()); 
		cMatrixExOutputLayerValveValue += cMatrixNewOutputLayerValve; 
 
		// 前向计算 
		BPForwardCalculate (nInputLayerNumber, 
							nHideLayerNumber, 
							nOutputLayerNumber, 
							bSimulateDataFlag, 
							nComboFunc, 
							matrixDemoDataInput, 
							matrixInputLayerValue, 
							matrixInputToHideWeightValue, 
							matrixHideLayerValveValue, 
							matrixHideLayerOutput, 
							matrixHideToOutputWeightValue, 
							matrixOutputLayerOutput, 
							matrixOutputLayerValveValue, 
							cMatrixExHideLayerValveValue, 
							cMatrixExOutputLayerValveValue 
							); 
 
 
		cMatrixNewOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput; 
		nSystemErrorNew = 	cMatrixNewOutputLayerError.GetSystemError (); 
 
		cMatrixOutputLayerError = cMatrixNewOutputLayerError; 
 
		if(nSystemErrorNew < nSystemErrorOld) 
		{ 
			nSystemErrorOld = nSystemErrorNew; 
		} 
		else 
		{ 
			nStep *= -0.1; 
		} 
 
		// 显示数据和程序运行状态 
		nSystemError = nSystemErrorOld; 
		nTrainTimes = nLoopTimes; 
 
 
		// 显示系统误差 
		CString	strSystemError; 
		strSystemError.Format ("%lf", nSystemError); 
		LPCTSTR	lpstrSystemError = (LPCTSTR)strSystemError; 
		HWND	hwnd = ::GetDlgItem (hWnd, ID_SYSTEM_ERROR); 
		::SetWindowText (hwnd, lpstrSystemError); 
	 
		// 显示训练次数 
		CString strTrainTimes; 
		strTrainTimes.Format ("%u", nTrainTimes + 1); 
		LPCTSTR lpstrTrainTimes = (LPCTSTR)strTrainTimes; 
		hwnd = ::GetDlgItem (hWnd, ID_TRAIN_TIMES); 
		::SetWindowText (hwnd, lpstrTrainTimes); 
 
	}// End the "for" loop 
	 
	return true; 
}