⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mat.cpp

📁 这是个人脸识别程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
return i;}//-----------------------------------------------------------------------------double Mat::trace () const{double sum = 0;#if GSL_RANGE_CHECKvoid CheckIsSquare(const Mat &A, const char *sMsg);	// forward declarationCheckIsSquare(*this, "Mat trace");#endiffor (int iRow = 0; iRow < nrows(); iRow++)	sum += getElem(iRow, iRow);return sum;}//-----------------------------------------------------------------------------Mat Mat::t () const 			// transpose of matrix{Mat result(ncols(), nrows());for (int i = 0; i < nrows(); i++)	for (int j = 0; j < ncols(); j++)		gsl_matrix_set(result.m, j, i, gsl_matrix_get(m, i, j));return result;}//-----------------------------------------------------------------------------Mat Mat::transposeMe (){assign(t());return *this;}//-----------------------------------------------------------------------------// Returns sum of log of absolute value of diag elems. If an elem is 0 returns -DBL_MAX// Equivalent to product of diag elems, but without overflow//// TODO not yet tested in test.cppdouble Mat::sumLnDiag () const{#if GSL_RANGE_CHECKCheckIsSquare(*this, "Mat sumLnDiag");#endifdouble sum = 0;for (int iRow = 0; iRow < nrows(); iRow++)	{	double Elem = fabs(getElem(iRow, iRow));	if (fEqual(Elem, 0))		return -DBL_MAX;	else		sum += log(Elem);	}return sum;}double Mat::prodDiag () const	// product of diag elements{#if GSL_RANGE_CHECKCheckIsSquare(*this, "Mat prodDiag");#endifdouble prod = 1;for (int iRow = 0; iRow < nrows(); iRow++)	prod *= getElem(iRow, iRow);return prod;}//-----------------------------------------------------------------------------double Mat::det (int sign) const{Mat a = *this;a = a.LU_decomp();return gsl_linalg_LU_det(a.m, sign);}//-----------------------------------------------------------------------------double Mat::lndet () const{Mat a = *this;a = a.LU_decomp();return gsl_linalg_LU_lndet(a.m);}//-----------------------------------------------------------------------------Mat Mat::inverse () const{gsl_permutation *pPerm = gsl_permutation_alloc(nrows());Mat A = *this;A = A.LU_decomp(pPerm);Mat AInverse(nrows(), ncols());int iRet = gsl_linalg_LU_invert(A.m, pPerm, AInverse.m);DASSERT(iRet == 0);gsl_permutation_free(pPerm);return AInverse;}//-----------------------------------------------------------------------------Mat Mat::invertMe (){assign(inverse());return *this;}//-----------------------------------------------------------------------------Mat Mat::LU_decomp (gsl_permutation *pPerm, int *pSign) const{bool fRetPerm = (pPerm != NULL);if (!pPerm)	pPerm = gsl_permutation_alloc(nrows());int Sign;Mat result = *this;int iRet = gsl_linalg_LU_decomp(result.m, pPerm, &Sign);// check if matrix is singular i.e. has a zero pivotfor (int i = result.nrows()-1; i >= 0; i--)		// smallest last so look there 1st	ASSERT(!fEqual(result(i,i), FLT_EPSILON));	// use FLT_EPSILON as a convenient small nbrDASSERT(iRet == 0);if (!fRetPerm)	gsl_permutation_free(pPerm);if (pSign)	*pSign = Sign;return result;}//-----------------------------------------------------------------------------// Set matrix print format// Expects a printf style format string like %g or %8.2f// The format applies to all matrices, not just this onevoid Mat::setPrintFormat (const char *sPrintFormat){if (sPrintFormat == NULL)		// if null parameter then use default format	sPrintFormat = PRINT_FORMAT;DASSERT(strlen(sPrintFormat) < sizeof(Mat::sPrintFormat)-1);sprintf(Mat::sPrintFormat, "%s ", sPrintFormat);// get nPrintWidth and nPrintPrecision from sPrintFormat, also checks sPrintFormat// TODO this may longer work with new PRINT_FORMAT, added space after %DASSERT(sPrintFormat[0] == '%');char c0 = 'x', c1 = 'x';if (sPrintFormat[1] >= '0' && sPrintFormat[1] <= '9')	sscanf(sPrintFormat+1, "%d%c%d%c", &nPrintWidth, &c0, &nPrintPrecision, &c1);else	sscanf(sPrintFormat+1, "%c", &c0);#if 0	//TODO fix this some time// sanity check format helps prevent crash later when used in a printfDASSERT(c0 == 'f' || c0 == 'g' || c0 == 'e' || c1 == 'f' || c1 == 'g' || c1 == 'e');#endif}//-----------------------------------------------------------------------------// If pFile is NULL then it is opened.  If pFile is already open then we append// to it (and sFile isn't used except for user messages).//// File format is://// # optional comments each prefixed by #// "optional mat tag string, can be read back or ignored by Mat::read, all chars except tilde allowed"// # more optional comments// {// nrows ncols			// comments NOT allowed between { and }// elements...// }//// { and } are header and footer chars (for sanity checking when reading).void Mat::write (const char *sFile, FILE *pFile, bool fVerbose, const char sComment[], const char sFormat[], bool fLimitOutputWidth) const{bool fCloseFile = false;ASSERT(!(pFile && !sFile));	// must give a file name for error reporting if pFile is givenif (pFile == NULL)	{	pFile = fopen(sFile, "w");	if (!pFile)		Err("Can't open %s", sFile);	fCloseFile = true;	}size_t nrows1 = nGetRows(), ncols1 = nGetCols();if (!sFile)		// make sure we have something to print in user messages	sFile = "file";if (fVerbose)	lprintf("Write %s %dx%d\n", sFile, nrows(), ncols());if (sComment)	fprintf(pFile, "# %s\n", sComment);char sStart[] = "{ ", sEnd[] = "}\n";if (2 != ::fwrite(sStart, 1, 2, pFile))	Err("Can't write matrix to %s", sFile);// we don't use gsl_matrix_fprintf because debugging is easier if matrix is laid out on a per row basisif (0 == fprintf(pFile, "%d %d", nrows1, ncols1))	Err("Can't write matrix to %s", sFile);if (nrows1 == 1 && ncols1 < 20)		// a little tweak so small vectors can be seen more easily	fprintf(pFile, " ");else	fprintf(pFile, "\n");int ncolsMax = ncols1;if (fLimitOutputWidth)	{	if (ncolsMax > 20)		ncolsMax = int(sqrt(ncols1));	if (ncolsMax > 20)		ncolsMax = 20;	}for (int iRow = 0; iRow < nrows1; iRow++)	for (int iCol = 0; iCol < ncols1; iCol++)		{		if (sFormat)			{			if (fprintf(pFile, sFormat, getElem(iRow, iCol)) < 1)				Err("Can't write matrix to %s", sFile);			}		else if (fprintf(pFile, "%13g", getElem(iRow, iCol)) < 13)			Err("Can't write matrix to %s", sFile);		if (iCol % ncolsMax == (ncolsMax-1) || iCol == ncols1-1)	// print \n every 20th number and at end of row			{			if (fprintf(pFile, "\n") != 1)				Err("Can't write matrix to %s", sFile);			}		else if (fprintf(pFile, " ") != 1)			Err("Can't write matrix to %s", sFile);		}if (2 != ::fwrite(sEnd, 1, 2, pFile))	Err("Can't write matrix to %s", sFile);if (fCloseFile)	fclose(pFile);}//-----------------------------------------------------------------------------// Like Mat::write but writes the matrix as a C language array// If sArrayName is NULL then we don't write the matrix name or terminating ";".// This is used in WriteMatVecACArray to write multiple matrices as big one array.void Mat::writeAsCArray (const char sArrayName[], const char *sFile, FILE *pFile,						 const char *sType, bool fVector, bool fVerbose) const{bool fCloseFile = false;ASSERT(!(pFile && !sFile));	// must give a file name for error reporting if pFile is givenif (pFile == NULL)	{	pFile = fopen(sFile, "w");	if (!pFile)		Err("Can't open %s", sFile);	fCloseFile = true;	}if (!sFile)		// make sure we have something to print in user messages	sFile = "file";size_t nrows1 = nGetRows(), ncols1 = nGetCols();if (fVerbose)	lprintf("Write %s %s[%d];\n", sType, sArrayName, (nrows1>1? nrows1: ncols1));char *sFormat;double Max;if (0 == strcmp(sType, "double"))	{ sFormat = "%g"; Max = DBL_MAX; }else if (0 == strcmp(sType, "float"))	{ sFormat = "%#gf"; Max = FLT_MAX; } // will print as 1.23f, the # forces decimal point (needed for f suffix)else if (0 == strcmp(sType, "int"))	{ sFormat = "%d"; Max = INT_MAX; }else if (0 == strcmp(sType, "short"))	{ sFormat = "%d"; Max = SHRT_MAX; }else if ( 0 == strcmp(sType, "char"))	{ sFormat = "%d"; Max = SCHAR_MAX; }else	SysErr("WriteMatVecAsCArray: sType must be one of double, float, int, short, char");if (sArrayName)	{	Fprintf(sFile, pFile, "#ifdef DEFS_ONLY\n");	if (fVector)		Fprintf(sFile, pFile, "extern %s %s[%d];\n", sType, sArrayName, (nrows1>1? nrows1: ncols1));	else		Fprintf(sFile, pFile, "extern %s %s[%d][%d];\n", sType, sArrayName, nrows1, ncols1);	Fprintf(sFile, pFile, "#else\n");	if (fVector)		Fprintf(sFile, pFile, "%s %s[%d] = {\n", sType, sArrayName, (nrows1>1? nrows1: ncols1));	else		Fprintf(sFile, pFile, "%s %s[%d][%d] = {\n", sType, sArrayName, nrows1, ncols1);	}for (int iRow = 0; iRow < nrows1; iRow++)	{	Fprintf(sFile, pFile, "\t");	if (!fVector)		Fprintf(sFile, pFile, "{");	for (int iCol = 0; iCol < ncols1; iCol++)		{		double Elem = getElem(iRow, iCol);		if (Elem < -Max+1 || Elem > Max-1)			{			Warn("writeAsCArray %s overflow %g range %g %g sFormat %s", sType, Elem, -Max+1, Max-1, sFormat);			Elem = (Elem < 0? -Max+1:Max-1);			}		if (sType[0] == 'i' || sType[0] == 's' || sType[0] == 'c')	// int or short or char type?			fprintf(pFile, sFormat, iRound(Elem));					// fprintf not Fprintf for speed		else			fprintf(pFile, sFormat, Elem);		if (iCol < ncols1-1)			fprintf(pFile, ",");		if ((iCol+1) % 12 == 0 && iCol < ncols1-1)				// limit output width (up to 12 numbers per line)			fprintf(pFile, "\n\t ");		}	if (!fVector)		Fprintf(sFile, pFile, "},");	Fprintf(sFile, pFile, "\n");	}if (sArrayName)	{	Fprintf(sFile, pFile, "};\n");	Fprintf(sFile, pFile, "#endif // DEFS_ONLY\n");	}if (fCloseFile)	fclose(pFile);}//-----------------------------------------------------------------------------// If pFile is NULL then it is opened.  If pFile is already open then we read// from it (and sFile isn't used except for user messages).//// If we try to read a matrix and can't find the matrix header '{' then we return// with an error message, if fExitOnErr is false.//// We copy the matrix tag string into sTag, if sTag is not null.// The caller must ensure that there is enough space in sTag.// A tag string is an optional string (with no ~) enclosed in quotes before the matrix first delimiter '{'.// It can be used for storing filenames and other info for the matrix.// The leading and closing quotes are removed before copying into sTag.// If there is no tag string, sTag[0] is set to 0.//// File format: see Mat::writechar *Mat::sread (const char *sFile, FILE *pFile, char *sTag, bool fVerbose, bool fExitOnErr){static char sErr[256];char sTag1[256]; sTag1[0] = 0;	// mat prefix we read from file, possibly copied into sTagif (sTag)	sTag[0] = 0;bool fCloseFile = false;ASSERT(!(pFile && !sFile));	// must give a file name for error reporting if pFile is givenif (pFile == NULL)	{	DASSERT(sFile);	pFile = fopen(sFile, "r");	if (!pFile)		if (fExitOnErr)			Err("Can't open %s", sFile);		else			return "Can't open file";	fCloseFile = true;	}size_t nrows, ncols;if (!sFile)	// make sure we have something to print for user messages	sFile = "file";if (fVerbose)	lprintf("Read %s ", sFile);// search for first delimiter '{', skipping optional comments prefixed by # or "char c;do {	if (1 != ::fread(&c, 1, 1, pFile))		{		sprintf(sErr, "Can't read matrix header from %s (no '{') [last valid tag string \"%s\"]", sFile, sTag1);		if (fExitOnErr)			Err(sErr);		else			{			if (fCloseFile)				fclose(pFile);			return sErr;			}		}	if (c == '#')						// comment?		{		while (c != '\n')				// if so, then skip it			if (1 != ::fread(&c, 1, 1, pFile))				{				sprintf(sErr, "Can't read matrix header from %s (no '{') [last valid tag string \"%s\"]", sFile, sTag1);				if (fExitOnErr)					Err(sErr);				else					{					if (fCloseFile)						fclose(pFile);					return sErr;					}				}		}	else if (c == '"')			// embedded string?		{		if (!fgets(sTag1, 256-1, pFile))			{			sprintf(sErr, "Can't read matrix header from %s (no '{') [last valid tag string \"%s\"]", sFile, sTag1);			if (fExitOnErr)				Err(sErr);			else				{				if (fCloseFile)					fclose(pFile);				return sErr;				}			}		if (sTag)			{			char *pDest = strchr(sTag1, '"');	// there may or may not be a terminating ", be lenient			int iLen = strlen(sTag1)-1;			if (pDest)				{				iLen--;				*pDest = 0;				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -