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

📄 spbuild.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  MATRIX BUILD MODULE * *  Author:                     Advising professor: *     Kenneth S. Kundert           Alberto Sangiovanni-Vincentelli *     UC Berkeley * *  This file contains the routines associated with clearing, loading and *  preprocessing the matrix for the sparse matrix routines. * *  >>> User accessible functions contained in this file: *  spClear *  spGetElement *  spFindElement *  spGetAdmittance *  spGetQuad *  spGetOnes *  spInstallInitInfo *  spGetInitInfo *  spInitialize * *  >>> Other functions contained in this file: *  spcFindElementInCol *  Translate *  spcCreateElement *  spcLinkRows *  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: spBuild.c,v 1.3 88/06/24 05:00:31 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"/* *  Function declarations */#ifdef __STDC__static void Translate( MatrixPtr, int*, int* );static void EnlargeMatrix( MatrixPtr, int );static void ExpandTranslationArrays( MatrixPtr, int );#else /* __STDC__ */static void Translate();static void EnlargeMatrix();static void ExpandTranslationArrays();#endif /* __STDC__ *//* *  CLEAR MATRIX * *  Sets every element of the matrix to zero and clears the error flag. * *  >>> Arguments: *  Matrix  <input>  (char *) *     Pointer to matrix that is to be cleared. * *  >>> Local variables: *  pElement  (ElementPtr) *     A pointer to the element being cleared. */voidspClear( eMatrix )char *eMatrix;{MatrixPtr  Matrix = (MatrixPtr)eMatrix;register  ElementPtr  pElement;register  int  I;/* Begin `spClear'. */    ASSERT( IS_SPARSE( Matrix ) );/* Clear matrix. */#if spCOMPLEX    if (Matrix->PreviousMatrixWasComplex OR Matrix->Complex)    {   for (I = Matrix->Size; I > 0; I--)        {   pElement = Matrix->FirstInCol[I];            while (pElement != NULL)            {   pElement->Real = 0.0;                pElement->Imag = 0.0;                pElement = pElement->NextInCol;            }        }    }    else#endif    {   for (I = Matrix->Size; I > 0; I--)        {   pElement = Matrix->FirstInCol[I];            while (pElement != NULL)            {   pElement->Real = 0.0;                pElement = pElement->NextInCol;            }        }    }/* Empty the trash. */    Matrix->TrashCan.Real = 0.0;#if spCOMPLEX    Matrix->TrashCan.Imag = 0.0;#endif    Matrix->Error = spOKAY;    Matrix->Factored = NO;    Matrix->SingularCol = 0;    Matrix->SingularRow = 0;    Matrix->PreviousMatrixWasComplex = Matrix->Complex;    return;}/* *  SINGLE ELEMENT LOCATION IN MATRIX BY INDEX * *  Finds element [Row,Col] and returns a pointer to it.  If element is *  not found then it is created and spliced into matrix.  This routine *  is only to be used after spCreate() and before spMNA_Preorder(), *  spFactor() or spOrderAndFactor().  Returns a pointer to the *  Real portion of a MatrixElement.  This pointer is later used by *  spADD_xxx_ELEMENT to directly access element. * *  >>> Returns: *  Returns a pointer to the element.  This pointer is then used to directly *  access the element during successive builds. * *  >>> Arguments: *  Matrix  <input>  (char *) *     Pointer to the matrix that the element is to be added to. *  Row  <input>  (int) *     Row index for element.  Must be in the range of [0..Size] unless *     the options EXPANDABLE or TRANSLATE are used. Elements placed in *     row zero are discarded.  In no case may Row be less than zero. *  Col  <input>  (int) *     Column index for element.  Must be in the range of [0..Size] unless *     the options EXPANDABLE or TRANSLATE are used. Elements placed in *     column zero are discarded.  In no case may Col be less than zero. * *  >>> Local variables: *  pElement  (RealNumber *) *     Pointer to the element. * *  >>> Possible errors: *  spNO_MEMORY *  Error is not cleared in this routine. */RealNumber *spFindElement( eMatrix, Row, Col )char *eMatrix;int  Row, Col;{MatrixPtr  Matrix = (MatrixPtr)eMatrix;RealNumber  *pElement;int index;ElementPtr spcFindElementInCol();void  Translate();/* Begin `spFindElement'. */    ASSERT( IS_SPARSE( Matrix ) AND Row >= 0 AND Col >= 0 );    if ((Row == 0) OR (Col == 0))        return &Matrix->TrashCan.Real;#if TRANSLATE    Translate( Matrix, &Row, &Col );    if (Matrix->Error == spNO_MEMORY) return NULL;#endif#if NOT TRANSLATE    ASSERT(Row <= Matrix->Size AND Col <= Matrix->Size);#endif/* * The condition part of the following if statement tests to see if the * element resides along the diagonal, if it does then it tests to see * if the element has been created yet (Diag pointer not NULL).  The * pointer to the element is then assigned to Element after it is cast * into a pointer to a RealNumber.  This casting makes the pointer into * a pointer to Real.  This statement depends on the fact that Real * is the first record in the MatrixElement structure. */    if ((Row != Col) OR ((pElement = (RealNumber *)Matrix->Diag[Row]) == NULL))    {/* * Element does not exist or does not reside along diagonal.  Search * column for element.  As in the if statement above, the pointer to the * element which is returned by spcFindElementInCol is cast into a * pointer to Real, a RealNumber. */        pElement = (RealNumber*)spcFindElementInCol( Matrix,                                                     &(Matrix->FirstInCol[Col]),                                                     Row, Col, NO );    }    return pElement;}/* *  SINGLE ELEMENT ADDITION TO MATRIX BY INDEX * *  Finds element [Row,Col] and returns a pointer to it.  If element is *  not found then it is created and spliced into matrix.  This routine *  is only to be used after spCreate() and before spMNA_Preorder(), *  spFactor() or spOrderAndFactor().  Returns a pointer to the *  Real portion of a MatrixElement.  This pointer is later used by *  spADD_xxx_ELEMENT to directly access element. * *  >>> Returns: *  Returns a pointer to the element.  This pointer is then used to directly *  access the element during successive builds. * *  >>> Arguments: *  Matrix  <input>  (char *) *     Pointer to the matrix that the element is to be added to. *  Row  <input>  (int) *     Row index for element.  Must be in the range of [0..Size] unless *     the options EXPANDABLE or TRANSLATE are used. Elements placed in *     row zero are discarded.  In no case may Row be less than zero. *  Col  <input>  (int) *     Column index for element.  Must be in the range of [0..Size] unless *     the options EXPANDABLE or TRANSLATE are used. Elements placed in *     column zero are discarded.  In no case may Col be less than zero. * *  >>> Local variables: *  pElement  (RealNumber *) *     Pointer to the element. * *  >>> Possible errors: *  spNO_MEMORY *  Error is not cleared in this routine. */RealNumber *spGetElement( eMatrix, Row, Col )char *eMatrix;int  Row, Col;{MatrixPtr  Matrix = (MatrixPtr)eMatrix;RealNumber  *pElement;ElementPtr spcFindElementInCol();void  Translate();/* Begin `spGetElement'. */    ASSERT( IS_SPARSE( Matrix ) AND Row >= 0 AND Col >= 0 );    if ((Row == 0) OR (Col == 0))        return &Matrix->TrashCan.Real;#if NOT TRANSLATE    ASSERT(Matrix->NeedsOrdering);#endif#if TRANSLATE    Translate( Matrix, &Row, &Col );    if (Matrix->Error == spNO_MEMORY) return NULL;#endif#if NOT TRANSLATE#if NOT EXPANDABLE    ASSERT(Row <= Matrix->Size AND Col <= Matrix->Size);#endif#if EXPANDABLE/* Re-size Matrix if necessary. */    if ((Row > Matrix->Size) OR (Col > Matrix->Size))        EnlargeMatrix( Matrix, MAX(Row, Col) );    if (Matrix->Error == spNO_MEMORY) return NULL;#endif#endif/* * The condition part of the following if statement tests to see if the * element resides along the diagonal, if it does then it tests to see * if the element has been created yet (Diag pointer not NULL).  The * pointer to the element is then assigned to Element after it is cast * into a pointer to a RealNumber.  This casting makes the pointer into * a pointer to Real.  This statement depends on the fact that Real * is the first record in the MatrixElement structure. */    if ((Row != Col) OR ((pElement = (RealNumber *)Matrix->Diag[Row]) == NULL))    {/* * Element does not exist or does not reside along diagonal.  Search * column for element.  As in the if statement above, the pointer to the * element which is returned by spcFindElementInCol is cast into a * pointer to Real, a RealNumber. */        pElement = (RealNumber*)spcFindElementInCol( Matrix,                                                     &(Matrix->FirstInCol[Col]),                                                     Row, Col, YES );    }    return pElement;}/* *  FIND ELEMENT BY SEARCHING COLUMN * *  Searches column starting at element specified at PtrAddr and finds element *  in Row. If Element does not exists, it is created. The pointer to the *  element is returned. * *  >>> Returned: *  A pointer to the desired element: * *  >>> Arguments: *  Matrix  <input>  (MatrixPtr) *      Pointer to Matrix. *  LastAddr  <input-output>  (ElementPtr *) *      Address of pointer that initially points to the element in Col at which *      the search is started.  The pointer in this location may be changed if *      a fill-in is required in and adjacent element. For this reason it is *      important that LastAddr be the address of a FirstInCol or a NextInCol *      rather than a temporary variable. *  Row  <input>  (int) *      Row being searched for. *  Col  (int) *      Column being searched. *  CreateIfMissing  <input>  (BOOLEAN) *      Indicates what to do if element is not found, create one or return a *      NULL pointer. * *  Local variables: *  pElement  (ElementPtr) *      Pointer used to search through matrix. */ElementPtrspcFindElementInCol( Matrix, LastAddr, Row, Col, CreateIfMissing )MatrixPtr Matrix;register ElementPtr *LastAddr;register int  Row;int  Col;BOOLEAN  CreateIfMissing;{register  ElementPtr  pElement;ElementPtr  spcCreateElement();/* Begin `spcFindElementInCol'. */    pElement = *LastAddr;/* Search for element. */    while (pElement != NULL)    {   if (pElement->Row < Row)        {/* Have not reached element yet. */            LastAddr = &(pElement->NextInCol);            pElement = pElement->NextInCol;        }        else if (pElement->Row == Row)        {/* Reached element. */            return pElement;        }

⌨️ 快捷键说明

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