Jspice3
spsolve.c
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  * >>> Other functions contained in this file:
16  * SolveComplexMatrix
17  * SolveComplexTransposedMatrix
18  */
19 
20 
21 /*
22  * Revision and copyright information.
23  *
24  * Copyright (c) 1985,86,87,88,89,90
25  * by Kenneth S. Kundert and the University of California.
26  *
27  * Permission to use, copy, modify, and distribute this software and
28  * its documentation for any purpose and without fee is hereby granted,
29  * provided that the copyright notices appear in all copies and
30  * supporting documentation and that the authors and the University of
31  * California are properly credited. The authors and the University of
32  * California make no representations as to the suitability of this
33  * software for any purpose. It is provided `as is', without express
34  * or implied warranty.
35  */
36 
37 #ifdef notdef
38 static char copyright[] =
39  "Sparse1.3: Copyright (c) 1985,86,87,88,89,90 by Kenneth S. Kundert";
40 static char RCSid[] =
41  "@(#)$Header: spSolve.c,v 1.3 88/06/24 05:02:49 kundert Exp $";
42 #endif
43 
44 
45 
46 /*
47  * IMPORTS
48  *
49  * >>> Import descriptions:
50  * spConfig.h
51  * Macros that customize the sparse matrix routines.
52  * spMatrix.h
53  * Macros and declarations to be imported by the user.
54  * spDefs.h
55  * Matrix type and macro definitions for the sparse matrix routines.
56  */
57 
58 #define spINSIDE_SPARSE
59 #include "spconfig.h"
60 #include "spmatrix.h"
61 #include "spdefs.h"
62 
63 
64 
65 
66 /*
67  * Function declarations
68  */
69 
70 #ifdef __STDC__
71 #if spSEPARATED_COMPLEX_VECTORS
72 static void SolveComplexMatrix( MatrixPtr,
76 #else
79 #endif
80 #else /* __STDC__ */
81 static void SolveComplexMatrix();
82 static void SolveComplexTransposedMatrix();
83 #endif /* __STDC__ */
84 
85 
86 
87 
88 
89 
90 
91 /*
92  * SOLVE MATRIX EQUATION
93  *
94  * Performs forward elimination and back substitution to find the
95  * unknown vector from the RHS vector and factored matrix. This
96  * routine assumes that the pivots are associated with the lower
97  * triangular (L) matrix and that the diagonal of the upper triangular
98  * (U) matrix consists of ones. This routine arranges the computation
99  * in different way than is traditionally used in order to exploit the
100  * sparsity of the right-hand side. See the reference in spRevision.
101  *
102  * >>> Arguments:
103  * Matrix <input> (char *)
104  * Pointer to matrix.
105  * RHS <input> (RealVector)
106  * RHS is the input data array, the right hand side. This data is
107  * undisturbed and may be reused for other solves.
108  * Solution <output> (RealVector)
109  * Solution is the output data array. This routine is constructed such that
110  * RHS and Solution can be the same array.
111  * iRHS <input> (RealVector)
112  * iRHS is the imaginary portion of the input data array, the right
113  * hand side. This data is undisturbed and may be reused for other solves.
114  * This argument is only necessary if matrix is complex and if
115  * spSEPARATED_COMPLEX_VECTOR is set true.
116  * iSolution <output> (RealVector)
117  * iSolution is the imaginary portion of the output data array. This
118  * routine is constructed such that iRHS and iSolution can be
119  * the same array. This argument is only necessary if matrix is complex
120  * and if spSEPARATED_COMPLEX_VECTOR is set true.
121  *
122  * >>> Local variables:
123  * Intermediate (RealVector)
124  * Temporary storage for use in forward elimination and backward
125  * substitution. Commonly referred to as c, when the LU factorization
126  * equations are given as Ax = b, Lc = b, Ux = c Local version of
127  * Matrix->Intermediate, which was created during the initial
128  * factorization in function spcCreateInternalVectors() in the matrix
129  * factorization module.
130  * pElement (ElementPtr)
131  * Pointer used to address elements in both the lower and upper triangle
132  * matrices.
133  * pExtOrder (int *)
134  * Pointer used to sequentially access each entry in IntToExtRowMap
135  * and IntToExtColMap arrays. Used to quickly scramble and unscramble
136  * RHS and Solution to account for row and column interchanges.
137  * pPivot (ElementPtr)
138  * Pointer that points to current pivot or diagonal element.
139  * Size (int)
140  * Size of matrix. Made local to reduce indirection.
141  * Temp (RealNumber)
142  * Temporary storage for entries in arrays.
143  *
144  * >>> Obscure Macros
145  * IMAG_VECTORS
146  * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and
147  * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears
148  * without a trace.
149  */
150 
151 /*VARARGS3*/
152 
153 void
154 spSolve( eMatrix, RHS, Solution IMAG_VECTORS )
155 
156 char *eMatrix;
158 {
159 MatrixPtr Matrix = (MatrixPtr)eMatrix;
160 register ElementPtr pElement;
162 register RealNumber Temp;
163 register int I, *pExtOrder, Size;
165 void SolveComplexMatrix();
166 
167 /* Begin `spSolve'. */
168  ASSERT( IS_VALID(Matrix) AND IS_FACTORED(Matrix) );
169 
170 #if spCOMPLEX
171  if (Matrix->Complex)
172  { SolveComplexMatrix( Matrix, RHS, Solution IMAG_VECTORS );
173  return;
174  }
175 #endif
176 
177 #if REAL
178  Intermediate = Matrix->Intermediate;
179  Size = Matrix->Size;
180 
181 /* Correct array pointers for ARRAY_OFFSET. */
182 #if NOT ARRAY_OFFSET
183  --RHS;
184  --Solution;
185 #endif
186 
187 /* Initialize Intermediate vector. */
188  pExtOrder = &Matrix->IntToExtRowMap[Size];
189  for (I = Size; I > 0; I--)
190  Intermediate[I] = RHS[*(pExtOrder--)];
191 
192 /* Forward elimination. Solves Lc = b.*/
193  for (I = 1; I <= Size; I++)
194  {
195 /* This step of the elimination is skipped if Temp equals zero. */
196  if ((Temp = Intermediate[I]) != 0.0)
197  { pPivot = Matrix->Diag[I];
198  Intermediate[I] = (Temp *= pPivot->Real);
199 
200  pElement = pPivot->NextInCol;
201  while (pElement != NULL)
202  { Intermediate[pElement->Row] -= Temp * pElement->Real;
203  pElement = pElement->NextInCol;
204  }
205  }
206  }
207 
208 /* Backward Substitution. Solves Ux = c.*/
209  for (I = Size; I > 0; I--)
210  { Temp = Intermediate[I];
211  pElement = Matrix->Diag[I]->NextInRow;
212  while (pElement != NULL)
213  { Temp -= pElement->Real * Intermediate[pElement->Col];
214  pElement = pElement->NextInRow;
215  }
216  Intermediate[I] = Temp;
217  }
218 
219 /* Unscramble Intermediate vector while placing data in to Solution vector. */
220  pExtOrder = &Matrix->IntToExtColMap[Size];
221  for (I = Size; I > 0; I--)
222  Solution[*(pExtOrder--)] = Intermediate[I];
223 
224  return;
225 #endif /* REAL */
226 }
227 
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 #if spCOMPLEX
239 /*
240  * SOLVE COMPLEX MATRIX EQUATION
241  *
242  * Performs forward elimination and back substitution to find the
243  * unknown vector from the RHS vector and factored matrix. This
244  * routine assumes that the pivots are associated with the lower
245  * triangular (L) matrix and that the diagonal of the upper triangular
246  * (U) matrix consists of ones. This routine arranges the computation
247  * in different way than is traditionally used in order to exploit the
248  * sparsity of the right-hand side. See the reference in spRevision.
249  *
250  * >>> Arguments:
251  * Matrix <input> (char *)
252  * Pointer to matrix.
253  * RHS <input> (RealVector)
254  * RHS is the real portion of the input data array, the right hand
255  * side. This data is undisturbed and may be reused for other solves.
256  * Solution <output> (RealVector)
257  * Solution is the real portion of the output data array. This routine
258  * is constructed such that RHS and Solution can be the same
259  * array.
260  * iRHS <input> (RealVector)
261  * iRHS is the imaginary portion of the input data array, the right
262  * hand side. This data is undisturbed and may be reused for other solves.
263  * If spSEPARATED_COMPLEX_VECTOR is set false, there is no need to
264  * supply this array.
265  * iSolution <output> (RealVector)
266  * iSolution is the imaginary portion of the output data array. This
267  * routine is constructed such that iRHS and iSolution can be
268  * the same array. If spSEPARATED_COMPLEX_VECTOR is set false, there is no
269  * need to supply this array.
270  *
271  * >>> Local variables:
272  * Intermediate (ComplexVector)
273  * Temporary storage for use in forward elimination and backward
274  * substitution. Commonly referred to as c, when the LU factorization
275  * equations are given as Ax = b, Lc = b, Ux = c.
276  * Local version of Matrix->Intermediate, which was created during
277  * the initial factorization in function spcCreateInternalVectors() in the
278  * matrix factorization module.
279  * pElement (ElementPtr)
280  * Pointer used to address elements in both the lower and upper triangle
281  * matrices.
282  * pExtOrder (int *)
283  * Pointer used to sequentially access each entry in IntToExtRowMap
284  * and IntToExtColMap arrays. Used to quickly scramble and unscramble
285  * RHS and Solution to account for row and column interchanges.
286  * pPivot (ElementPtr)
287  * Pointer that points to current pivot or diagonal element.
288  * Size (int)
289  * Size of matrix. Made local to reduce indirection.
290  * Temp (ComplexNumber)
291  * Temporary storage for entries in arrays.
292  *
293  * >>> Obscure Macros
294  * IMAG_VECTORS
295  * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and
296  * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears
297  * without a trace.
298  */
299 
300 static void
301 SolveComplexMatrix( Matrix, RHS, Solution IMAG_VECTORS )
302 
303 MatrixPtr Matrix;
304 RealVector RHS, Solution IMAG_VECTORS;
305 {
306 register ElementPtr pElement;
307 register ComplexVector Intermediate;
308 register int I, *pExtOrder, Size;
310 register ComplexVector ExtVector;
312 
313 /* Begin `SolveComplexMatrix'. */
314 
315  Size = Matrix->Size;
316  Intermediate = (ComplexVector)Matrix->Intermediate;
317 
318 /* Correct array pointers for ARRAY_OFFSET. */
319 #if NOT ARRAY_OFFSET
321  --RHS; --iRHS;
322  --Solution; --iSolution;
323 #else
324  RHS -= 2; Solution -= 2;
325 #endif
326 #endif
327 
328 /* Initialize Intermediate vector. */
329  pExtOrder = &Matrix->IntToExtRowMap[Size];
330 
332  for (I = Size; I > 0; I--)
333  { Intermediate[I].Real = RHS[*(pExtOrder)];
334  Intermediate[I].Imag = iRHS[*(pExtOrder--)];
335  }
336 #else
337  ExtVector = (ComplexVector)RHS;
338  for (I = Size; I > 0; I--)
339  Intermediate[I] = ExtVector[*(pExtOrder--)];
340 #endif
341 
342 /* Forward substitution. Solves Lc = b.*/
343  for (I = 1; I <= Size; I++)
344  { Temp = Intermediate[I];
345 
346 /* This step of the substitution is skipped if Temp equals zero. */
347  if ((Temp.Real != 0.0) OR (Temp.Imag != 0.0))
348  { pPivot = Matrix->Diag[I];
349 /* Cmplx expr: Temp *= (1.0 / Pivot). */
350  CMPLX_MULT_ASSIGN(Temp, *pPivot);
351  Intermediate[I] = Temp;
352  pElement = pPivot->NextInCol;
353  while (pElement != NULL)
354  {
355 /* Cmplx expr: Intermediate[Element->Row] -= Temp * *Element. */
356  CMPLX_MULT_SUBT_ASSIGN(Intermediate[pElement->Row],
357  Temp, *pElement);
358  pElement = pElement->NextInCol;
359  }
360  }
361  }
362 
363 /* Backward Substitution. Solves Ux = c.*/
364  for (I = Size; I > 0; I--)
365  { Temp = Intermediate[I];
366  pElement = Matrix->Diag[I]->NextInRow;
367 
368  while (pElement != NULL)
369  {
370 /* Cmplx expr: Temp -= *Element * Intermediate[Element->Col]. */
371  CMPLX_MULT_SUBT_ASSIGN(Temp, *pElement,Intermediate[pElement->Col]);
372  pElement = pElement->NextInRow;
373  }
374  Intermediate[I] = Temp;
375  }
376 
377 /* Unscramble Intermediate vector while placing data in to Solution vector. */
378  pExtOrder = &Matrix->IntToExtColMap[Size];
379 
380 #if spSEPARATED_COMPLEX_VECTORS
381  for (I = Size; I > 0; I--)
382  { Solution[*(pExtOrder)] = Intermediate[I].Real;
383  iSolution[*(pExtOrder--)] = Intermediate[I].Imag;
384  }
385 #else
386  ExtVector = (ComplexVector)Solution;
387  for (I = Size; I > 0; I--)
388  ExtVector[*(pExtOrder--)] = Intermediate[I];
389 #endif
390 
391  return;
392 }
393 #endif /* spCOMPLEX */
394 
395 
396 
397 
398 
399 
400 
401 
402 
403 
404 
405 
406 
407 
408 #if TRANSPOSE
409 /*
410  * SOLVE TRANSPOSED MATRIX EQUATION
411  *
412  * Performs forward elimination and back substitution to find the
413  * unknown vector from the RHS vector and transposed factored
414  * matrix. This routine is useful when performing sensitivity analysis
415  * on a circuit using the adjoint method. This routine assumes that
416  * the pivots are associated with the untransposed lower triangular
417  * (L) matrix and that the diagonal of the untransposed upper
418  * triangular (U) matrix consists of ones.
419  *
420  * >>> Arguments:
421  * Matrix <input> (char *)
422  * Pointer to matrix.
423  * RHS <input> (RealVector)
424  * RHS is the input data array, the right hand side. This data is
425  * undisturbed and may be reused for other solves.
426  * Solution <output> (RealVector)
427  * Solution is the output data array. This routine is constructed such that
428  * RHS and Solution can be the same array.
429  * iRHS <input> (RealVector)
430  * iRHS is the imaginary portion of the input data array, the right
431  * hand side. This data is undisturbed and may be reused for other solves.
432  * If spSEPARATED_COMPLEX_VECTOR is set false, or if matrix is real, there
433  * is no need to supply this array.
434  * iSolution <output> (RealVector)
435  * iSolution is the imaginary portion of the output data array. This
436  * routine is constructed such that iRHS and iSolution can be
437  * the same array. If spSEPARATED_COMPLEX_VECTOR is set false, or if
438  * matrix is real, there is no need to supply this array.
439  *
440  * >>> Local variables:
441  * Intermediate (RealVector)
442  * Temporary storage for use in forward elimination and backward
443  * substitution. Commonly referred to as c, when the LU factorization
444  * equations are given as Ax = b, Lc = b, Ux = c. Local version of
445  * Matrix->Intermediate, which was created during the initial
446  * factorization in function spcCreateInternalVectors() in the matrix
447  * factorization module.
448  * pElement (ElementPtr)
449  * Pointer used to address elements in both the lower and upper triangle
450  * matrices.
451  * pExtOrder (int *)
452  * Pointer used to sequentially access each entry in IntToExtRowMap
453  * and IntToExtRowMap arrays. Used to quickly scramble and unscramble
454  * RHS and Solution to account for row and column interchanges.
455  * pPivot (ElementPtr)
456  * Pointer that points to current pivot or diagonal element.
457  * Size (int)
458  * Size of matrix. Made local to reduce indirection.
459  * Temp (RealNumber)
460  * Temporary storage for entries in arrays.
461  *
462  * >>> Obscure Macros
463  * IMAG_VECTORS
464  * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and
465  * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears
466  * without a trace.
467  */
468 
469 /*VARARGS3*/
470 
471 void
472 spSolveTransposed( eMatrix, RHS, Solution IMAG_VECTORS )
473 
474 char *eMatrix;
475 RealVector RHS, Solution IMAG_VECTORS;
476 {
477 MatrixPtr Matrix = (MatrixPtr)eMatrix;
478 register ElementPtr pElement;
479 register RealVector Intermediate;
480 register int I, *pExtOrder, Size;
484 
485 /* Begin `spSolveTransposed'. */
486  ASSERT( IS_VALID(Matrix) AND IS_FACTORED(Matrix) );
487 
488 #if spCOMPLEX
489  if (Matrix->Complex)
490  { SolveComplexTransposedMatrix( Matrix, RHS, Solution IMAG_VECTORS );
491  return;
492  }
493 #endif
494 
495 #if REAL
496  Size = Matrix->Size;
497  Intermediate = Matrix->Intermediate;
498 
499 /* Correct array pointers for ARRAY_OFFSET. */
500 #if NOT ARRAY_OFFSET
501  --RHS;
502  --Solution;
503 #endif
504 
505 /* Initialize Intermediate vector. */
506  pExtOrder = &Matrix->IntToExtColMap[Size];
507  for (I = Size; I > 0; I--)
508  Intermediate[I] = RHS[*(pExtOrder--)];
509 
510 /* Forward elimination. */
511  for (I = 1; I <= Size; I++)
512  {
513 /* This step of the elimination is skipped if Temp equals zero. */
514  if ((Temp = Intermediate[I]) != 0.0)
515  { pElement = Matrix->Diag[I]->NextInRow;
516  while (pElement != NULL)
517  { Intermediate[pElement->Col] -= Temp * pElement->Real;
518  pElement = pElement->NextInRow;
519  }
520 
521  }
522  }
523 
524 /* Backward Substitution. */
525  for (I = Size; I > 0; I--)
526  { pPivot = Matrix->Diag[I];
527  Temp = Intermediate[I];
528  pElement = pPivot->NextInCol;
529  while (pElement != NULL)
530  { Temp -= pElement->Real * Intermediate[pElement->Row];
531  pElement = pElement->NextInCol;
532  }
533  Intermediate[I] = Temp * pPivot->Real;
534  }
535 
536 /* Unscramble Intermediate vector while placing data in to Solution vector. */
537  pExtOrder = &Matrix->IntToExtRowMap[Size];
538  for (I = Size; I > 0; I--)
539  Solution[*(pExtOrder--)] = Intermediate[I];
540 
541  return;
542 #endif /* REAL */
543 }
544 #endif /* TRANSPOSE */
545 
546 
547 
548 
549 
550 
551 
552 
553 
554 
555 #if TRANSPOSE AND spCOMPLEX
556 /*
557  * SOLVE COMPLEX TRANSPOSED MATRIX EQUATION
558  *
559  * Performs forward elimination and back substitution to find the
560  * unknown vector from the RHS vector and transposed factored
561  * matrix. This routine is useful when performing sensitivity analysis
562  * on a circuit using the adjoint method. This routine assumes that
563  * the pivots are associated with the untransposed lower triangular
564  * (L) matrix and that the diagonal of the untransposed upper
565  * triangular (U) matrix consists of ones.
566  *
567  * >>> Arguments:
568  * Matrix <input> (char *)
569  * Pointer to matrix.
570  * RHS <input> (RealVector)
571  * RHS is the input data array, the right hand
572  * side. This data is undisturbed and may be reused for other solves.
573  * This vector is only the real portion if the matrix is complex and
574  * spSEPARATED_COMPLEX_VECTORS is set true.
575  * Solution <output> (RealVector)
576  * Solution is the real portion of the output data array. This routine
577  * is constructed such that RHS and Solution can be the same array.
578  * This vector is only the real portion if the matrix is complex and
579  * spSEPARATED_COMPLEX_VECTORS is set true.
580  * iRHS <input> (RealVector)
581  * iRHS is the imaginary portion of the input data array, the right
582  * hand side. This data is undisturbed and may be reused for other solves.
583  * If either spCOMPLEX or spSEPARATED_COMPLEX_VECTOR is set false, there
584  * is no need to supply this array.
585  * iSolution <output> (RealVector)
586  * iSolution is the imaginary portion of the output data array. This
587  * routine is constructed such that iRHS and iSolution can be
588  * the same array. If spCOMPLEX or spSEPARATED_COMPLEX_VECTOR is set
589  * false, there is no need to supply this array.
590  *
591  * >>> Local variables:
592  * Intermediate (ComplexVector)
593  * Temporary storage for use in forward elimination and backward
594  * substitution. Commonly referred to as c, when the LU factorization
595  * equations are given as Ax = b, Lc = b, Ux = c. Local version of
596  * Matrix->Intermediate, which was created during
597  * the initial factorization in function spcCreateInternalVectors() in the
598  * matrix factorization module.
599  * pElement (ElementPtr)
600  * Pointer used to address elements in both the lower and upper triangle
601  * matrices.
602  * pExtOrder (int *)
603  * Pointer used to sequentially access each entry in IntToExtRowMap
604  * and IntToExtColMap arrays. Used to quickly scramble and unscramble
605  * RHS and Solution to account for row and column interchanges.
606  * pPivot (ElementPtr)
607  * Pointer that points to current pivot or diagonal element.
608  * Size (int)
609  * Size of matrix. Made local to reduce indirection.
610  * Temp (ComplexNumber)
611  * Temporary storage for entries in arrays.
612  *
613  * >>> Obscure Macros
614  * IMAG_VECTORS
615  * Replaces itself with `, iRHS, iSolution' if the options spCOMPLEX and
616  * spSEPARATED_COMPLEX_VECTORS are set, otherwise it disappears
617  * without a trace.
618  */
619 
620 static void
621 SolveComplexTransposedMatrix(Matrix, RHS, Solution IMAG_VECTORS )
622 
623 MatrixPtr Matrix;
624 RealVector RHS, Solution IMAG_VECTORS;
625 {
626 register ElementPtr pElement;
627 register ComplexVector Intermediate;
628 register int I, *pExtOrder, Size;
629 register ComplexVector ExtVector;
632 
633 /* Begin `SolveComplexTransposedMatrix'. */
634 
635  Size = Matrix->Size;
636  Intermediate = (ComplexVector)Matrix->Intermediate;
637 
638 /* Correct array pointers for ARRAY_OFFSET. */
639 #if NOT ARRAY_OFFSET
641  --RHS; --iRHS;
642  --Solution; --iSolution;
643 #else
644  RHS -= 2; Solution -= 2;
645 #endif
646 #endif
647 
648 /* Initialize Intermediate vector. */
649  pExtOrder = &Matrix->IntToExtColMap[Size];
650 
652  for (I = Size; I > 0; I--)
653  { Intermediate[I].Real = RHS[*(pExtOrder)];
654  Intermediate[I].Imag = iRHS[*(pExtOrder--)];
655  }
656 #else
657  ExtVector = (ComplexVector)RHS;
658  for (I = Size; I > 0; I--)
659  Intermediate[I] = ExtVector[*(pExtOrder--)];
660 #endif
661 
662 /* Forward elimination. */
663  for (I = 1; I <= Size; I++)
664  { Temp = Intermediate[I];
665 
666 /* This step of the elimination is skipped if Temp equals zero. */
667  if ((Temp.Real != 0.0) OR (Temp.Imag != 0.0))
668  { pElement = Matrix->Diag[I]->NextInRow;
669  while (pElement != NULL)
670  {
671 /* Cmplx expr: Intermediate[Element->Col] -= Temp * *Element. */
672  CMPLX_MULT_SUBT_ASSIGN( Intermediate[pElement->Col],
673  Temp, *pElement);
674  pElement = pElement->NextInRow;
675  }
676  }
677  }
678 
679 /* Backward Substitution. */
680  for (I = Size; I > 0; I--)
681  { pPivot = Matrix->Diag[I];
682  Temp = Intermediate[I];
683  pElement = pPivot->NextInCol;
684 
685  while (pElement != NULL)
686  {
687 /* Cmplx expr: Temp -= Intermediate[Element->Row] * *Element. */
688  CMPLX_MULT_SUBT_ASSIGN(Temp,Intermediate[pElement->Row],*pElement);
689 
690  pElement = pElement->NextInCol;
691  }
692 /* Cmplx expr: Intermediate = Temp * (1.0 / *pPivot). */
693  CMPLX_MULT(Intermediate[I], Temp, *pPivot);
694  }
695 
696 /* Unscramble Intermediate vector while placing data in to Solution vector. */
697  pExtOrder = &Matrix->IntToExtRowMap[Size];
698 
699 #if spSEPARATED_COMPLEX_VECTORS
700  for (I = Size; I > 0; I--)
701  { Solution[*(pExtOrder)] = Intermediate[I].Real;
702  iSolution[*(pExtOrder--)] = Intermediate[I].Imag;
703  }
704 #else
705  ExtVector = (ComplexVector)Solution;
706  for (I = Size; I > 0; I--)
707  ExtVector[*(pExtOrder--)] = Intermediate[I];
708 #endif
709 
710  return;
711 }
712 #endif /* TRANSPOSE AND spCOMPLEX */
#define CMPLX_MULT_ASSIGN(to, from)
Definition: spdefs.h:241
#define IS_FACTORED(matrix)
Definition: spdefs.h:131
int Size
Definition: spdefs.h:859
register int * pExtOrder
Definition: spsolve.c:163
#define spSEPARATED_COMPLEX_VECTORS
Definition: spconfig.h:285
RealNumber Real
Definition: spdefs.h:539
spREAL * RealVector
Definition: spdefs.h:458
struct ComplexNumber * ComplexVector
RealVector Solution IMAG_VECTORS
Definition: spsolve.c:157
#define CMPLX_MULT_SUBT_ASSIGN(to, from_a, from_b)
Definition: spdefs.h:297
struct MatrixElement * NextInCol
Definition: spdefs.h:547
#define IS_VALID(matrix)
Definition: spdefs.h:127
ASSERT(IS_VALID(Matrix) AND IS_FACTORED(Matrix))
RealNumber Imag
Definition: spdefs.h:483
#define NULL
Definition: spdefs.h:121
#define OR
Definition: fteparse.h:93
register ElementPtr pElement
Definition: spsolve.c:158
static void SolveComplexTransposedMatrix()
int * IntToExtColMap
Definition: spdefs.h:840
register int Size
Definition: spsolve.c:163
int * IntToExtRowMap
Definition: spdefs.h:841
BOOLEAN Complex
Definition: spdefs.h:823
RealVector Intermediate
Definition: spdefs.h:838
RealNumber Real
Definition: spdefs.h:482
void spSolveTransposed()
spREAL RealNumber
Definition: spdefs.h:458
void spSolve(eMatrix, RHS, Solution IMAG_VECTORS) char *eMatrix
RealVector RHS
Definition: spsolve.c:157
static void SolveComplexMatrix()
struct MatrixElement * NextInRow
Definition: spdefs.h:546
ArrayOfElementPtrs Diag
Definition: spdefs.h:825
#define NOT
Definition: fteparse.h:94
register int I
Definition: spsolve.c:163
register RealNumber Temp
Definition: spsolve.c:162
struct MatrixFrame * MatrixPtr
Definition: spdefs.h:871
#define CMPLX_MULT(to, from_a, from_b)
Definition: spdefs.h:233
ElementPtr pPivot
Definition: spsolve.c:164
register RealVector Intermediate
Definition: spsolve.c:161
#define AND
Definition: fteparse.h:92