⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spalloc.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  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 + -