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

📄 spfactor.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 5 页
字号:
	    Matrix->Error = spNO_MEMORY;    }    if (Matrix->Error != spNO_MEMORY)	Matrix->InternalVectorsAllocated = YES;    return;}/* *  COUNT MARKOWITZ * *  Scans Matrix to determine the Markowitz counts for each row and column. * *  >>> Arguments: *  Matrix  <input>  (MatrixPtr) *      Pointer to matrix. *  RHS  <input>  (RealVector) *      Representative right-hand side vector that is used to determine *      pivoting order when the right hand side vector is sparse.  If *      RHS is a NULL pointer then the RHS vector is assumed to be full *      and it is not used when determining the pivoting order. *  Step  <input>  (int) *     Index of the diagonal currently being eliminated. * *  >>> Local variables: *  Count  (int) *     Temporary counting variable. *  ExtRow  (int) *     The external row number that corresponds to I. *  pElement  (ElementPtr) *     Pointer to matrix elements. *  Size  (int) *     The size of the matrix. */static voidCountMarkowitz(MatrixPtr Matrix,  RealVector  RHS, int Step){    int  Count, I, Size = Matrix->Size;    ElementPtr  pElement;    int  ExtRow;    /* Begin `CountMarkowitz'. */    /* Generate MarkowitzRow Count for each row. */    for (I = Step; I <= Size; I++) {	/* Set Count to -1 initially to remove count due to pivot element. */        Count = -1;        pElement = Matrix->FirstInRow[I];        while (pElement != NULL && pElement->Col < Step)            pElement = pElement->NextInRow;        while (pElement != NULL) {	    Count++;            pElement = pElement->NextInRow;        }	/* Include nonzero elements in the RHS vector. */        ExtRow = Matrix->IntToExtRowMap[I];        if (RHS != NULL)            if (RHS[ExtRow] != 0.0)		Count++;        Matrix->MarkowitzRow[I] = Count;    }    /* Generate the MarkowitzCol count for each column. */    for (I = Step; I <= Size; I++) {	/* Set Count to -1 initially to remove count due to pivot element. */        Count = -1;        pElement = Matrix->FirstInCol[I];        while (pElement != NULL && pElement->Row < Step)            pElement = pElement->NextInCol;        while (pElement != NULL) {	    Count++;            pElement = pElement->NextInCol;        }        Matrix->MarkowitzCol[I] = Count;    }    return;}/* *  MARKOWITZ PRODUCTS * *  Calculates MarkowitzProduct for each diagonal element from the Markowitz *  counts. * *  >>> Arguments: *  Matrix  <input>  (MatrixPtr) *      Pointer to matrix. *  Step  <input>  (int) *      Index of the diagonal currently being eliminated. * *  >>> Local Variables: *  pMarkowitzProduct  (long *) *      Pointer that points into MarkowitzProduct array. Is used to *      sequentially access entries quickly. *  pMarkowitzRow  (int *) *      Pointer that points into MarkowitzRow array. Is used to sequentially *      access entries quickly. *  pMarkowitzCol  (int *) *      Pointer that points into MarkowitzCol array. Is used to sequentially *      access entries quickly. *  Product  (long) *      Temporary storage for Markowitz product./ *  Size  (int) *      The size of the matrix. */static voidMarkowitzProducts(MatrixPtr Matrix, int Step){    int  I, *pMarkowitzRow, *pMarkowitzCol;    long  Product, *pMarkowitzProduct;    int  Size = Matrix->Size;    double fProduct;    /* Begin `MarkowitzProducts'. */    Matrix->Singletons = 0;    pMarkowitzProduct = &(Matrix->MarkowitzProd[Step]);    pMarkowitzRow = &(Matrix->MarkowitzRow[Step]);    pMarkowitzCol = &(Matrix->MarkowitzCol[Step]);    for (I = Step; I <= Size; I++) {	/* If chance of overflow, use real numbers. */        if ((*pMarkowitzRow > LARGEST_SHORT_INTEGER && *pMarkowitzCol != 0) ||            (*pMarkowitzCol > LARGEST_SHORT_INTEGER && *pMarkowitzRow != 0)) {	    fProduct = (double)(*pMarkowitzRow++) * (double)(*pMarkowitzCol++);            if (fProduct >= LARGEST_LONG_INTEGER)                *pMarkowitzProduct++ = LARGEST_LONG_INTEGER;            else                *pMarkowitzProduct++ = fProduct;        } else {	    Product = *pMarkowitzRow++ * *pMarkowitzCol++;            if ((*pMarkowitzProduct++ = Product) == 0)                Matrix->Singletons++;        }    }    return;}/* *  SEARCH FOR BEST PIVOT * *  Performs a search to determine the element with the lowest Markowitz *  Product that is also acceptable.  An acceptable element is one that is *  larger than the AbsThreshold and at least as large as RelThreshold times *  the largest element in the same column.  The first step is to look for *  singletons if any exist.  If none are found, then all the diagonals are *  searched. The diagonal is searched once quickly using the assumption that *  elements on the diagonal are large compared to other elements in their *  column, and so the pivot can be chosen only on the basis of the Markowitz *  criterion.  After a element has been chosen to be pivot on the basis of *  its Markowitz product, it is checked to see if it is large enough. *  Waiting to the end of the Markowitz search to check the size of a pivot *  candidate saves considerable time, but is not guaranteed to find an *  acceptable pivot.  Thus if unsuccessful a second pass of the diagonal is *  made.  This second pass checks to see if an element is large enough during *  the search, not after it.  If still no acceptable pivot candidate has *  been found, the search expands to cover the entire matrix. * *  >>> Returned: *  A pointer to the element chosen to be pivot.  If every element in the *  matrix is zero, then NULL is returned. * *  >>> Arguments: *  Matrix  <input>  (MatrixPtr) *      Pointer to matrix. *  Step  <input>  (int) *      The row and column number of the beginning of the reduced submatrix. * *  >>> Local variables: *  ChosenPivot  (ElementPtr) *      Pointer to element that has been chosen to be the pivot. * *  >>> Possible errors: *  spSINGULAR *  spSMALL_PIVOT */static ElementPtrSearchForPivot( Matrix, Step, DiagPivoting )MatrixPtr Matrix;int Step, DiagPivoting;{ElementPtr  ChosenPivot;ElementPtr  SearchForSingleton();ElementPtr  QuicklySearchDiagonal();ElementPtr  SearchDiagonal();ElementPtr  SearchEntireMatrix(); /* Begin `SearchForPivot'. */ /* If singletons exist, look for an acceptable one to use as pivot. */    if (Matrix->Singletons)    {    ChosenPivot = SearchForSingleton( Matrix, Step );        if (ChosenPivot != NULL)        {    Matrix->PivotSelectionMethod = 's';            return ChosenPivot;        }    }#if DIAGONAL_PIVOTING    if (DiagPivoting)    { /* * Either no singletons exist or they weren't acceptable.  Take quick first * pass at searching diagonal.  First search for element on diagonal of  * remaining submatrix with smallest Markowitz product, then check to see * if it okay numerically.  If not, QuicklySearchDiagonal fails. */        ChosenPivot = QuicklySearchDiagonal( Matrix, Step );        if (ChosenPivot != NULL)        {    Matrix->PivotSelectionMethod = 'q';            return ChosenPivot;        } /* * Quick search of diagonal failed, carefully search diagonal and check each * pivot candidate numerically before even tentatively accepting it. */        ChosenPivot = SearchDiagonal( Matrix, Step );        if (ChosenPivot != NULL)        {    Matrix->PivotSelectionMethod = 'd';            return ChosenPivot;        }    }#endif /* DIAGONAL_PIVOTING */ /* No acceptable pivot found yet, search entire matrix. */    ChosenPivot = SearchEntireMatrix( Matrix, Step );    Matrix->PivotSelectionMethod = 'e';    return ChosenPivot;}/* *  SEARCH FOR SINGLETON TO USE AS PIVOT * *  Performs a search to find a singleton to use as the pivot.  The *  first acceptable singleton is used.  A singleton is acceptable if *  it is larger in magnitude than the AbsThreshold and larger *  than RelThreshold times the largest of any other elements in the same *  column.  It may seem that a singleton need not satisfy the *  relative threshold criterion, however it is necessary to prevent *  excessive growth in the RHS from resulting in overflow during the *  forward and backward substitution.  A singleton does not need to *  be on the diagonal to be selected. * *  >>> Returned: *  A pointer to the singleton chosen to be pivot.  In no singleton is *  acceptable, return NULL. * *  >>> Arguments: *  Matrix  <input>  (MatrixPtr) *      Pointer to matrix. *  Step  <input>  (int) *      Index of the diagonal currently being eliminated. * *  >>> Local variables: *  ChosenPivot  (ElementPtr) *      Pointer to element that has been chosen to be the pivot. *  PivotMag  (RealNumber) *      Magnitude of ChosenPivot. *  Singletons  (int) *      The count of the number of singletons that can be used as pivots. *      A local version of Matrix->Singletons. *  pMarkowitzProduct  (long *) *      Pointer that points into MarkowitzProduct array. It is used to quickly *      access successive Markowitz products. */static ElementPtrSearchForSingleton( Matrix, Step )MatrixPtr Matrix;int Step;{ ElementPtr  ChosenPivot; int  I; long  *pMarkowitzProduct;int  Singletons;RealNumber  PivotMag, FindBiggestInColExclude(); /* Begin `SearchForSingleton'. */ /* Initialize pointer that is to scan through MarkowitzProduct vector. */    pMarkowitzProduct = &(Matrix->MarkowitzProd[Matrix->Size+1]);    Matrix->MarkowitzProd[Matrix->Size+1] = Matrix->MarkowitzProd[Step]; /* Decrement the count of available singletons, on the assumption that an * acceptable one will be found. */    Singletons = Matrix->Singletons--; /* * Assure that following while loop will always terminate, this is just * preventive medicine, if things are working right this should never * be needed. */    Matrix->MarkowitzProd[Step-1] = 0;    while (Singletons-- > 0)    { /* Singletons exist, find them. */ /* * This is tricky.  Am using a pointer to sequentially step through the * MarkowitzProduct array.  Search terminates when singleton (Product = 0) * is found.  Note that the conditional in the while statement * ( *pMarkowitzProduct ) is TRUE as long as the MarkowitzProduct is not * equal to zero.  The row (and column)strchr on the diagonal is then * calculated by subtracting the pointer to the Markowitz product of * the first diagonal from the pointer to the Markowitz product of the * desired element, the singleton. * * Search proceeds from the end (high row and column numbers) to the * beginning (low row and column numbers) so that rows and columns with * large Markowitz products will tend to be move to the bottom of the * matrix.  However, choosing Diag[Step] is desirable because it would * require no row and column interchanges, so inspect it first by * putting its Markowitz product at the end of the MarkowitzProd * vector. */        while ( *pMarkowitzProduct-- )        {    /*             * N bottles of beer on the wall;             * N bottles of beer.             * you take one down and pass it around;             * N-1 bottles of beer on the wall.             */        }        I = pMarkowitzProduct - Matrix->MarkowitzProd + 1; /* Assure that I is valid. */        if (I < Step) break;  /* while (Singletons-- > 0) */        if (I > Matrix->Size) I = Step; /* Singleton has been found in either/both row or/and column I. */        if ((ChosenPivot = Matrix->Diag[I]) != NULL)        { /* Singleton lies on the diagonal. */            PivotMag = ELEMENT_MAG(ChosenPivot);            if            (    PivotMag > Matrix->AbsThreshold &&                 PivotMag > Matrix->RelThreshold *                            FindBiggestInColExclude( Matrix, ChosenPivot, Step )            ) return ChosenPivot;        }        else

⌨️ 快捷键说明

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