NEURON
spsolve.cpp
Go to the documentation of this file.
1 /*
2  * MATRIX SOLVE MODULE
3  *
4  * Author: Advising professor:
5  * Kenneth S. Kundert Alberto Sangiovanni-Vincentelli
6  * UC Berkeley
7  *
8  * This file contains the forward and backward substitution routines for
9  * the sparse matrix routines.
10  *
11  * >>> User accessible functions contained in this file:
12  * spSolve
13  * spSolveTransposed
14  */
15 
16 /*
17  * Revision and copyright information.
18  *
19  * Copyright (c) 1985,86,87,88
20  * by Kenneth S. Kundert and the University of California.
21  *
22  * Permission to use, copy, modify, and distribute this software and
23  * its documentation for any purpose and without fee is hereby granted,
24  * provided that the copyright notices appear in all copies and
25  * supporting documentation and that the authors and the University of
26  * California are properly credited. The authors and the University of
27  * California make no representations as to the suitability of this
28  * software for any purpose. It is provided `as is', without express
29  * or implied warranty.
30  */
31 
32 /*
33  * IMPORTS
34  *
35  * >>> Import descriptions:
36  * spconfig.h
37  * Macros that customize the sparse matrix routines.
38  * spmatrix.h
39  * Macros and declarations to be imported by the user.
40  * spdefs.h
41  * Matrix type and macro definitions for the sparse matrix routines.
42  */
43 
44 #define spINSIDE_SPARSE
45 #include "spconfig.h"
46 #include "spdefs.h"
47 #include "spmatrix.h"
48 
49 /*
50  * SOLVE MATRIX EQUATION
51  *
52  * Performs forward elimination and back substitution to find the
53  * unknown vector from the RHS vector and factored matrix. This
54  * routine assumes that the pivots are associated with the lower
55  * triangular (L) matrix and that the diagonal of the upper triangular
56  * (U) matrix consists of ones. This routine arranges the computation
57  * in different way than is traditionally used in order to exploit the
58  * sparsity of the right-hand side. See the reference in spRevision.
59  *
60  * >>> Arguments:
61  * Matrix <input> (char *)
62  * Pointer to matrix.
63  * RHS <input> (RealVector)
64  * RHS is the input data array, the right hand side. This data is
65  * undisturbed and may be reused for other solves.
66  * Solution <output> (RealVector)
67  * Solution is the output data array. This routine is constructed such that
68  * RHS and Solution can be the same array.
69  * iRHS <optional input> (RealVector)
70  * iRHS is the imaginary portion of the input data array, the right
71  * hand side. This data is undisturbed and may be reused for other solves.
72  * This argument is only necessary if matrix is complex and if
73  * spSEPARATED_COMPLEX_VECTOR is set true.
74  * iSolution <optional output> (RealVector)
75  * iSolution is the imaginary portion of the output data array. This
76  * routine is constructed such that iRHS and iSolution can be
77  * the same array. This argument is only necessary if matrix is complex
78  * and if spSEPARATED_COMPLEX_VECTOR is set true.
79  *
80  * >>> Local variables:
81  * Intermediate (RealVector)
82  * Temporary storage for use in forward elimination and backward
83  * substitution. Commonly referred to as c, when the LU factorization
84  * equations are given as Ax = b, Lc = b, Ux = c Local version of
85  * Matrix->Intermediate, which was created during the initial
86  * factorization in function CreateInternalVectors() in the matrix
87  * factorization module.
88  * pElement (ElementPtr)
89  * Pointer used to address elements in both the lower and upper triangle
90  * matrices.
91  * pExtOrder (int *)
92  * Pointer used to sequentially access each entry in IntToExtRowMap
93  * and IntToExtColMap arrays. Used to quickly scramble and unscramble
94  * RHS and Solution to account for row and column interchanges.
95  * pPivot (ElementPtr)
96  * Pointer that points to current pivot or diagonal element.
97  * Size (int)
98  * Size of matrix. Made local to reduce indirection.
99  * Temp (RealNumber)
100  * Temporary storage for entries in arrays.
101  */
102 
103 /*VARARGS3*/
104 void spSolve(char* eMatrix, RealVector RHS, RealVector Solution, std::optional<RealVector> iRHS, std::optional<RealVector> iSolution)
105 {
106  MatrixPtr Matrix = (MatrixPtr)eMatrix;
107  ElementPtr pElement;
108  RealVector Intermediate;
109  RealNumber Temp;
110  int I, *pExtOrder, Size;
111  ElementPtr pPivot;
112 
113  /* Begin `spSolve'. */
115 
116 
117 #if REAL
118  Intermediate = Matrix->Intermediate;
119  Size = Matrix->Size;
120 
121 /* Correct array pointers for ARRAY_OFFSET. */
122 #if NOT ARRAY_OFFSET
123  --RHS;
124  --Solution;
125 #endif
126 
127  /* Initialize Intermediate vector. */
128  pExtOrder = &Matrix->IntToExtRowMap[Size];
129  for (I = Size; I > 0; I--)
130  Intermediate[I] = RHS[*(pExtOrder--)];
131 
132  /* Forward elimination. Solves Lc = b.*/
133  for (I = 1; I <= Size; I++) {
134  /* This step of the elimination is skipped if Temp equals zero. */
135  if ((Temp = Intermediate[I]) != 0.0) {
136  pPivot = Matrix->Diag[I];
137  Intermediate[I] = (Temp *= pPivot->Real);
138 
139  pElement = pPivot->NextInCol;
140  while (pElement != NULL) {
141  Intermediate[pElement->Row] -= Temp * pElement->Real;
142  pElement = pElement->NextInCol;
143  }
144  }
145  }
146 
147  /* Backward Substitution. Solves Ux = c.*/
148  for (I = Size; I > 0; I--) {
149  Temp = Intermediate[I];
150  pElement = Matrix->Diag[I]->NextInRow;
151  while (pElement != NULL) {
152  Temp -= pElement->Real * Intermediate[pElement->Col];
153  pElement = pElement->NextInRow;
154  }
155  Intermediate[I] = Temp;
156  }
157 
158  /* Unscramble Intermediate vector while placing data in to Solution vector. */
159  pExtOrder = &Matrix->IntToExtColMap[Size];
160  for (I = Size; I > 0; I--)
161  Solution[*(pExtOrder--)] = Intermediate[I];
162 
163  return;
164 #endif /* REAL */
165 }
166 
167 #if TRANSPOSE
168 /*
169  * SOLVE TRANSPOSED MATRIX EQUATION
170  *
171  * Performs forward elimination and back substitution to find the
172  * unknown vector from the RHS vector and transposed factored
173  * matrix. This routine is useful when performing sensitivity analysis
174  * on a circuit using the adjoint method. This routine assumes that
175  * the pivots are associated with the untransposed lower triangular
176  * (L) matrix and that the diagonal of the untransposed upper
177  * triangular (U) matrix consists of ones.
178  *
179  * >>> Arguments:
180  * Matrix <input> (char *)
181  * Pointer to matrix.
182  * RHS <input> (RealVector)
183  * RHS is the input data array, the right hand side. This data is
184  * undisturbed and may be reused for other solves.
185  * Solution <output> (RealVector)
186  * Solution is the output data array. This routine is constructed such that
187  * RHS and Solution can be the same array.
188  * iRHS <optional input> (RealVector)
189  * iRHS is the imaginary portion of the input data array, the right
190  * hand side. This data is undisturbed and may be reused for other solves.
191  * If spSEPARATED_COMPLEX_VECTOR is set false, or if matrix is real, there
192  * is no need to supply this array.
193  * iSolution <optional output> (RealVector)
194  * iSolution is the imaginary portion of the output data array. This
195  * routine is constructed such that iRHS and iSolution can be
196  * the same array. If spSEPARATED_COMPLEX_VECTOR is set false, or if
197  * matrix is real, there is no need to supply this array.
198  *
199  * >>> Local variables:
200  * Intermediate (RealVector)
201  * Temporary storage for use in forward elimination and backward
202  * substitution. Commonly referred to as c, when the LU factorization
203  * equations are given as Ax = b, Lc = b, Ux = c. Local version of
204  * Matrix->Intermediate, which was created during the initial
205  * factorization in function CreateInternalVectors() in the matrix
206  * factorization module.
207  * pElement (ElementPtr)
208  * Pointer used to address elements in both the lower and upper triangle
209  * matrices.
210  * pExtOrder (int *)
211  * Pointer used to sequentially access each entry in IntToExtRowMap
212  * and IntToExtRowMap arrays. Used to quickly scramble and unscramble
213  * RHS and Solution to account for row and column interchanges.
214  * pPivot (ElementPtr)
215  * Pointer that points to current pivot or diagonal element.
216  * Size (int)
217  * Size of matrix. Made local to reduce indirection.
218  * Temp (RealNumber)
219  * Temporary storage for entries in arrays.
220  *
221  */
222 
223 /*VARARGS3*/
224 
225 void spSolveTransposed(char* eMatrix, RealVector RHS, RealVector Solution, std::optional<RealVector> iRHS, std::optional<RealVector> iSolution)
226 {
227  MatrixPtr Matrix = (MatrixPtr)eMatrix;
228  ElementPtr pElement;
229  RealVector Intermediate;
230  int I, *pExtOrder, Size;
231  ElementPtr pPivot;
232  RealNumber Temp;
233 
234  /* Begin `spSolveTransposed'. */
236 
237 #if REAL
238  Size = Matrix->Size;
239  Intermediate = Matrix->Intermediate;
240 
241 /* Correct array pointers for ARRAY_OFFSET. */
242 #if NOT ARRAY_OFFSET
243  --RHS;
244  --Solution;
245 #endif
246 
247  /* Initialize Intermediate vector. */
248  pExtOrder = &Matrix->IntToExtColMap[Size];
249  for (I = Size; I > 0; I--)
250  Intermediate[I] = RHS[*(pExtOrder--)];
251 
252  /* Forward elimination. */
253  for (I = 1; I <= Size; I++) {
254  /* This step of the elimination is skipped if Temp equals zero. */
255  if ((Temp = Intermediate[I]) != 0.0) {
256  pElement = Matrix->Diag[I]->NextInRow;
257  while (pElement != NULL) {
258  Intermediate[pElement->Col] -= Temp * pElement->Real;
259  pElement = pElement->NextInRow;
260  }
261  }
262  }
263 
264  /* Backward Substitution. */
265  for (I = Size; I > 0; I--) {
266  pPivot = Matrix->Diag[I];
267  Temp = Intermediate[I];
268  pElement = pPivot->NextInCol;
269  while (pElement != NULL) {
270  Temp -= pElement->Real * Intermediate[pElement->Row];
271  pElement = pElement->NextInCol;
272  }
273  Intermediate[I] = Temp * pPivot->Real;
274  }
275 
276  /* Unscramble Intermediate vector while placing data in to Solution vector. */
277  pExtOrder = &Matrix->IntToExtRowMap[Size];
278  for (I = Size; I > 0; I--)
279  Solution[*(pExtOrder--)] = Intermediate[I];
280 
281  return;
282 #endif /* REAL */
283 }
284 #endif /* TRANSPOSE */
#define RHS(i)
Definition: multisplit.cpp:57
#define NULL
Definition: spdefs.h:105
struct MatrixFrame * MatrixPtr
Definition: spdefs.h:549
spREAL RealNumber
Definition: spdefs.h:202
#define IS_VALID(matrix)
Definition: spdefs.h:110
#define IS_FACTORED(matrix)
Definition: spdefs.h:111
spREAL * RealVector
Definition: spdefs.h:202
#define ASSERT(condition)
Definition: spdefs.h:151
#define AND
Definition: spdefs.h:100
void spSolve(char *eMatrix, RealVector RHS, RealVector Solution, std::optional< RealVector > iRHS, std::optional< RealVector > iSolution)
Definition: spsolve.cpp:104
void spSolveTransposed(char *eMatrix, RealVector RHS, RealVector Solution, std::optional< RealVector > iRHS, std::optional< RealVector > iSolution)
Definition: spsolve.cpp:225
RealNumber Real
Definition: spdefs.h:245
struct MatrixElement * NextInCol
Definition: spdefs.h:249
struct MatrixElement * NextInRow
Definition: spdefs.h:248