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

📄 sputils.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            for (K = Size; K > 0; K--) T[K] *= ScaleFactor;            E *= ScaleFactor;        }    }/* Compute 1-norm of T, which now contains y, and scale ||T|| to 1/SLACK. */    for (ASy = 0.0, I = Size; I > 0; I--) ASy += ABS(T[I]);    ScaleFactor = 1.0 / (SLACK * ASy);    if (ScaleFactor < 0.5)    {   for (I = Size; I > 0; I--) T[I] *= ScaleFactor;        ASy = 1.0 / SLACK;        E *= ScaleFactor;    }/* Compute infinity-norm of T for O'Leary's estimate. */    for (MaxY = 0.0, I = Size; I > 0; I--)        if (MaxY < ABS(T[I])) MaxY = ABS(T[I]);/* * Part 2.  A* z = y where the * represents the transpose. * Recall that A = LU implies A* = U* L*. *//* Forward elimination, U* v = y. */    for (I = 1; I <= Size; I++)    {   pElement = Matrix->Diag[I]->NextInRow;        while (pElement != NULL)        {   T[pElement->Col] -= T[I] * pElement->Real;            pElement = pElement->NextInRow;        }        if (ABS(T[I]) > SLACK)        {   ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(T[I]) );            for (K = Size; K > 0; K--) T[K] *= ScaleFactor;            ASy *= ScaleFactor;        }    }/* Compute 1-norm of T, which now contains v, and scale ||T|| to 1/SLACK. */    for (ASv = 0.0, I = Size; I > 0; I--) ASv += ABS(T[I]);    ScaleFactor = 1.0 / (SLACK * ASv);    if (ScaleFactor < 0.5)    {   for (I = Size; I > 0; I--) T[I] *= ScaleFactor;        ASy *= ScaleFactor;    }/* Backward Substitution, L* z = v. */    for (I = Size; I >= 1; I--)    {   pPivot = Matrix->Diag[I];        pElement = pPivot->NextInCol;        while (pElement != NULL)        {   T[I] -= pElement->Real * T[pElement->Row];            pElement = pElement->NextInCol;        }        T[I] *= pPivot->Real;        if (ABS(T[I]) > SLACK)        {   ScaleFactor = 1.0 / MAX( SQR( SLACK ), ABS(T[I]) );            for (K = Size; K > 0; K--) T[K] *= ScaleFactor;            ASy *= ScaleFactor;        }    }/* Compute 1-norm of T, which now contains z. */    for (ASz = 0.0, I = Size; I > 0; I--) ASz += ABS(T[I]);#if NOT spCOMPLEX    FREE( Tm );#endif    Linpack = ASy / ASz;    OLeary = E / MaxY;    InvNormOfInverse = MIN( Linpack, OLeary );    return InvNormOfInverse / NormOfMatrix;#endif /* REAL */}#if spCOMPLEX/* *  ESTIMATE CONDITION NUMBER * *  Complex version of spCondition(). * *  >>> Returns: *  The reciprocal of the condition number. * *  >>> Arguments: *  Matrix  <input>  (MatrixPtr) *      Pointer to the matrix. *  NormOfMatrix  <input>  (RealNumber) *      The L-infinity norm of the unfactored matrix as computed by *      spNorm(). *  pError  <output>  (int *) *      Used to return error code. * *  >>> Possible errors: *  spNO_MEMORY */static RealNumberComplexCondition( Matrix, NormOfMatrix, pError )MatrixPtr Matrix;RealNumber NormOfMatrix;int *pError;{register ElementPtr pElement;register ComplexVector T, Tm;register int I, K, Row;ElementPtr pPivot;int Size;RealNumber E, Em, ASp, ASm, ASw, ASy, ASv, ASz, MaxY, ScaleFactor;RealNumber Linpack, OLeary, InvNormOfInverse;ComplexNumber Wp, Wm;/* Begin `ComplexCondition'. */    Size = Matrix->Size;    T = (ComplexVector)Matrix->Intermediate;    Tm = ALLOC( ComplexNumber, Size+1 );    if (Tm == NULL)    {   *pError = spNO_MEMORY;        return 0.0;    }    for (I = Size; I > 0; I--) T[I].Real = T[I].Imag = 0.0;/* * Part 1.  Ay = e. * Solve Ay = LUy = e where e consists of +1 and -1 terms with the sign * chosen to maximize the size of w in Lw = e.  Since the terms in w can * get very large, scaling is used to avoid overflow. *//* Forward elimination. Solves Lw = e while choosing e. */    E = 1.0;    for (I = 1; I <= Size; I++)    {   pPivot = Matrix->Diag[I];        if (T[I].Real < 0.0) Em = -E; else Em = E;        Wm = T[I];        Wm.Real += Em;        ASm = CMPLX_1_NORM( Wm );        CMPLX_MULT_ASSIGN( Wm, *pPivot );        if (CMPLX_1_NORM(Wm) > SLACK)        {   ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(Wm) );            for (K = Size; K > 0; K--) SCLR_MULT_ASSIGN( T[K], ScaleFactor );            E *= ScaleFactor;            Em *= ScaleFactor;            ASm *= ScaleFactor;            SCLR_MULT_ASSIGN( Wm, ScaleFactor );        }        Wp = T[I];        Wp.Real -= Em;        ASp = CMPLX_1_NORM( Wp );        CMPLX_MULT_ASSIGN( Wp, *pPivot );/* Update T for both values of W, minus value is placed in Tm. */        pElement = pPivot->NextInCol;        while (pElement != NULL)        {   Row = pElement->Row;            /* Cmplx expr: Tm[Row] = T[Row] - (Wp * *pElement). */            CMPLX_MULT_SUBT( Tm[Row], Wm, *pElement, T[Row] );            /* Cmplx expr: T[Row] -= Wp * *pElement. */            CMPLX_MULT_SUBT_ASSIGN( T[Row], Wm, *pElement );            ASp += CMPLX_1_NORM(T[Row]);            ASm += CMPLX_1_NORM(Tm[Row]);            pElement = pElement->NextInCol;        }/* If minus value causes more growth, overwrite T with its values. */        if (ASm > ASp)        {   T[I] = Wm;            pElement = pPivot->NextInCol;            while (pElement != NULL)            {   T[pElement->Row] = Tm[pElement->Row];                pElement = pElement->NextInCol;            }        }        else T[I] = Wp;    }/* Compute 1-norm of T, which now contains w, and scale ||T|| to 1/SLACK. */    for (ASw = 0.0, I = Size; I > 0; I--) ASw += CMPLX_1_NORM(T[I]);    ScaleFactor = 1.0 / (SLACK * ASw);    if (ScaleFactor < 0.5)    {   for (I = Size; I > 0; I--) SCLR_MULT_ASSIGN( T[I], ScaleFactor );        E *= ScaleFactor;    }/* Backward Substitution. Solves Uy = w.*/    for (I = Size; I >= 1; I--)    {   pElement = Matrix->Diag[I]->NextInRow;        while (pElement != NULL)        {   /* Cmplx expr: T[I] -= T[pElement->Col] * *pElement. */            CMPLX_MULT_SUBT_ASSIGN( T[I], T[pElement->Col], *pElement );            pElement = pElement->NextInRow;        }        if (CMPLX_1_NORM(T[I]) > SLACK)        {   ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(T[I]) );            for (K = Size; K > 0; K--) SCLR_MULT_ASSIGN( T[K], ScaleFactor );            E *= ScaleFactor;        }    }/* Compute 1-norm of T, which now contains y, and scale ||T|| to 1/SLACK. */    for (ASy = 0.0, I = Size; I > 0; I--) ASy += CMPLX_1_NORM(T[I]);    ScaleFactor = 1.0 / (SLACK * ASy);    if (ScaleFactor < 0.5)    {   for (I = Size; I > 0; I--) SCLR_MULT_ASSIGN( T[I], ScaleFactor );        ASy = 1.0 / SLACK;        E *= ScaleFactor;    }/* Compute infinity-norm of T for O'Leary's estimate. */    for (MaxY = 0.0, I = Size; I > 0; I--)        if (MaxY < CMPLX_1_NORM(T[I])) MaxY = CMPLX_1_NORM(T[I]);/* * Part 2.  A* z = y where the * represents the transpose. * Recall that A = LU implies A* = U* L*. *//* Forward elimination, U* v = y. */    for (I = 1; I <= Size; I++)    {   pElement = Matrix->Diag[I]->NextInRow;        while (pElement != NULL)        {   /* Cmplx expr: T[pElement->Col] -= T[I] * *pElement. */            CMPLX_MULT_SUBT_ASSIGN( T[pElement->Col], T[I], *pElement );            pElement = pElement->NextInRow;        }        if (CMPLX_1_NORM(T[I]) > SLACK)        {   ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(T[I]) );            for (K = Size; K > 0; K--) SCLR_MULT_ASSIGN( T[K], ScaleFactor );            ASy *= ScaleFactor;        }    }/* Compute 1-norm of T, which now contains v, and scale ||T|| to 1/SLACK. */    for (ASv = 0.0, I = Size; I > 0; I--) ASv += CMPLX_1_NORM(T[I]);    ScaleFactor = 1.0 / (SLACK * ASv);    if (ScaleFactor < 0.5)    {   for (I = Size; I > 0; I--) SCLR_MULT_ASSIGN( T[I], ScaleFactor );        ASy *= ScaleFactor;    }/* Backward Substitution, L* z = v. */    for (I = Size; I >= 1; I--)    {   pPivot = Matrix->Diag[I];        pElement = pPivot->NextInCol;        while (pElement != NULL)        {   /* Cmplx expr: T[I] -= T[pElement->Row] * *pElement. */            CMPLX_MULT_SUBT_ASSIGN( T[I], T[pElement->Row], *pElement );            pElement = pElement->NextInCol;        }        CMPLX_MULT_ASSIGN( T[I], *pPivot );        if (CMPLX_1_NORM(T[I]) > SLACK)        {   ScaleFactor = 1.0 / MAX( SQR( SLACK ), CMPLX_1_NORM(T[I]) );            for (K = Size; K > 0; K--) SCLR_MULT_ASSIGN( T[K], ScaleFactor );            ASy *= ScaleFactor;        }    }/* Compute 1-norm of T, which now contains z. */    for (ASz = 0.0, I = Size; I > 0; I--) ASz += CMPLX_1_NORM(T[I]);    FREE( Tm );    Linpack = ASy / ASz;    OLeary = E / MaxY;    InvNormOfInverse = MIN( Linpack, OLeary );    return InvNormOfInverse / NormOfMatrix;}#endif /* spCOMPLEX *//* *  L-INFINITY MATRIX NORM  * *  Computes the L-infinity norm of an unfactored matrix.  It is a fatal *  error to pass this routine a factored matrix. * *  One difficulty is that the rows may not be linked. * *  >>> Returns: *  The largest absolute row sum of matrix. * *  >>> Arguments: *  eMatrix  <input>  (char *) *      Pointer to the matrix. */RealNumberspNorm( eMatrix )char *eMatrix;{MatrixPtr  Matrix = (MatrixPtr)eMatrix;register ElementPtr pElement;register int I;RealNumber Max = 0.0, AbsRowSum;/* Begin `spNorm'. */    ASSERT( IS_SPARSE(Matrix) AND NOT IS_FACTORED(Matrix) );    if (NOT Matrix->RowsLinked) spcLinkRows( Matrix );/* Compute row sums. */#if REAL    if (NOT Matrix->Complex)    {   for (I = Matrix->Size; I > 0; I--)        {   pElement = Matrix->FirstInRow[I];            AbsRowSum = 0.0;            while (pElement != NULL)            {   AbsRowSum += ABS( pElement->Real );                pElement = pElement->NextInRow;            }            if (Max < AbsRowSum) Max = AbsRowSum;        }    }#endif#if spCOMPLEX    if (Matrix->Complex)    {   for (I = Matrix->Size; I > 0; I--)        {   pElement = Matrix->FirstInRow[I];            AbsRowSum = 0.0;            while (pElement != NULL)            {   AbsRowSum += CMPLX_1_NORM( *pElement );                pElement = pElement->NextInRow;            }            if (Max < AbsRowSum) Max = AbsRowSum;        }    }#endif    return Max;}#endif /* CONDITION */#if STABILITY/* *  STABILITY OF FACTORIZATION * *  The following routines are used to gauge the stability of a *  factorization.  If the factorization is determined to be too unstable, *  then the matrix should be reordered.  The routines compute quantities *  that are needed in the computation of a bound on the error attributed *  to any one element in the matrix during the factorization.  In other *  words, there is a matrix E = [e_ij] of error terms such that A+E = LU. *  This routine finds a bound on |e_ij|.  Erisman & Reid [1] showed that *  |e_ij| < 3.01 u rho m_ij, where u is the machine rounding unit, *  rho = max a_ij where the max is taken over every row i, column j, and *  step k, and m_ij is the number of multiplications required in the *  computation of l_ij if i > j or u_ij otherwise.  Barlow [2] showed that *  rho < max_i || l_i ||_p max_j || u_j ||_q where 1/p + 1/q = 1. * *  The first routine finds the magnitude on the largest element in the *  matrix.  If the matrix has not yet been factored, the largest *  element is found by direct search.  If the matrix is factored, a *  bound on the largest element in any of the reduced submatrices is *  computed using Barlow with p = oo and q = 1.  The ratio of these *  two numbers is the growth, which can be used to determine if the *  pivoting order is adequate.  A large growth implies that *  considerable error has been made in the factorization and that it *  is probably a good idea to reorder the matrix.  If a large growth *  in encountered after using spFactor(), reconstruct the matrix and *  refactor using spOrderAndFactor().  If a large growth is *  encountered after using spOrderAndFactor(), refactor using *  spOrderAndFactor() with the pivot threshold increased, say to 0.1. * *  Using only the size of the matrix as an upper bound on m_ij and *  Barlow's bound, the user can estimate the size of the matrix error *  terms e_ij using the bound of Erisman and Reid.  The second routine *  computes a tighter bound (with more work) based on work by Gear *  [3], |e_ij| < 1.01 u rho (t c^3 + (1 + t)c^2) where t is the *  threshold and c is the maximum number of off-diagonal elements in *  any row of L.  The expensive part of computing this bound is *  determining the maximum number of off-diagonals in L, which changes *  only when the order of the matrix changes.  This number is computed *  and saved, and only recomputed if the matrix is reordered. * *  [1] A. M. Erisman, J. K. Reid.  Monitoring the stability of the *      triangular factorization of a sparse matrix.  Numerische *      Mathematik.  Vol. 22, No. 3, 1974, pp 183-186. * *  [2] J. L. Barlow.  A note on monitoring the stability of triangular *      decomposition of sparse matrices.  "SIAM Journal of Scientific *      and Statistical Computing."  Vol. 7, No. 1, January 1986, pp 166-168. * *  [3] I. S. Duff, A. M. Erisman, J. K. Reid.  "Direct Methods for Sparse *      Matrices."  Oxford 1986. pp 99. *//* *  LARGEST ELEMENT IN MATRIX * *  >>> Returns: *  If matrix is not factored, returns the magnitude of the largest element in *  the matrix.  If the matrix is factored, a bound on the magnitude of the *  largest element in any of the reduced submatrices is returned. * *  >>> Arguments:

⌨️ 快捷键说明

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