📄 cmat.cpp
字号:
/***********************************************************************
* Normalize each column of the matrix
***********************************************************************/
void CMatrix::NormalizeCol()
{
long c, l, llen, clen;
double val, val2;
llen = GetLi();
clen = GetCol();
Lock();
for (c = 1L; c <= clen; c++)
{
val = 0.0;
for (l = 1L; l <= llen; l++)
{
val += (double)GetAt(l, c) * (double)GetAt(l, c);
}
val = sqrt(val);
if (val > 1E-7)
{
for (l = 1L; l <= llen; l++)
{
val2 = (double)GetAt(l, c) / val;
SetAt(l, c, (valtype2)val2);
}
}
else
{
for (l = 1L; l <= llen; l++)
{
SetAt(l, c, (valtype2)0);
}
}
}
Unlock();
}
/***********************************************************************
* Put in pC, a pointer to a symmetric matrix, the outer product of
* this matrix. The outer product, C, of the matrix X is :
* C = X * Transpose(X) Where X is a R*C matrix.
* pC must be symmetric R*R matrix.
***********************************************************************/
void CMatrix::OuterProduct(CMatrixSym *pC)
{
long r, c, y, x, i;
valtype val;
r = GetLi();
c = GetCol();
Lock();
pC->Lock();
for (y = 1; y <= r; y++)
{
for (x = y; x <= r; x++)
{
val = 0;
for (i = 1; i<= c; i++)
{
val += GetAt(x, i) * GetAt(y, i);
}
pC->SetAt(y, x, val);
}
}
pC->Unlock();
Unlock();
}
/***********************************************************************
* Put in pC, a pointer to a symmetric matrix, the inner product of
* this matrix. The inner product, C, of the matrix X is :
* C = Transpose(X) * X, Where X is a R*C matrix.
* pC must be symmetric C*C matrix.
***********************************************************************/
void CMatrix::InnerProduct(CMatrixSym *pC)
{
long r, c, y, x, i;
valtype val;
r = GetLi();
c = GetCol();
Lock();
pC->Lock();
for (y = 1; y <= c; y++)
{
for (x = y; x <= c; x++)
{
val = 0;
for (i = 1; i<= r; i++)
{
val += GetAt(i, x) * GetAt(i, y);
}
pC->SetAt(y, x, val);
}
}
pC->Unlock();
Unlock();
}
/***********************************************************************
* Same as above, but the return matrix is a pointer to a CMatrix not a CMatrixSym
***********************************************************************/
void CMatrix::InnerProduct(CMatrix *pC)
{
long r, c, y, x, i;
valtype val;
r = GetLi();
c = GetCol();
Lock();
pC->Lock();
for (y = 1; y <= c; y++)
{
for (x = y; x <= c; x++)
{
val = 0;
for (i = 1; i<= r; i++)
{
val += GetAt(i, x) * GetAt(i, y);
}
pC->SetAt(y, x, val);
pC->SetAt(x, y, val);
}
}
pC->Unlock();
Unlock();
}
/***********************************************************************
* Sets all the elements to 0
***********************************************************************/
void CMatrix::Initialize()
{
long r, c, x, y;
r = GetLi();
c = GetCol();
Lock();
for (y = 1; y <= r; y++)
{
for (x = 1; x <= c; x++)
{
SetAt(y, x, (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 CMatrix::GetAt(long l, long c)
{
if (bTranspose == FALSE)
{
#ifdef CHECK_BOUNDARY
if (l <= 0 || c <= 0 || l > li || c > col)
Fail(NULL);
#endif
return pData[(l-1L)*col + c-1L];
}
else
{
#ifdef CHECK_BOUNDARY
if (l <= 0 || c <= 0 || l > col || c > li)
Fail(NULL);
#endif
return pData[(c-1L)*col + l-1L];
}
}
/***********************************************************************
* Obvious. Becareful to bTranspose
***********************************************************************/
inline void CMatrix::SetAt(long l, long c, valtype value)
{
if (bTranspose == FALSE)
{
#ifdef CHECK_BOUNDARY
if (l <= 0 || c <= 0 || l > li || c > col)
Fail(NULL);
#endif
pData[(l-1L)*col + c-1L] = value;
}
else
{
#ifdef CHECK_BOUNDARY
if (l <= 0 || c <= 0 || l > col || c > li)
Fail(NULL);
#endif
pData[(c-1L)*col + l-1L] = value;
}
}
/***********************************************************************
* Set the bTranspose parameter
***********************************************************************/
void CMatrix::SetTranspose(BOOL bTransposet)
{
bTranspose = bTransposet;
}
/***********************************************************************
* Allocate (or reallocate) the memory needed by pData.
* Call the CMemory's Allocate fct
***********************************************************************/
void CMatrix::Allocate()
{
if (pMem == NULL)
{ /*Allocate memory*/
pMem = new CMemory();
pMem->Allocate((col*li+1L)*sizeof(valtype));
}
else
{ /*Reallocate memory*/
if (bLocked == TRUE)
{
Unlock();
}
pMem->Reallocate((col*li+1L)*sizeof(valtype));
}
}
/***********************************************************************
* Lock pMem and validate pData
***********************************************************************/
void CMatrix::Lock()
{
if (bLocked == FALSE)
pData = (valtype*)pMem->GetPtr();
bLocked = TRUE;
}
/***********************************************************************
* Unlock pMem and Unvalidate pData
***********************************************************************/
void CMatrix::Unlock()
{
if (bLocked == TRUE)
pMem->ReleasePtr();
bLocked = FALSE;
}
long CMatrix::GetCol()
{
if (bTranspose == FALSE)
return col;
else
return li;
}
long CMatrix::GetLi()
{
if (bTranspose == FALSE)
return li;
else
return col;
}
/***********************************************************************
* Puts in this matrix the its eigenvectors and in ev the eigenvalues of this matrix.
* This matrix MUST be a REAL SQUARE SYMMETRIC matrix
* ev is a pointer to a vector of li elements
* lEigen is a long giving the number of eigenvectors needed
***********************************************************************/
int CMatrix::Eigen(CVect *ev, long lEigen)
{
CVect *offdiag;
long r = GetLi();
offdiag = new CVect(r);
Lock();
ev->Lock();
offdiag->Lock();
tred2(this, r, ev, offdiag);
tqli(ev, offdiag, r, this);
ev->Unlock();
offdiag->Unlock();
Unlock();
delete offdiag;
return 0;
}
/***********************************************************************
* Expand Calculates the shift and the scale which applicate to the column c
* of the matrix makes its element in the range dest_min to dest_max
***********************************************************************/
void CMatrix::Expand(long c, float *scale, float *shift, valtype dest_min, valtype dest_max)
{
valtype val, src_min, src_max;
long r, row = GetLi();
src_min = MAXFLOAT;
src_max = -MAXFLOAT;
Lock();
for (r = 1; r <= row; r++)
{
val = GetAt(r, c);
if (val < src_min)
src_min = val;
if (val > src_max)
src_max = val;
}
Unlock();
if (src_max == src_min)
{
*scale = 1.0;
*shift = 0.0;
}
else
{
*scale = fabs((dest_max - dest_min)) / fabs((src_max - src_min));
*shift = dest_min - *scale * src_min;
}
}
int CMatrix::SetColName(long col, char *str)
{
long l, lcol = GetCol();
char *str2;
if (pMemName == NULL)
{
pMemName = new CMemory();
if (pMemName == NULL)
return -1;
pMemName->Allocate(lcol*MAX_NAME*sizeof(char));
}
str2 = (char*)pMemName->GetPtr();
if (str2 == NULL)
return -1;
strncpy(&(str2[(col-1)*MAX_NAME]), str, min(strlen(str), MAX_NAME));
pMemName->ReleasePtr();
return 0;
}
int CMatrix::GetColName(long col, char *str, int len)
{
char *str2;
if (pMemName != NULL)
{
str2 = (char*)pMemName->GetPtr();
if (str2 == NULL)
return -1;
strncpy(str, &(str2[(col-1)*MAX_NAME]), min(len, MAX_NAME));
pMemName->ReleasePtr();
}
else
return -1;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -