📄 spsolve.c
字号:
pElement = pElement->NextInCol; } } }/* Backward Substitution. Solves Ux = c.*/ for (I = Size; I > 0; I--) { Temp = Intermediate[I]; pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) {/* Cmplx expr: Temp -= *Element * Intermediate[Element->Col]. */ CMPLX_MULT_SUBT_ASSIGN(Temp, *pElement,Intermediate[pElement->Col]); pElement = pElement->NextInRow; } Intermediate[I] = Temp; }/* Unscramble Intermediate vector while placing data in to Solution vector. */ pExtOrder = &Matrix->IntToExtColMap[Size];#if spSEPARATED_COMPLEX_VECTORS for (I = Size; I > 0; I--) { Solution[*(pExtOrder)] = Intermediate[I].Real; iSolution[*(pExtOrder--)] = Intermediate[I].Imag; }#else ExtVector = (ComplexVector)Solution; for (I = Size; I > 0; I--) ExtVector[*(pExtOrder--)] = Intermediate[I];#endif return;}#endif /* spCOMPLEX */#if TRANSPOSE/* * SOLVE TRANSPOSED MATRIX EQUATION * * Performs forward elimination and back substitution to find the * unknown vector from the RHS vector and transposed factored * matrix. This routine is useful when performing sensitivity analysis * on a circuit using the adjoint method. This routine assumes that * the pivots are associated with the untransposed lower triangular * (L) matrix and that the diagonal of the untransposed upper * triangular (U) matrix consists of ones. * * >>> Arguments: * Matrix <input> (char *) * Pointer to matrix. * RHS <input> (RealVector) * RHS is the input data array, the right hand side. This data is * undisturbed and may be reused for other solves. * Solution <output> (RealVector) * Solution is the output data array. This routine is constructed such that * RHS and Solution can be the same array. * iRHS <input> (RealVector) * iRHS is the imaginary portion of the input data array, the right * hand side. This data is undisturbed and may be reused for other solves. * If spSEPARATED_COMPLEX_VECTOR is set false, or if matrix is real, there * is no need to supply this array. * iSolution <output> (RealVector) * iSolution is the imaginary portion of the output data array. This * routine is constructed such that iRHS and iSolution can be * the same array. If spSEPARATED_COMPLEX_VECTOR is set false, or if * matrix is real, there is no need to supply this array. * * >>> Local variables: * Intermediate (RealVector) * Temporary storage for use in forward elimination and backward * substitution. Commonly referred to as c, when the LU factorization * equations are given as Ax = b, Lc = b, Ux = c. Local version of * Matrix->Intermediate, which was created during the initial * factorization in function spcCreateInternalVectors() in the matrix * factorization module. * pElement (ElementPtr) * Pointer used to address elements in both the lower and upper triangle * matrices. * pExtOrder (int *) * Pointer used to sequentially access each entry in IntToExtRowMap * and IntToExtRowMap arrays. Used to quickly scramble and unscramble * RHS and Solution to account for row and column interchanges. * pPivot (ElementPtr) * Pointer that points to current pivot or diagonal element. * Size (int) * Size of matrix. Made local to reduce indirection. * Temp (RealNumber) * Temporary storage for entries in arrays. * * >>> 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. *//*VARARGS3*/voidspSolveTransposed( eMatrix, RHS, Solution IMAG_VECTORS )char *eMatrix;RealVector RHS, Solution IMAG_VECTORS;{MatrixPtr Matrix = (MatrixPtr)eMatrix;register ElementPtr pElement;register RealVector Intermediate;register int I, *pExtOrder, Size;ElementPtr pPivot;RealNumber Temp;void SolveComplexTransposedMatrix();/* Begin `spSolveTransposed'. */ ASSERT( IS_VALID(Matrix) AND IS_FACTORED(Matrix) );#if spCOMPLEX if (Matrix->Complex) { SolveComplexTransposedMatrix( Matrix, RHS, Solution IMAG_VECTORS ); return; }#endif#if REAL Size = Matrix->Size; Intermediate = Matrix->Intermediate;/* Correct array pointers for ARRAY_OFFSET. */#if NOT ARRAY_OFFSET --RHS; --Solution;#endif/* Initialize Intermediate vector. */ pExtOrder = &Matrix->IntToExtColMap[Size]; for (I = Size; I > 0; I--) Intermediate[I] = RHS[*(pExtOrder--)];/* Forward elimination. */ for (I = 1; I <= Size; I++) { /* This step of the elimination is skipped if Temp equals zero. */ if ((Temp = Intermediate[I]) != 0.0) { pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) { Intermediate[pElement->Col] -= Temp * pElement->Real; pElement = pElement->NextInRow; } } }/* Backward Substitution. */ for (I = Size; I > 0; I--) { pPivot = Matrix->Diag[I]; Temp = Intermediate[I]; pElement = pPivot->NextInCol; while (pElement != NULL) { Temp -= pElement->Real * Intermediate[pElement->Row]; pElement = pElement->NextInCol; } Intermediate[I] = Temp * pPivot->Real; }/* Unscramble Intermediate vector while placing data in to Solution vector. */ pExtOrder = &Matrix->IntToExtRowMap[Size]; for (I = Size; I > 0; I--) Solution[*(pExtOrder--)] = Intermediate[I]; return;#endif /* REAL */}#endif /* TRANSPOSE */#if TRANSPOSE AND spCOMPLEX/* * SOLVE COMPLEX TRANSPOSED MATRIX EQUATION * * Performs forward elimination and back substitution to find the * unknown vector from the RHS vector and transposed factored * matrix. This routine is useful when performing sensitivity analysis * on a circuit using the adjoint method. This routine assumes that * the pivots are associated with the untransposed lower triangular * (L) matrix and that the diagonal of the untransposed upper * triangular (U) matrix consists of ones. * * >>> Arguments: * Matrix <input> (char *) * Pointer to matrix. * RHS <input> (RealVector) * RHS is the input data array, the right hand * side. This data is undisturbed and may be reused for other solves. * This vector is only the real portion if the matrix is complex and * spSEPARATED_COMPLEX_VECTORS is set true. * Solution <output> (RealVector) * Solution is the real portion of the output data array. This routine * is constructed such that RHS and Solution can be the same array. * This vector is only the real portion if the matrix is complex and * spSEPARATED_COMPLEX_VECTORS is set true. * iRHS <input> (RealVector) * iRHS is the imaginary portion of the input data array, the right * hand side. This data is undisturbed and may be reused for other solves. * If either spCOMPLEX or spSEPARATED_COMPLEX_VECTOR is set false, there * is no need to supply this array. * iSolution <output> (RealVector) * iSolution is the imaginary portion of the output data array. This * routine is constructed such that iRHS and iSolution can be * the same array. If spCOMPLEX or spSEPARATED_COMPLEX_VECTOR is set * false, there is no need to supply this array. * * >>> Local variables: * Intermediate (ComplexVector) * Temporary storage for use in forward elimination and backward * substitution. Commonly referred to as c, when the LU factorization * equations are given as Ax = b, Lc = b, Ux = c. Local version of * Matrix->Intermediate, which was created during * the initial factorization in function spcCreateInternalVectors() in the * matrix factorization module. * pElement (ElementPtr) * Pointer used to address elements in both the lower and upper triangle * matrices. * pExtOrder (int *) * Pointer used to sequentially access each entry in IntToExtRowMap * and IntToExtColMap arrays. Used to quickly scramble and unscramble * RHS and Solution to account for row and column interchanges. * pPivot (ElementPtr) * Pointer that points to current pivot or diagonal element. * Size (int) * Size of matrix. Made local to reduce indirection. * Temp (ComplexNumber) * Temporary storage for entries in arrays. * * >>> 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 voidSolveComplexTransposedMatrix(Matrix, RHS, Solution IMAG_VECTORS )MatrixPtr Matrix;RealVector RHS, Solution IMAG_VECTORS;{register ElementPtr pElement;register ComplexVector Intermediate;register int I, *pExtOrder, Size;register ComplexVector ExtVector;ElementPtr pPivot;ComplexNumber Temp;/* Begin `SolveComplexTransposedMatrix'. */ Size = Matrix->Size; Intermediate = (ComplexVector)Matrix->Intermediate;/* 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. */ pExtOrder = &Matrix->IntToExtColMap[Size];#if spSEPARATED_COMPLEX_VECTORS for (I = Size; I > 0; I--) { Intermediate[I].Real = RHS[*(pExtOrder)]; Intermediate[I].Imag = iRHS[*(pExtOrder--)]; }#else ExtVector = (ComplexVector)RHS; for (I = Size; I > 0; I--) Intermediate[I] = ExtVector[*(pExtOrder--)];#endif/* Forward elimination. */ for (I = 1; I <= Size; I++) { Temp = Intermediate[I];/* This step of the elimination is skipped if Temp equals zero. */ if ((Temp.Real != 0.0) OR (Temp.Imag != 0.0)) { pElement = Matrix->Diag[I]->NextInRow; while (pElement != NULL) {/* Cmplx expr: Intermediate[Element->Col] -= Temp * *Element. */ CMPLX_MULT_SUBT_ASSIGN( Intermediate[pElement->Col], Temp, *pElement); pElement = pElement->NextInRow; } } }/* Backward Substitution. */ for (I = Size; I > 0; I--) { pPivot = Matrix->Diag[I]; Temp = Intermediate[I]; pElement = pPivot->NextInCol; while (pElement != NULL) {/* Cmplx expr: Temp -= Intermediate[Element->Row] * *Element. */ CMPLX_MULT_SUBT_ASSIGN(Temp,Intermediate[pElement->Row],*pElement); pElement = pElement->NextInCol; }/* Cmplx expr: Intermediate = Temp * (1.0 / *pPivot). */ CMPLX_MULT(Intermediate[I], Temp, *pPivot); }/* Unscramble Intermediate vector while placing data in to Solution vector. */ pExtOrder = &Matrix->IntToExtRowMap[Size];#if spSEPARATED_COMPLEX_VECTORS for (I = Size; I > 0; I--) { Solution[*(pExtOrder)] = Intermediate[I].Real; iSolution[*(pExtOrder--)] = Intermediate[I].Imag; }#else ExtVector = (ComplexVector)Solution; for (I = Size; I > 0; I--) ExtVector[*(pExtOrder--)] = Intermediate[I];#endif return;}#endif /* TRANSPOSE AND spCOMPLEX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -