📄 cvect.cpp
字号:
#include "stdafx.h"
#include "str.h"
#include "c:\face\program\windows\pca\srcpca\utilcpp.h"
#include "error.h"
#include "CVect.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
CVect::CVect()
{
li = 0;
bLocked = FALSE;
pData = NULL;
pMem = NULL;
}
CVect::CVect(long l)
{
li = l;
pData = NULL;
pMem = NULL;
bLocked = FALSE;
Allocate();
}
CVect::~CVect()
{
if (pMem != NULL)
{
delete pMem;
pMem = NULL;
}
}
int CVect::Load(char *filename)
{
int fh;
long lrow;
char *str, *pstr, *str_float;
unsigned int filelen, nread;
CMemory *pmem;
valtype val;
Msg(1, str_LOADING, filename);
fh = _open(filename, _O_RDONLY | _O_TEXT); /*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);
filelen = _tell(fh); /*Calculates the file lenght*/
if (filelen == -1L)
{
Msg(0, strerror(errno));
_close(fh); /*Close the file*/
return -errno;
}
_lseek(fh, 0, SEEK_SET);
pmem = new CMemory();
pmem->Allocate(filelen);
str = (char *)pmem->GetPtr();
/*Read the header which is the dimension of the matrix*/
nread = _read(fh, str, filelen);
if (nread == -1)
{
Msg(-1, str_ERR_FILE_READ, strerror(errno));
return -errno;
}
_close(fh);
li = atol(strtok(str, str_TABRT));
if (li == 0L)
{
Msg(-1, str_ERR_MAT_LOAD_ROW);
return ERR_MAT_LOAD_ROW;
}
pstr = strtok(NULL, str_TABRT);
if (atol(pstr) == 0)
{
Msg(-1, str_ERR_MAT_LOAD_HDR);
return ERR_MAT_LOAD_HDR;
}
Allocate();
Lock();
/* while (isdigit(pstr[0]) == 0 && pstr[0] != '+' && pstr[0] != '-')
pstr++;
pstr = strtok(pstr, str_TABRT);
*/
for (lrow = 1L; lrow <= li; lrow++)
{
val = atof(pstr);
SetAt(lrow, val);
pstr = strtok(NULL, str_TABRT);
}
Unlock();
Msg(-1, str_LOADED);
pmem->ReleasePtr();
delete pmem;
return 0;
}
/***********************************************************************
* Save the vector in a text file. The only parameter to this fct is the file name
* The file format is as follow:
*
* <element number>\n
* <el1>\n
* <el2>\n
* .
* .
* .
* <eln>\n
* EOF
***********************************************************************/
int CVect::Save(char *filename)
{
int fh;
long row, 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;
}
lrow = GetLi();
Lock();
sprintf(str, "%ld\n", lrow);
_write(fh, str, strlen(str));
for (row = 1L; row <= lrow; row++)
{
sprintf(str, "%.6E\n", GetAt(row));
_write(fh, str, strlen(str));
}
Unlock();
if (_close(fh) == -1)
{
Msg(0, str_ERR_FILE_CLOSE);
}
Msg(-1, str_SAVED);
return 0;
}
/***********************************************************************
* Sets all the elements to 0
***********************************************************************/
void CVect::Initialize()
{
long r, y;
r = GetLi();
Lock();
for (y = 1; y <= r; y++)
{
SetAt(y, (valtype)0);
}
Unlock();
}
/***********************************************************************
* Get the element at (l,c) of the matrix if bTranspose == FALSE, and of the
* transposed matrix if bTranspose == TRUE
***********************************************************************/
/*inline*/ valtype CVect::GetAt(long l)
{
#ifdef CHECK_BOUNDARY
if (l <= 0 || l > li)
Fail(NULL);
#endif
return pData[l-1L];
}
/***********************************************************************
* Obvious. Becareful to bTranspose
***********************************************************************/
/*inline*/ void CVect::SetAt(long l, valtype value)
{
#ifdef CHECK_BOUNDARY
if (l <= 0 || l > li)
Fail(NULL);
#endif
pData[l-1L] = value;
}
/***********************************************************************
* Allocate (or reallocate) the memory needed by pData.
* Call the CMemory's Allocate fct
***********************************************************************/
void CVect::Allocate()
{
if (pMem == NULL)
{ /*Allocate memory*/
pMem = new CMemory();
pMem->Allocate((li+1L)*sizeof(valtype));
}
else
{ /*Reallocate memory*/
if (bLocked == TRUE)
{
Unlock();
}
pMem->Reallocate((li+1L)*sizeof(valtype));
}
}
/***********************************************************************
* Lock pMem and validate pData
***********************************************************************/
void CVect::Lock()
{
if (bLocked == FALSE)
pData = (valtype*)pMem->GetPtr();
bLocked = TRUE;
}
/***********************************************************************
* Unlock pMem and Unvalidate pData
***********************************************************************/
void CVect::Unlock()
{
if (bLocked == TRUE)
pMem->ReleasePtr();
bLocked = FALSE;
}
long CVect::GetLi()
{
return li;
}
/***********************************************************************
* Pow each individual component of the vector
***********************************************************************/
void CVect::PowCmp(float exp)
{
long i, r = GetLi();
Lock();
for (i = 1; i <= r; i++)
{
SetAt(i, pow(GetAt(i), exp));
}
Unlock();
}
/***********************************************************************************
* Invert the order of the columns, but keep the matrix diagonal
***********************************************************************************/
void CVect::Invert()
{
long l, n, li = GetLi();
valtype temp;
n = floor((double)li / 2.0);
Lock();
for (l = 1; l <= n; l++)
{
temp = GetAt(li - l + 1L);
SetAt(li - l + 1L, GetAt(l));
SetAt(l, temp);
}
Unlock();
}
/***********************************************************************
* Swap the order of 2 elements : Put the element l1 at the position of l2
* and vice-versa.
* BEWARE : The vector must be locked before the call to this fct.
***********************************************************************/
void CVect::SwapCol(long l1, long l2)
{
valtype val;
val = GetAt(l1);
SetAt(l1, GetAt(l2));
SetAt(l2, val);
}
/***********************************************************************
* Discard the element l and put the nextr one at its place (and so one for the next ones)
* BEWARE : The vector must be locked before the call to this fct.
***********************************************************************/
void CVect::Discard(long l)
{
long lrow;
for (lrow = l; lrow < li; lrow++)
{
SetAt(lrow, GetAt(lrow+1L));
}
SetAt(li, (valtype)0);
li--;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -