📄 spalloc.c
字号:
/* * FILL-IN ALLOCATION * * This routine allocates space for matrix fill-ins. It requests * large blocks of storage from the system and doles out individual * elements as required. This technique, as opposed to allocating * elements individually, tends to speed the allocation process. * * >>> Returned: * A pointer to the fill-in. * * >>> Arguments: * Matrix <input> (MatrixPtr) * Pointer to matrix. * * >>> Possible errors: * spNO_MEMORY */ElementPtrspcGetFillin(MatrixPtr Matrix){ /* Begin `spcGetFillin'. */#if !STRIP || LINT if (Matrix->FillinsRemaining == 0) return spcGetElement( Matrix );#endif#if STRIP || 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 tmalloc or calloc. These pointers are * saved in a list so that they can be easily freed. * * >>> Possible errors: * spNO_MEMORY */static voidRecordAllocation(MatrixPtr Matrix, void *AllocatedPtr ){ /* Begin `RecordAllocation'. */ /* If Allocated pointer is NULL, assume that tmalloc 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 voidAllocateBlockOfAllocationList(MatrixPtr Matrix){ int I; 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;}/* * MATRIX DEALLOCATION * * Deallocates pointers and elements of Matrix. * * >>> Arguments: * Matrix <input> (void *) * Pointer to the matrix frame which is to be removed from memory. * * >>> 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. */voidspDestroy(void *eMatrix){ MatrixPtr Matrix = (MatrixPtr)eMatrix; 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; if ((void *) ListPtr == ListPtr->AllocatedPtr) { FREE( ListPtr ); } else { FREE( ListPtr->AllocatedPtr ); } ListPtr = NextListPtr; } return;}/* * RETURN MATRIX ERROR STATUS * * This function is used to determine the error status of the given * matrix. * * >>> Returned: * The error status of the given matrix. * * >>> Arguments: * eMatrix <input> (void *) * The matrix for which the error status is desired. */intspError(void *eMatrix ){ /* Begin `spError'. */ if (eMatrix != NULL) { assert(((MatrixPtr)eMatrix)->ID == SPARSE_ID); return ((MatrixPtr)eMatrix)->Error; } else { /* This error may actually be spPANIC, no way to tell. */ return spNO_MEMORY; }}/* * WHERE IS MATRIX SINGULAR * * This function returns the row and column number where the matrix was * detected as singular or where a zero was detected on the diagonal. * * >>> Arguments: * eMatrix <input> (void *) * The matrix for which the error status is desired. * pRow <output> (int *) * The row number. * pCol <output> (int *) * The column number. */voidspWhereSingular(void *eMatrix, int *pRow, int *pCol){ MatrixPtr Matrix = (MatrixPtr)eMatrix; /* Begin `spWhereSingular'. */ assert( IS_SPARSE( Matrix ) ); if (Matrix->Error == spSINGULAR || Matrix->Error == spZERO_DIAG) { *pRow = Matrix->SingularRow; *pCol = Matrix->SingularCol; } else *pRow = *pCol = 0; return;}/* * MATRIX SIZE * * Returns the size of the matrix. Either the internal or external size of * the matrix is returned. * * >>> Arguments: * eMatrix <input> (void *) * Pointer to matrix. * External <input> (int) * If 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 TRANSLATE option is set TRUE. */intspGetSize(void *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}/* * SET MATRIX COMPLEX OR REAL * * Forces matrix to be either real or complex. * * >>> Arguments: * eMatrix <input> (void *) * Pointer to matrix. */voidspSetReal(void *eMatrix){ /* Begin `spSetReal'. */ assert( IS_SPARSE( (MatrixPtr)eMatrix )); ((MatrixPtr)eMatrix)->Complex = NO; return;}voidspSetComplex(void *eMatrix){ /* Begin `spSetComplex'. */ assert( IS_SPARSE( (MatrixPtr)eMatrix )); ((MatrixPtr)eMatrix)->Complex = YES; return;}/* * ELEMENT, FILL-IN OR ORIGINAL COUNT * * Two functions used to return simple statistics. Either the number * of total elements, or the number of fill-ins, or the number * of original elements can be returned. * * >>> Arguments: * eMatrix <input> (void *) * Pointer to matrix. */intspFillinCount(void *eMatrix){ /* Begin `spFillinCount'. */ assert( IS_SPARSE( (MatrixPtr)eMatrix ) ); return ((MatrixPtr)eMatrix)->Fillins;}intspElementCount(void *eMatrix){ /* Begin `spElementCount'. */ assert( IS_SPARSE( (MatrixPtr)eMatrix ) ); return ((MatrixPtr)eMatrix)->Elements;}intspOriginalCount(void *eMatrix){ /* Begin `spOriginalCount'. */ assert( IS_SPARSE( (MatrixPtr)eMatrix ) ); return ((MatrixPtr)eMatrix)->Originals;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -