#include "stdafx.h"
#include "CMemory.h"
#include "CMatPtr.h"
#include "def.h"
#include
CMatrixPtr::CMatrixPtr()
{
li = 0;
col = 0;
bTranspose = FALSE;
pColPtr = NULL;
pMemPtr = NULL;
pData2 = NULL;
pMem = NULL;
bAlloc = FALSE;
}
CMatrixPtr::CMatrixPtr(long l, long c)
{
li = l;
col = c;
bTranspose = FALSE;
pData2 = NULL;
pMem = NULL;
pMemPtr = NULL;
pColPtr = NULL;
bAlloc = FALSE;
Allocate();
}
CMatrixPtr::~CMatrixPtr()
{
Unlock();
FreeCol();
if (pMem != NULL)
{
delete pMem;
pMem = NULL;
}
if (pMemPtr != NULL)
{
delete pMemPtr;
pMemPtr = NULL;
}
}
/***********************************************************************
* Get the element at (l,c) of the matrix if bTranspose == FALSE, and of the
* transposed matrix if bTranspose == TRUE
***********************************************************************/
inline valtype2 CMatrixPtr::GetAt(long l, long c)
{
if (bTranspose == FALSE)
{
/*Verify that l and c are not overflow*/
#ifdef CHECK_BOUNDARY
if (l col)
Fail(0);
#endif
return (valtype)((pData2[c-1L])[l-1L]);
}
else
{
#ifdef CHECK_BOUNDARY
if (l li)
Fail(0);
#endif
return (valtype)((pData2[l-1L])[c-1L]);
}
}
/***********************************************************************
* Obvious. Becareful to bTranspose
***********************************************************************/
inline void CMatrixPtr::SetAt(long l, long c, valtype2 value)
{
if (bTranspose == FALSE)
{
/*Verify that l and c are not overflow*/
#ifdef CHECK_BOUNDARY
if (l col)
Fail(0);
#endif
(pData2[c-1L])[l-1L] = (valtype2)value;
}
else
{
/*Verify that l and c are not overflow*/
#ifdef CHECK_BOUNDARY
if (l li)
Fail(0);
#endif
(pData2[l-1L])[c-1L] = (valtype2)value;
}
}
/***********************************************************************
* Allocate (or reallocate) the memory needed by pColPtr.
* Call the CMemory's Allocate fct
***********************************************************************/
void CMatrixPtr::Allocate()
{
if (pMem == NULL)
{ /*Allocate memory*/
pMem = new CMemory();
pMem->Allocate(col*sizeof(CMemory*));
pMemPtr = new CMemory();
pMemPtr->Allocate(col*sizeof(valtype2*));
}
else
{ /*Reallocate memory*/
if (bLocked == TRUE)
{
Unlock();
}
pMem->Reallocate((col+1L)*sizeof(CMemory*));
pMemPtr->Reallocate((col+1L)*sizeof(valtype2*));
}
}
/***********************************************************************
* set li and col, call Allocate() and AllocateCol()
***********************************************************************/
void CMatrixPtr::Allocate(long lrow, long lcol)
{
li = lrow;
col = lcol;
Allocate();
AllocateCol();
}
/***********************************************************************
* Allocate the memory needed to store the columns elements. This fct must be called
* right after the creation of the CMatrixPtr if the data are not given by another object
*
* Call the CMemory's Allocate fct
***********************************************************************/
void CMatrixPtr::AllocateCol()
{
CMemory **pmemory;
long l, llen, clen;
clen = GetCol();
llen = GetLi();
pmemory = (CMemory**)pMem->GetPtr();
for (l = 0; l < clen; l++)
{
pmemory[l] = new CMemory();
pmemory[l]->Allocate(llen*sizeof(valtype2));
}
pMem->ReleasePtr();
bAlloc = TRUE;
}
/***********************************************************************
* Free the memory needed to store the columns elements. This fct must be called
* just before the destruction of the CMatrixPtr, if the data were not given by another
* object
*
* Call the CMemory's Allocate fct
***********************************************************************/
void CMatrixPtr::FreeCol()
{
CMemory **pmemory;
long l, clen;
if (bAlloc == FALSE)
return;
bAlloc = FALSE;
clen = GetCol();
pmemory = (CMemory**)pMem->GetPtr();
for (l = 0; l < clen; l++)
{
delete pmemory[l];
}
pMem->ReleasePtr();
}
/***********************************************************************
* This fct copy, for each column, the address of a CMemory object containing the
* column's data into the array pointed by pMem.
***********************************************************************/
void CMatrixPtr::SetColumn(long c, CMemory *pCol)
{
BOOL bRelock = FALSE;
/* The fct Lock cannot be called for the moment, because it not only locks pMem (containing
the array of CMemory object) but also locks the column's CMemory. However, the
columns' CMemory object are not yet assigned, so it would lock a non existing object.
That is why Lock is not called, but pMem->GetPtr() instead.*/
if (bLocked == FALSE)
{
pColPtr = (CMemory**)(pMem->GetPtr()); /*Get the pointer to the column CMemory array*/
bRelock = TRUE;
}
pColPtr[c-1L] = pCol;
if (bRelock == TRUE)
{
pMem->ReleasePtr();
}
}
/***********************************************************************
* This fct copy, for each column, the address of a CMemory object containing the
* column's data into the array pointed by pMem.
***********************************************************************/
CMemory *CMatrixPtr::GetColumn(long c)
{
CMemory *pCol;
BOOL bRelock = FALSE;
/* The fct Lock cannot be called for the moment, because it not only locks pMem (containing
the array of CMemory object) but also locks the column's CMemory. However, the
columns' CMemory object are not yet assigned, so it would lock a non existing object.
That is why Lock is not called, but pMem->GetPtr() instead.*/
if (bLocked == FALSE)
{
pColPtr = (CMemory**)(pMem->GetPtr()); /*Get the pointer to the column CMemory array*/
bRelock = TRUE;
}
pCol = pColPtr[c-1L];
if (bRelock == TRUE)
{
pMem->ReleasePtr();
}
return pCol;
}
/***********************************************************************
* Invert the order of the columns of this matrix
***********************************************************************/
void CMatrixPtr::InvertCol()
{
CMemory *pTemp;
long l, n, col;
BOOL bRelock = FALSE;
if (bLocked == FALSE)
{
pColPtr = (CMemory**)(pMem->GetPtr()); /*Get the pointer to the column CMemory array*/
bRelock = TRUE;
}
col = GetCol() - 1;
n = floor((double)col / 2.0);
for (l = 0; l < n; l++)
{
pTemp = pColPtr[col - l];
pColPtr[col - l] = pColPtr[l];
pColPtr[l] = pTemp;
}
if (bRelock == TRUE)
{
pMem->ReleasePtr();
}
}
/***********************************************************************
* Swap the order of 2 columns : Puts the column l1 at the position of l2
* and vice-versa
***********************************************************************/
void CMatrixPtr::SwapCol(long l1, long l2)
{
CMemory *pTemp;
BOOL bRelock = FALSE;
if (bLocked == FALSE)
{
pColPtr = (CMemory**)(pMem->GetPtr()); /*Get the pointer to the column CMemory array*/
bRelock = TRUE;
}
pTemp = pColPtr[l1 - 1L];
pColPtr[l1 - 1L] = pColPtr[l2 - 1L];
pColPtr[l2 - 1L] = pTemp;
if (bRelock == TRUE)
{
pMem->ReleasePtr();
}
}
/***********************************************************************
* Discard the column l and put the next one at its place (and so one for the next ones)
***********************************************************************/
void CMatrixPtr::Discard(long l)
{
long lcol;
BOOL bRelock = FALSE;
if (bLocked == FALSE)
{
pColPtr = (CMemory**)(pMem->GetPtr()); /*Get the pointer to the column CMemory array*/
bRelock = TRUE;
}
if (bAlloc == TRUE)
delete pColPtr[l-1L];
for (lcol = l; lcol < col; lcol++)
{
pColPtr[lcol-1L] = pColPtr[lcol];
}
pColPtr[col-1L] = NULL;
col--;
if (bRelock == TRUE)
{
pMem->ReleasePtr();
}
}
/**********************************************************************\
| Lock pMem and validate pColPtr |
| Lock pMemPtr and validate pData2 |
| validate also each column of pData2 |
\**********************************************************************/
void CMatrixPtr::Lock()
{
long i;
CMemory *pMemory;
if (bLocked == FALSE)
{
pColPtr = (CMemory**)pMem->GetPtr();
pData2 = (valtype2**)pMemPtr->GetPtr();
for (i = 0; i < col; i++)
{
pMemory = (CMemory*)pColPtr[i];
pData2[i] = (valtype2*)(pMemory->GetPtr());
}
}
bLocked = TRUE;
}
/***********************************************************************
* Unlock pMem and Unvalidate pColPtr
***********************************************************************/
void CMatrixPtr::Unlock()
{
long i;
if (bLocked == TRUE)
{
for (i = 0; i < col; i++)
{
((CMemory*)pColPtr[i])->ReleasePtr();
}
pMemPtr->ReleasePtr();
pMem->ReleasePtr();
}
bLocked = FALSE;
}