📄 spsolve.c
字号:
/* * MATRIX SOLVE MODULE * * Author: Advising professor: * Kenneth S. Kundert Alberto Sangiovanni-Vincentelli * UC Berkeley * * This file contains the forward and backward substitution routines for * the sparse matrix routines. * * >>> User accessible functions contained in this file: * spSolve * spSolveTransposed * * >>> Other functions contained in this file: * SolveComplexMatrix * SolveComplexTransposedMatrix *//* * 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. */#ifdef notdefstatic char copyright[] = "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert";static char RCSid[] = "@(#)$Header: spSolve.c,v 1.3 88/06/24 05:02:49 kundert Exp $";#endif/* * 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. */#define spINSIDE_SPARSE#include "spconfig.h"#include "spmatrix.h"#include "spdefs.h"/* * Function declarations */#ifdef __STDC__#if spSEPARATED_COMPLEX_VECTORSstatic void SolveComplexMatrix( MatrixPtr, RealVector, RealVector, RealVector, RealVector );static void SolveComplexTransposedMatrix( MatrixPtr, RealVector, RealVector, RealVector, RealVector );#elsestatic void SolveComplexMatrix( MatrixPtr, RealVector, RealVector );static void SolveComplexTransposedMatrix( MatrixPtr, RealVector, RealVector );#endif#else /* __STDC__ */static void SolveComplexMatrix();static void SolveComplexTransposedMatrix();#endif /* __STDC__ *//* * SOLVE MATRIX EQUATION * * Performs forward elimination and back substitution to find the * unknown vector from the RHS vector and factored matrix. This * routine assumes that the pivots are associated with the lower * triangular (L) matrix and that the diagonal of the upper triangular * (U) matrix consists of ones. This routine arranges the computation * in different way than is traditionally used in order to exploit the * sparsity of the right-hand side. See the reference in spRevision. * * >>> 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. * This argument is only necessary if matrix is complex and if * spSEPARATED_COMPLEX_VECTOR is set true. * 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. This argument is only necessary if matrix is complex * and if spSEPARATED_COMPLEX_VECTOR is set true. * * >>> 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 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 (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*/voidspSolve( eMatrix, RHS, Solution IMAG_VECTORS )char *eMatrix;RealVector RHS, Solution IMAG_VECTORS;{MatrixPtr Matrix = (MatrixPtr)eMatrix;register ElementPtr pElement;register RealVector Intermediate;register RealNumber Temp;register int I, *pExtOrder, Size;ElementPtr pPivot;void SolveComplexMatrix();/* Begin `spSolve'. */ ASSERT( IS_VALID(Matrix) AND IS_FACTORED(Matrix) );#if spCOMPLEX if (Matrix->Complex) { SolveComplexMatrix( Matrix, RHS, Solution IMAG_VECTORS ); return; }#endif#if REAL Intermediate = Matrix->Intermediate; Size = Matrix->Size;/* Correct array pointers for ARRAY_OFFSET. */#if NOT ARRAY_OFFSET --RHS; --Solution;#endif/* Initialize Intermediate vector. */ pExtOrder = &Matrix->IntToExtRowMap[Size]; for (I = Size; I > 0; I--) Intermediate[I] = RHS[*(pExtOrder--)];/* Forward elimination. Solves Lc = b.*/ for (I = 1; I <= Size; I++) { /* This step of the elimination is skipped if Temp equals zero. */ if ((Temp = Intermediate[I]) != 0.0) { pPivot = Matrix->Diag[I]; Intermediate[I] = (Temp *= pPivot->Real); pElement = pPivot->NextInCol; while (pElement != NULL) { Intermediate[pElement->Row] -= Temp * pElement->Real; 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) { Temp -= pElement->Real * Intermediate[pElement->Col]; pElement = pElement->NextInRow; } Intermediate[I] = Temp; }/* Unscramble Intermediate vector while placing data in to Solution vector. */ pExtOrder = &Matrix->IntToExtColMap[Size]; for (I = Size; I > 0; I--) Solution[*(pExtOrder--)] = Intermediate[I]; return;#endif /* REAL */}#if spCOMPLEX/* * SOLVE COMPLEX MATRIX EQUATION * * Performs forward elimination and back substitution to find the * unknown vector from the RHS vector and factored matrix. This * routine assumes that the pivots are associated with the lower * triangular (L) matrix and that the diagonal of the upper triangular * (U) matrix consists of ones. This routine arranges the computation * in different way than is traditionally used in order to exploit the * sparsity of the right-hand side. See the reference in spRevision. * * >>> Arguments: * Matrix <input> (char *) * Pointer to matrix. * RHS <input> (RealVector) * RHS is the real portion of 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 real portion of 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, 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, 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 voidSolveComplexMatrix( Matrix, RHS, Solution IMAG_VECTORS )MatrixPtr Matrix;RealVector RHS, Solution IMAG_VECTORS;{register ElementPtr pElement;register ComplexVector Intermediate;register int I, *pExtOrder, Size;ElementPtr pPivot;register ComplexVector ExtVector;ComplexNumber Temp;/* Begin `SolveComplexMatrix'. */ 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->IntToExtRowMap[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 substitution. Solves Lc = b.*/ for (I = 1; I <= Size; I++) { Temp = Intermediate[I];/* This step of the substitution is skipped if Temp equals zero. */ if ((Temp.Real != 0.0) OR (Temp.Imag != 0.0)) { pPivot = Matrix->Diag[I];/* Cmplx expr: Temp *= (1.0 / Pivot). */ CMPLX_MULT_ASSIGN(Temp, *pPivot); Intermediate[I] = Temp; pElement = pPivot->NextInCol; while (pElement != NULL) {/* Cmplx expr: Intermediate[Element->Row] -= Temp * *Element. */ CMPLX_MULT_SUBT_ASSIGN(Intermediate[pElement->Row], Temp, *pElement);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -