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

📄 spbuild.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 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. *//* *  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>#define spINSIDE_SPARSE#include "spconfig.h"#include "spmatrix.h"#include "spdefs.h"/* *  Function declarations */static void Translate( MatrixPtr, int*, int* );static void EnlargeMatrix( MatrixPtr, int );static void ExpandTranslationArrays( MatrixPtr, int );/* *  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(void *eMatrix ){    MatrixPtr  Matrix = (MatrixPtr)eMatrix;     ElementPtr  pElement;     int  I;    /* Begin `spClear'. */    assert( IS_SPARSE( Matrix ) );    /* Clear matrix. */    if (Matrix->PreviousMatrixWasComplex || 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    {	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;    Matrix->TrashCan.Imag = 0.0;    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( void *eMatrix, int Row, int Col ){MatrixPtr  Matrix = (MatrixPtr)eMatrix;RealNumber  *pElement;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) *     Rowstrchr 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) *     Columnstrchr 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(void *eMatrix, int Row, int Col){    MatrixPtr  Matrix = (MatrixPtr)eMatrix;    RealNumber  *pElement;    ElementPtr spcFindElementInCol();    void  Translate();    /* Begin `spGetElement'. */    assert( IS_SPARSE( Matrix ) && Row >= 0 && Col >= 0 );    if ((Row == 0) || (Col == 0))	return &Matrix->TrashCan.Real;#if !TRANSLATE    assert(Matrix->NeedsOrdering);#endif#if TRANSLATE    Translate( Matrix, &Row, &Col );    if (Matrix->Error == spNO_MEMORY) return NULL;#endif#if !TRANSLATE#if !EXPANDABLE    assert(Row <= Matrix->Size && Col <= Matrix->Size);#endif#if EXPANDABLE    /* Re-size Matrix if necessary. */    if ((Row > Matrix->Size) || (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) || ((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>  (int) *      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(MatrixPtr Matrix, ElementPtr *LastAddr,		    int  Row, int  Col, int  CreateIfMissing){    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;        }	else break;  /* while loop */    }    /* Element does not exist and must be created. */    if (CreateIfMissing)	return spcCreateElement( Matrix, Row, Col, LastAddr, NO );    else	return NULL;}

⌨️ 快捷键说明

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