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