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

📄 spalloc.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 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. */#ifdef notdefstatic char copyright[] =    "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert";static char RCSid[] =    "@(#)$Header: spAllocate.c,v 1.3 88/06/24 05:00:11 kundert Exp $";#endif/* *  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. */#define spINSIDE_SPARSE#include "spconfig.h"#include "spmatrix.h"#include "spdefs.h"#ifdef PARALLEL_ARCH#define COMBINE 1#endif /* PARALLEL_ARCH *//* *  Function declarations */#ifdef __STDC__static void InitializeElementBlocks( MatrixPtr, int, int );static void RecordAllocation( MatrixPtr, char* );static void AllocateBlockOfAllocationList( MatrixPtr );#else /* __STDC__ */static void InitializeElementBlocks();static void RecordAllocation();static void AllocateBlockOfAllocationList();#endif /* __STDC__ *//* *  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. */char *spCreate( Size, Complex, pError )int  Size, *pError;BOOLEAN  Complex;{register  unsigned  SizePlusOne;register  MatrixPtr  Matrix;register  int  I;int  AllocatedSize;/* Begin `spCreate'. *//* Clear error flag. */    *pError = spOKAY;/* Test for valid size. */    if ((Size < 0) OR (Size == 0 AND NOT EXPANDABLE))    {   *pError = spPANIC;        return NULL;    }/* Test for valid type. */#if NOT spCOMPLEX    if (Complex)    {   *pError = spPANIC;        return NULL;    }#endif#if NOT REAL    if (NOT 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, (char *)Matrix );    if (Matrix->Error == spNO_MEMORY) goto MemoryError;/* Take out the trash. */    Matrix->TrashCan.Real = 0.0;#if spCOMPLEX    Matrix->TrashCan.Imag = 0.0;#endif    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 (char *)Matrix;MemoryError:/* Deallocate matrix and return no pointer to matrix if there is not enough   memory. */    *pError = spNO_MEMORY;    spDestroy( (char *)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( Matrix )MatrixPtr Matrix;{struct ElementListNodeStruct *pListNode;ElementPtr  pElements;/* Begin `spcGetElement'. */#if NOT COMBINE OR STRIP OR LINT/* Allocate block of MatrixElements if necessary. */    if (Matrix->ElementsRemaining == 0)    {   pElements = ALLOC(struct MatrixElement, ELEMENTS_PER_ALLOCATION);        RecordAllocation( Matrix, (char *)pElements );        if (Matrix->Error == spNO_MEMORY) return NULL;        Matrix->ElementsRemaining = ELEMENTS_PER_ALLOCATION;        Matrix->NextAvailElement = pElements;    }#endif#if COMBINE OR STRIP OR 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, (char *)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, (char *)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( Matrix, InitialNumberOfElements,                         NumberOfFillinsExpected )MatrixPtr Matrix;int  InitialNumberOfElements, NumberOfFillinsExpected;{ElementPtr  pElement;/* Begin `InitializeElementBlocks'. *//* Allocate block of MatrixElements for elements. */    pElement = ALLOC(struct MatrixElement, InitialNumberOfElements);    RecordAllocation( Matrix, (char *)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, (char *)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, (char *)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, (char *)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 + -