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

📄 sputils.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 5 页
字号:
{MatrixPtr  Matrix = (MatrixPtr)eMatrix;register ElementPtr  pElement;register int  I, lSize, *pExtOrder;RealNumber  ScaleFactor;void ScaleComplexMatrix();/* Begin `spScale'. */    ASSERT( IS_VALID(Matrix) AND NOT Matrix->Factored );    if (NOT Matrix->RowsLinked) spcLinkRows( Matrix );#if spCOMPLEX    if (Matrix->Complex)    {   ScaleComplexMatrix( Matrix, RHS_ScaleFactors, SolutionScaleFactors );        return;    }#endif#if REAL    lSize = Matrix->Size;/* Correct pointers to arrays for ARRAY_OFFSET */#if NOT ARRAY_OFFSET    --RHS_ScaleFactors;    --SolutionScaleFactors;#endif/* Scale Rows */    pExtOrder = &Matrix->IntToExtRowMap[1];    for (I = 1; I <= lSize; I++)    {   if ((ScaleFactor = RHS_ScaleFactors[*(pExtOrder++)]) != 1.0)        {   pElement = Matrix->FirstInRow[I];            while (pElement != NULL)            {   pElement->Real *= ScaleFactor;                pElement = pElement->NextInRow;            }        }    }/* Scale Columns */    pExtOrder = &Matrix->IntToExtColMap[1];    for (I = 1; I <= lSize; I++)    {   if ((ScaleFactor = SolutionScaleFactors[*(pExtOrder++)]) != 1.0)        {   pElement = Matrix->FirstInCol[I];            while (pElement != NULL)            {   pElement->Real *= ScaleFactor;                pElement = pElement->NextInCol;            }        }    }    return;#endif /* REAL */}#endif /* SCALING */#if spCOMPLEX AND SCALING/* *  SCALE COMPLEX MATRIX * *  This function scales the matrix to enhance the possibility of *  finding a good pivoting order.  Note that scaling enhances accuracy *  of the solution only if it affects the pivoting order, so it makes *  no sense to scale the matrix before spFactor().  If scaling is *  desired it should be done before spOrderAndFactor().  There *  are several things to take into account when choosing the scale *  factors.  First, the scale factors are directly multiplied against *  the elements in the matrix.  To prevent roundoff, each scale factor *  should be equal to an integer power of the number base of the *  machine.  Since most machines operate in base two, scale factors *  should be a power of two.  Second, the matrix should be scaled such *  that the matrix of element uncertainties is equilibrated.  Third, *  this function multiplies the scale factors by the elements, so if *  one row tends to have uncertainties 1000 times smaller than the *  other rows, then its scale factor should be 1024, not 1/1024. *  Fourth, to save time, this function does not scale rows or columns *  if their scale factors are equal to one.  Thus, the scale factors *  should be normalized to the most common scale factor.  Rows and *  columns should be normalized separately.  For example, if the size *  of the matrix is 100 and 10 rows tend to have uncertainties near *  1e-6 and the remaining 90 have uncertainties near 1e-12, then the *  scale factor for the 10 should be 1/1,048,576 and the scale factors *  for the remaining 90 should be 1. Fifth, since this routine *  directly operates on the matrix, it is necessary to apply the scale *  factors to the RHS and Solution vectors.  It may be easier to *  simply use spOrderAndFactor() on a scaled matrix to choose the *  pivoting order, and then throw away the matrix.  Subsequent *  factorizations, performed with spFactor(), will not need to have *  the RHS and Solution vectors descaled.  Lastly, this function *  should not be executed before the function spMNA_Preorder. * *  >>> Arguments: *  Matrix  <input> (char *) *      Pointer to the matrix to be scaled. *  SolutionScaleFactors  <input>  (RealVector) *      The array of Solution scale factors.  These factors scale the columns. *      All scale factors are real valued. *  RHS_ScaleFactors  <input>  (RealVector) *      The array of RHS scale factors.  These factors scale the rows. *      All scale factors are real valued. * *  >>> Local variables: *  lSize  (int) *      Local version of the size of the matrix. *  pElement  (ElementPtr) *      Pointer to an element in the matrix. *  pExtOrder  (int *) *      Pointer into either IntToExtRowMap or IntToExtColMap vector. Used to *      compensate for any row or column swaps that have been performed. *  ScaleFactor  (RealNumber) *      The scale factor being used on the current row or column. */static voidScaleComplexMatrix( Matrix, RHS_ScaleFactors, SolutionScaleFactors )MatrixPtr  Matrix;register  RealVector  RHS_ScaleFactors, SolutionScaleFactors;{register ElementPtr  pElement;register int  I, lSize, *pExtOrder;RealNumber  ScaleFactor;/* Begin `ScaleComplexMatrix'. */    lSize = Matrix->Size;/* Correct pointers to arrays for ARRAY_OFFSET */#if NOT ARRAY_OFFSET    --RHS_ScaleFactors;    --SolutionScaleFactors;#endif/* Scale Rows */    pExtOrder = &Matrix->IntToExtRowMap[1];    for (I = 1; I <= lSize; I++)    {   if ((ScaleFactor = RHS_ScaleFactors[*(pExtOrder++)]) != 1.0)        {   pElement = Matrix->FirstInRow[I];            while (pElement != NULL)            {   pElement->Real *= ScaleFactor;                pElement->Imag *= ScaleFactor;                pElement = pElement->NextInRow;            }        }    }/* Scale Columns */    pExtOrder = &Matrix->IntToExtColMap[1];    for (I = 1; I <= lSize; I++)    {   if ((ScaleFactor = SolutionScaleFactors[*(pExtOrder++)]) != 1.0)        {   pElement = Matrix->FirstInCol[I];            while (pElement != NULL)            {   pElement->Real *= ScaleFactor;                pElement->Imag *= ScaleFactor;                pElement = pElement->NextInCol;            }        }    }    return;}#endif /* SCALING AND spCOMPLEX */#if MULTIPLICATION/* *  MATRIX MULTIPLICATION * *  Multiplies matrix by solution vector to find source vector. *  Assumes matrix has not been factored.  This routine can be used *  as a test to see if solutions are correct.  It should not be used *  before spMNA_Preorder(). * *  >>> Arguments: *  eMatrix  <input>  (char *) *      Pointer to the matrix. *  RHS  <output>  (RealVector) *      RHS is the right hand side. This is what is being solved for. *  Solution  <input>  (RealVector) *      Solution is the vector being multiplied by the matrix. *  iRHS  <output>  (RealVector) *      iRHS is the imaginary portion of the right hand side. This is *      what is being solved for.  This is only necessary if the matrix is *      complex and spSEPARATED_COMPLEX_VECTORS is true. *  iSolution  <input>  (RealVector) *      iSolution is the imaginary portion of the vector being multiplied *      by the matrix. This is only necessary if the matrix is *      complex and spSEPARATED_COMPLEX_VECTORS is true. * *  >>> Obscure Macros *  IMAG_VECTORS *      Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and *      spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears *      without a trace. */voidspMultiply( eMatrix, RHS, Solution IMAG_VECTORS )char *eMatrix;RealVector RHS, Solution IMAG_VECTORS;{register  ElementPtr  pElement;register  RealVector  Vector;register  RealNumber  Sum;register  int  I, *pExtOrder;MatrixPtr  Matrix = (MatrixPtr)eMatrix;extern void ComplexMatrixMultiply();/* Begin `spMultiply'. */    ASSERT( IS_SPARSE( Matrix ) AND NOT Matrix->Factored );    if (NOT Matrix->RowsLinked)	spcLinkRows(Matrix);    if (NOT Matrix->InternalVectorsAllocated)	spcCreateInternalVectors( Matrix );#if spCOMPLEX    if (Matrix->Complex)    {   ComplexMatrixMultiply( Matrix, RHS, Solution IMAG_VECTORS );        return;    }#endif#if REAL#if NOT ARRAY_OFFSET/* Correct array pointers for ARRAY_OFFSET. */    --RHS;    --Solution;#endif/* Initialize Intermediate vector with reordered Solution vector. */    Vector = Matrix->Intermediate;    pExtOrder = &Matrix->IntToExtColMap[Matrix->Size];    for (I = Matrix->Size; I > 0; I--)        Vector[I] = Solution[*(pExtOrder--)];    pExtOrder = &Matrix->IntToExtRowMap[Matrix->Size];    for (I = Matrix->Size; I > 0; I--)    {   pElement = Matrix->FirstInRow[I];        Sum = 0.0;        while (pElement != NULL)        {   Sum += pElement->Real * Vector[pElement->Col];            pElement = pElement->NextInRow;        }        RHS[*pExtOrder--] = Sum;    }    return;#endif /* REAL */}#endif /* MULTIPLICATION */#if spCOMPLEX AND MULTIPLICATION/* *  COMPLEX MATRIX MULTIPLICATION * *  Multiplies matrix by solution vector to find source vector. *  Assumes matrix has not been factored.  This routine can be  used *  as a test to see if solutions are correct. * *  >>> Arguments: *  Matrix  <input>  (char *) *      Pointer to the matrix. *  RHS  <output>  (RealVector) *      RHS is the right hand side. This is what is being solved for. *      This is only the real portion of the right-hand side if the matrix *      is complex and spSEPARATED_COMPLEX_VECTORS is set true. *  Solution  <input>  (RealVector) *      Solution is the vector being multiplied by the matrix. This is only *      the real portion if the matrix is complex and *      spSEPARATED_COMPLEX_VECTORS is set true. *  iRHS  <output>  (RealVector) *      iRHS is the imaginary portion of the right hand side. This is *      what is being solved for.  This is only necessary if the matrix is *      complex and spSEPARATED_COMPLEX_VECTORS is true. *  iSolution  <input>  (RealVector) *      iSolution is the imaginary portion of the vector being multiplied *      by the matrix. This is only necessary if the matrix is *      complex and spSEPARATED_COMPLEX_VECTORS is true. * *  >>> Obscure Macros *  IMAG_VECTORS *      Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and *      spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears *      without a trace. */static voidComplexMatrixMultiply( Matrix, RHS, Solution IMAG_VECTORS )MatrixPtr  Matrix;RealVector RHS, Solution IMAG_VECTORS;{register  ElementPtr  pElement;register  ComplexVector  Vector;ComplexNumber  Sum;register  int  I, *pExtOrder;/* Begin `ComplexMatrixMultiply'. *//* Correct array pointers for ARRAY_OFFSET. */#if NOT ARRAY_OFFSET#if spSEPARATED_COMPLEX_VECTORS    --RHS;              --iRHS;    --Solution;         --iSolution;#else    RHS -= 2;           Solution -= 2;#endif#endif/* Initialize Intermediate vector with reordered Solution vector. */    Vector = (ComplexVector)Matrix->Intermediate;    pExtOrder = &Matrix->IntToExtColMap[Matrix->Size];#if spSEPARATED_COMPLEX_VECTORS    for (I = Matrix->Size; I > 0; I--)    {   Vector[I].Real = Solution[*pExtOrder];        Vector[I].Imag = iSolution[*(pExtOrder--)];    }#else    for (I = Matrix->Size; I > 0; I--)        Vector[I] = ((ComplexVector)Solution)[*(pExtOrder--)];#endif    pExtOrder = &Matrix->IntToExtRowMap[Matrix->Size];    for (I = Matrix->Size; I > 0; I--)    {   pElement = Matrix->FirstInRow[I];        Sum.Real = Sum.Imag = 0.0;        while (pElement != NULL)        {   /* Cmplx expression : Sum += Element * Vector[Col] */            CMPLX_MULT_ADD_ASSIGN( Sum, *pElement, Vector[pElement->Col] );            pElement = pElement->NextInRow;        }#if spSEPARATED_COMPLEX_VECTORS        RHS[*pExtOrder] = Sum.Real;        iRHS[*pExtOrder--] = Sum.Imag;#else        ((ComplexVector)RHS)[*pExtOrder--] = Sum;#endif    }    return;}#endif /* spCOMPLEX AND MULTIPLICATION */#if MULTIPLICATION AND TRANSPOSE/* *  TRANSPOSED MATRIX MULTIPLICATION * *  Multiplies transposed matrix by solution vector to find source vector. *  Assumes matrix has not been factored.  This routine can be used *  as a test to see if solutions are correct.  It should not be used *  before spMNA_Preorder(). * *  >>> Arguments: *  eMatrix  <input>  (char *) *      Pointer to the matrix. *  RHS  <output>  (RealVector) *      RHS is the right hand side. This is what is being solved for. *  Solution  <input>  (RealVector) *      Solution is the vector being multiplied by the matrix. *  iRHS  <output>  (RealVector) *      iRHS is the imaginary portion of the right hand side. This is *      what is being solved for.  This is only necessary if the matrix is *      complex and spSEPARATED_COMPLEX_VECTORS is true. *  iSolution  <input>  (RealVector) *      iSolution is the imaginary portion of the vector being multiplied *      by the matrix. This is only necessary if the matrix is *      complex and spSEPARATED_COMPLEX_VECTORS is true. * *  >>> Obscure Macros *  IMAG_VECTORS *      Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and *      spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears *      without a trace. */voidspMultTransposed( eMatrix, RHS, Solution IMAG_VECTORS )char *eMatrix;RealVector RHS, Solution IMAG_VECTORS;

⌨️ 快捷键说明

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