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

📄 cmat.cpp

📁 face recognition test source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"

#include "str.h"
#include "error.h"
#include "CDiag.h"
#include "CMat.h"
#include "CMatSym.h"
#include "eigen.h"
#include "math.h"
#include "def.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>

CMatrix::CMatrix()
	{
	li = 0;
	col = 0;
	bTranspose = FALSE;
	bLocked = FALSE;
	pData = NULL;
	pMem = NULL;
	pMemName = NULL;
	}

CMatrix::CMatrix(long l, long c)
	{
	li = l;
	col = c;
	bTranspose = FALSE;
	pData = NULL;
	pMem = NULL;
	bLocked = FALSE;
	pMemName = NULL;
	Allocate();
	}

CMatrix::~CMatrix()
	{
	long l;
	Unlock();
	if (pMem != NULL)
		{
		delete pMem;
		pMem = NULL;
		}
	if (pMemName != NULL)
		{
		delete pMemName;
		}
	}

void CMatrix::Allocate(long l1, long l2)
	{
	li = l1;
	col = l2;
	Allocate();
	}

/***********************************************************************
* Load a matrix from a text file.
* For the format look at the Save() fct right after this one.
* BEWARE, there is a severe limitation : all numbers MAY NOT be longer than 13 characters.
* Otherwize the matrix actually get is not at all the one expected !!!
* If you save the matrix with the Save() fct (as it is expected), this limitation is 
* respected and there is nothing to worry about.
***********************************************************************/
int CMatrix::Load(char *filename)
	{
	int fh;
  	long lcol, lrow;
  	CMemory *pmem;
  	char *str, *pstr;
  	valtype val; 
  	long lfilelen, lprevpos;
  	unsigned int nread, nbuflen = 60000, ntmplen = 40;
   	
	Msg(1, str_LOADING, filename);
	fh = _open(filename, _O_RDONLY | _O_BINARY);		/*Open the file in text mode, overwites it if it doesn't exist*/
	if (fh == -1)
		{
		Msg(-1, str_ERR_FILE_OPEN, strerror(errno));
		return ERR_FILE_OPEN;
		}
	
	/*Allocate reading memory*/
	_lseek(fh, 0, SEEK_END);
	lfilelen = _tell(fh);									/*Calculates the file lenght*/
	if (lfilelen == -1L)
		{
		Msg(0, strerror(errno));
		_close(fh);												/*Close the file*/
		return -errno;
		}
	_lseek(fh, 0, SEEK_SET);
	
	if (lfilelen < (long)nbuflen)
		nbuflen = lfilelen;
	lprevpos = 0;
	
	pmem = new CMemory();
	pmem->Allocate(nbuflen);
	str = (char *)pmem->GetPtr();
	
	/*Read the first part of the file*/
	nread = _read(fh, str, nbuflen);
	if (nread == -1)
		{
		Msg(-1, str_ERR_FILE_READ, strerror(errno));
		return -errno;
		}
	
	/*Read the matrix's number of rows*/
	li = atol(strtok(str, str_TABRT));
	if (li == 0L)
		{
		Msg(-1, str_ERR_MAT_LOAD_ROW);
		return ERR_MAT_LOAD_ROW;
		}
	
	/*Read the matrix's number of columns*/
	col = atol(strtok(NULL, str_TABRT));
	if (col == 0L)
		{
		Msg(-1, str_ERR_MAT_LOAD_COL);
		return ERR_MAT_LOAD_COL;
		}
	
	pstr = strtok(NULL, str_TABRT);
	if (atof(pstr) == 0.0)
		{
		Msg(-1, str_ERR_MAT_LOAD_HDR);
		return ERR_MAT_LOAD_HDR;
		}
	
	Allocate(li, col);										/*In case of a CMatrixPtr object, it has to allocate memory for the columns*/
	
	Lock();
	
/*	while (isdigit(pstr[0]) == 0 && pstr[0] != '+' && pstr[0] != '-')
		pstr++;
	pstr = strtok(pstr, str_TABRT);
*/
		
	for (lrow = 1L; lrow <= li; lrow++)
		{
		for (lcol = 1L; lcol <= col/* - 1L*/; lcol++)
			{
			val = atof(pstr);
			SetAt(lrow, lcol, val);
			pstr = strtok(NULL, str_TABRT);
			if ((long)pstr - (long)str > (long)(nread - ntmplen))
				{													/*read the next part of the file*/
				lprevpos = _lseek(fh, lprevpos + (long)pstr - (long)str, SEEK_SET);
				nread = _read(fh, str, nbuflen);
				if (nread == -1)
					{
					Msg(-1, str_ERR_FILE_READ, strerror(errno));
					return -errno;
					}
				pstr = strtok(str, str_TABRT);
				}
			}
		}
	
	_close(fh);
	Unlock();
	
	pmem->ReleasePtr();
	delete pmem;
	
	Msg(-1, str_LOADED);
	
	return 0;
	}

/***********************************************************************
* Save the matrix in a text file. The only parameter to this fct is the file name
* The file format is as follow:
*
* <row number>\t<Column number>\n
* <col1 name>\t<col2 name>\t...
* <el11>\t<el12>\t...\t<el1n>\n
* <el21>\t...........\t<el2n>\n
* .
* .
* .
* <elm1>\t...........\t<elmn>\n
* EOF
***********************************************************************/
int CMatrix::Save(char *filename)
	{
	int fh;
  	long row, col, lcol, lrow;
  	char str[20];
   	
	Msg(1, str_SAVING, filename);
	fh = _open(filename, _O_CREAT | _O_WRONLY | _O_TEXT, _S_IREAD | _S_IWRITE);
																	/*Create the file in text mode, overwites it if it already exists*/
	if (fh == -1)
		{
		Msg(-1, str_ERR_FILE_OPEN, strerror(errno));
		return ERR_FILE_OPEN;
		}
	
	lcol = GetCol();
	lrow = GetLi();
	
	Lock();
	
	sprintf(str, "%ld\t%ld\n", lrow, lcol);
	_write(fh, str, strlen(str));
	
	char name[MAX_NAME];
	if (GetColName(1, name, sizeof(name)) == 0)
		{
		/*There are cols name, so save it*/
		for (col = 1L; col <= lcol; col++)
			{
			if (GetColName(col, name, sizeof(name)) < 0)
				break;
			if (col == lcol)
				sprintf(str, "%s\n", name);
			else
				sprintf(str, "%s\t", name);
			_write(fh, str, strlen(str));
			}
		}
		
	for (row = 1L; row <= lrow; row++)
		{
		for (col = 1L; col <= lcol; col++)
			{
			sprintf(str, "%.6E\t", GetAt(row, col));			
			_write(fh, str, strlen(str));
			}
		_write(fh, "\n", 1);
		}
	
	Unlock();
	
	if (_close(fh) == -1)
		{
		Msg(0, str_ERR_FILE_CLOSE, strerror(errno));
		}
	
	Msg(-1, str_SAVED);
	
	return 0;
	}

/***********************************************************************
* Add to this matrix the matrix pMat2
***********************************************************************/
void CMatrix::Add(CMatrix *pMat2)
	{
	long c, l, llen, clen;
	/*Verify that the matrices have the same dimension*/
	if (pMat2->GetCol() != col || pMat2->GetLi() != li)
		Fail(NULL);
	llen = GetLi();
	clen = GetCol();
	Lock();
	pMat2->Lock();
	for (l = 1; l <= llen; l++)
		{
		for (c = 1; c <= clen; c++)
			{
 			SetAt(l, c, GetAt(l, c) + pMat2->GetAt(l, c));
 			}
 		}
 
 	Unlock();
 	pMat2->Unlock();
	}
 
/***********************************************************************
* Multiply pMat1 by pMat2, and put the result in this matrix
*
* if bResize is FALSE, does nothing else than a normal matrix multiplication
*
* if bResize is TRUE, and if the number of rows in pMat2 is < than the number of columns 
* of pMat1, it adds some rows at the end of pMat2 (their value being zero) in order to be able
* to actually do the multiplication
* if bResize is true it computes the mulpitiplation only on the elements of this matrix
* up to the column lNewCol and to the row lNewRow
***********************************************************************/
void CMatrix::Multiply(CMatrix *pMat1, CMatrix *pMat2, BOOL bResize, long lNewRow, long lNewCol)
 	{
 	long c, l, r, llen, clen, k;
 	valtype val;
 
 	if (col == 0 || li == 0)
 		{                                      				/*the matrix was not initialised*/
 		col = pMat2->GetCol();
 		li = pMat1->GetLi();
 		Allocate();
 		}
 	else
 		{													/*Verify that the matrices have the same dimension*/
 		if (bResize != TRUE && (pMat2->GetCol() != col || pMat1->GetLi() != li))
 			Fail(NULL);
 		}
 
 	//Initialize();
 
 	r = lmin(pMat2->GetLi(), pMat1->GetCol());
 	if (bResize == FALSE)
 		{
 		llen = GetLi();
 		clen = GetCol();
 		}
 	else
 		{
 		llen = lNewRow;
 		clen = lNewCol;
 		}
 		
 	Lock();
 	pMat2->Lock();
 	pMat1->Lock();
 
 	for (l = 1L; l <= llen; l++)
 		{
 		for (c = 1L; c <= clen; c++)
 			{
 			val = (valtype)0;
 			for (k = 1L; k <= r; k++)
 				{
 				val += pMat1->GetAt(l, k) * pMat2->GetAt(k, c);
 				}
 			SetAt(l, c, val);
 			}
 		}
 
 	Unlock();
 	pMat2->Unlock();
 	pMat1->Unlock();
 	}
 
/***********************************************************************
* Multiply this matrix by the diagonal matrix pDiag
*
* If bResize = FALSE, and the columns' number of this matrix is different than the rows' 
* number of the diagonal matrix, an exception is thrown.
*
* If bResize is TRUE, then col's number may be < than the row's number. The diagonal matrix
* will then be seen as a smaller matrix. 
***********************************************************************/
void CMatrix::Multiply(CDiag *pDiag, BOOL bResize)
 	{
 	long c, l, llen, clen;
 	
	/*Verify that the matrices have the same dimension*/
	if (bResize == FALSE && pDiag->GetLi() != GetCol())
		Fail(NULL);
 
 	llen = GetLi();
 	clen = GetCol();
 
 	Lock();
 	pDiag->Lock();
 
 	for (l = 1L; l <= llen; l++)
 		{
 		for (c = 1L; c <= clen; c++)
 			{
			SetAt(l, c, GetAt(l, c) * pDiag->GetAt(c));
			}
 		}
 
 	Unlock();
 	pDiag->Unlock();
 	}
 

⌨️ 快捷键说明

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