📄 spallocate.c
字号:
*
* >>> Arguments:
* Matrix <input> (MatrixPtr)
* Pointer to matrix.
*
* >>> Possible errors:
* spNO_MEMORY
*/
ElementPtr
spcGetFillin( MatrixPtr Matrix )
{
struct FillinListNodeStruct *pListNode;
ElementPtr pFillins;
/* Begin `spcGetFillin'. */
#if NOT STRIP OR LINT
if (Matrix->FillinsRemaining == 0)
return spcGetElement( Matrix );
#endif
#if STRIP OR LINT
if (Matrix->FillinsRemaining == 0)
{ pListNode = Matrix->LastFillinListNode;
/* First see if there are any stripped fill-ins left. */
if (pListNode->Next != NULL)
{ Matrix->LastFillinListNode = pListNode = pListNode->Next;
Matrix->FillinsRemaining = pListNode->NumberOfFillinsInList;
Matrix->NextAvailFillin = pListNode->pFillinList;
}
else
{
/* Allocate block of fill-ins. */
pFillins = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);
RecordAllocation( Matrix, (void *)pFillins );
if (Matrix->Error == spNO_MEMORY) return NULL;
Matrix->FillinsRemaining = ELEMENTS_PER_ALLOCATION;
Matrix->NextAvailFillin = pFillins;
/* Allocate a fill-in list structure. */
pListNode->Next = ALLOC(struct FillinListNodeStruct,1);
RecordAllocation( Matrix, (void *)pListNode->Next );
if (Matrix->Error == spNO_MEMORY) return NULL;
Matrix->LastFillinListNode = pListNode = pListNode->Next;
pListNode->pFillinList = pFillins;
pListNode->NumberOfFillinsInList = ELEMENTS_PER_ALLOCATION;
pListNode->Next = NULL;
}
}
#endif
/* Update Fill-in counter and return pointer to Fill-in. */
Matrix->FillinsRemaining--;
return Matrix->NextAvailFillin++;
}
/*
* RECORD A MEMORY ALLOCATION
*
* This routine is used to record all memory allocations so that the memory
* can be freed later.
*
* >>> Arguments:
* Matrix <input> (MatrixPtr)
* Pointer to the matrix.
* AllocatedPtr <input> (void *)
* The pointer returned by malloc or calloc. These pointers are saved in
* a list so that they can be easily freed.
*
* >>> Possible errors:
* spNO_MEMORY
*/
static void
RecordAllocation(
MatrixPtr Matrix,
void *AllocatedPtr
)
{
/* Begin `RecordAllocation'. */
/*
* If Allocated pointer is NULL, assume that malloc returned a NULL pointer,
* which indicates a spNO_MEMORY error.
*/
if (AllocatedPtr == NULL)
{ Matrix->Error = spNO_MEMORY;
return;
}
/* Allocate block of MatrixElements if necessary. */
if (Matrix->RecordsRemaining == 0)
{ AllocateBlockOfAllocationList( Matrix );
if (Matrix->Error == spNO_MEMORY)
{ FREE(AllocatedPtr);
return;
}
}
/* Add Allocated pointer to Allocation List. */
(++Matrix->TopOfAllocationList)->AllocatedPtr = AllocatedPtr;
Matrix->RecordsRemaining--;
return;
}
/*
* ADD A BLOCK OF SLOTS TO ALLOCATION LIST
*
* This routine increases the size of the allocation list.
*
* >>> Arguments:
* Matrix <input> (MatrixPtr)
* Pointer to the matrix.
*
* >>> Local variables:
* ListPtr (AllocationListPtr)
* Pointer to the list that contains the pointers to segments of memory
* that were allocated by the operating system for the current matrix.
*
* >>> Possible errors:
* spNO_MEMORY
*/
static void
AllocateBlockOfAllocationList( MatrixPtr Matrix )
{
register int I;
register AllocationListPtr ListPtr;
/* Begin `AllocateBlockOfAllocationList'. */
/* Allocate block of records for allocation list. */
ListPtr = ALLOC(struct AllocationRecord, (ELEMENTS_PER_ALLOCATION+1));
if (ListPtr == NULL)
{ Matrix->Error = spNO_MEMORY;
return;
}
/* String entries of allocation list into singly linked list. List is linked
such that any record points to the one before it. */
ListPtr->NextRecord = Matrix->TopOfAllocationList;
Matrix->TopOfAllocationList = ListPtr;
ListPtr += ELEMENTS_PER_ALLOCATION;
for (I = ELEMENTS_PER_ALLOCATION; I > 0; I--)
{ ListPtr->NextRecord = ListPtr - 1;
ListPtr--;
}
/* Record allocation of space for allocation list on allocation list. */
Matrix->TopOfAllocationList->AllocatedPtr = (void *)ListPtr;
Matrix->RecordsRemaining = ELEMENTS_PER_ALLOCATION;
return;
}
/*!
* Destroys a matrix and frees all memory associated with it.
*
* \param eMatrix
* Pointer to the matrix frame which is to be destroyed.
*/
/* >>> Local variables:
* ListPtr (AllocationListPtr)
* Pointer into the linked list of pointers to allocated data structures.
* Points to pointer to structure to be freed.
* NextListPtr (AllocationListPtr)
* Pointer into the linked list of pointers to allocated data structures.
* Points to the next pointer to structure to be freed. This is needed
* because the data structure to be freed could include the current node
* in the allocation list.
*/
void
spDestroy( spMatrix eMatrix )
{
MatrixPtr Matrix = (MatrixPtr)eMatrix;
register AllocationListPtr ListPtr, NextListPtr;
/* Begin `spDestroy'. */
ASSERT_IS_SPARSE( Matrix );
/* Deallocate the vectors that are located in the matrix frame. */
FREE( Matrix->IntToExtColMap );
FREE( Matrix->IntToExtRowMap );
FREE( Matrix->ExtToIntColMap );
FREE( Matrix->ExtToIntRowMap );
FREE( Matrix->Diag );
FREE( Matrix->FirstInRow );
FREE( Matrix->FirstInCol );
FREE( Matrix->MarkowitzRow );
FREE( Matrix->MarkowitzCol );
FREE( Matrix->MarkowitzProd );
FREE( Matrix->DoCmplxDirect );
FREE( Matrix->DoRealDirect );
FREE( Matrix->Intermediate );
/* Sequentially step through the list of allocated pointers freeing pointers
* along the way. */
ListPtr = Matrix->TopOfAllocationList;
while (ListPtr != NULL)
{ NextListPtr = ListPtr->NextRecord;
free( ListPtr->AllocatedPtr );
ListPtr = NextListPtr;
}
return;
}
/*!
* This function returns the error status of the given matrix.
*
* \return
* The error status of the given matrix.
*
* \param eMatrix
* The pointer to the matrix for which the error status is desired.
*/
spError
spErrorState( spMatrix eMatrix )
{
/* Begin `spErrorState'. */
if (eMatrix != NULL)
{ ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
return ((MatrixPtr)eMatrix)->Error;
}
else return spNO_MEMORY; /* This error may actually be spPANIC,
* no way to tell. */
}
/*!
* This function returns the row and column number where the matrix was
* detected as singular (if pivoting was allowed on the last factorization)
* or where a zero was detected on the diagonal (if pivoting was not
* allowed on the last factorization). Pivoting is performed only in
* spOrderAndFactor().
*
* \param eMatrix
* The matrix for which the error status is desired.
* \param pRow
* The row number.
* \param pCol
* The column number.
*/
void
spWhereSingular(
spMatrix eMatrix,
int *pRow,
int *pCol
)
{
MatrixPtr Matrix = (MatrixPtr)eMatrix;
/* Begin `spWhereSingular'. */
ASSERT_IS_SPARSE( Matrix );
if (Matrix->Error == spSINGULAR OR Matrix->Error == spZERO_DIAG)
{ *pRow = Matrix->SingularRow;
*pCol = Matrix->SingularCol;
}
else *pRow = *pCol = 0;
return;
}
/*!
* Returns the size of the matrix. Either the internal or external size of
* the matrix is returned.
*
* \param eMatrix
* Pointer to matrix.
* \param External
* If \a External is set true, the external size , i.e., the value of the
* largest external row or column number encountered is returned.
* Otherwise the true size of the matrix is returned. These two sizes
* may differ if the \a TRANSLATE option is set true.
*/
int
spGetSize(
spMatrix eMatrix,
int External
)
{
MatrixPtr Matrix = (MatrixPtr)eMatrix;
/* Begin `spGetSize'. */
ASSERT_IS_SPARSE( Matrix );
#if TRANSLATE
if (External)
return Matrix->ExtSize;
else
return Matrix->Size;
#else
return Matrix->Size;
#endif
}
/*!
* Forces matrix to be real.
*
* \param eMatrix
* Pointer to matrix.
*/
void
spSetReal( spMatrix eMatrix )
{
/* Begin `spSetReal'. */
ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
vASSERT( REAL, "Sparse not compiled to handle real matrices" );
((MatrixPtr)eMatrix)->Complex = NO;
return;
}
/*!
* Forces matrix to be complex.
*
* \param eMatrix
* Pointer to matrix.
*/
void
spSetComplex( spMatrix eMatrix )
{
/* Begin `spSetComplex'. */
ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
vASSERT( spCOMPLEX, "Sparse not compiled to handle complex matrices" );
((MatrixPtr)eMatrix)->Complex = YES;
return;
}
/*!
* This function returns the number of fill-ins that currently exists in a matrix.
*
* \param eMatrix
* Pointer to matrix.
*/
int
spFillinCount( spMatrix eMatrix )
{
/* Begin `spFillinCount'. */
ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
return ((MatrixPtr)eMatrix)->Fillins;
}
/*!
* This function returns the total number of elements (including fill-ins) that currently exists in a matrix.
*
* \param eMatrix
* Pointer to matrix.
*/
int
spElementCount( spMatrix eMatrix )
{
/* Begin `spElementCount'. */
ASSERT_IS_SPARSE( (MatrixPtr)eMatrix );
return ((MatrixPtr)eMatrix)->Elements;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -