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

📄 mat.cpp

📁 这是个人脸识别程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// $mat\mat.cpp 1.5 milbo$// Initiallly derived from gslwrap-0.2\matrix_double.cc// Warning: this is raw research code -- expect it to be quite messy.// milbo jun 05, petaluma#include <iomanip>#include <stdio.h>#include <float.h>#include <limits.h>#pragma warning(disable:4786)		// MSC compiler: disable warnings about extremely long variable names in STL#include "cvec.hpp"#include "mcommon.hpp"#include "mfile.hpp"#include "mat.hpp"#include "matview.hpp"#include "mchol.hpp"#include "memstate.hpp"#define USE_EQ_DOUBLES	1	// 1 to for match within tolerance when testing for div by zero etc.#define TRACE			0	// for debug printfs#define PRINT_FORMAT 	"% 8.2f"	// default print formatnamespace GslMat{// Matrix printing format, global setting for all matriceschar Mat::sPrintFormat[20] = PRINT_FORMAT;	// for function printint  Mat::nPrintWidth = 8;					// for operator<<, derived from sgPrintFormatint  Mat::nPrintPrecision = 2;				// dittobool Mat::fAutoRedimOnAssign = false;//-----------------------------------------------------------------------------Mat::Mat (const double Vals[], size_t nrows1, size_t ncols1){m = gsl_matrix_alloc(nrows1, ncols1);int iVal = 0;for (int iRow = 0; iRow < nrows1; iRow++)	for (int iCol = 0; iCol < ncols1; iCol++)		gsl_matrix_set(m, iRow, iCol, Vals[iVal++]);}//-----------------------------------------------------------------------------Mat::Mat (const double Vals[], size_t nelems, const char sIsRowVec[]) // declare matrix as vector and init{int iVal = 0;if (sIsRowVec)								// create row vector if ANY string	{										// column matrix: one column, many rows	m = gsl_matrix_alloc(1, nelems);	for (int iCol = 0; iCol < nelems; iCol++)		gsl_matrix_set(m, 0, iCol, Vals[iVal++]);	}else										// row matrix: one row, many columns	{	m = gsl_matrix_alloc(nelems, 1);	for (int iRow = 0; iRow < nelems; iRow++)		gsl_matrix_set(m, iRow, 0, Vals[iVal++]);	}}//-----------------------------------------------------------------------------void Mat::getDim (int *pnrows, int *pncols) const{if (m)	{	*pnrows = nrows();	*pncols = ncols();	}else	{	*pnrows = 0;	*pncols = 0;	}}//-----------------------------------------------------------------------------// If dimensions are same then matrix not touched.// Else redimensions the matrix.  The new contents are unspecified.// This function is quicker than dimKeep() or dimClear()void Mat::dim (size_t nrows1, size_t ncols1){if (nrows1 == 0 || ncols1 == 0)	// zero size?	{	if (m)		{		DASSERT(m->owner);		// only the owner can change the size (a view can't)		gsl_matrix_free(m);		m = NULL;		}	}else if (!m)	m = gsl_matrix_alloc(nrows1, ncols1);else if (nrows() != nrows1 || ncols() != ncols1)	{	DASSERT(m->owner);		// only the owner can change the size (a view can't)	gsl_matrix_free(m);	m = gsl_matrix_alloc(nrows1, ncols1);	}}void Mat::dim(size_t nelems, const char *sIsRowVec) 	// redimension, new contents unspecified{if (sIsRowVec)								// create row vector if ANY string	dim(1, nelems);else	dim(nelems, 1);}void Mat::dim (const Mat &other)		// make this the same size as other{dim(other.nrows(), other.ncols());}//-----------------------------------------------------------------------------// If dimensions are same then matrix not touched.// Else clears the matrix when it actually redimensions it.void Mat::dimClear (size_t nrows1, size_t ncols1){if (nrows1 == 0 || ncols1 == 0)	// zero size?	{	if (m)		{		DASSERT(m->owner);	// only the owner can change the size (a view can't)		gsl_matrix_free(m);		m = NULL;		}	}else if (!m)	m = gsl_matrix_calloc(nrows1, ncols1);else if (nrows() != nrows1 || ncols() != ncols1)	{	DASSERT(m->owner);	gsl_matrix_free(m);	m = gsl_matrix_calloc(nrows1, ncols1);	}}//-----------------------------------------------------------------------------// This preserves as much of the old data as possible.  If new matrix is// bigger than or same size as the old matrix then all data will be preserved.// Unused entries in the new matrix are cleared i.e. set to 0.void Mat::dimKeep (size_t nrows1, size_t ncols1){if (nrows1 == 0 || ncols1 == 0)	// zero size?	{	if (m)		{		DASSERT(m->owner);	// only the owner can change the size (a view can't)		gsl_matrix_free(m);		m = NULL;		}	}else if (!m)	m = gsl_matrix_calloc(nrows1, ncols1);else if (nrows() != nrows1 || ncols() != ncols1)	{	DASSERT(m->owner);	gsl_matrix *p = gsl_matrix_calloc( nrows1, ncols1);	// copy as much of the data as will fit in the new matrix	size_t nMinrows = __min(nrows1, nrows());	size_t nMincols = __min(ncols1, ncols());	for (size_t i = 0; i < nMinrows; i++)		for (size_t j = 0; j < nMincols; j++)			gsl_matrix_set(p, i, j, gsl_matrix_get(m, i, j));	gsl_matrix_free(m);	m = p;					// copy top structure only, not values, for speed	}}//-----------------------------------------------------------------------------// Redimension this to the same size as other and copy other into this// If no redimensioning is needed this is about as fast as operator=void Mat::assign (const Mat &other){dim(other.nrows(), other.ncols());copy(other);}//-----------------------------------------------------------------------------// Helper functionconst Mat Mat::reshapeAux (const Mat &A, size_t nNewRows, size_t nNewCols,			bool fRowMajor,	size_t nStartRow, size_t nStartCol, size_t nrows1, size_t ncols1){if (nrows1 == 0)	nrows1 = A.nrows() - nStartRow;if (ncols1 == 0)	ncols1 = A.ncols() - nStartCol;#if GSL_RANGE_CHECKDASSERT(nStartRow >= 0 && nStartCol >= 0);if (nStartRow + nrows1 > A.nrows() || nStartCol + ncols1 > A.ncols())	SysErr("Mat::reshape rows %d+%d > %d or columns %d+%d > %d",		nStartRow, nrows1, A.nrows(), nStartCol, ncols1, A.ncols());if (nrows1 * ncols1 < nNewRows * nNewCols)	SysErr("Mat::reshape old dimensions %dx%d < new dimensions %dx%d",		nrows1, ncols1, nNewRows, nNewCols);#endifMat m(nNewRows, nNewCols);int i0 = 0, j0 = 0;if (fRowMajor)	{	for (size_t j = nStartCol; j < nStartCol + ncols1; j++)		for (size_t i = nStartRow; i < nStartRow + nrows1; i++)			{			m(i0, j0) = A(i,j);			if (++i0 == nNewRows)				{				i0 = 0;				j0++;				if (j0 == nNewCols)					return m;				}			}	}else	{	for (size_t i = nStartRow; i < nStartRow + nrows1; i++)		for (size_t j = nStartCol; j < nStartCol + ncols1; j++)			{			m(i0, j0) = A(i,j);			if (++j0 == nNewCols)				{				j0 = 0;				i0++;				if (i0 == nNewRows)					return m;				}			}	}DASSERT(false);	// should never get herereturn m;}//-----------------------------------------------------------------------------// Return a submatrix of this, redimensioned to nNewRows and nNewCols// If you just want a submatrix then use submatrix().//// nStartRow nStartCol nrows1 ncols1 specify the submatrix in the original matrix//// nNewRows and nNewCols specify the layout in the new matrix//// If nrows1=0 it will be set to max possible, ditto for ncols1//// Thus if just want to relayout the rows and cols of a matrix then set all// of nStartRow nStartRow nStartCol nrows1 ncols1 to 0 and nNewRows and// nNewCols to the new layout.//// If you want to access parts of a matrix without data copying, perhaps a// view will suit you better -- see MatView in matview.hpp.  This is usually// more efficient.Mat	Mat::reshape (size_t nNewRows, size_t nNewCols, bool fRowMajor,				size_t nStartRow, size_t nStartCol, size_t nrows1, size_t ncols1){return reshapeAux(*this, nNewRows, nNewCols, fRowMajor, nStartRow, nStartCol, nrows1, ncols1);}//-----------------------------------------------------------------------------// Make me a submatrix of myself, redimensioned to nNewRows and nNewCols// See header comments in reshape().Mat Mat::reshapeMe (size_t nNewRows, size_t nNewCols, bool fRowMajor,				size_t nStartRow, size_t nStartCol, size_t nrows1, size_t ncols1){Mat result(reshapeAux(*this, nNewRows, nNewCols, fRowMajor, nStartRow, nStartCol, nrows1, ncols1));this->assign(result);return *this;}//-----------------------------------------------------------------------------void Mat::printAux (const char sMsg[], const char sFormat[], 	// helper for print()					const char *sFile, FILE *pFile, int nMax, bool fPrintRowIndex) const{bool fCloseFile = false;ASSERT(!(pFile && !sFile));	// must give a file name for error reporting if pFile is givenif (sFile && 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";if (nMax == 0)	nMax = CONF_nMaxMatDim;int nrows1 = __min(nMax, nrows());int ncols1 = __min(nMax, ncols());if (sMsg)	if (pFile)		fprintf(pFile, sMsg, nrows(), ncols());	else		lprintf(sMsg, nrows(), ncols());for (size_t iRow = 0; iRow < nrows1; iRow++)	{	if (fPrintRowIndex)		if (pFile)			fprintf(pFile, "%3d: ", iRow);		else			lprintf("%3d: ", iRow);   	for (size_t iCol = 0; iCol < ncols1; iCol++)		if (pFile)			if (sFormat)				fprintf(pFile, sFormat, getElem(iRow, iCol));			else				fprintf(pFile, sPrintFormat, getElem(iRow, iCol));		else			if (sFormat)				lprintf(sFormat, getElem(iRow, iCol));			else				lprintf(sPrintFormat, getElem(iRow, iCol));	if (iRow < nrows1)		{		if (pFile)			fprintf(pFile, "\n");		else			lprintf("\n");		}	}if (pFile)	fflush(pFile);	// flush it out so it can be seen even if application crashes laterelse	fflush(stdout);if (fCloseFile)	fclose(pFile);}void Mat::print (const char sMsg[], const char sFormat[],					const char *sFile, FILE *pFile, int nMax, bool fPrintRowIndex) const{printAux(sMsg, sFormat, sFile, pFile, nMax, fPrintRowIndex);}void Mat::print (const char sMsg[], const char sFormat[],					const char *sFile, FILE *pFile, int nMax, bool fPrintRowIndex){printAux(sMsg, sFormat, sFile, pFile, nMax, fPrintRowIndex);}//-----------------------------------------------------------------------------#if OSTREAM_SUPPORTostream& operator<< (ostream& os, const Mat &m){using namespace std;os.setf(ios::fixed);os << setprecision(Mat::nPrintPrecision);for (size_t iRow = 0; iRow < m.nrows(); iRow++)	{   	for (size_t iCol = 0; iCol < m.ncols(); iCol++)		os << setw(Mat::nPrintWidth) << m.getElem(iRow, iCol) << " ";	if (iRow < m.nrows()-1)		os << endl;	}return os;}#endif//-----------------------------------------------------------------------------// You should init nrows() and ncols() before calling this routineMat& Mat::operator= (const double Vals[])	// assign an array of doubles{int iVal = 0;for (int iRow = 0; iRow < nrows(); iRow++)		for (int iCol = 0; iCol < ncols(); iCol++)			gsl_matrix_set(m, iRow, iCol, Vals[iVal++]);return *this;}//-----------------------------------------------------------------------------bool Mat::operator== (const Mat &other) const{if (nrows() != other.nrows() || ncols() != other.ncols())  return false;for (size_t iRow = 0; iRow < nrows(); iRow++) 	for (size_t iCol = 0; iCol < ncols(); iCol++)		if (this->getElem(iRow, iCol) != other.getElem(iRow, iCol))			return false;return true;}//-----------------------------------------------------------------------------Mat Mat::operator+ (const Mat &other) const{Mat result(*this);gsl_matrix_add(result.m, other.m);return result;}//-----------------------------------------------------------------------------Mat Mat::operator+ (const double &d) const{Mat result(*this);gsl_matrix_add_constant(result.m, d);return result;}//-----------------------------------------------------------------------------Mat operator+ (const double &d, const Mat &other){Mat result(other);gsl_matrix_add_constant(result.m, d);return result;}//-----------------------------------------------------------------------------Mat &Mat::operator+= (const double &d){gsl_matrix_add_constant(m, d);return *this;}//-----------------------------------------------------------------------------Mat &Mat::operator+= (const Mat &other){gsl_matrix_add(m, other.m);

⌨️ 快捷键说明

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