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

📄 spalloc.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  MATRIX ALLOCATION MODULE * *  Author:                     Advising professor: *      Kenneth S. Kundert          Alberto Sangiovanni-Vincentelli *      UC Berkeley * *  This file contains the allocation and deallocation routines for the *  sparse matrix routines. * *  >>> User accessible functions contained in this file: *  spCreate *  spDestroy *  spError *  spWhereSingular *  spGetSize *  spSetReal *  spSetComplex *  spFillinCount *  spElementCount *  spOriginalCount * *  >>> Other functions contained in this file: *  spcGetElement *  InitializeElementBlocks *  spcGetFillin *  RecordAllocation *  AllocateBlockOfAllocationList *  EnlargeMatrix *  ExpandTranslationArrays *//* *  Revision and copyright information. * *  Copyright (c) 1985,86,87,88,89,90 *  by Kenneth S. Kundert and the University of California. * *  Permission to use, copy, modify, and distribute this software and *  its documentation for any purpose and without fee is hereby granted, *  provided that the copyright notices appear in all copies and *  supporting documentation and that the authors and the University of *  California are properly credited.  The authors and the University of *  California make no representations as to the suitability of this *  software for any purpose.  It is provided `as is', without express *  or implied warranty. *//* *  IMPORTS * *  >>> Import descriptions: *  spConfig.h *      Macros that customize the sparse matrix routines. *  spMatrix.h *      Macros and declarations to be imported by the user. *  spDefs.h *      Matrix type and macro definitions for the sparse matrix routines. */#include <assert.h>#include <stdlib.h>#define spINSIDE_SPARSE#include "spconfig.h"#include "spmatrix.h"#include "spdefs.h"#ifdef PARALLEL_ARCH#define COMBINE 1#endif /* PARALLEL_ARCH *//* *  Function declarations */static void InitializeElementBlocks( MatrixPtr, int, int );static void RecordAllocation( MatrixPtr, void *);static void AllocateBlockOfAllocationList( MatrixPtr );/* *  MATRIX ALLOCATION * *  Allocates and initializes the data structures associated with a matrix. * *  >>> Returned: *  A pointer to the matrix is returned cast into the form of a pointer to *  a character.  This pointer is then passed and used by the other matrix *  routines to refer to a particular matrix.  If an error occurs, the NULL *  pointer is returned. * *  >>> Arguments: *  Size  <input>  (int) *      Size of matrix or estimate of size of matrix if matrix is EXPANDABLE. *  Complex  <input>  (int) *      Type of matrix.  If Complex is 0 then the matrix is real, otherwise *      the matrix will be complex.  Note that if the routines are not set up *      to handle the type of matrix requested, then a spPANIC error will occur. *      Further note that if a matrix will be both real and complex, it must *      be specified here as being complex. *  pError  <output>  (int *) *      Returns error flag, needed because function spError() will not work *      correctly if spCreate() returns NULL. * *  >>> Local variables: *  AllocatedSize  (int) *      The size of the matrix being allocated. *  Matrix  (MatrixPtr) *      A pointer to the matrix frame being created. * *  >>> Possible errors: *  spNO_MEMORY *  spPANIC *  Error is cleared in this routine. */void *spCreate(int Size, int Complex, int *pError){    unsigned  SizePlusOne;    MatrixPtr  Matrix;    int  I;    int  AllocatedSize;    /* Begin `spCreate'. */    /* Clear error flag. */    *pError = spOKAY;    /* Test for valid size. */    if ((Size < 0) || (Size == 0 && !EXPANDABLE)) {	*pError = spPANIC;        return NULL;    }#if 0  /* pn: skipped for cider */    /* Test for valid type. */    if (!Complex) {	*pError = spPANIC;	return NULL;    }#endif    /* Create Matrix. */    AllocatedSize = MAX( Size, MINIMUM_ALLOCATED_SIZE );    SizePlusOne = (unsigned)(AllocatedSize + 1);    if ((Matrix = ALLOC(struct MatrixFrame, 1)) == NULL) {	*pError = spNO_MEMORY;	return NULL;    }    /* Initialize matrix */    Matrix->ID = SPARSE_ID;    Matrix->Complex = Complex;    Matrix->PreviousMatrixWasComplex = Complex;    Matrix->Factored = NO;    Matrix->Elements = 0;    Matrix->Error = *pError;    Matrix->Originals = 0;    Matrix->Fillins = 0;    Matrix->Reordered = NO;    Matrix->NeedsOrdering = YES;    Matrix->NumberOfInterchangesIsOdd = NO;    Matrix->Partitioned = NO;    Matrix->RowsLinked = NO;    Matrix->InternalVectorsAllocated = NO;    Matrix->SingularCol = 0;    Matrix->SingularRow = 0;    Matrix->Size = Size;    Matrix->AllocatedSize = AllocatedSize;    Matrix->ExtSize = Size;    Matrix->AllocatedExtSize = AllocatedSize;    Matrix->CurrentSize = 0;    Matrix->ExtToIntColMap = NULL;    Matrix->ExtToIntRowMap = NULL;    Matrix->IntToExtColMap = NULL;    Matrix->IntToExtRowMap = NULL;    Matrix->MarkowitzRow = NULL;    Matrix->MarkowitzCol = NULL;    Matrix->MarkowitzProd = NULL;    Matrix->DoCmplxDirect = NULL;    Matrix->DoRealDirect = NULL;    Matrix->Intermediate = NULL;    Matrix->RelThreshold = DEFAULT_THRESHOLD;    Matrix->AbsThreshold = 0.0;    Matrix->TopOfAllocationList = NULL;    Matrix->RecordsRemaining = 0;    Matrix->ElementsRemaining = 0;    Matrix->FillinsRemaining = 0;    RecordAllocation( Matrix, (void *)Matrix );    if (Matrix->Error == spNO_MEMORY) goto MemoryError;    /* Take out the trash. */    Matrix->TrashCan.Real = 0.0;    Matrix->TrashCan.Imag = 0.0;    Matrix->TrashCan.Row = 0;    Matrix->TrashCan.Col = 0;    Matrix->TrashCan.NextInRow = NULL;    Matrix->TrashCan.NextInCol = NULL;#if INITIALIZE    Matrix->TrashCan.pInitInfo = NULL;#endif    /* Allocate space in memory for Diag pointer vector. */    CALLOC( Matrix->Diag, ElementPtr, SizePlusOne);    if (Matrix->Diag == NULL)        goto MemoryError;    /* Allocate space in memory for FirstInCol pointer vector. */    CALLOC( Matrix->FirstInCol, ElementPtr, SizePlusOne);    if (Matrix->FirstInCol == NULL)        goto MemoryError;    /* Allocate space in memory for FirstInRow pointer vector. */    CALLOC( Matrix->FirstInRow, ElementPtr, SizePlusOne);    if (Matrix->FirstInRow == NULL)        goto MemoryError;    /* Allocate space in memory for IntToExtColMap vector. */    if (( Matrix->IntToExtColMap = ALLOC(int, SizePlusOne)) == NULL)        goto MemoryError;    /* Allocate space in memory for IntToExtRowMap vector. */    if (( Matrix->IntToExtRowMap = ALLOC(int, SizePlusOne)) == NULL)        goto MemoryError;    /* Initialize MapIntToExt vectors. */    for (I = 1; I <= AllocatedSize; I++)    {	Matrix->IntToExtRowMap[I] = I;        Matrix->IntToExtColMap[I] = I;    }#if TRANSLATE    /* Allocate space in memory for ExtToIntColMap vector. */    if (( Matrix->ExtToIntColMap = ALLOC(int, SizePlusOne)) == NULL)        goto MemoryError;    /* Allocate space in memory for ExtToIntRowMap vector. */    if (( Matrix->ExtToIntRowMap = ALLOC(int, SizePlusOne)) == NULL)        goto MemoryError;    /* Initialize MapExtToInt vectors. */    for (I = 1; I <= AllocatedSize; I++) {	Matrix->ExtToIntColMap[I] = -1;	Matrix->ExtToIntRowMap[I] = -1;    }    Matrix->ExtToIntColMap[0] = 0;    Matrix->ExtToIntRowMap[0] = 0;#endif    /* Allocate space for fill-ins and initial set of elements. */    InitializeElementBlocks( Matrix, SPACE_FOR_ELEMENTS*AllocatedSize,			     SPACE_FOR_FILL_INS*AllocatedSize );    if (Matrix->Error == spNO_MEMORY)        goto MemoryError;    return (void *)Matrix; MemoryError:    /* Deallocate matrix and return no pointer to matrix if there is not enough       memory. */    *pError = spNO_MEMORY;    spDestroy( (void *)Matrix);    return NULL;}/* *  ELEMENT ALLOCATION * *  This routine allocates space for matrix elements. 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 an element. * *  >>> Arguments: *  Matrix  <input>  (MatrixPtr) *      Pointer to matrix. * *  >>> Local variables: *  pElement  (ElementPtr) *      A pointer to the first element in the group of elements being allocated. * *  >>> Possible errors: *  spNO_MEMORY */ElementPtrspcGetElement(MatrixPtr Matrix){    ElementPtr  pElements;    /* Begin `spcGetElement'. */#if !COMBINE || STRIP || LINT    /* Allocate block of MatrixElements if necessary. */    if (Matrix->ElementsRemaining == 0) {	pElements = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);        RecordAllocation( Matrix, (void *)pElements );        if (Matrix->Error == spNO_MEMORY) return NULL;        Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;        Matrix->NextAvailElement = pElements;    }#endif#if COMBINE || STRIP || LINT    if (Matrix->ElementsRemaining == 0)    {	pListNode = Matrix->LastElementListNode;	/* First see if there are any stripped elements left. */        if (pListNode->Next != NULL) {	    Matrix->LastElementListNode = pListNode = pListNode->Next;            Matrix->ElementsRemaining = pListNode->NumberOfElementsInList;            Matrix->NextAvailElement = pListNode->pElementList;        } else {	    /* Allocate block of elements. */            pElements = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);            RecordAllocation( Matrix, (void *)pElements );            if (Matrix->Error == spNO_MEMORY) return NULL;            Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;            Matrix->NextAvailElement = pElements;	    /* Allocate an element list structure. */            pListNode->Next = ALLOC(struct ElementListNodeStruct,1);            RecordAllocation( Matrix, (void *)pListNode->Next );            if (Matrix->Error == spNO_MEMORY)		return NULL;            Matrix->LastElementListNode = pListNode = pListNode->Next;            pListNode->pElementList = pElements;            pListNode->NumberOfElementsInList = ELEMENTS_PER_ALLOCATION;            pListNode->Next = NULL;        }    }#endif    /* Update Element counter and return pointer to Element. */    Matrix->ElementsRemaining--;    return Matrix->NextAvailElement++;}/* *  ELEMENT ALLOCATION INITIALIZATION * *  This routine allocates space for matrix fill-ins and an initial *  set of elements.  Besides being faster than allocating space for *  elements one at a time, it tends to keep the fill-ins physically *  close to the other matrix elements in the computer memory.  This *  keeps virtual memory paging to a minimum. * *  >>> Arguments: *  Matrix  <input>    (MatrixPtr) *      Pointer to the matrix. *  InitialNumberOfElements  <input> (int) *      This number is used as the size of the block of memory, in *      MatrixElements, reserved for elements. If more than this number of *      elements are generated, then more space is allocated later. *  NumberOfFillinsExpected  <input> (int) *      This number is used as the size of the block of memory, in *      MatrixElements, reserved for fill-ins. If more than this number of *      fill-ins are generated, then more space is allocated, but they may *      not be physically close in computer's memory. * *  >>> Local variables: *  pElement  (ElementPtr) *      A pointer to the first element in the group of elements being allocated. * *  >>> Possible errors: *  spNO_MEMORY */static voidInitializeElementBlocks(MatrixPtr Matrix, int InitialNumberOfElements,			int NumberOfFillinsExpected){    ElementPtr  pElement;    /* Begin `InitializeElementBlocks'. */    /* Allocate block of MatrixElements for elements. */    pElement = ALLOC(struct MatrixElement, InitialNumberOfElements);    RecordAllocation( Matrix, (void *)pElement );    if (Matrix->Error == spNO_MEMORY) return;    Matrix->ElementsRemaining = InitialNumberOfElements;    Matrix->NextAvailElement = pElement;    /* Allocate an element list structure. */    Matrix->FirstElementListNode = ALLOC(struct ElementListNodeStruct,1);    RecordAllocation( Matrix, (void *)Matrix->FirstElementListNode );    if (Matrix->Error == spNO_MEMORY) return;    Matrix->LastElementListNode = Matrix->FirstElementListNode;    Matrix->FirstElementListNode->pElementList = pElement;    Matrix->FirstElementListNode->NumberOfElementsInList =	    InitialNumberOfElements;    Matrix->FirstElementListNode->Next = NULL;    /* Allocate block of MatrixElements for fill-ins. */    pElement = ALLOC(struct MatrixElement, NumberOfFillinsExpected);    RecordAllocation( Matrix, (void *)pElement );    if (Matrix->Error == spNO_MEMORY) return;    Matrix->FillinsRemaining = NumberOfFillinsExpected;    Matrix->NextAvailFillin = pElement;    /* Allocate a fill-in list structure. */    Matrix->FirstFillinListNode = ALLOC(struct FillinListNodeStruct,1);    RecordAllocation( Matrix, (void *)Matrix->FirstFillinListNode );    if (Matrix->Error == spNO_MEMORY) return;    Matrix->LastFillinListNode = Matrix->FirstFillinListNode;    Matrix->FirstFillinListNode->pFillinList = pElement;    Matrix->FirstFillinListNode->NumberOfFillinsInList =NumberOfFillinsExpected;    Matrix->FirstFillinListNode->Next = NULL;    return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -